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

pmt_cb() passes mp4_descr + mp4_descr_count as the output base but
MAX_MP4_DESCR_COUNT (16) as the capacity, not the remaining capacity.
init_MP4DescrParseContext() resets d->descr_count to 0 on every call,
so the bounds check at parse_MP4ESDescrTag compares a fresh 0 against
16 regardless of the shifted base.

A PMT with two IOD descriptors of 16 ESDescrs each will crash. The first
fills the buffer mp4_descr[0..15], and then the second writes
mp4_descr[16..31] -- 1152 bytes past the end of the stack.

This change passes the remaining capacity instead of always passing 16.
The writeback in mp4_read_iods is incremented so the caller's running
count is preserved.

Fixes: stack-buffer-overflow

Found-by: Nicholas Carlini <[email protected]>


>From 89df937817cb02cc8e0f135fad6f460f5a8e275c Mon Sep 17 00:00:00 2001
From: Nicholas Carlini <[email protected]>
Date: Sun, 15 Mar 2026 23:10:51 +0000
Subject: [PATCH] avformat/mpegts: fix descriptor accounting across multiple
 IOD descriptors

pmt_cb() passes mp4_descr + mp4_descr_count as the output base but
MAX_MP4_DESCR_COUNT (16) as the capacity, not the remaining capacity.
init_MP4DescrParseContext() resets d->descr_count to 0 on every call,
so the bounds check at parse_MP4ESDescrTag compares a fresh 0 against
16 regardless of the shifted base.

A PMT with two IOD descriptors of 16 ESDescrs each will crash. The first
fills the buffer mp4_descr[0..15], and then the second writes
mp4_descr[16..31] -- 1152 bytes past the end of the stack.

This change passes the remaining capacity instead of always passing 16.
The writeback in mp4_read_iods is incremented so the caller's running
count is preserved.

Fixes: stack-buffer-overflow

Found-by: Nicholas Carlini <[email protected]>
---
 libavformat/mpegts.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index bfbdbf5b19..4b326d309b 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -1703,7 +1703,7 @@ static int mp4_read_iods(AVFormatContext *s, const 
uint8_t *buf, unsigned size,
 
     ret = parse_mp4_descr(&d, avio_tell(&d.pb.pub), size, MP4IODescrTag);
 
-    *descr_count = d.descr_count;
+    *descr_count += d.descr_count;
     return ret;
 }
 
@@ -2614,7 +2614,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
             get8(&p, p_end); // label
             len -= 2;
             mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count,
-                          &mp4_descr_count, MAX_MP4_DESCR_COUNT);
+                          &mp4_descr_count, MAX_MP4_DESCR_COUNT - 
mp4_descr_count);
         } else if (tag == REGISTRATION_DESCRIPTOR && len >= 4) {
             prog_reg_desc = bytestream_get_le32(&p);
             len -= 4;
-- 
2.52.0

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

Reply via email to