Commit Graph
152 Commits
Author SHA1 Message Date
Romain Beauxis ad74ac4cee avcodec/aac: export the seek pre-roll
AAC decoding overlaps each frame with the previous one, so the first
frame decoded after a seek is only reliable once the frame before it has
been decoded. Opus declares its pre-roll in AVCodecParameters.seek_preroll,
AAC did not.

Have the decoder export its pre-roll, as it knows the frame length: 1024
or 960 samples, half of it for LD and ELD, and 1024 or 768 for USAC.
ELD needs three frames, as its low delay filterbank uses a window four
frames long. SBR keeps the state of the frame before, in its
filterbanks, its high-frequency generator and its gain smoothing, and
codes its envelopes and noise floors relative to the frame before, so
it needs one more frame, of twice as many output samples when it
doubles the sample rate. Without it, the first 256 samples decoded
after a seek into HE-AAC differ from continuous decoding by -36.6 dB
with one frame of pre-roll, and not at all with two.

Implicit SBR is only known once found in a frame, so the pre-roll is
raised then, as it is for USAC, whose frame length depends on its SBR
ratio. Demuxers get it through the stream probing, whatever the
container. A larger pre-roll declared by the container is kept, and the
documentation of AVCodecContext.seek_preroll now says a decoder may
raise it.

The output of an AAC-LC stream decoded after a seek has an error of
-9.5 dB in the first 1024 samples, against -85 dB elsewhere, which one
frame of pre-roll removes.

The pre-roll tests now show the declared value, for AAC in every
container, 4096 samples for HE-AAC, explicit or implicit, 2048 for SBR
that does not double the sample rate, and 1536 for ELD.
2026-10-23 15:38:04 +00:00
Marvin Scholz 8319541103 avcodec/aac: fix null dereference in che_configure
During USAC decoding (ff_aac_usac_decode_frame), configuration elements
can be mapped and instantiated via che_configure(). For newly allocated
ChannelElement structs, che_configure calls sbr_ctx_alloc_init() which
dynamically allocates ac->che[type][id]. However, che_configure did not
subsequently map the output pointer of the nested SingleChannelElement
elements back to their statically-sized internal ret_buf arrays, causing
a null pointer dereference during IMDCT windowing.

The fix explicitly initializes these pointers following allocation.

Signed-off-by: Marvin Scholz <epirat07@gmail.com>
2026-10-21 19:13:48 +00:00
Michael Niedermayer acaba8d7f2 avcodec/aac/aacdec_usac: map USAC channel elements from the UsacConfig only
Fixes: th6ELuT3oDwj
Fixes: wrong channel mapping and rejected frames
Wrong channel mapping and rejected frames Replicated through UnModified FFmpeg with plain output diff
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24677
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24678
2026-10-20 20:41:50 +00:00
Michael Niedermayer 30455d58d2 avcodec/aac: do not keep the frame pointer after decoding
Fixes: use after free
Fixes: MbYbttK2ue35
Regression since: eee5fa0808
Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24678
Use after free Replicated through UnModified FFmpeg with ASAN
2026-10-20 02:25:09 +00:00
Michael Niedermayer 5e42af52ad avcodec/aac/aacdec_usac: reject LPD channel streams
Found during triage/review of the security report GITTfi6VsK4u
(ANT-2026-5KX1BXM6), which does not report this.
2026-10-19 23:40:15 +00:00
Michael Niedermayer 88cb0da84a avcodec/aac/aacdec_usac: apply SBR to the downmix and output it on both channels
Found during triage/review of the security report GITTfi6VsK4u
(ANT-2026-5KX1BXM6), which does not report this.
2026-10-19 23:40:15 +00:00
Michael Niedermayer 0d6ab4c619 avcodec/aac/aacdec_usac: reject SBR ratios other than 2:1
Found during triage/review of the security report GITTfi6VsK4u
(ANT-2026-5KX1BXM6), which does not report this.

Fixes: use of uninitialized memory
Fixes: A-codecs/AAC/xhe-aac/Sintel_24kbps_rap5s.mp4
Use of uninitialized memory Replicated through API with MSAN
2026-10-19 23:40:15 +00:00
Michael Niedermayer 561130d30b avcodec/aac/aacdec_usac_mps212: avoid shifting a negative IPD index
Undefined shift Replicated through API with UBSAN

