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 {