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

Fixes: stack buffer overflow
Fixes: M3Ib1Zm6OX8V/testcase/crafted.asf / gen.py
Fixes: M3Ib1Zm6OX8V
Found-by: Zheng Yu @ Depthfirst


>From 8e6f8e6649ff1070de5aa2492a9d4eaa35e7263f Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 15 Sep 2026 06:02:19 +0200
Subject: [PATCH 1/3] avformat/asfdec_f: index the seek position table by ASF
 stream number

Fixes: stack buffer overflow
Fixes: M3Ib1Zm6OX8V/testcase/crafted.asf / gen.py
Fixes: M3Ib1Zm6OX8V
Found-by: Zheng Yu @ Depthfirst
---
 libavformat/asfdec_f.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index a1a0428184..eb30283ce1 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -1451,9 +1451,9 @@ static int64_t asf_read_pts(AVFormatContext *s, int 
stream_index,
     int64_t pts;
     int64_t pos = *ppos;
     int i;
-    int64_t start_pos[ASF_MAX_STREAMS];
+    int64_t start_pos[FF_ARRAY_ELEMS(asf->streams)];
 
-    for (i = 0; i < s->nb_streams; i++)
+    for (i = 0; i < FF_ARRAY_ELEMS(start_pos); i++)
         start_pos[i] = pos;
 
     if (s->packet_size > 0)
@@ -1475,17 +1475,17 @@ static int64_t asf_read_pts(AVFormatContext *s, int 
stream_index,
         pts = pkt->dts;
 
         if (pkt->flags & AV_PKT_FLAG_KEY) {
-            i = pkt->stream_index;
+            AVStream *st = s->streams[pkt->stream_index];
 
-            asf_st = &asf->streams[s->streams[i]->id];
+            asf_st = &asf->streams[st->id];
 
 //            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 
0);
             pos = asf_st->packet_pos;
             av_assert1(pkt->pos == asf_st->packet_pos);
 
-            av_add_index_entry(s->streams[i], pos, pts, pkt->size,
-                               pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
-            start_pos[i] = asf_st->packet_pos + 1;
+            av_add_index_entry(st, pos, pts, pkt->size,
+                               pos - start_pos[st->id] + 1, AVINDEX_KEYFRAME);
+            start_pos[st->id] = asf_st->packet_pos + 1;
 
             if (pkt->stream_index == stream_index) {
                 av_packet_unref(pkt);
-- 
2.52.0


>From a098ec76fbb959d6700069f1ba3112f27cecb3e5 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 15 Sep 2026 22:53:10 +0200
Subject: [PATCH 2/3] avformat/asfdec_f: index keyframes at the packet position
 in asf_read_pts()

Fixes: assertion failure
Found during triage/review of the security report M3Ib1Zm6OX8V
---
 libavformat/asfdec_f.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index eb30283ce1..212ad44964 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -1447,7 +1447,6 @@ static int64_t asf_read_pts(AVFormatContext *s, int 
stream_index,
     FFFormatContext *const si = ffformatcontext(s);
     ASFContext *asf     = s->priv_data;
     AVPacket pkt1, *pkt = &pkt1;
-    ASFStream *asf_st;
     int64_t pts;
     int64_t pos = *ppos;
     int i;
@@ -1477,15 +1476,10 @@ static int64_t asf_read_pts(AVFormatContext *s, int 
stream_index,
         if (pkt->flags & AV_PKT_FLAG_KEY) {
             AVStream *st = s->streams[pkt->stream_index];
 
-            asf_st = &asf->streams[st->id];
-
-//            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 
0);
-            pos = asf_st->packet_pos;
-            av_assert1(pkt->pos == asf_st->packet_pos);
-
+            pos = pkt->pos;
             av_add_index_entry(st, pos, pts, pkt->size,
                                pos - start_pos[st->id] + 1, AVINDEX_KEYFRAME);
-            start_pos[st->id] = asf_st->packet_pos + 1;
+            start_pos[st->id] = pos + 1;
 
             if (pkt->stream_index == stream_index) {
                 av_packet_unref(pkt);
-- 
2.52.0


>From a618ca733b8c39927d4711b4701216c08680cc5d Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Tue, 15 Sep 2026 22:54:29 +0200
Subject: [PATCH 3/3] avformat/asfdec_f: drop the stream count limit

Found during triage/review of the security report M3Ib1Zm6OX8V
---
 libavformat/asfdec_f.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index 212ad44964..d02c843ba6 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -134,7 +134,6 @@ static const AVClass asf_class = {
 #undef NDEBUG
 #include <assert.h>
 
-#define ASF_MAX_STREAMS 127
 #define FRAME_HEADER_SIZE 6
 // Fix Me! FRAME_HEADER_SIZE may be different.
 // (7 is known to be too large for GipsyGuitar.wmv)
@@ -311,11 +310,6 @@ static int asf_read_stream_properties(AVFormatContext *s, 
int64_t size)
     int64_t pos1, pos2, start_time;
     int test_for_ext_stream_audio, is_dvr_ms_audio = 0;
 
-    if (s->nb_streams == ASF_MAX_STREAMS) {
-        av_log(s, AV_LOG_ERROR, "too many streams\n");
-        return AVERROR(EINVAL);
-    }
-
     pos1 = avio_tell(pb);
 
     st = avformat_new_stream(s, NULL);
-- 
2.52.0

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

Reply via email to