Commit 88117dbe4c for ffmpeg

commit 88117dbe4c338c0612c15bb9dbde3dc5fb60adf9
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Sun Oct 11 07:19:20 2026 +0200

    avcodec/aac/aacdec_usac: do not store the custom channel layout in the output configuration

    OutputConfiguration is copied by value between oc[0] and oc[1]. A custom
    channel layout built from bsOutputChannelPos that cannot be retyped to a
    native layout owns a heap allocated map, the copies alias it and it is
    freed twice.

    The layout only reaches avctx->ch_layout and is replaced by the one derived
    from the elements when the configuration is parsed completely.

    Fixes: double free
    Fixes: Qn47KDJBCeGk
    Regression since: eee5fa0808
    Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24677
    Double free Replicated through UnModified FFmpeg with ASAN

diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c
index 7a34cf63d3..3587c76c07 100644
--- a/libavcodec/aac/aacdec_usac.c
+++ b/libavcodec/aac/aacdec_usac.c
@@ -625,24 +625,22 @@ int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx,
         if (nb_channels > 64)
             return AVERROR(EINVAL);

-        av_channel_layout_uninit(&ac->oc[1].ch_layout);
+        AVChannelLayout ch_layout = { 0 };

-        ret = av_channel_layout_custom_init(&ac->oc[1].ch_layout, nb_channels);
+        ret = av_channel_layout_custom_init(&ch_layout, nb_channels);
         if (ret < 0)
             return ret;

         for (int i = 0; i < nb_channels; i++) {
-            AVChannelCustom *cm = &ac->oc[1].ch_layout.u.map[i];
+            AVChannelCustom *cm = &ch_layout.u.map[i];
             cm->id = usac_ch_pos_to_av[get_bits(gb, 5)]; /* bsOutputChannelPos */
         }

-        ret = av_channel_layout_retype(&ac->oc[1].ch_layout,
-                                       AV_CHANNEL_ORDER_NATIVE,
+        ret = av_channel_layout_retype(&ch_layout, AV_CHANNEL_ORDER_NATIVE,
                                        AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
-        if (ret < 0)
-            return ret;
-
-        ret = av_channel_layout_copy(&avctx->ch_layout, &ac->oc[1].ch_layout);
+        if (ret >= 0)
+            ret = av_channel_layout_copy(&avctx->ch_layout, &ch_layout);
+        av_channel_layout_uninit(&ch_layout);
         if (ret < 0)
             return ret;
     } else {