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]

Reply via email to