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

Multiple FFmpeg demuxers call avio_read() without checking the return value.
With truncated input, destination buffers remain uninitialized but are still
used (memcmp, metadata handling, offset calculations), leading to undefined
behavior detectable with Valgrind/MSan.

This patch series fixes three demuxers:
- libavformat/dss.c: dss_read_seek() 
- libavformat/dtshddec.c: dtshd_read_header() FILEINFO path
- libavformat/mlvdec.c: check_file_header()

Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21520



>From 457930d5598f1bd010d90b0ed0e52a12959de4cc Mon Sep 17 00:00:00 2001
From: Sankalpa Sarkar <[email protected]>
Date: Sun, 22 Feb 2026 13:47:34 +0530
Subject: [PATCH 1/3] avformat/dss: check avio_read() return value in
 dss_read_seek()

dss_read_seek() reads into a stack buffer via avio_read() but does not
check the return value. With truncated input, the header buffer remains
uninitialized and is used to derive offsets and branch conditions,
leading to undefined behavior detectable with Valgrind.

Fixes part of: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21520

Signed-off-by: Sankalpa Sarkar <[email protected]>
---
 libavformat/dss.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavformat/dss.c b/libavformat/dss.c
index 6cabdb5421..af56d1b271 100644
--- a/libavformat/dss.c
+++ b/libavformat/dss.c
@@ -339,7 +339,9 @@ static int dss_read_seek(AVFormatContext *s, int 
stream_index,
     if (ret < 0)
         return ret;
 
-    avio_read(s->pb, header, DSS_AUDIO_BLOCK_HEADER_SIZE);
+    ret = avio_read(s->pb, header, DSS_AUDIO_BLOCK_HEADER_SIZE);
+    if (ret < DSS_AUDIO_BLOCK_HEADER_SIZE)
+        return ret < 0 ? ret : AVERROR_EOF;
     ctx->swap = !!(header[0] & 0x80);
     offset = 2*header[1] + 2*ctx->swap;
     if (offset < DSS_AUDIO_BLOCK_HEADER_SIZE)
-- 
2.52.0


>From b68ce209820a7210b289eefae4c2035b90a4f02a Mon Sep 17 00:00:00 2001
From: Sankalpa Sarkar <[email protected]>
Date: Sun, 22 Feb 2026 13:47:51 +0530
Subject: [PATCH 2/3] avformat/dtshddec: check avio_read() return value in
 FILEINFO path

dtshd_read_header() FILEINFO path uses avio_read() without checking
the return value. On truncated input, the heap buffer may be partially
uninitialized but is still used for metadata, leading to undefined
behavior.

Fixes part of: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21520

Signed-off-by: Sankalpa Sarkar <[email protected]>
---
 libavformat/dtshddec.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavformat/dtshddec.c b/libavformat/dtshddec.c
index b980fde6a9..779f8aa576 100644
--- a/libavformat/dtshddec.c
+++ b/libavformat/dtshddec.c
@@ -125,8 +125,12 @@ static int dtshd_read_header(AVFormatContext *s)
             value = av_malloc(chunk_size);
             if (!value)
                 goto skip;
-            avio_read(pb, value, chunk_size);
-            value[chunk_size - 1] = 0;
+            ret = avio_read(pb, value, chunk_size);
+            if (ret < 0) {
+                av_free(value);
+                return ret;
+            }
+            value[ret - 1] = 0;
             av_dict_set(&s->metadata, "fileinfo", value,
                         AV_DICT_DONT_STRDUP_VAL);
             break;
-- 
2.52.0


>From c900277eadde4e5b4c39a584e878d5e4dae81621 Mon Sep 17 00:00:00 2001
From: Sankalpa Sarkar <[email protected]>
Date: Sun, 22 Feb 2026 13:48:11 +0530
Subject: [PATCH 3/3] avformat/mlvdec: check avio_read() return value in
 check_file_header()

check_file_header() uses avio_read() to read the version field but does
not check the return value. With truncated input, the version buffer
remains uninitialized and is used in memcmp(), leading to undefined
behavior detectable with Valgrind/MSan.

Fixes part of: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21520

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

diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c
index 3a5d211085..4036c748dc 100644
--- a/libavformat/mlvdec.c
+++ b/libavformat/mlvdec.c
@@ -79,7 +79,8 @@ static int check_file_header(AVIOContext *pb, uint64_t guid)
     size = avio_rl32(pb);
     if (size < 52)
         return AVERROR_INVALIDDATA;
-    avio_read(pb, version, 8);
+    if (avio_read(pb, version, 8) < 8)
+        return AVERROR_INVALIDDATA;
     if (memcmp(version, MLV_VERSION, 5) || avio_rl64(pb) != guid)
         return AVERROR_INVALIDDATA;
     avio_skip(pb, size - 24);
-- 
2.52.0

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

Reply via email to