PR #25572 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25572 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25572.patch
>From 317c0513b72002109c5646c73d26b17735bdb1d8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 24 Oct 2026 06:08:23 +0200 Subject: [PATCH 1/6] avcodec/hevc/ps: skip the depth lookup table bits in one step Fixes: GPcB3jXFiizH/testcase/final_dear.hevc Fixes: GPcB3jXFiizH Fixes: AISLE-2026-0150-00055 Fixes: excessive CPU time Excessive CPU time Replicated through UnModified FFmpeg with /usr/bin/time Found-by: Joshua Rogers (AISLE) Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/hevc/ps.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index c303ae4c13c..3341458379f 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -1940,11 +1940,10 @@ static void delta_dlt(GetBitContext *gb, HEVCPPS *pps) len = av_log2(max_diff) + 1; min_diff_minus1 = get_bits(gb, len); } - if (max_diff > (min_diff_minus1 + 1)) - for (int k = 1; k < num_val_delta_dlt; k++) { - len = av_log2(max_diff - (min_diff_minus1 + 1)) + 1; - skip_bits(gb, len); // delta_val_diff_minus_min - } + if (max_diff > (min_diff_minus1 + 1)) { + len = av_log2(max_diff - (min_diff_minus1 + 1)) + 1; + skip_bits_long(gb, (num_val_delta_dlt - 1) * len); // delta_val_diff_minus_min + } } } @@ -1960,8 +1959,7 @@ static int pps_3d_extension(GetBitContext *gb, AVCodecContext *avctx, if (get_bits1(gb)) { // dlt_flag[i] if (!get_bits1(gb)) { // dlt_pred_flag[i] if (get_bits1(gb)) { // dlt_val_flags_present_flag[i] - for (int j = 0; j <= ((1 << (pps->pps_bit_depth_for_depth_layers_minus8 + 8)) - 1); j++) - skip_bits1(gb); // dlt_value_flag[i][j] + skip_bits_long(gb, 1 << (pps->pps_bit_depth_for_depth_layers_minus8 + 8)); // dlt_value_flag[i][j] } else delta_dlt(gb, pps); } -- 2.54.0 >From 84db011975d5278dc48a1b91c683ba7e4cc68db3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 24 Oct 2026 06:08:23 +0200 Subject: [PATCH 2/6] avcodec/aom_film_grain: reject scaling points with a repeated x value The AV1 specification requires the points to be strictly increasing, and the AFGS1 scaling function is undefined for equal x values. Fixes: xaXnd8wemUUh/testcase/afgs1_dup.hevc Fixes: xaXnd8wemUUh Fixes: AISLE-2026-0150-00067 Fixes: division by zero Division by zero Replicated through UnModified FFmpeg with UBSAN Found-by: Joshua Rogers (AISLE) Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/aom_film_grain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/aom_film_grain.c b/libavcodec/aom_film_grain.c index bb60c557741..205e93604f8 100644 --- a/libavcodec/aom_film_grain.c +++ b/libavcodec/aom_film_grain.c @@ -247,7 +247,7 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s, bits_scaling = get_bits(gb, 2) + 5; for (i = 0; i < aom->num_y_points; i++) { y_value += get_bits(gb, bits_inc); - if (y_value > UINT8_MAX) + if (y_value > UINT8_MAX || i && y_value == aom->y_points[i - 1][0]) goto error; aom->y_points[i][0] = y_value; aom->y_points[i][1] = get_bits(gb, bits_scaling); @@ -298,7 +298,7 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s, uv_offset = get_bits(gb, 8); for (i = 0; i < aom->num_uv_points[uv]; i++) { uv_value += get_bits(gb, bits_inc); - if (uv_value > UINT8_MAX) + if (uv_value > UINT8_MAX || i && uv_value == aom->uv_points[uv][i - 1][0]) goto error; aom->uv_points[uv][i][0] = uv_value; aom->uv_points[uv][i][1] = get_bits(gb, bits_scaling) + uv_offset; -- 2.54.0 >From 4596c790bad790c2e5505a2cee73caca2260e3d1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 24 Oct 2026 06:08:23 +0200 Subject: [PATCH 3/6] avcodec/dynamic_hdr_vivid: check the bits left after reading the counts Fixes: wWr5pGP6ODIp/testcase/vivid_short.hevc Fixes: wWr5pGP6ODIp Fixes: AISLE-2026-0150-00259 Truncated payload accepted Replicated through UnModified FFmpeg with ffprobe Found-by: Joshua Rogers (AISLE) Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/dynamic_hdr_vivid.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libavcodec/dynamic_hdr_vivid.c b/libavcodec/dynamic_hdr_vivid.c index 319d13b90a4..20b413a4a58 100644 --- a/libavcodec/dynamic_hdr_vivid.c +++ b/libavcodec/dynamic_hdr_vivid.c @@ -98,16 +98,18 @@ int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t if (tm_params->three_Spline_enable_flag) { AVHDRVivid3SplineParams *three_spline; - if (get_bits_left(gb) < 1 + tm_params->three_Spline_num * (2 + 12 + 28 + 1)) + if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; tm_params->three_Spline_num = get_bits(gb, 1) + 1; if (tm_params->three_Spline_num > FF_ARRAY_ELEMS(tm_params->three_spline)) return AVERROR_INVALIDDATA; for (int j = 0; j < tm_params->three_Spline_num; j++) { three_spline = &tm_params->three_spline[j]; + if (get_bits_left(gb) < 2 + 12 + 10 + 10 + 8) + return AVERROR_INVALIDDATA; three_spline->th_mode = get_bits(gb, 2); if (three_spline->th_mode == 0 || three_spline->th_mode == 2) { - if (get_bits_left(gb) < 8) + if (get_bits_left(gb) < 8 + 12 + 10 + 10 + 8) return AVERROR_INVALIDDATA; three_spline->th_enable_mb = (AVRational){get_bits(gb, 8), 255}; } @@ -120,12 +122,15 @@ int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t } } + if (get_bits_left(gb) < 1) + return AVERROR_INVALIDDATA; params->color_saturation_mapping_flag = get_bits(gb, 1); if (params->color_saturation_mapping_flag) { - if (get_bits_left(gb) < 3 + params->color_saturation_num * 8) + if (get_bits_left(gb) < 3) return AVERROR_INVALIDDATA; - params->color_saturation_num = get_bits(gb, 3); + if (get_bits_left(gb) < params->color_saturation_num * 8) + return AVERROR_INVALIDDATA; for (int i = 0; i < params->color_saturation_num; i++) { params->color_saturation_gain[i] = (AVRational){get_bits(gb, 8), color_saturation_gain_den}; } -- 2.54.0 >From c405c293b75180e2ed6545c43fd1411300003872 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 24 Oct 2026 06:08:53 +0200 Subject: [PATCH 4/6] avcodec/vvc/refs: check the rpl allocation size for overflow Fixes: sapW3mP74hBd/testcase/rpl_wrap.mp4 Fixes: sapW3mP74hBd Fixes: AISLE-2026-0150-00723 Fixes: out of array write Out of array write Replicated through UnModified FFmpeg with ASAN (i386 build) Found-by: Joshua Rogers (AISLE) Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/vvc/refs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/vvc/refs.c b/libavcodec/vvc/refs.c index 4deb489b521..a5a2d28c938 100644 --- a/libavcodec/vvc/refs.c +++ b/libavcodec/vvc/refs.c @@ -145,7 +145,10 @@ static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc) 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)); + size_t rpl_size; + if (av_size_mult(s->current_frame.nb_units, sizeof(RefPicListTab), &rpl_size) < 0) + goto fail; + frame->rpl = av_refstruct_allocz(rpl_size); if (!frame->rpl) goto fail; frame->nb_rpl_elems = s->current_frame.nb_units; -- 2.54.0 >From ec2374290ac2ffcfe4f0e15551d2417374d8bebf Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 24 Oct 2026 06:08:55 +0200 Subject: [PATCH 5/6] avcodec/vvc/refs: reject slices with more active reference indices than list entries H.266 8.3.2 requires num_ref_entries to be at least NumRefIdxActive. Fixes: UfO9ZQ9qW76g/testcase/gdr_rpl2.bit Fixes: UfO9ZQ9qW76g Fixes: AISLE-2026-0150-00775 Fixes: division by zero Division by zero Replicated through UnModified FFmpeg with UBSAN Found-by: Joshua Rogers (AISLE) Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/vvc/refs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/vvc/refs.c b/libavcodec/vvc/refs.c index a5a2d28c938..e0eab0cefa7 100644 --- a/libavcodec/vvc/refs.c +++ b/libavcodec/vvc/refs.c @@ -597,6 +597,8 @@ int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc) return ret; } } + if (rsh->num_ref_idx_active[lx] > rpl->nb_refs) + return AVERROR_INVALIDDATA; if (ph->r->ph_temporal_mvp_enabled_flag && (!rsh->sh_collocated_from_l0_flag) == lx && rsh->sh_collocated_ref_idx < rpl->nb_refs) { -- 2.54.0 >From eae96d31331f42ee01cb9014a54141b45023f5dc Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 24 Oct 2026 06:08:55 +0200 Subject: [PATCH 6/6] avcodec/vp9: reject frames with different U and V strides Fixes: K1QeU7Q1W8m1/testcase/vp9_driver.c Fixes: K1QeU7Q1W8m1 Fixes: AISLE-2026-0150-00612 Out of array write Replicated through API with ASAN Found-by: Joshua Rogers (AISLE) The report suggested using linesize[2] for the V plane throughout the decoder or rejecting unequal strides after get_buffer2(). Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/vp9.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 83d712bb25b..c4d84775434 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -114,6 +114,12 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) if (ret < 0) return ret; + if (f->tf.f->linesize[1] != f->tf.f->linesize[2]) { + av_log(avctx, AV_LOG_ERROR, "uv stride mismatch unsupported\n"); + ret = AVERROR_PATCHWELCOME; + goto fail; + } + sz = 64 * s->sb_cols * s->sb_rows; if (sz != s->frame_extradata_pool_size) { av_refstruct_pool_uninit(&s->frame_extradata_pool); -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
