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

## impact
these changes fix an uninitialized-memory disclosure in the fsb and genh thp 
extradata handling.
the issue is similar in nature to the recent webp fix in commit `cfaaf00`, 
where truncated input could result in uninitialized memory being exposed.
the primary issue is that the demuxers assumed that the requested extradata was 
fully read without verifying the actual amount returned by the io operation.

## verification
the changes were ai-assisted (Claude Opus 5 and 4.8) and reviewed and verified 
by unfunnyatearug.
a proof of concept is included:

* `poc.fsb`
* `leak_demo.c`

the poc demonstrates the truncated extradata condition and the resulting memory 
disclosure behavior.


>From 604863fed0666f778b6a688713a3eccffb7c63a5 Mon Sep 17 00:00:00 2001
From: unfunnyatearug <[email protected]>
Date: Tue, 18 Aug 2026 14:46:35 +0300
Subject: [PATCH 1/2] avformat/fsb: reject truncated thp coefficient extradata

the fsb demuxer used `avio_read(..., 32)` for each channel but ignored the 
return value.
`ff_alloc_extradata()` only clears the padding area. if the input file is 
truncated, the remaining extradata can therefore contain uninitialized memory.
`nb_channels` is a 16-bit value and was only limited by the `int_max / 32` 
calculation. this allows a truncated file to cause a leak of up to ~2 MB of 
uninitialized memory.
the affected extradata is used by the `adpcm_thp` decoder and can also be 
copied to the output during remuxing.
the fix replaces the unchecked reads with `ffio_read_size()`, which reports an 
error when the requested amount of data cannot be read. both the thp v3 and v4 
paths are fixed.

Signed-off-by: unfunnyatearug <[email protected]>
---
 libavformat/fsb.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavformat/fsb.c b/libavformat/fsb.c
index 0febeffd56..1164f48b94 100644
--- a/libavformat/fsb.c
+++ b/libavformat/fsb.c
@@ -23,6 +23,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "avio.h"
+#include "avio_internal.h"
 #include "demux.h"
 #include "internal.h"
 
@@ -93,7 +94,9 @@ static int fsb_read_header(AVFormatContext *s)
                 return ret;
             avio_seek(pb, 0x68, SEEK_SET);
             for (c = 0; c < par->ch_layout.nb_channels; c++) {
-                avio_read(pb, par->extradata + 32 * c, 32);
+                ret = ffio_read_size(pb, par->extradata + 32 * c, 32);
+                if (ret < 0)
+                    return ret;
                 avio_skip(pb, 14);
             }
         } else {
@@ -146,7 +149,9 @@ static int fsb_read_header(AVFormatContext *s)
                 return ret;
             avio_seek(pb, 0x80, SEEK_SET);
             for (c = 0; c < par->ch_layout.nb_channels; c++) {
-                avio_read(pb, par->extradata + 32 * c, 32);
+                ret = ffio_read_size(pb, par->extradata + 32 * c, 32);
+                if (ret < 0)
+                    return ret;
                 avio_skip(pb, 14);
             }
             par->block_align = 8 * par->ch_layout.nb_channels;
-- 
2.52.0


>From af9676a31357554348aa37163ae35f5f618b7713 Mon Sep 17 00:00:00 2001
From: unfunnyatearug <[email protected]>
Date: Tue, 18 Aug 2026 14:46:35 +0300
Subject: [PATCH 2/2] avformat/genh: check thp extradata read and allocation

the genh demuxer had the same short-read issue at one location. the read is now 
performed with `ffio_read_size()` so truncated input is rejected instead of 
leaving uninitialized data in the extradata.
`ff_alloc_extradata()` also had its return value unchecked. if allocation 
failed, the code could dereference a null pointer. the return value is now 
checked.
the affected path is capped at two channels, so the potential information leak 
is relatively small, but it is the same underlying bug class.

Signed-off-by: unfunnyatearug <[email protected]>
---
 libavformat/genh.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavformat/genh.c b/libavformat/genh.c
index deecca4a4c..32cad7382b 100644
--- a/libavformat/genh.c
+++ b/libavformat/genh.c
@@ -22,6 +22,7 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "demux.h"
 #include "internal.h"
 
@@ -132,14 +133,18 @@ static int genh_read_header(AVFormatContext *s)
             return AVERROR_PATCHWELCOME;
         }
 
-        ff_alloc_extradata(st->codecpar, 32 * 
st->codecpar->ch_layout.nb_channels);
+        ret = ff_alloc_extradata(st->codecpar, 32 * 
st->codecpar->ch_layout.nb_channels);
+        if (ret < 0)
+            return ret;
         for (ch = 0; ch < st->codecpar->ch_layout.nb_channels; ch++) {
             if (coef_type & 1) {
                 avpriv_request_sample(s, "coef_type & 1");
                 return AVERROR_PATCHWELCOME;
             } else {
                 avio_seek(s->pb, coef[ch], SEEK_SET);
-                avio_read(s->pb, st->codecpar->extradata + 32 * ch, 32);
+                ret = ffio_read_size(s->pb, st->codecpar->extradata + 32 * ch, 
32);
+                if (ret < 0)
+                    return ret;
             }
         }
 
-- 
2.52.0

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

Reply via email to