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

`mov_write_avid_tag()` accepts DNxHD extradata longer than 0x29 bytes, but then 
reads the compression ID with `AV_RB32(extradata + 0x28)` (bytes 0x28-0x2B) 
and, for `AVdh`, `extradata[0x2C]`. So extradata of 42-44 bytes is read up to 3 
bytes past its end.

Extradata that arrives as `AV_PKT_DATA_NEW_EXTRADATA` side data is copied into 
`MOVTrack.extradata` with `av_memdup()` and is not padded, so these reads leave 
the allocation. For example, remuxing a DNxHD (`AVdh`) NUT file whose packet 
carries 42 bytes of new extradata starting with a DNxHD header prefix:

```
ffmpeg -i poc42.nut -c copy out.mov
```

ASan reports a heap-buffer-overflow READ of size 4 in `mov_write_avid_tag` (42 
and 43 bytes) and of size 1 at `extradata[0x2C]` (44 bytes). The bytes read end 
up in the ACLR/ADHR atoms of the output.

The fix requires more than 0x2C bytes before using the header fields. With it, 
the 42-44 byte cases take the existing "vos_data too small" path and ASan is 
clean. Output for regular DNxHD input is unchanged: a 64-byte control file 
remuxes byte-identically, and the DNxHD and MOV FATE tests 
(`fate-vsynth{1,2}-dnxhd-*` including the `-mov` variants, `fate-lavf-mov`, 
`fate-lavf-mp4`, `fate-lavf-ismv`, `fate-api-movenc`, 39 tests) pass.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified 
manually.

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



From 8d96d880389fdea681e791b5464dad20d53f619a Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Mon, 26 Oct 2026 20:06:05 +0800
Subject: [PATCH] avformat/movenc: require enough DNxHD header bytes for the
 Avid tags

mov_write_avid_tag() accepted extradata longer than 0x29 bytes, but
reads the compression ID at 0x28-0x2B and, for AVdh, the byte at 0x2C.
New extradata from AV_PKT_DATA_NEW_EXTRADATA side data is copied with
av_memdup() and not padded, so 42-44 bytes of it with a DNxHD header
prefix made these reads go up to 3 bytes past the buffer, and the
bytes ended up in the ACLR/ADHR atoms. Require more than 0x2C bytes.

Signed-off-by: Martin Mirchev <[email protected]>
---
 libavformat/movenc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index debe1acb7e0..8f288877228 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1820,7 +1820,8 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack 
*track)
     int display_width = track->par->width;
     const uint8_t *extradata;
 
-    if (track->extradata[track->last_stsd_index] && 
track->extradata_size[track->last_stsd_index] > 0x29) {
+    /* the header fields read below go up to offset 0x2C */
+    if (track->extradata[track->last_stsd_index] && 
track->extradata_size[track->last_stsd_index] > 0x2C) {
         if 
(ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
             /* looks like a DNxHD bit stream */
             extradata = track->extradata[track->last_stsd_index];
-- 
2.54.0

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

Reply via email to