Fixes: left shift of negative value -1
Fixes: 536321788/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AAC_DEC_fuzzer-4601480396210176
Fixes: IsFvv6HEhVCP

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-10-12 23:55:55 +00:00
Michael Niedermayer dbe7ccee05 avcodec/aac/aacdec_usac: release the extension payload buffers before clearing the configuration
The buffers of fragmented extension payloads were lost when a new
configuration was parsed.

Fixes: memleak
Fixes: yxoDgZkJaJ4D
Regression since: eee5fa0808
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24677
Memleak Replicated through UnModified FFmpeg with ASAN
2026-10-12 21:18:53 +00:00
Michael Niedermayer d314aa0c8f avcodec/aac: do not overwrite avctx->ch_layout when restoring the output configuration
ff_aac_output_configure() copies the restored layout into avctx->ch_layout,
the plain assignment before it dropped whatever avctx->ch_layout owned.

This is hardening, no leak was replicated.
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24677
2026-10-12 21:18:53 +00:00
Michael Niedermayer 88117dbe4c 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
2026-10-12 21:18:53 +00:00
Michael Niedermayer 7442df24f5 avcodec/aac/aacdec_usac: check the return value of ff_aac_output_configure()
ff_aac_usac_decode_frame() went on decoding the frame after the output
configuration failed.

Found during triage/review of a security report.
2026-10-11 00:52:56 +00:00
Michael Niedermayer 694934cc05 avcodec/aac/aacdec_usac: store the element count only after the elements parsed
Fixes: stack buffer overflow
Fixes: CJwFCf3E6R4m
Fixes: ANT-2026-5C280R3A
Fixes: ANT-2026-5C280R3A-attack_a.flv
Fixes: ANT-2026-5C280R3A-attack_b.flv
See: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/22956
Regression since: baad75cafa
Found-by: Claude and Ada Logics
2026-10-11 00:52:56 +00:00
Michael Niedermayer 23316a12ac avcodec/aac/aacdec_usac: check the element list against the channel configuration
Fixes: NULL pointer dereference
Fixes: bMZdbdGgJICu
Fixes: aac_usac_null.mp4
Regression since: eee5fa0808
Found-by: Glops Elemiu
2026-10-03 22:43:51 +00:00
Romain Beauxis 9cee5ae719 avcodec/aac: zero the output of a missing channel element 2026-09-24 15:47:09 +00:00
Lynne a51ec04adf aacdec_usac: parse loudnessInfoV1
Real-world xHE-AAC streams and the ISO/IEC 23003-3 conformance
sequences carry their loudness metadata exclusively as loudnessInfoV1()
inside loudnessInfoSetExtension(), which was previously rejected with
AVERROR_PATCHWELCOME, making such streams undecodable and loudness
normalization inoperative on them.

loudnessInfoV1() is identical to loudnessInfo() apart from an added
eqSetId field. Parse it, restrict measurement selection to
eqSetId == 0 (in line with the downmixId/drcSetId restrictions), and
skip unknown loudnessInfoSetExtension() payloads using their explicitly
coded size instead of erroring out.
2026-06-17 17:34:24 +09:00
Zhao Zhili 1659781894 avcodec/aacdec: fix double-increment of height_tags in loop
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
2026-06-15 17:45:16 +08:00
Lynne f1b4b5b5f6 aacdec_usac: apply volume normalization settings 2026-06-10 18:04:22 +09:00
Lynne 71b59582e2 aacdec_usac: implement basic DRC parameter decoding 2026-06-10 18:04:22 +09:00
James Almer a1e4aee2f0 avcodec/aac/aacdec: support height channels signaled with PCE
Signed-off-by: James Almer <jamrial@gmail.com>
2026-06-02 20:06:00 -03:00
Michael Niedermayer 69c9f1158c avcodec/aac/aacdec_usac: avoid signed overflow in decode_tsd
decode_tsd() computes the binomial coefficient c = C(k, p) incrementally.
this commit makes it less overflow prone

Fixes: 515703905/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AAC_DEC_fuzzer-4890954254581760
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-02 00:59:38 +00:00
Michael Niedermayer e711e60827 avcodec/aac/aacdec: reject decoded frame without a valid sample rate
Later code will turn this into AVERROR_BUG

