mirror of
https://mirror.skon.top/https://github.com/FFmpeg/FFmpeg
synced 2026-04-20 21:00:41 +08:00
avformat: check avio_read() return values in dss/dtshd/mlv
Multiple demuxers call avio_read() without checking its return value. When input is truncated, destination buffers remain uninitialized but are still used for offset calculations, memcmp, and metadata handling. This results in undefined behavior (detectable with Valgrind/MSan). Fix this by checking the return value of avio_read() in: - dss.c: dss_read_seek() — check before using header buffer - dtshddec.c: FILEINFO chunk — check before using value buffer - mlvdec.c: check_file_header() — check before memcmp on version Fixes: #21520
This commit is contained in:
committed by
Marton Balint
parent
1e031d4af7
commit
65eed0732c
@@ -26,6 +26,7 @@
|
||||
#include "avformat.h"
|
||||
#include "demux.h"
|
||||
#include "internal.h"
|
||||
#include "avio_internal.h"
|
||||
|
||||
#define DSS_HEAD_OFFSET_AUTHOR 0xc
|
||||
#define DSS_AUTHOR_SIZE 16
|
||||
@@ -339,7 +340,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 = ffio_read_size(s->pb, header, DSS_AUDIO_BLOCK_HEADER_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ctx->swap = !!(header[0] & 0x80);
|
||||
offset = 2*header[1] + 2*ctx->swap;
|
||||
if (offset < DSS_AUDIO_BLOCK_HEADER_SIZE)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "avformat.h"
|
||||
#include "demux.h"
|
||||
#include "internal.h"
|
||||
#include "avio_internal.h"
|
||||
|
||||
#define AUPR_HDR 0x415550522D484452
|
||||
#define AUPRINFO 0x41555052494E464F
|
||||
@@ -125,7 +126,11 @@ static int dtshd_read_header(AVFormatContext *s)
|
||||
value = av_malloc(chunk_size);
|
||||
if (!value)
|
||||
goto skip;
|
||||
avio_read(pb, value, chunk_size);
|
||||
ret = ffio_read_size(pb, value, chunk_size);
|
||||
if (ret < 0) {
|
||||
av_free(value);
|
||||
goto skip;
|
||||
}
|
||||
value[chunk_size - 1] = 0;
|
||||
av_dict_set(&s->metadata, "fileinfo", value,
|
||||
AV_DICT_DONT_STRDUP_VAL);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "avformat.h"
|
||||
#include "demux.h"
|
||||
#include "internal.h"
|
||||
#include "avio_internal.h"
|
||||
#include "riff.h"
|
||||
|
||||
#define MLV_VERSION "v2.0"
|
||||
@@ -74,12 +75,15 @@ static int check_file_header(AVIOContext *pb, uint64_t guid)
|
||||
{
|
||||
unsigned int size;
|
||||
uint8_t version[8];
|
||||
int ret;
|
||||
|
||||
avio_skip(pb, 4);
|
||||
size = avio_rl32(pb);
|
||||
if (size < 52)
|
||||
return AVERROR_INVALIDDATA;
|
||||
avio_read(pb, version, 8);
|
||||
ret = ffio_read_size(pb, version, 8);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (memcmp(version, MLV_VERSION, 5) || avio_rl64(pb) != guid)
|
||||
return AVERROR_INVALIDDATA;
|
||||
avio_skip(pb, size - 24);
|
||||
|
||||
Reference in New Issue
Block a user