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


>From e87c181ab23d5aa5dc8953d00f5703ceec01a9e7 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 02:15:18 +0100
Subject: [PATCH 1/6] avcodec/interplayacm: reject blocks larger than 1M
 samples

The limit is libacm's MAX_BLOCK_LEN (1024 * 1024 samples, decode.c);
libacm is the decoder this one derives from and is what the games'
modding tools use, so no file decodable by it is rejected. Real files
from Baldur's Gate, Baldur's Gate II, Icewind Dale, Icewind Dale II and
Planescape: Torment use level 7 or 8 with 16 rows, blocks of 2048 or
4096 samples, and the snd2acm / DLTCEP encoder defaults to level 7 with
16 rows, 256 times below the limit.

Excessive memory allocation (peak RSS 944 MB from a 78 byte file)
Replicated through UnModified FFmpeg with ASAN

Fixes: out of memory
Fixes: fi1TMFhPx2mP
Fixes: AISLE-2026-0150-00274

Found-by: Joshua Rogers (AISLE)
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/interplayacm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/interplayacm.c b/libavcodec/interplayacm.c
index cd2e6faa676..0188390884b 100644
--- a/libavcodec/interplayacm.c
+++ b/libavcodec/interplayacm.c
@@ -96,6 +96,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
     s->cols  = 1 << s->level;
     s->wrapbuf_len = 2 * s->cols - 2;
     s->block_len = s->rows * s->cols;
+    if (s->block_len > 1024 * 1024) {
+        av_log(avctx, AV_LOG_ERROR, "Block of %d samples is too large\n", 
s->block_len);
+        return AVERROR_INVALIDDATA;
+    }
     s->max_framesize = s->block_len;
 
     s->block   = av_calloc(s->block_len, sizeof(int));
-- 
2.54.0


>From aaf66c34dbaf144c55d6d76d88dd1e8e45d819d9 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 02:15:24 +0100
Subject: [PATCH 2/6] avformat/sbgdec: reject sample rates above 192 kHz

Excessive memory allocation (peak RSS 2.3 GB from a 69 byte script)
Replicated through UnModified FFmpeg with ASAN

The limit of 192kHz is based on the assumtation that the output is for
playback and human listening

Fixes: out of memory
Fixes: 6m4Av2yQJEhE
Fixes: AISLE-2026-0150-00550

Found-by: Joshua Rogers (AISLE)
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavformat/sbgdec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/sbgdec.c b/libavformat/sbgdec.c
index 24f7d5161d1..36de40e0b2b 100644
--- a/libavformat/sbgdec.c
+++ b/libavformat/sbgdec.c
@@ -437,7 +437,7 @@ static int parse_options(struct sbg_parser *p)
                                  "syntax error for option -r");
                         return AVERROR_INVALIDDATA;
                     }
