PR #25036 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25036
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25036.patch


>From 808f51692859c25aab5204e0475766983fa99724 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:01:35 +0200
Subject: [PATCH 01/24] avutil/opt: do not store an image size that failed to
 parse

Fixes: use of uninitialized memory
Fixes: yEDlrREdlez4
Regression since: bd68a61304
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24757
Use of uninitialized memory Replicated through UnModified FFmpeg with Valgrind
---
 libavutil/opt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 03fca6ad15..041ad30280 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -534,8 +534,10 @@ static int set_string_image_size(void *obj, const AVOption 
*o, const char *val,
         return 0;
     }
     ret = av_parse_video_size(&tmp[0], &tmp[1], val);
-    if (ret < 0)
+    if (ret < 0) {
         av_log(logctx, AV_LOG_ERROR, "Unable to parse \"%s\" option value 
\"%s\" as image size\n", o->name, val);
+        return ret;
+    }
     if (dst)
         memcpy(dst, tmp, sizeof(tmp));
     return ret;
-- 
2.52.0


>From 6739caf91863d8f63815fb5ac6640f93aa7f8944 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:03:27 +0200
Subject: [PATCH 02/24] avutil/opt: do not store a color that failed to parse

Fixes: use of uninitialized memory
Fixes: f78pyZFASSy9
Regression since: bd68a61304
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24757
Use of uninitialized memory Replicated through UnModified FFmpeg with Valgrind
---
 libavutil/opt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 041ad30280..0f69e04b3b 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -565,8 +565,10 @@ static int set_string_color(void *obj, const AVOption *o, 
const char *val, uint8
     } else {
         uint8_t tmp[4];
         ret = av_parse_color(tmp, val, -1, obj);
-        if (ret < 0)
+        if (ret < 0) {
             av_log(logctx, AV_LOG_ERROR, "Unable to parse \"%s\" option value 
\"%s\" as color\n", o->name, val);
+            return ret;
+        }
         if (dst)
             memcpy(dst, tmp, sizeof(tmp));
         return ret;
-- 
2.52.0


>From 08cc9134ecfeadde105b90d46a258b17786c8c28 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:04:57 +0200
Subject: [PATCH 03/24] 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
---
 libavcodec/aac/aacdec.c      | 1 +
 libavcodec/aac/aacdec_latm.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c
index 66ab648016..700f16c56a 100644
--- a/libavcodec/aac/aacdec.c
+++ b/libavcodec/aac/aacdec.c
@@ -2612,6 +2612,7 @@ static int aac_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
     default:
         err = aac_decode_frame_int(avctx, frame, got_frame_ptr, &gb, avpkt);
     }
+    ac->frame = NULL;
     if (err < 0)
         return err;
 
diff --git a/libavcodec/aac/aacdec_latm.h b/libavcodec/aac/aacdec_latm.h
index 398d40741b..d9e836e949 100644
--- a/libavcodec/aac/aacdec_latm.h
+++ b/libavcodec/aac/aacdec_latm.h
@@ -308,6 +308,7 @@ static int latm_decode_frame(AVCodecContext *avctx, AVFrame 
*out,
     default:
         err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt);
     }
+    latmctx->aac_ctx.frame = NULL;
     if (err < 0)
         return err;
 
-- 
2.52.0


>From db07e7b2196f043c5db4b9e09677fc736f24f63c Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:06:36 +0200
Subject: [PATCH 04/24] avcodec/ratecontrol: check the picture number in
 ff_get_2pass_fcode()

Fixes: out of array read
Fixes: H7ATVBRB6ALZ
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24758
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavcodec/mpegvideo_enc.c |  4 +++-
 libavcodec/ratecontrol.c   | 11 +++++++++--
 libavcodec/ratecontrol.h   |  2 +-
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 3908628504..3a7d1e2749 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -3706,7 +3706,9 @@ static int encode_picture(MPVMainEncContext *const m, 
const AVPacket *pkt)
         ret = estimate_qp(m, 1);
         if (ret < 0)
             return ret;
-        ff_get_2pass_fcode(m);
+        ret = ff_get_2pass_fcode(m);
+        if (ret < 0)
+            return ret;
     } else if (!(s->c.avctx->flags & AV_CODEC_FLAG_QSCALE)) {
         if (s->c.pict_type == AV_PICTURE_TYPE_B)
             s->lambda = m->last_lambda_for[s->c.pict_type];
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 397a235821..130f09b9b7 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -900,14 +900,21 @@ static void adaptive_quantization(RateControlContext 
*const rcc,
     }
 }
 
-void ff_get_2pass_fcode(MPVMainEncContext *const m)
+int ff_get_2pass_fcode(MPVMainEncContext *const m)
 {
     MPVEncContext *const s = &m->s;
     const RateControlContext *rcc = &m->rc_context;
-    const RateControlEntry   *rce = &rcc->entry[s->picture_number];
+    const RateControlEntry   *rce;
+
+    if (s->picture_number >= rcc->num_entries) {
+        av_log(s->c.avctx, AV_LOG_ERROR, "Input is longer than 2-pass log 
file\n");
+        return AVERROR(EINVAL);
+    }
+    rce = &rcc->entry[s->picture_number];
 
     s->f_code = rce->f_code;
     s->b_code = rce->b_code;
+    return 0;
 }
 
 // FIXME rd or at least approx for dquant
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index 3bcfa5658a..f4f8af5bf5 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -100,7 +100,7 @@ int ff_rate_control_init(MPVMainEncContext *m);
 float ff_rate_estimate_qscale(MPVMainEncContext *m, int dry_run);
 void ff_write_pass1_stats(MPVMainEncContext *m);
 int ff_vbv_update(MPVMainEncContext *m, int frame_size);
-void ff_get_2pass_fcode(MPVMainEncContext *m);
+int ff_get_2pass_fcode(MPVMainEncContext *m);
 void ff_rate_control_uninit(RateControlContext *rcc);
 
 #endif /* AVCODEC_RATECONTROL_H */
-- 
2.52.0


>From fa13733064f4b3fb2881b81cd2da3281a2d5f99a Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:07:46 +0200
Subject: [PATCH 05/24] avcodec/ratecontrol: check the fcode and bcode of the
 2-pass log

Fixes: out of array access
Fixes: DY618nKRv9YY
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24758
Out of array access Replicated through UnModified FFmpeg with ASAN
---
 libavcodec/ratecontrol.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 130f09b9b7..98e05601da 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -635,6 +635,11 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const 
m)
                        rce->pict_type, i);
                 return -1;
             }
