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]
