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

# Summary of changes

Commit: `avformat/nutdec: fail on a short read of an elision header`.

decode_main_header() fills each av_malloc()ed elision header with an unchecked 
avio_read(),
and decode_frame() later copies the whole header into every packet that 
references it. The
reserved-bytes skip and the checksum normally reject a truncated main header; 
they do not when
the declared length ends exactly at the end of the file and the bytes present 
carry a matching
checksum. Found by reading the code, not reproduced with a sample.

The fix uses ffio_read_size() and the existing failure path; `nut->header[i]` 
is assigned before
the read so that path frees it. fate-lavf-nut passes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


From 6698903c734ec34f1b85be0ae8a0808af9187c0f Mon Sep 17 00:00:00 2001
From: StressTestor <[email protected]>
Date: Sun, 11 Oct 2026 22:30:07 -0600
Subject: [PATCH] avformat/nutdec: fail on a short read of an elision header

decode_main_header() allocates each elision header with av_malloc()
and fills it with avio_read() without checking the return value. The
headers are later memcpy'd verbatim into the start of every packet
that references them (decode_frame), so a main header that ends
inside an elision header would hand uninitialised heap bytes to the
packet payload. The reserved-bytes skip and the checksum that follow
normally reject such a header; they do not when the declared packet
length ends exactly at the end of the file and the bytes that are
present carry a matching checksum.

Found by reading the code; not reproduced with a sample.

Use ffio_read_size() and take the existing failure path, which frees
the headers allocated so far. nut->header[i] is assigned before the
read so that path also frees the one that failed.

Same class as c2394a0ff3 (binka), 29f513af78 (fsb), 4b47405e1c (genh).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: StressTestor <[email protected]>
---
 libavformat/nutdec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 7ec8526a06..d00ba492b6 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -337,8 +337,10 @@ static int decode_main_header(NUTContext *nut)
                 ret = AVERROR(ENOMEM);
                 goto fail;
             }
-            avio_read(bc, hdr, nut->header_len[i]);
             nut->header[i] = hdr;
+            ret = ffio_read_size(bc, hdr, nut->header_len[i]);
+            if (ret < 0)
+                goto fail;
         }
         av_assert0(nut->header_len[0] == 0);
     }
-- 
2.52.0

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

Reply via email to