When returning sample_rate == 0 samples is considered a bug, we have no
nice choice but to error out cleanly

Fixes: assertion failure
Fixes: ffmpeg_AV_CODEC_ID_AAC_DEC_fuzzer crash-0a86d46fef2442b222ee34403c21f7f582ffccb0
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-02 00:59:38 +00:00
Michael Niedermayer 620e59bbec avcodec/aac/aacdec: More detailed warning about sample rates
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-02 00:59:38 +00:00
Michael Niedermayer 263374ac7d avcodec/aac/aacdec_usac: reject explicit usacSamplingFrequency of 0
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-06-02 00:59:38 +00:00
James Almer 79e30c18e6 avcodec/aacdec_tab: add side channels to ff_aac_channel_map
Signed-off-by: James Almer <jamrial@gmail.com>
2026-05-20 13:05:57 -03:00
Andreas Rheinhardt 3cf225b5f8 avcodec/aac/aacdec: Fix shadowing
Reviewed-by: Ramiro Polla <ramiro.polla@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-05-03 18:22:42 +02:00
Andreas Rheinhardt d29cbb87c3 avcodec/aac/aacdec: Add av_fallthrough
Reviewed-by: Ramiro Polla <ramiro.polla@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-05-03 18:22:39 +02:00
Michael Niedermayer 2e32276872 avcodec/aac/aacdec_usac_mps212: fix attach_lsb() OOB after huff_decode
Fixes: VS-FF-2026-0001/poc.wav

Reported-by: Vuln Seeker Cyber Security Team
2026-05-03 15:11:28 +00:00
Marvin Scholz dc7692b831 avcodec/aac: add fall-through annotations 2026-04-28 12:29:37 +00:00
Lynne c1b19ee69f aacdec: add support for 960-frame HE-AAC (DAB+) decoding
Finally, after so many years. I'm sure there's good DAB+ content
out there being broadcast. Go and listen to it.
2026-04-17 16:46:52 +02:00
Michael Niedermayer ddcb9dd3b5 avcodec/aac/aacdec_usac: Implement missing bits of otts_bands_phase and residual_bands computation
Fixes: out of array access
Fixes: matejsmycka/poc.mp4

Introducing commit: `baad75cafa6bac298b72c177f657a2eb8e31cff1` — "aacdec_usac: add support for parsing Mpsp212 (MPEG surround)", 2025-11-17.

Found-by: Matěj Smyčka <matejsmycka@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-31 22:29:18 +00:00
Michael Niedermayer 770bc1c23a avcodec/aac/aacdec_usac_mps212: Introduce a temporary array for ff_aac_ec_data_dec()
This also reverts: c2364e9222

Fixes: out of array access (testcase exists but did not replicate for me)

Founbd-by: Gil Portnoy <dddhkts1@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-14 21:23:53 +01:00
Gil Portnoy e1d9080e6a avcodec/aac/aacdec_usac_mps212: Fix wrong end_band parameter to coarse_to_fine()
note, all call sites set start_band=0, this is thus a cosmetic fix

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-13 23:03:36 +01:00
Gil Portnoy d75b7c2252 avcodec/aac/aacdec_usac_mps212: Fix typo in huff_data_2d()
This is not a security issue

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-13 23:03:36 +01:00
Gil Portnoy 8b9851b005 avcodec/aac/aacdec_usac_mps212: Off-by-one bounds check in ff_aac_ec_data_deci()
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

No testcase, the check seems redundant
2026-03-13 23:03:35 +01:00
Oliver ChangandCodeMender d519ab8993 aacdec_usac: skip FD-specific decoding for LPD channels
`spectrum_decode` currently executes Frequency Domain (FD) decoding steps
for all channels, regardless of their `core_mode`. When a channel is in
Linear Prediction Domain (LPD) mode (`core_mode == 1`), FD-specific
parameters such as scalefactor offsets (`sfo`) and individual channel
stream (`ics`) information are not parsed.

This causes a global-buffer-overflow in `dequant_scalefactors`. Because
`spectrum_scale` is called on LPD channels, it uses stale or
uninitialized `sfo` values to index `ff_aac_pow2sf_tab`. In the reported
crash, a stale `sfo` value of 240 resulted in an index of 440
(240 + POW_SF2_ZERO), exceeding the table's size of 428.