-                    if (r < 40) {
+                    if (r < 40 || r > 192000) {
                         snprintf(p->err_msg, sizeof(p->err_msg),
                                  "invalid sample rate");
                         return AVERROR_PATCHWELCOME;
-- 
2.54.0


>From 32434e13bc39bfcd6a9d8e0954fe9d5b4edef638 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 02:15:31 +0100
Subject: [PATCH 3/6] avcodec/apedec: reject legacy frames with more than 73728
 samples

Excessive memory allocation (peak RSS 2.58 GB from a 52 byte file)
Replicated through UnModified FFmpeg with ASAN

Fixes: out of memory
Fixes: 2cNjGsVIMOVX
Fixes: AISLE-2026-0150-00053

Found-by: Joshua Rogers (AISLE)
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/apedec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 9a184f98072..466c3c2001c 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -1598,7 +1598,8 @@ static int ape_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
                 skip_bits_long(&s->gb, offset);
         }
 
-        if (!nblocks || nblocks > INT_MAX / 2 / sizeof(*s->decoded_buffer) - 
8) {
+        if (!nblocks || nblocks > INT_MAX / 2 / sizeof(*s->decoded_buffer) - 8 
||
+            (s->fileversion < 3930 && nblocks > 73728)) {
             av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %"PRIu32".\n",
                    nblocks);
             return AVERROR_INVALIDDATA;
-- 
2.54.0


>From 30efa39d929808e98f95c24af93790722d71acdd Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 02:15:38 +0100
Subject: [PATCH 4/6] avcodec/takdec: require the multichannel channel list to
 cover all channels

Use of uninitialized memory Replicated through UnModified FFmpeg with MSAN

Fixes: use of uninitialized memory
Fixes: aWhU4kuts0tn
Fixes: AISLE-2026-0150-00040

Found-by: Joshua Rogers (AISLE)
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/takdec.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index ff77c3bfc6a..2f18ff77f2f 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -835,6 +835,10 @@ static int tak_decode_frame(AVCodecContext *avctx, AVFrame 
*frame,
 
                     ch_mask |= 1 << nbit;
                 }
+                if (ch_mask != (1 << avctx->ch_layout.nb_channels) - 1) {
+                    avpriv_request_sample(avctx, "Channel list not covering 
all channels");
+                    return AVERROR_PATCHWELCOME;
+                }
             } else {
                 chan = avctx->ch_layout.nb_channels;
                 for (i = 0; i < chan; i++) {
-- 
2.54.0


>From 49d9819b358d04a4320213d8fb0f84f9db3a8b70 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 02:15:38 +0100
Subject: [PATCH 5/6] avcodec/mlz: reject string codes beyond the dictionary

Use of uninitialized memory Replicated through UnModified FFmpeg with MSAN
Use of uninitialized memory Replicated through API with MSAN

Fixes: use of uninitialized memory
Fixes: ln0NC22XPto3
Fixes: AISLE-2026-0150-00420

Found-by: Joshua Rogers (AISLE)
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/mlz.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/mlz.c b/libavcodec/mlz.c
index 5176366439d..df994af4b45 100644
--- a/libavcodec/mlz.c
+++ b/libavcodec/mlz.c
@@ -159,6 +159,10 @@ int ff_mlz_decompression(MLZ* mlz, GetBitContext* gb, int 
size, unsigned char *b
                     mlz->bump_code = mlz->current_dic_index_max - 1;
                 } else {
                     if (string_code >= mlz->next_code) {
+                        if (string_code > mlz->next_code || last_string_code 
== CODE_UNSET) {
+                            av_log(mlz->context, AV_LOG_ERROR, "String code %d 
is not in the dictionary\n", string_code);
+                            return output_chars;
+                        }
                         int ret = decode_string(mlz, &buff[output_chars], 
last_string_code, &char_code, size - output_chars);
                         if (ret < 0 || ret > size - output_chars) {
                             av_log(mlz->context, AV_LOG_ERROR, "output chars 
overflow\n");
-- 
2.54.0


>From 8c8625d96b73b1170f852d469565c729eb077bf8 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 3 Nov 2026 02:15:38 +0100
Subject: [PATCH 6/6] avcodec/adxdec: validate the sample rate before changing
 the channel layout

Null pointer dereference Replicated through UnModified FFmpeg with ASAN

Fixes: null pointer dereference
Fixes: kmrMEk1So1o7
Fixes: AISLE-2026-0150-00566

Found-by: Joshua Rogers (AISLE)
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/adxdec.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index a79ae430aa6..3dfcf9be23c 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -50,7 +50,7 @@
 static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
                              int bufsize, int *header_size, int *coeff)
 {
-    int offset, cutoff, channels;
+    int offset, cutoff, channels, sample_rate;
 
     if (bufsize < 24)
         return AVERROR_INVALIDDATA;
@@ -74,17 +74,17 @@ static int adx_decode_header(AVCodecContext *avctx, const 
uint8_t *buf,
     if (channels <= 0 || channels > MAX_CHANNELS)
         return AVERROR_INVALIDDATA;
 
+    /* sample rate */
+    sample_rate = AV_RB32(buf + 8);
+    if (sample_rate < 1 || sample_rate > INT_MAX / (channels * BLOCK_SIZE * 8))
+        return AVERROR_INVALIDDATA;
+
     if (avctx->ch_layout.nb_channels != channels) {
         av_channel_layout_uninit(&avctx->ch_layout);
         avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
         avctx->ch_layout.nb_channels = channels;
     }
-
-    /* sample rate */
-    avctx->sample_rate = AV_RB32(buf + 8);
-    if (avctx->sample_rate < 1 ||
-        avctx->sample_rate > INT_MAX / (channels * BLOCK_SIZE * 8))
-        return AVERROR_INVALIDDATA;
+    avctx->sample_rate = sample_rate;
 
     /* bit rate */
     avctx->bit_rate = avctx->sample_rate * channels * BLOCK_SIZE * 8 / 
BLOCK_SAMPLES;
-- 
2.54.0

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

Reply via email to