aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2011-02-06 11:32:03 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-02-09 03:31:17 +0100
commit14d735bd4f7c1dda547d4a4bd3de31536ef11a2a (patch)
tree13aa9d5947b791b3a27b8d37936c88482b305836
parentcb9f7fd34c07de6bceb1fb03057f5f0fe42ca0e8 (diff)
downloadffmpeg-14d735bd4f7c1dda547d4a4bd3de31536ef11a2a.tar.gz
matroskadec: add generic element length validation.
This validate the length of a mkv element directly after reading it. This has the advantage that it is easy to add new limits and makes it less likely to forget to add checks and also avoids issues like bits of the length value above the first 32 being ignored because the parsing functions only takes an int. Previously discussed in the "mkv 0-byte integer parsing" thread. Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com> (cherry picked from commit 95ec3d4cacd084e2448c3a1aba420e7d8f00e19b)
-rw-r--r--libavformat/matroskadec.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 1a87f4a0c6..9a670e86c8 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -58,6 +58,7 @@ typedef enum {
EBML_NEST,
EBML_PASS,
EBML_STOP,
+ EBML_TYPE_COUNT
} EbmlType;
typedef const struct EbmlSyntax {
@@ -780,6 +781,16 @@ static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
static int ebml_parse_elem(MatroskaDemuxContext *matroska,
EbmlSyntax *syntax, void *data)
{
+ static const uint64_t max_lengths[EBML_TYPE_COUNT] = {
+ [EBML_UINT] = 8,
+ [EBML_FLOAT] = 8,
+ // max. 16 MB for strings
+ [EBML_STR] = 0x1000000,
+ [EBML_UTF8] = 0x1000000,
+ // max. 256 MB for binary data
+ [EBML_BIN] = 0x10000000,
+ // no limits for anything else
+ };
ByteIOContext *pb = matroska->ctx->pb;
uint32_t id = syntax->id;
uint64_t length;
@@ -798,6 +809,12 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
matroska->current_id = 0;
if ((res = ebml_read_length(matroska, pb, &length)) < 0)
return res;
+ if (max_lengths[syntax->type] && length > max_lengths[syntax->type]) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Invalid length 0x%"PRIx64" > 0x%"PRIx64" for syntax element %i\n",
+ length, max_lengths[syntax->type], syntax->type);
+ return AVERROR_INVALIDDATA;
+ }
}
switch (syntax->type) {