PR #25088 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25088 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25088.patch
>From 9fed68c38e0a281195ce6e0ce931b5c2fdd2d4dd Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 12 Oct 2026 03:12:36 +0200 Subject: [PATCH 1/6] cosmetics: avcodec/vvc/ps: factor the tile scans of subpic_tiles() into a helper --- libavcodec/vvc/ps.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c index d40c8050db..460877246e 100644 --- a/libavcodec/vvc/ps.c +++ b/libavcodec/vvc/ps.c @@ -438,28 +438,26 @@ static int pps_single_slice_picture(VVCPPS *pps, int *off) return 0; } +static int tile_at_or_after(const uint16_t *bd, const int ctb_pos) +{ + int tile = 0; + + while (bd[tile] < ctb_pos) + tile++; + + return tile; +} + static void subpic_tiles(int *tile_x, int *tile_y, int *tile_x_end, int *tile_y_end, const VVCSPS *sps, const VVCPPS *pps, const int i) { const int rx = sps->r->sps_subpic_ctu_top_left_x[i]; const int ry = sps->r->sps_subpic_ctu_top_left_y[i]; - *tile_x = *tile_y = 0; - - while (pps->col_bd[*tile_x] < rx) - (*tile_x)++; - - while (pps->row_bd[*tile_y] < ry) - (*tile_y)++; - - *tile_x_end = (*tile_x); - *tile_y_end = (*tile_y); - - while (pps->col_bd[*tile_x_end] < rx + sps->r->sps_subpic_width_minus1[i] + 1) - (*tile_x_end)++; - - while (pps->row_bd[*tile_y_end] < ry + sps->r->sps_subpic_height_minus1[i] + 1) - (*tile_y_end)++; + *tile_x = tile_at_or_after(pps->col_bd, rx); + *tile_y = tile_at_or_after(pps->row_bd, ry); + *tile_x_end = tile_at_or_after(pps->col_bd, rx + sps->r->sps_subpic_width_minus1[i] + 1); + *tile_y_end = tile_at_or_after(pps->row_bd, ry + sps->r->sps_subpic_height_minus1[i] + 1); } static int pps_subpic_less_than_one_tile_slice(VVCPPS *pps, const VVCSPS *sps, const int i, const int tx, const int ty, int *off) -- 2.52.0 >From 75cc10ec9c21b1031cd6415bf134553a83c6ff61 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 12 Oct 2026 03:12:36 +0200 Subject: [PATCH 2/6] avcodec/vvc/ps: bound the tile scans in subpic_tiles() Fixes: heap-buffer-overflow (read) Fixes: q0RFgfMenefI Fixes: ANT-2026-HRT03RV0 Fixes: vvc-subpic-tiles.mkv Found-by: Claude and Ada Logics Out of array read Replicated through UnModified FFmpeg with ASAN --- libavcodec/vvc/ps.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c index 460877246e..48468f5019 100644 --- a/libavcodec/vvc/ps.c +++ b/libavcodec/vvc/ps.c @@ -438,11 +438,11 @@ static int pps_single_slice_picture(VVCPPS *pps, int *off) return 0; } -static int tile_at_or_after(const uint16_t *bd, const int ctb_pos) +static int tile_at_or_after(const uint16_t *bd, const int num_tiles, const int ctb_pos) { int tile = 0; - while (bd[tile] < ctb_pos) + while (tile < num_tiles && bd[tile] < ctb_pos) tile++; return tile; @@ -451,13 +451,14 @@ static int tile_at_or_after(const uint16_t *bd, const int ctb_pos) static void subpic_tiles(int *tile_x, int *tile_y, int *tile_x_end, int *tile_y_end, const VVCSPS *sps, const VVCPPS *pps, const int i) { + const H266RawPPS *r = pps->r; const int rx = sps->r->sps_subpic_ctu_top_left_x[i]; const int ry = sps->r->sps_subpic_ctu_top_left_y[i]; - *tile_x = tile_at_or_after(pps->col_bd, rx); - *tile_y = tile_at_or_after(pps->row_bd, ry); - *tile_x_end = tile_at_or_after(pps->col_bd, rx + sps->r->sps_subpic_width_minus1[i] + 1); - *tile_y_end = tile_at_or_after(pps->row_bd, ry + sps->r->sps_subpic_height_minus1[i] + 1); + *tile_x = tile_at_or_after(pps->col_bd, r->num_tile_columns, rx); + *tile_y = tile_at_or_after(pps->row_bd, r->num_tile_rows, ry); + *tile_x_end = tile_at_or_after(pps->col_bd, r->num_tile_columns, rx + sps->r->sps_subpic_width_minus1[i] + 1); + *tile_y_end = tile_at_or_after(pps->row_bd, r->num_tile_rows, ry + sps->r->sps_subpic_height_minus1[i] + 1); } static int pps_subpic_less_than_one_tile_slice(VVCPPS *pps, const VVCSPS *sps, const int i, const int tx, const int ty, int *off) -- 2.52.0 >From d7e92ccd248b7cbd4eda1d33b9ca8cab70843f86 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 01:42:48 +0200 Subject: [PATCH 3/6] avcodec/vvc/refs: take the SPS and PPS references only once the frame buffer is allocated Found during triage/review of the security report q0RFgfMenefI (ANT-2026-HRT03RV0), whose control file vvc-subpic-control-corner.mkv triggers it. Fixes: memleak Regression since: e70225e0a8 Memleak Replicated through UnModified FFmpeg with ASAN --- libavcodec/vvc/refs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/vvc/refs.c b/libavcodec/vvc/refs.c index 6939a22732..c50cd32f5c 100644 --- a/libavcodec/vvc/refs.c +++ b/libavcodec/vvc/refs.c @@ -130,9 +130,6 @@ static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc) if (frame->frame->buf[0]) continue; - frame->sps = av_refstruct_ref_c(fc->ps.sps); - frame->pps = av_refstruct_ref_c(fc->ps.pps); - // Add LCEVC SEI metadata here, as it's needed in get_buffer() if (fc->sei.common.itut_t35.lcevc) { ret = ff_frame_new_side_data_from_buf(s->avctx, frame->frame, @@ -145,6 +142,9 @@ static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc) if (ret < 0) return NULL; + frame->sps = av_refstruct_ref_c(fc->ps.sps); + frame->pps = av_refstruct_ref_c(fc->ps.pps); + frame->rpl = av_refstruct_allocz(s->current_frame.nb_units * sizeof(RefPicListTab)); if (!frame->rpl) goto fail; -- 2.52.0 >From c011eb335fbd3b77bba03b76e88b991de56ea150 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 12 Oct 2026 03:04:40 +0200 Subject: [PATCH 4/6] 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 --- libavcodec/aac/aacdec_usac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index 5c6d04226d..021f817fb8 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -588,6 +588,10 @@ int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx, } usac->core_sbr_frame_len_idx = get_bits(gb, 3); /* coreSbrFrameLengthIndex */ + if (usac->core_sbr_frame_len_idx == 2 || usac->core_sbr_frame_len_idx == 4) { + avpriv_report_missing_feature(avctx, "USAC SBR with a ratio other than 2:1"); + return AVERROR_PATCHWELCOME; + } m4ac->frame_length_short = usac->core_sbr_frame_len_idx == 0 || usac->core_sbr_frame_len_idx == 2; -- 2.52.0 >From bffe2639b0be1fc6513bf65b030a84d569489551 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 12 Oct 2026 03:04:40 +0200 Subject: [PATCH 5/6] 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. --- libavcodec/aac/aacdec_usac.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index 021f817fb8..ae63761030 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -1875,12 +1875,12 @@ static int decode_usac_core_coder(AACDecContext *ac, AACUSACConfig *usac, } } - if (ec->sbr.ratio) { - int sbr_ch = nb_channels; - if (nb_channels == 2 && - !(ec->stereo_config_index == 0 || ec->stereo_config_index == 3)) - sbr_ch = 1; + int sbr_ch = nb_channels; + if (nb_channels == 2 && + !(ec->stereo_config_index == 0 || ec->stereo_config_index == 3)) + sbr_ch = 1; + if (ec->sbr.ratio) { ret = ff_aac_sbr_decode_usac_data(ac, che, ec, gb, sbr_ch, indep_flag); if (ret < 0) return ret; @@ -1895,11 +1895,16 @@ static int decode_usac_core_coder(AACDecContext *ac, AACUSACConfig *usac, spectrum_decode(ac, usac, che, core_nb_channels); if (ac->oc[1].m4ac.sbr > 0) { - ac->proc.sbr_apply(ac, che, nb_channels == 2 ? TYPE_CPE : TYPE_SCE, 0, + ac->proc.sbr_apply(ac, che, sbr_ch == 2 ? TYPE_CPE : TYPE_SCE, 0, che->ch[0].output, che->ch[1].output); } + /* The MPS212 upmix is not implemented, output the downmix on both channels */ + if (sbr_ch < nb_channels) + memcpy(che->ch[1].output, che->ch[0].output, + ac->frame->nb_samples * sizeof(*che->ch[0].output)); + return 0; } -- 2.52.0 >From 99bee15833d15a9977bcc7865b5c73661dd4f132 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 12 Oct 2026 03:04:40 +0200 Subject: [PATCH 6/6] 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. --- libavcodec/aac/aacdec_usac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index ae63761030..a11e4b5ffc 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -1788,7 +1788,8 @@ static int decode_usac_core_coder(AACDecContext *ac, AACUSACConfig *usac, ret = ff_aac_ldp_parse_channel_stream(ac, usac, ue, gb); if (ret < 0) return ret; - continue; + avpriv_report_missing_feature(ac->avctx, "AAC USAC LPD"); + return AVERROR_PATCHWELCOME; } if ((core_nb_channels == 1) || -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