+            if ((unsigned)rce->f_code > MAX_FCODE || (unsigned)rce->b_code > 
MAX_FCODE) {
+                av_log(avctx, AV_LOG_ERROR, "invalid fcode %d / bcode %d at 
line %d\n",
+                       rce->f_code, rce->b_code, i);
+                return -1;
+            }
 
             p = next;
         }
-- 
2.52.0


>From ec3bf2499c942b7cf6bccea7148ed6732a56225b Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:09:06 +0200
Subject: [PATCH 06/24] avformat/mov: saturate the fragment timestamp
 arithmetic in mov_read_trun()

Fixes: signed integer overflow
Fixes: 5NVcwD9UoHmO
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24878
Signed integer overflow Replicated through UnModified FFmpeg with UBSAN
---
 libavformat/mov.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 90decf17f5..fab34da3a7 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6301,7 +6301,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     frag_stream_info = get_current_frag_stream_info(&c->frag_index);
     if (frag_stream_info) {
         if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
-            dts = frag_stream_info->next_trun_dts - sc->time_offset;
+            dts = av_sat_sub64(frag_stream_info->next_trun_dts, 
sc->time_offset);
         } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
             c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
             pts = frag_stream_info->first_tfra_pts;
@@ -6326,7 +6326,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
             }
 
             if (has_tfdt && c->use_tfdt || fallback_tfdt) {
-                dts = frag_stream_info->tfdt_dts - sc->time_offset;
+                dts = av_sat_sub64(frag_stream_info->tfdt_dts, 
sc->time_offset);
                 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
                         ", using it for dts\n", dts);
             } else if (has_sidx && !c->use_tfdt || fallback_sidx) {
@@ -6336,13 +6336,13 @@ static int mov_read_trun(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
                 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
                         ", using it for dts\n", frag_stream_info->sidx_pts);
             } else {
-                dts = sc->track_end - sc->time_offset;
+                dts = av_sat_sub64(sc->track_end, sc->time_offset);
                 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
                         ", using it for dts\n", dts);
             }
         }
     } else {
-        dts = sc->track_end - sc->time_offset;
+        dts = av_sat_sub64(sc->track_end, sc->time_offset);
         av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
                 ", using it for dts\n", dts);
     }
@@ -6432,11 +6432,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 
         mov_update_dts_shift(sc, ctts_duration, c->fc);
         if (pts != AV_NOPTS_VALUE) {
-            dts = pts - sc->dts_shift;
+            dts = av_sat_sub64(pts, sc->dts_shift);
             if (flags & MOV_TRUN_SAMPLE_CTS) {
-                dts -= ctts_duration;
+                dts = av_sat_sub64(dts, ctts_duration);
             } else {
-                dts -= sc->time_offset;
+                dts = av_sat_sub64(dts, sc->time_offset);
             }
             av_log(c->fc, AV_LOG_DEBUG,
                    "pts %"PRId64" calculated dts %"PRId64
@@ -6490,7 +6490,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
         }
     }
     if (frag_stream_info)
