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


>From bf6eb41e6325adbbc358efea76a2750f32dfea99 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 04:46:19 +0100
Subject: [PATCH 1/4] avcodec/sanm: apply the codec 23 LUT loaded from the
 frame

Fixes: 4dmaFsb0C0KW
Fixes: AISLE-2026-0150-00882
Fixes: use of uninitialized memory
Use of uninitialized memory Replicated through UnModified FFmpeg with MSAN

Found-by: Joshua Rogers (AISLE)
---
 libavcodec/sanm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index 749d003a1b0..041466b210b 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -797,6 +797,7 @@ static int old_codec23(SANMVideoContext *ctx, 
GetByteContext *gb, int top, int l
         if (bytestream2_get_bytes_left(gb) < 256)
             return AVERROR_INVALIDDATA;
         bytestream2_get_bufferu(gb, ctx->c23lut, 256);
+        memcpy(lut, ctx->c23lut, 256);
     } else if (param2 < 256) {
         for (i = 0; i < 256; i++)
             lut[i] = (i + param2) & 0xff;
-- 
2.54.0


>From 7d8e8c64c5e5fac88a70d66dd2792c6fbc9d6245 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 04:46:19 +0100
Subject: [PATCH 2/4] avcodec/cfhd: allocate the inverse transform scratch
 buffer zeroed

Fixes: 1ivYPVLs04AI
Fixes: AISLE-2026-0150-00896
Fixes: use of uninitialized memory
Use of uninitialized memory Replicated through UnModified FFmpeg with MSAN
(CFHD AVI sample with the ImageHeight tag raised from 720 to 1080)

Found-by: Joshua Rogers (AISLE)
---
 libavcodec/cfhd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index 28ec749cba4..e4f54ba1965 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -289,13 +289,13 @@ static int alloc_buffers(AVCodecContext *avctx)
             s->plane[i].idwt_buf =
                 av_calloc(s->plane[i].idwt_size, 
sizeof(*s->plane[i].idwt_buf));
             s->plane[i].idwt_tmp =
-                av_malloc_array(s->plane[i].idwt_size, 
sizeof(*s->plane[i].idwt_tmp));
+                av_calloc(s->plane[i].idwt_size, 
sizeof(*s->plane[i].idwt_tmp));
         } else {
             s->plane[i].idwt_size = FFALIGN(height, 8) * stride * 2;
             s->plane[i].idwt_buf =
                 av_calloc(s->plane[i].idwt_size, 
sizeof(*s->plane[i].idwt_buf));
             s->plane[i].idwt_tmp =
-                av_malloc_array(s->plane[i].idwt_size, 
sizeof(*s->plane[i].idwt_tmp));
+                av_calloc(s->plane[i].idwt_size, 
sizeof(*s->plane[i].idwt_tmp));
         }
 
         if (!s->plane[i].idwt_buf || !s->plane[i].idwt_tmp)
-- 
2.54.0


>From 45bf018ed7cdd11b97d584529785119520cdafc0 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 04:46:19 +0100
Subject: [PATCH 3/4] avcodec/mimic: set up the bit reader before publishing
 the frame

Fixes: ZiiTReozL7KE
Fixes: AISLE-2026-0150-00435
Fixes: deadlock
Deadlock Replicated through UnModified FFmpeg with timeout (AVI with a
268435476 byte Mimic intra frame followed by inter frames; ffmpeg with
frame threading never exits)

Found-by: Joshua Rogers (AISLE)
---
 libavcodec/mimic.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index e9ed1a9b7c5..e9f77d90d95 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -385,6 +385,17 @@ static int mimic_decode_frame(AVCodecContext *avctx, 
AVFrame *rframe,
         return AVERROR_INVALIDDATA;
     }
 
+    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
+    if (!ctx->swap_buf)
+        return AVERROR(ENOMEM);
+
+    ctx->bbdsp.bswap_buf(ctx->swap_buf,
+                         (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
+                         swap_buf_size >> 2);
+    res = init_get_bits8(&ctx->gb, ctx->swap_buf, swap_buf_size);
+    if (res < 0)
+        return res;
+
     ff_progress_frame_unref(&ctx->frames[ctx->cur_index]);
     res = ff_progress_frame_get_buffer(avctx, &ctx->frames[ctx->cur_index],
                                        AV_GET_BUFFER_FLAG_REF);
@@ -398,17 +409,6 @@ static int mimic_decode_frame(AVCodecContext *avctx, 
AVFrame *rframe,
 
     ff_thread_finish_setup(avctx);
 
-    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
-    if (!ctx->swap_buf)
-        return AVERROR(ENOMEM);
-
-    ctx->bbdsp.bswap_buf(ctx->swap_buf,
-                         (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
-                         swap_buf_size >> 2);
-    res = init_get_bits8(&ctx->gb, ctx->swap_buf, swap_buf_size);
-    if (res < 0)
-        return res;
-
     res = decode(ctx, quality, num_coeffs, !is_pframe);
     ff_progress_frame_report(&ctx->frames[ctx->cur_index], INT_MAX);
     if (res < 0) {
-- 
2.54.0


>From 4eef04fa412e9c2c0b7050deb2439d0a9b3a21c5 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 04:46:20 +0100
Subject: [PATCH 4/4] avcodec/vc1dec: free the slice buffer when
 init_get_bits8() fails

Fixes: Ju3bQZ3z2paC
Fixes: AISLE-2026-0150-00166
Fixes: memory leak
Memory leak Replicated through UnModified FFmpeg with ASAN (AVI with one
268435475 byte WVC1 packet holding a single slice start code)

Found-by: Joshua Rogers (AISLE)
---
 libavcodec/vc1dec.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 94bccbfa505..a4d465dd0b3 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -856,8 +856,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame 
*pict,
                     buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size,
                                                               
slices[n_slices].buf);
                     ret = init_get_bits8(&slices[n_slices].gb, 
slices[n_slices].buf, buf_size3);
-                    if (ret < 0)
+                    if (ret < 0) {
+                        av_freep(&slices[n_slices].buf);
                         goto err;
+                    }
                     slices[n_slices].mby_start = avctx->coded_height + 31 >> 5;
                     slices[n_slices].rawbuf = start;
                     slices[n_slices].raw_size = size + 4;
@@ -889,8 +891,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame 
*pict,
                     buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size,
                                                               
slices[n_slices].buf);
                     ret = init_get_bits8(&slices[n_slices].gb, 
slices[n_slices].buf, buf_size3);
-                    if (ret < 0)
+                    if (ret < 0) {
+                        av_freep(&slices[n_slices].buf);
                         goto err;
+                    }
                     slices[n_slices].mby_start = 
get_bits(&slices[n_slices].gb, 9);
                     slices[n_slices].rawbuf = start;
                     slices[n_slices].raw_size = size + 4;
@@ -924,8 +928,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame 
*pict,
                 }
                 buf_size3 = v->vc1dsp.vc1_unescape_buffer(divider + 4, buf + 
buf_size - divider - 4, slices[n_slices].buf);
                 ret = init_get_bits8(&slices[n_slices].gb, 
slices[n_slices].buf, buf_size3);
-                if (ret < 0)
+                if (ret < 0) {
+                    av_freep(&slices[n_slices].buf);
                     goto err;
+                }
                 slices[n_slices].mby_start = s->mb_height + 1 >> 1;
                 slices[n_slices].rawbuf = divider;
                 slices[n_slices].raw_size = buf + buf_size - divider;
-- 
2.54.0

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

Reply via email to