Fix this by ensuring `spectrum_scale` and `imdct_and_windowing` are only
called for channels where `core_mode == 0` (FD).

Co-authored-by: CodeMender <codemender-patching@google.com>
Fixes: https://issues.oss-fuzz.com/486160985
2026-03-13 22:57:25 +01:00
Lynne 7c79c79a50 aacdec_usac_mps212: reject reserved freq_res value 2026-03-11 17:43:09 +00:00
Andreas Rheinhardt 0afa879a69 avcodec/aac/aacdec_usac: Fix shadowing
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-03-10 13:52:19 +01:00
Lynne b8a4d8a18d aacdec_usac_mps212: fix CID 1681700
Fixes Coverity issue #1681700
2026-03-07 11:56:47 +00:00
Lynne c40318d663 aacdec_usac_mps212: Fix CID 1681701
Fixes Coverity issue #1681701
2026-03-07 11:56:47 +00:00
Lynne 46cf8f1873 aacdec_usac_mps212: fix CID 1681703
Fixes Coverity issue #1681703
2026-03-07 11:56:47 +00:00
Lynne 558738a6d0 aacdec_usac_mps212: Fix CID 1681704
Fixes Coverity issue #1681704
2026-03-07 11:56:47 +00:00
Lynne e7e001a804 aacdec_usac_mps212: fix CID 1681705
Fixes Coverity issue #1681705
2026-03-07 11:56:47 +00:00
Michael Niedermayer c2364e9222 avcodec/aac/aacdec_usac_mps212: Fix invalid array index
Without the specification, limiting the index is the best that can be done.

Fixes: out of array access
Fixes: 487591441/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AAC_LATM_fuzzer-6205915698364416

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-07 11:11:52 +00:00
Michael Niedermayer c4ee599760 avcodec/aac/aacdec_usac_mps212: Fix invalid shift
Fixes: left shift of negative value -2
Fixes: 487591441/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AAC_LATM_fuzzer-6205915698364416

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-03-07 11:11:52 +00:00
Lynne baad75cafa aacdec_usac: add support for parsing Mpsp212 (MPEG surround)
This commit adds the full bitstream parsing for Mps212.
2026-02-23 07:57:57 +01:00
Lynne 86977fdb6b aacdec_tab: add Mps212 tables
To be used in the following commit.
2026-02-23 07:57:57 +01:00
Lynne a4ab4a98c4 aacdec_tab: split up tables init 2026-02-23 07:57:57 +01:00
Ruikai Peng be82aef7cc lavc/aacdec_usac: fix CPE channel index in ff_aac_usac_reset_state()
fix a simple index bug in ff_aac_usac_reset_state()
that writes past the end of ChannelElement.ch[2] for CPE

ff_aac_usac_reset_state() loops over channels with j < ch, but
incorrectly takes &che->ch[ch]. For CPE (ch == 2) this becomes
che->ch[2], which is one past the end of ChannelElement.ch[2], and the
subsequent memset() causes an intra-object out-of-bounds write.

index the channel element with the loop variable (j).
2026-01-15 19:32:52 +00:00
Oliver Chang d6458f6a8b avcodec/aacdec: Fix heap-use-after-free in USAC decoding
A heap-use-after-free vulnerability was identified in
`libavcodec/aac/aacdec.c`.  When `che_configure` frees a
`ChannelElement` (`ac->che[type][id]`), it failed to clear all
references to it in `ac->tag_che_map`.  `ac->tag_che_map` caches
pointers to `ChannelElement`s and can contain cross-type mappings (e.g.,
a `TYPE_SCE` tag mapping to a `TYPE_LFE` element).

In a USAC stream reconfiguration scenario, an LFE element was freed, but
a stale pointer remained in `ac->tag_che_map`. Subsequent calls to
`ff_aac_get_che` returned this dangling pointer, leading to a crash in
`decode_usac_core_coder`.

This commit fixes the issue by iterating over the entire
`ac->tag_che_map` in `che_configure` and clearing any entries that point
to the `ChannelElement` about to be freed, ensuring no dangling pointers
remain.

Fixes: https://issues.oss-fuzz.com/issues/440220467
2025-12-04 09:34:32 +00:00