-        frag_stream_info->next_trun_dts = dts + sc->time_offset;
+        frag_stream_info->next_trun_dts = av_sat_add64(dts, sc->time_offset);
     if (i < entries) {
         // EOF found before reading all entries.  Fix the hole this would
         // leave in index_entries and tts_data
@@ -6537,7 +6537,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 
     frag->implicit_offset = offset;
 
-    sc->track_end = dts + sc->time_offset;
+    sc->track_end = av_sat_add64(dts, sc->time_offset);
     if (st->duration < sc->track_end)
         st->duration = sc->track_end;
 
-- 
2.52.0


>From e5c6a32385caab6d469f8e370beb8a388fa945b2 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:10:17 +0200
Subject: [PATCH 07/24] avformat/hls: saturate the timestamps of ID3
 timestamped streams

Fixes: signed integer overflow
Fixes: CniIhjP8pfgr
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24873
Signed integer overflow Replicated through UnModified FFmpeg with UBSAN
---
 libavformat/hls.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 506c8c0f49..b1793cc1c8 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2661,12 +2661,12 @@ static int recheck_discard_flags(AVFormatContext *s, 
int first)
 static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
 {
     if (pls->id3_offset >= 0) {
-        pls->pkt->dts = pls->id3_mpegts_timestamp +
-                                 av_rescale_q(pls->id3_offset,
-                                              
pls->ctx->streams[pls->pkt->stream_index]->time_base,
-                                              MPEG_TIME_BASE_Q);
+        pls->pkt->dts = av_sat_add64(pls->id3_mpegts_timestamp,
+                                     av_rescale_q(pls->id3_offset,
+                                                  
pls->ctx->streams[pls->pkt->stream_index]->time_base,
+                                                  MPEG_TIME_BASE_Q));
         if (pls->pkt->duration)
-            pls->id3_offset += pls->pkt->duration;
+            pls->id3_offset = av_sat_add64(pls->id3_offset, 
pls->pkt->duration);
         else
             pls->id3_offset = -1;
     } else {
-- 
2.52.0


>From 117224293ac7495933038c4ba257ff64fdac14aa Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:11:45 +0200
Subject: [PATCH 08/24] avformat/hls: saturate the playlist timestamp offset
 arithmetic

Fixes: signed integer overflow
Fixes: 2PuIAHF3wU0b
Regression since: e27ad5760c
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24873
Signed integer overflow Replicated through UnModified FFmpeg with UBSAN
---
 libavformat/hls.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index b1793cc1c8..bb57488234 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2637,8 +2637,8 @@ static int recheck_discard_flags(AVFormatContext *s, int 
first)
             pls->pb.pub.eof_reached = 0;
             if (c->cur_timestamp != AV_NOPTS_VALUE) {
                 /* catch up */
-                pls->seek_timestamp = c->cur_timestamp +
-                    (pls->ts_offset != AV_NOPTS_VALUE ? pls->ts_offset : 0);
+                pls->seek_timestamp = av_sat_add64(c->cur_timestamp,
+                    pls->ts_offset != AV_NOPTS_VALUE ? pls->ts_offset : 0);
                 pls->seek_flags = AVSEEK_FLAG_ANY;
                 pls->seek_stream_index = -1;
             }
@@ -2769,7 +2769,7 @@ static int hls_read_packet(AVFormatContext *s, AVPacket 
*pkt)
                                               get_timebase(pls), 
AV_TIME_BASE_Q);
 
                     for (int64_t k = 0; k < seg_idx && k < pls->n_segments; 
k++)
-                        ts -= pls->segments[k]->duration;
+                        ts = av_sat_sub64(ts, pls->segments[k]->duration);
 
                     if (c->first_timestamp == AV_NOPTS_VALUE) {
                         c->first_timestamp = ts;
@@ -2780,19 +2780,19 @@ static int hls_read_packet(AVFormatContext *s, AVPacket 
*pkt)
                          * order, but another stream in the same segment may
                          * start earlier. Lower the estimate while packets of
                          * that segment are still arriving. */
-                        int64_t delta = c->first_timestamp - ts;
+                        int64_t delta = av_sat_sub64(c->first_timestamp, ts);
 
                         if (delta > 0 && delta <= pls->target_duration) {
                             c->first_timestamp = ts;
                             for (int k = 0; k < c->n_playlists; k++)
                                 if (c->playlists[k]->ts_offset != 
AV_NOPTS_VALUE)
-                                    c->playlists[k]->ts_offset += delta;
+                                    c->playlists[k]->ts_offset = 
av_sat_add64(c->playlists[k]->ts_offset, delta);
                             adjusted = 1;
                         }
                     }
 
                     if (pls->ts_offset == AV_NOPTS_VALUE)
-                        pls->ts_offset = ts - c->first_timestamp;
+                        pls->ts_offset = av_sat_sub64(ts, c->first_timestamp);
 
                     if (adjusted) {
                         for (unsigned k = 0; k < s->nb_streams; k++)
@@ -3058,7 +3058,7 @@ static int hls_read_seek(AVFormatContext *s, int 
stream_index,
          * have different DTS baselines, so translate the threshold onto this
          * playlist's own baseline using its captured offset. */
         if (pls->ts_offset != AV_NOPTS_VALUE)
-            pls->seek_timestamp = seek_timestamp + pls->ts_offset;
+            pls->seek_timestamp = av_sat_add64(seek_timestamp, pls->ts_offset);
         else
             pls->seek_timestamp = seek_timestamp;
         pls->seek_flags = flags;
-- 
2.52.0


>From 68a89f59626678f9e7aa8cfa43839db708d28e1f Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:15:55 +0200
Subject: [PATCH 09/24] avfilter/af_sofalizer: reject SOFA files with an IR
 length of 0

Fixes: undefined clz of 0
Fixes: jj9j0M05l3SP
Regression since: 7ea4b928a2
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24624
Undefined clz of 0 Replicated through UnModified FFmpeg with UBSAN
---
 libavfilter/af_sofalizer.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c
index 01278c2d42..e1670d08e7 100644
--- a/libavfilter/af_sofalizer.c
+++ b/libavfilter/af_sofalizer.c
@@ -153,6 +153,11 @@ static int preload_sofa(AVFilterContext *ctx, char 
*filename, int *samplingrate)
         return ret;
     }
 
+    if (!mysofa->N) {
+        av_log(ctx, AV_LOG_ERROR, "Selected SOFA file has inconsistent 
dimensions.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     if (s->normalize)
         mysofa_loudness(s->sofa.hrtf);
 
-- 
2.52.0


>From d86a85cf53768770ad8ced3da21b62a784028d5b Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:16:17 +0200
Subject: [PATCH 10/24] avfilter/af_sofalizer: check the IR length against the
 IR data

Fixes: out of array read
Fixes: 65nc8s5OIq4Z
Regression since: 4096c670ab
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24624
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/af_sofalizer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c
index e1670d08e7..caf833c19a 100644
--- a/libavfilter/af_sofalizer.c
+++ b/libavfilter/af_sofalizer.c
@@ -153,7 +153,7 @@ static int preload_sofa(AVFilterContext *ctx, char 
*filename, int *samplingrate)
         return ret;
     }
 
-    if (!mysofa->N) {
+    if (!mysofa->N || mysofa->DataIR.elements / mysofa->M / mysofa->R < 
mysofa->N) {
         av_log(ctx, AV_LOG_ERROR, "Selected SOFA file has inconsistent 
dimensions.\n");
         return AVERROR_INVALIDDATA;
     }
-- 
2.52.0


>From b02d7163974eaf5125a8fd185a67345f430490cb Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:16:53 +0200
Subject: [PATCH 11/24] avfilter/af_sofalizer: check the size of the delay data

Fixes: NULL pointer dereference
Fixes: d80uw1EIP3Pa
Regression since: ee64b64c02
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24624
NULL pointer dereference Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/af_sofalizer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavfilter/af_sofalizer.c b/libavfilter/af_sofalizer.c
index caf833c19a..fa15937402 100644
--- a/libavfilter/af_sofalizer.c
+++ b/libavfilter/af_sofalizer.c
@@ -153,7 +153,8 @@ static int preload_sofa(AVFilterContext *ctx, char 
*filename, int *samplingrate)
         return ret;
     }
 
-    if (!mysofa->N || mysofa->DataIR.elements / mysofa->M / mysofa->R < 
mysofa->N) {
+    if (!mysofa->N || mysofa->DataIR.elements / mysofa->M / mysofa->R < 
mysofa->N ||
+        (mysofa->DataDelay.elements != mysofa->R && mysofa->DataDelay.elements 
/ mysofa->R < mysofa->M)) {
         av_log(ctx, AV_LOG_ERROR, "Selected SOFA file has inconsistent 
dimensions.\n");
         return AVERROR_INVALIDDATA;
     }
-- 
2.52.0


>From 941bac1a438225a6c33f978d3c4628cd980f2692 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:17:45 +0200
Subject: [PATCH 12/24] avfilter/vidstabutils: do not offer packed RGB formats

Fixes: assertion failure
Fixes: CSKmF1Dx1jig
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24608
Assertion failure Replicated through UnModified FFmpeg
Crash Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/vidstabutils.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libavfilter/vidstabutils.c b/libavfilter/vidstabutils.c
index a0c1fc990e..7c87477f3f 100644
--- a/libavfilter/vidstabutils.c
+++ b/libavfilter/vidstabutils.c
@@ -25,7 +25,6 @@ const enum AVPixelFormat ff_vidstab_pix_fmts[] =  {
     AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
     AV_PIX_FMT_YUV411P,  AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P,
     AV_PIX_FMT_YUV440P,  AV_PIX_FMT_GRAY8,
-    AV_PIX_FMT_RGB24,    AV_PIX_FMT_BGR24,   AV_PIX_FMT_RGBA,
     AV_PIX_FMT_NONE
 };
 
@@ -41,9 +40,6 @@ VSPixelFormat ff_av2vs_pixfmt(AVFilterContext *ctx, enum 
AVPixelFormat pf)
     case AV_PIX_FMT_YUV440P:  return PF_YUV440P;
     case AV_PIX_FMT_YUVA420P: return PF_YUVA420P;
     case AV_PIX_FMT_GRAY8:    return PF_GRAY8;
-    case AV_PIX_FMT_RGB24:    return PF_RGB24;
-    case AV_PIX_FMT_BGR24:    return PF_BGR24;
-    case AV_PIX_FMT_RGBA:     return PF_RGBA;
     default:
         av_log(ctx, AV_LOG_ERROR, "cannot deal with pixel format %i\n", pf);
         return PF_NONE;
-- 
2.52.0


>From 934a0d0883e1673c749c89b202751f1795da619d Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:25:23 +0200
Subject: [PATCH 13/24] avfilter/vf_libopencv: reject shapes too big for OpenCV

Fixes: out of array write
Fixes: EVA3Y4e693ul
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24753
Out of array write Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/vf_libopencv.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index cdfa678860..e34bcb9da7 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -240,6 +240,12 @@ static int parse_iplconvkernel(IplConvKernel **kernel, 
char *buf, void *log_ctx)
         goto out;
     }
 
+    if (rows > (INT_MAX - sizeof(IplConvKernel) - 32) / sizeof(int) / cols) {
+        av_log(log_ctx, AV_LOG_ERROR, "Shape size %dx%d is too big\n", cols, 
rows);
+        ret = AVERROR(EINVAL);
+        goto out;
+    }
+
     if (anchor_x < 0 || anchor_y < 0 || anchor_x >= cols || anchor_y >= rows) {
         av_log(log_ctx, AV_LOG_ERROR,
                "Shape anchor %dx%d is not inside the rectangle with size 
%dx%d.\n",
-- 
2.52.0


>From a8509fe4a75231d7cefe1ee21c31a68183e4c3be Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:27:49 +0200
Subject: [PATCH 14/24] avfilter/vf_deshake: use the linesize of the reference
 frame

Fixes: out of array read
Fixes: Au41rSBM5kGS
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/vf_deshake.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index afd0989e05..8a2dbe2fa5 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -171,16 +171,16 @@ static double clean_mean(double *values, int count)
  * chooses the most likely shift by the smallest difference in blocks.
  */
 static void find_block_motion(DeshakeContext *deshake, uint8_t *src1,
-                              uint8_t *src2, int cx, int cy, int stride,
-                              IntMotionVector *mv)
+                              uint8_t *src2, int cx, int cy, int stride1,
+                              int stride2, IntMotionVector *mv)
 {
     int x, y;
     int diff;
     int smallest = INT_MAX;
     int tmp, tmp2;
 
-    #define CMP(i, j) deshake->sad(src1 + cy  * stride + cx,  stride,\
-                                   src2 + (j) * stride + (i), stride)
+    #define CMP(i, j) deshake->sad(src1 + cy  * stride1 + cx,  stride1,\
+                                   src2 + (j) * stride2 + (i), stride2)
 
     if (deshake->search == EXHAUSTIVE) {
         // Compare every possible position - this is sloooow!
@@ -285,7 +285,7 @@ static double block_angle(int x, int y, int cx, int cy, 
IntMotionVector *shift)
  * motion vector (1, -2).
  */
 static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2,
-                        int width, int height, int stride, Transform *t)
+                        int width, int height, int stride1, int stride2, 
Transform *t)
 {
     int x, y;
     IntMotionVector mv = {0, 0};
@@ -312,10 +312,10 @@ static void find_motion(DeshakeContext *deshake, uint8_t 
*src1, uint8_t *src2,
         for (x = deshake->rx; x < width - deshake->rx - 16; x += 16) {
             // If the contrast is too low, just skip this block as it probably
             // won't be very useful to us.
-            contrast = block_contrast(src2, x, y, stride, deshake->blocksize);
+            contrast = block_contrast(src2, x, y, stride2, deshake->blocksize);
             if (contrast > deshake->contrast) {
                 //av_log(NULL, AV_LOG_ERROR, "%d\n", contrast);
-                find_block_motion(deshake, src1, src2, x, y, stride, &mv);
+                find_block_motion(deshake, src1, src2, x, y, stride1, stride2, 
&mv);
                 if (mv.x != -1 && mv.y != -1) {
                     deshake->counts[mv.x + deshake->rx][mv.y + deshake->ry] += 
1;
                     if (x > deshake->rx && y > deshake->ry)
@@ -476,7 +476,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     }
     av_frame_copy_props(out, in);
 
-    aligned = !((intptr_t)in->data[0] & 15 | in->linesize[0] & 15);
+    const AVFrame *ref = deshake->ref ? deshake->ref : in;
+    aligned = !((intptr_t)ref->data[0] & 15 | ref->linesize[0] & 15);
     deshake->sad = av_pixelutils_get_sad_fn(4, 4, aligned, deshake); // 16x16, 
2nd source unaligned
     if (!deshake->sad) {
         ret = AVERROR(EINVAL);
@@ -485,9 +486,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
 
     if (deshake->cx < 0 || deshake->cy < 0 || deshake->cw < 0 || deshake->ch < 
0) {
         // Find the most likely global motion for the current frame
-        find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : 
deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t);
+        find_motion(deshake, ref->data[0], in->data[0], link->w, link->h, 
ref->linesize[0], in->linesize[0], &t);
     } else {
-        uint8_t *src1 = (deshake->ref == NULL) ? in->data[0] : 
deshake->ref->data[0];
+        uint8_t *src1 = ref->data[0];
         uint8_t *src2 = in->data[0];
 
         deshake->cx = FFMIN(deshake->cx, link->w);
@@ -499,10 +500,10 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
         // Quadword align right margin
         deshake->cw &= ~15;
 
-        src1 += deshake->cy * in->linesize[0] + deshake->cx;
+        src1 += deshake->cy * ref->linesize[0] + deshake->cx;
         src2 += deshake->cy * in->linesize[0] + deshake->cx;
 
-        find_motion(deshake, src1, src2, deshake->cw, deshake->ch, 
in->linesize[0], &t);
+        find_motion(deshake, src1, src2, deshake->cw, deshake->ch, 
ref->linesize[0], in->linesize[0], &t);
     }
 
 
-- 
2.52.0


>From ee7fe63d02253059738243b725e0e556507c76c4 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:28:10 +0200
Subject: [PATCH 15/24] avfilter/vf_idet: use the linesize of the previous and
 next frame

Fixes: out of array read
Fixes: Au41rSBM5kGS
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/vf_idet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index c217021ae9..02dc14fb7a 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -156,9 +156,9 @@ static void filter(AVFilterContext *ctx)
         }
 
         for (y = 2; y < h - 2; y++) {
-            uint8_t *prev = &idet->prev->data[i][y*refs];
+            uint8_t *prev = &idet->prev->data[i][y*idet->prev->linesize[i]];
             uint8_t *cur  = &idet->cur ->data[i][y*refs];
-            uint8_t *next = &idet->next->data[i][y*refs];
+            uint8_t *next = &idet->next->data[i][y*idet->next->linesize[i]];
             alpha[ y   &1] += filter_line(cur-refs, prev, cur+refs, w);
             alpha[(y^1)&1] += filter_line(cur-refs, next, cur+refs, w);
             delta          += filter_line(cur-refs,  cur, cur+refs, w);
-- 
2.52.0


>From b7951aa4b07aa2e7ef243beb0d1a453dc7bcaa89 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:28:42 +0200
Subject: [PATCH 16/24] avfilter/vf_photosensitivity: blend only the visible
 part of the lines

Fixes: out of array read
Fixes: Au41rSBM5kGS
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/vf_photosensitivity.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_photosensitivity.c 
b/libavfilter/vf_photosensitivity.c
index 3f040f8c89..97347ad2c9 100644
--- a/libavfilter/vf_photosensitivity.c
+++ b/libavfilter/vf_photosensitivity.c
@@ -152,12 +152,12 @@ static int blend_frame_partial(AVFilterContext *ctx, void 
*arg, int jobnr, int n
     const uint16_t t_mul = 0x100 - s_mul;
     const int slice_start = ff_slice_pos(td->target->height, jobnr, nb_jobs);
     const int slice_end = ff_slice_pos(td->target->height, jobnr + 1, nb_jobs);
-    const int linesize = td->target->linesize[0];
+    const int width = td->target->width * NUM_CHANNELS;
 
     for (y = slice_start; y < slice_end; y++) {
         t = td->target->data[0] + y * td->target->linesize[0];
         s = td->source->data[0] + y * td->source->linesize[0];
-        for (x = 0; x < linesize; x++) {
+        for (x = 0; x < width; x++) {
             *t = (*t * t_mul + *s * s_mul) >> 8;
             t++; s++;
         }
-- 
2.52.0


>From 30ed485715e9fe7c848ffce7234f571a3b7c0efc Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:30:15 +0200
Subject: [PATCH 17/24] avfilter/motion_estimation: use separate linesizes for
 the current and reference frame

Fixes: out of array read
Fixes: Au41rSBM5kGS
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/motion_estimation.c |  9 +++++----
 libavfilter/motion_estimation.h |  2 +-
 libavfilter/vf_mestimate.c      |  5 +++--
 libavfilter/vf_minterpolate.c   | 25 +++++++++++++++----------
 4 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/libavfilter/motion_estimation.c b/libavfilter/motion_estimation.c
index 2bf5ce6155..a275e2bd6f 100644
--- a/libavfilter/motion_estimation.c
+++ b/libavfilter/motion_estimation.c
@@ -59,18 +59,19 @@ void ff_me_init_context(AVMotionEstContext *me_ctx, int 
mb_size, int search_para
 
 uint64_t ff_me_cmp_sad(AVMotionEstContext *me_ctx, int x_mb, int y_mb, int 
x_mv, int y_mv)
 {
-    const int linesize = me_ctx->linesize;
+    const int linesize_ref = me_ctx->linesize_ref;
+    const int linesize_cur = me_ctx->linesize_cur;
     uint8_t *data_ref = me_ctx->data_ref;
     uint8_t *data_cur = me_ctx->data_cur;
     uint64_t sad = 0;
     int i, j;
 
-    data_ref += y_mv * linesize;
-    data_cur += y_mb * linesize;
+    data_ref += y_mv * linesize_ref;
+    data_cur += y_mb * linesize_cur;
 
     for (j = 0; j < me_ctx->mb_size; j++)
         for (i = 0; i < me_ctx->mb_size; i++)
-            sad += FFABS(data_ref[x_mv + i + j * linesize] - data_cur[x_mb + i 
+ j * linesize]);
+            sad += FFABS(data_ref[x_mv + i + j * linesize_ref] - data_cur[x_mb 
+ i + j * linesize_cur]);
 
     return sad;
 }
diff --git a/libavfilter/motion_estimation.h b/libavfilter/motion_estimation.h
index be627ec3b0..e5f69bec4a 100644
--- a/libavfilter/motion_estimation.h
+++ b/libavfilter/motion_estimation.h
@@ -40,7 +40,7 @@ typedef struct AVMotionEstPredictor {
 
 typedef struct AVMotionEstContext {
     uint8_t *data_cur, *data_ref;
-    int linesize;
+    int linesize_cur, linesize_ref;
 
     int mb_size;
     int search_param;
diff --git a/libavfilter/vf_mestimate.c b/libavfilter/vf_mestimate.c
index 759883df45..6c71a309f0 100644
--- a/libavfilter/vf_mestimate.c
+++ b/libavfilter/vf_mestimate.c
@@ -184,10 +184,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame 
*frame)
     }
 
     me_ctx->data_cur = s->cur->data[0];
-    me_ctx->linesize = s->cur->linesize[0];
+    me_ctx->linesize_cur = s->cur->linesize[0];
 
     for (dir = 0; dir < nb_dirs; dir++) {
-        me_ctx->data_ref = (dir ? s->next : s->prev)->data[0];
+        me_ctx->data_ref     = (dir ? s->next : s->prev)->data[0];
+        me_ctx->linesize_ref = (dir ? s->next : s->prev)->linesize[0];
 
         if (s->method == AV_ME_METHOD_DS)
             SEARCH_MV(ds);
diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c
index c996713553..75bffd4bf5 100644
--- a/libavfilter/vf_minterpolate.c
+++ b/libavfilter/vf_minterpolate.c
@@ -251,7 +251,8 @@ static uint64_t get_sbad(AVMotionEstContext *me_ctx, int x, 
int y, int x_mv, int
 {
     uint8_t *data_cur = me_ctx->data_cur;
     uint8_t *data_next = me_ctx->data_ref;
-    int linesize = me_ctx->linesize;
+    int linesize_cur  = me_ctx->linesize_cur;
+    int linesize_next = me_ctx->linesize_ref;
     int mv_x1 = x_mv - x;
     int mv_y1 = y_mv - y;
     int mv_x, mv_y, i, j;
@@ -262,12 +263,12 @@ static uint64_t get_sbad(AVMotionEstContext *me_ctx, int 
x, int y, int x_mv, int
     mv_x = av_clip(x_mv - x, -FFMIN(x - me_ctx->x_min, me_ctx->x_max - x), 
FFMIN(x - me_ctx->x_min, me_ctx->x_max - x));
     mv_y = av_clip(y_mv - y, -FFMIN(y - me_ctx->y_min, me_ctx->y_max - y), 
FFMIN(y - me_ctx->y_min, me_ctx->y_max - y));
 
-    data_cur += (y + mv_y) * linesize;
-    data_next += (y - mv_y) * linesize;
+    data_cur += (y + mv_y) * linesize_cur;
+    data_next += (y - mv_y) * linesize_next;
 
     for (j = 0; j < me_ctx->mb_size; j++)
         for (i = 0; i < me_ctx->mb_size; i++)
-            sbad += FFABS(data_cur[x + mv_x + i + j * linesize] - data_next[x 
- mv_x + i + j * linesize]);
+            sbad += FFABS(data_cur[x + mv_x + i + j * linesize_cur] - 
data_next[x - mv_x + i + j * linesize_next]);
 
     return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - 
me_ctx->pred_y)) * COST_PRED_SCALE;
 }
@@ -276,7 +277,8 @@ static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int 
x, int y, int x_mv,
 {
     uint8_t *data_cur = me_ctx->data_cur;
     uint8_t *data_next = me_ctx->data_ref;
-    int linesize = me_ctx->linesize;
+    int linesize_cur  = me_ctx->linesize_cur;
+    int linesize_next = me_ctx->linesize_ref;
     int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
     int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
     int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
@@ -293,7 +295,7 @@ static uint64_t get_sbad_ob(AVMotionEstContext *me_ctx, int 
x, int y, int x_mv,
 
     for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
         for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
-            sbad += FFABS(data_cur[x + mv_x + i + (y + mv_y + j) * linesize] - 
data_next[x - mv_x + i + (y - mv_y + j) * linesize]);
+            sbad += FFABS(data_cur[x + mv_x + i + (y + mv_y + j) * 
linesize_cur] - data_next[x - mv_x + i + (y - mv_y + j) * linesize_next]);
 
     return sbad + (FFABS(mv_x1 - me_ctx->pred_x) + FFABS(mv_y1 - 
me_ctx->pred_y)) * COST_PRED_SCALE;
 }
@@ -302,7 +304,8 @@ static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int 
x, int y, int x_mv, i
 {
     uint8_t *data_ref = me_ctx->data_ref;
     uint8_t *data_cur = me_ctx->data_cur;
-    int linesize = me_ctx->linesize;
+    int linesize_ref = me_ctx->linesize_ref;
+    int linesize_cur = me_ctx->linesize_cur;
     int x_min = me_ctx->x_min + me_ctx->mb_size / 2;
     int x_max = me_ctx->x_max - me_ctx->mb_size / 2;
     int y_min = me_ctx->y_min + me_ctx->mb_size / 2;
@@ -319,7 +322,7 @@ static uint64_t get_sad_ob(AVMotionEstContext *me_ctx, int 
x, int y, int x_mv, i
 
     for (j = -me_ctx->mb_size / 2; j < me_ctx->mb_size * 3 / 2; j++)
         for (i = -me_ctx->mb_size / 2; i < me_ctx->mb_size * 3 / 2; i++)
-            sad += FFABS(data_ref[x_mv + i + (y_mv + j) * linesize] - 
data_cur[x + i + (y + j) * linesize]);
+            sad += FFABS(data_ref[x_mv + i + (y_mv + j) * linesize_ref] - 
data_cur[x + i + (y + j) * linesize_cur]);
 
     return sad + (FFABS(mv_x - me_ctx->pred_x) + FFABS(mv_y - me_ctx->pred_y)) 
* COST_PRED_SCALE;
 }
@@ -753,7 +756,8 @@ static int inject_frame(AVFilterLink *inlink, AVFrame 
*avf_in)
 
             if (mi_ctx->frames[1].avf) {
                 for (dir = 0; dir < 2; dir++) {
-                    mi_ctx->me_ctx.linesize = 
mi_ctx->frames[2].avf->linesize[0];
+                    mi_ctx->me_ctx.linesize_cur = 
mi_ctx->frames[2].avf->linesize[0];
+                    mi_ctx->me_ctx.linesize_ref = mi_ctx->frames[dir ? 3 : 
1].avf->linesize[0];
                     mi_ctx->me_ctx.data_cur = mi_ctx->frames[2].avf->data[0];
                     mi_ctx->me_ctx.data_ref = mi_ctx->frames[dir ? 3 : 
1].avf->data[0];
 
@@ -770,7 +774,8 @@ static int inject_frame(AVFilterLink *inlink, AVFrame 
*avf_in)
             if (!mi_ctx->frames[0].avf)
                 return 0;
 
-            mi_ctx->me_ctx.linesize = mi_ctx->frames[0].avf->linesize[0];
+            mi_ctx->me_ctx.linesize_cur = mi_ctx->frames[1].avf->linesize[0];
+            mi_ctx->me_ctx.linesize_ref = mi_ctx->frames[2].avf->linesize[0];
             mi_ctx->me_ctx.data_cur = mi_ctx->frames[1].avf->data[0];
             mi_ctx->me_ctx.data_ref = mi_ctx->frames[2].avf->data[0];
 
-- 
2.52.0


>From a39ea8d56ec644201b142e782ae2a13b07dbd7ca Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:32:19 +0200
Subject: [PATCH 18/24] avfilter/vf_drawbox: check the expression results
 before converting them to int

Fixes: out of range float to int conversion
Fixes: signed integer overflow
Fixes: 4jtp2TTOoEsQ
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of range float to int conversion Replicated through UnModified FFmpeg with 
UBSAN
Signed integer overflow Replicated through UnModified FFmpeg with UBSAN
---
 libavfilter/vf_drawbox.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index ec409603d3..cd2b55a7c7 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -309,37 +309,49 @@ static int config_input(AVFilterLink *inlink)
                                           var_names, var_values,
                                           NULL, NULL, NULL, NULL, NULL, 0, 
ctx)) < 0 && i == NUM_EXPR_EVALS)
             goto fail;
-        s->x = var_values[VAR_X] = res;
+        var_values[VAR_X] = res;
 
         var_values[VAR_MAX] = inlink->h;
         if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
                                           var_names, var_values,
                                           NULL, NULL, NULL, NULL, NULL, 0, 
ctx)) < 0 && i == NUM_EXPR_EVALS)
             goto fail;
-        s->y = var_values[VAR_Y] = res;
+        var_values[VAR_Y] = res;
 
-        var_values[VAR_MAX] = inlink->w - s->x;
+        var_values[VAR_MAX] = inlink->w - trunc(var_values[VAR_X]);
         if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
                                           var_names, var_values,
                                           NULL, NULL, NULL, NULL, NULL, 0, 
ctx)) < 0 && i == NUM_EXPR_EVALS)
             goto fail;
-        s->w = var_values[VAR_W] = res;
+        var_values[VAR_W] = res;
 
-        var_values[VAR_MAX] = inlink->h - s->y;
+        var_values[VAR_MAX] = inlink->h - trunc(var_values[VAR_Y]);
         if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
                                           var_names, var_values,
                                           NULL, NULL, NULL, NULL, NULL, 0, 
ctx)) < 0 && i == NUM_EXPR_EVALS)
             goto fail;
-        s->h = var_values[VAR_H] = res;
+        var_values[VAR_H] = res;
 
         var_values[VAR_MAX] = INT_MAX;
         if ((ret = av_expr_parse_and_eval(&res, (expr = s->t_expr),
                                           var_names, var_values,
                                           NULL, NULL, NULL, NULL, NULL, 0, 
ctx)) < 0 && i == NUM_EXPR_EVALS)
             goto fail;
-        s->thickness = var_values[VAR_T] = res;
+        var_values[VAR_T] = res;
     }
 
+    if (!(fabs(var_values[VAR_X]) <= INT_MAX / 4 && fabs(var_values[VAR_Y]) <= 
INT_MAX / 4 &&
+          fabs(var_values[VAR_W]) <= INT_MAX / 4 && fabs(var_values[VAR_H]) <= 
INT_MAX / 4 &&
+          fabs(var_values[VAR_T]) <= INT_MAX)) {
+        av_log(ctx, AV_LOG_ERROR, "Position, size or thickness out of 
range.\n");
+        return AVERROR(EINVAL);
+    }
+    s->x         = var_values[VAR_X];
+    s->y         = var_values[VAR_Y];
+    s->w         = var_values[VAR_W];
+    s->h         = var_values[VAR_H];
+    s->thickness = var_values[VAR_T];
+
     /* if w or h are zero, use the input w/h */
     s->w = (s->w > 0) ? s->w : inlink->w;
     s->h = (s->h > 0) ? s->h : inlink->h;
-- 
2.52.0


>From 642bbfacde9ac93bfa8bb85b5fdbe8f1eaa26e35 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:41:46 +0200
Subject: [PATCH 19/24] avfilter/dnn_backend_openvino: set the number of
 outputs together with the output ports

Fixes: NULL pointer dereference
Fixes: gJMHsT6GErl5
Regression since: 22652b576c
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617
NULL pointer dereference Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/dnn/dnn_backend_openvino.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavfilter/dnn/dnn_backend_openvino.c 
b/libavfilter/dnn/dnn_backend_openvino.c
index 4a372f5f54..9eea57b596 100644
--- a/libavfilter/dnn/dnn_backend_openvino.c
+++ b/libavfilter/dnn/dnn_backend_openvino.c
@@ -682,7 +682,6 @@ static int init_model_ov(OVModel *ov_model, const char 
*input_name, const char *
         }
         nb_outputs = output_size;
     }
-    ov_model->nb_outputs = nb_outputs;
     for (int i = 0; i < nb_outputs; i++) {
         if (output_names)
             status = ov_preprocess_prepostprocessor_get_output_info_by_name(
@@ -764,6 +763,7 @@ static int init_model_ov(OVModel *ov_model, const char 
*input_name, const char *
             ret = AVERROR(ENOMEM);
             goto err;
         }
+        ov_model->nb_outputs = nb_outputs;
     } else
         for (int i = 0; i < nb_outputs; i++) {
             ov_output_const_port_free(ov_model->output_ports[i]);
-- 
2.52.0


>From 126bf8599176340a56d7de063d2405de7da7a364 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:42:03 +0200
Subject: [PATCH 20/24] avfilter/dnn_backend_openvino: do not free the model
 when updating it fails

Fixes: double free
Fixes: QIOnvFKEz80N
Regression since: 22652b576c
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24617
Double free Replicated through UnModified FFmpeg with ASAN
---
 libavfilter/dnn/dnn_backend_openvino.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libavfilter/dnn/dnn_backend_openvino.c 
b/libavfilter/dnn/dnn_backend_openvino.c
index 9eea57b596..808adc0b35 100644
--- a/libavfilter/dnn/dnn_backend_openvino.c
+++ b/libavfilter/dnn/dnn_backend_openvino.c
@@ -749,8 +749,6 @@ static int init_model_ov(OVModel *ov_model, const char 
*input_name, const char *
     status = ov_preprocess_prepostprocessor_build(ov_model->preprocess, 
&ov_model->ov_model);
     if (status != OK) {
         av_log(ctx, AV_LOG_ERROR, "Failed to update OV model\n");
-        ov_model_free(tmp_ov_model);
-        tmp_ov_model = NULL;
         ret = ov2_map_error(status, NULL);
         goto err;
     }
-- 
2.52.0


>From 101ab7ff65c74fe4e879b8d9e0264b72c4cb808c Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 02:48:35 +0200
Subject: [PATCH 21/24] avutil/hwcontext_cuda: copy only the bytes of the
 visible rows

Fixes: out of array access
Fixes: ZqshmgSdN2Q2
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24595
Out of array read and write Replicated through API with ASAN
Out of array read Replicated through UnModified FFmpeg with a guard page 
allocator
---
 libavutil/hwcontext_cuda.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c
index 0ee6bb4945..776c321652 100644
--- a/libavutil/hwcontext_cuda.c
+++ b/libavutil/hwcontext_cuda.c
@@ -567,10 +567,16 @@ static int cuda_transfer_data(AVHWFramesContext *ctx, 
AVFrame *dst,
         int src_is_nonplanar_cuarray = 0;
         int dst_is_nonplanar_cuarray = 0;
 
+        int bytewidth = av_image_get_linesize(ctx->sw_format, src->width, i);
+        if (bytewidth < 0) {
+            ret = bytewidth;
+            goto fail;
+        }
+
         CUDA_MEMCPY2D cpy = {
             .srcPitch      = src->linesize[i],
             .dstPitch      = dst->linesize[i],
-            .WidthInBytes  = FFMIN(src->linesize[i], dst->linesize[i]),
+            .WidthInBytes  = bytewidth,
             .Height        = AV_CEIL_RSHIFT(src->height, ((i == 0 || i == 3) ? 
0 : priv->shift_height)),
         };
 
-- 
2.52.0


>From c98957e999084dc05d3e3e24bb2434b0982f59db Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 03:52:42 +0200
Subject: [PATCH 22/24] avcodec: declare support for parameter changes in the
 rawvideo and wrapped_avframe encoders

Both encoders take the size and format of every frame from the frame
itself.
---
 libavcodec/rawenc.c          | 2 +-
 libavcodec/wrapped_avframe.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index 8c577006d9..97726db599 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -87,7 +87,7 @@ const FFCodec ff_rawvideo_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RAWVIDEO,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
-                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE | 
AV_CODEC_CAP_PARAM_CHANGE,
     .init           = raw_encode_init,
     FF_CODEC_ENCODE_CB(raw_encode),
 };
diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c
index a513bb3d39..751ab4f346 100644
--- a/libavcodec/wrapped_avframe.c
+++ b/libavcodec/wrapped_avframe.c
@@ -108,7 +108,7 @@ const FFCodec ff_wrapped_avframe_encoder = {
     CODEC_LONG_NAME("AVFrame to AVPacket passthrough"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WRAPPED_AVFRAME,
-    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE | 
AV_CODEC_CAP_PARAM_CHANGE,
     FF_CODEC_ENCODE_CB(wrapped_avframe_encode),
 };
 
-- 
2.52.0


>From 8bf6bdd78dcdf8152d586c5ed4ee6c1a55b83fe8 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 04:01:02 +0200
Subject: [PATCH 23/24] avcodec/encode: reject video frames that do not match
 the encoder

Fixes: out of array read
Fixes: DdI1HfjoEG1l
Found during triage of the review of 
https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of array read Replicated through UnModified FFmpeg with ASAN
---
 libavcodec/encode.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 6fbbe86d8f..fd503f01e1 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -518,6 +518,15 @@ static int encode_send_frame_internal(AVCodecContext 
*avctx, const AVFrame *src)
                 }
             }
         }
+    } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format);
+
+        if (!(desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
+            (src->format != avctx->pix_fmt ||
+             src->width  < avctx->width  || src->height < avctx->height)) {
+            av_log(avctx, AV_LOG_ERROR, "Frame size or pixel format does not 
match the encoder\n");
+            return AVERROR(EINVAL);
+        }
     }
 
     ret = av_frame_ref(dst, src);
-- 
2.52.0


>From 52da53a88c569c90a7e4e3e11f0c209980d30cd6 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 04:06:17 +0200
Subject: [PATCH 24/24] swscale: reject planes whose size does not fit in int

Fixes: signed integer overflow
Fixes: out of array access
Fixes: pdA1vTaOO5Be
Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24851
Signed integer overflow Replicated through API with UBSAN
Out of array access Replicated through API with ASAN
---
 libswscale/swscale.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 070b0f5939..1ed59c4bad 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -726,7 +726,7 @@ static void reset_ptr(const uint8_t *src[], enum 
AVPixelFormat format)
 }
 
 static int check_image_pointers(const uint8_t * const data[4], enum 
AVPixelFormat pix_fmt,
-                                const int linesizes[4])
+                                const int linesizes[4], int h)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     int i;
@@ -735,7 +735,7 @@ static int check_image_pointers(const uint8_t * const 
data[4], enum AVPixelForma
 
     for (i = 0; i < 4; i++) {
         int plane = desc->comp[i].plane;
-        if (!data[plane] || !linesizes[plane])
+        if (!data[plane] || !linesizes[plane] || 
FFABS((int64_t)linesizes[plane]) * h > INT_MAX)
             return 0;
     }
 
@@ -1060,12 +1060,12 @@ static int scale_internal(SwsContext *sws,
         return AVERROR(EINVAL);
     }
 
-    if (!check_image_pointers(srcSlice, sws->src_format, srcStride)) {
-        av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
+    if (!check_image_pointers(srcSlice, sws->src_format, srcStride, 
sws->src_h)) {
+        av_log(c, AV_LOG_ERROR, "bad src image pointers or strides\n");
         return AVERROR(EINVAL);
     }
-    if (!check_image_pointers((const uint8_t* const*)dstSlice, 
sws->dst_format, dstStride)) {
-        av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
+    if (!check_image_pointers((const uint8_t* const*)dstSlice, 
sws->dst_format, dstStride, sws->dst_h)) {
+        av_log(c, AV_LOG_ERROR, "bad dst image pointers or strides\n");
         return AVERROR(EINVAL);
     }
 
@@ -1402,6 +1402,14 @@ int sws_receive_slice(SwsContext *sws, unsigned int 
slice_start,
                           dst, c->frame_dst->linesize, slice_start, 
slice_height);
 }
 
+static int frame_strides_fit(const AVFrame *frame)
+{
+    for (int i = 0; i < FF_ARRAY_ELEMS(frame->linesize); i++)
+        if (FFABS((int64_t)frame->linesize[i]) * frame->height > INT_MAX)
+            return 0;
+    return 1;
+}
+
 int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
 {
     int ret, allocated = 0;
@@ -1432,6 +1440,11 @@ int sws_scale_frame(SwsContext *sws, AVFrame *dst, const 
AVFrame *src)
     if (!src->data[0])
         return 0;
 
+    if (!frame_strides_fit(src) || !frame_strides_fit(dst)) {
+        av_log(sws, AV_LOG_ERROR, "Frame planes larger than INT_MAX bytes are 
not supported\n");
+        return AVERROR(EINVAL);
+    }
+
     const SwsGraph *top = c->graph[FIELD_TOP];
     const SwsGraph *bot = c->graph[FIELD_BOTTOM];
     if (dst->data[0]) /* user-provided buffers */
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to