mkvparser: Handle invalid lengths and rollover in ParseElementHeader().
BUG=23224239 Change-Id: I597054dc552b54f99a6716fb8f1b0f2480f2a29b
This commit is contained in:
@@ -289,31 +289,42 @@ long mkvparser::UnserializeString(IMkvReader* pReader, long long pos,
|
|||||||
long mkvparser::ParseElementHeader(IMkvReader* pReader, long long& pos,
|
long mkvparser::ParseElementHeader(IMkvReader* pReader, long long& pos,
|
||||||
long long stop, long long& id,
|
long long stop, long long& id,
|
||||||
long long& size) {
|
long long& size) {
|
||||||
if ((stop >= 0) && (pos >= stop))
|
if (stop >= 0 && pos >= stop)
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
long len;
|
long len;
|
||||||
|
|
||||||
id = ReadUInt(pReader, pos, len);
|
id = ReadUInt(pReader, pos, len);
|
||||||
|
|
||||||
if (id < 0)
|
if (id < 0 || len < 1 || len > 4)
|
||||||
|
// An ID must be at least 1 byte long, and cannot exceed 4.
|
||||||
|
// See EBMLMaxIDLength: http://www.matroska.org/technical/specs/index.html
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
pos += len; // consume id
|
pos += len; // consume id
|
||||||
|
|
||||||
if ((stop >= 0) && (pos >= stop))
|
if (stop >= 0 && pos >= stop)
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
size = ReadUInt(pReader, pos, len);
|
size = ReadUInt(pReader, pos, len);
|
||||||
|
|
||||||
if (size < 0)
|
if (size < 0 || len < 1 || len > 8) {
|
||||||
|
// Invalid: Negative payload size, negative or 0 length integer, or integer
|
||||||
|
// larger than 64 bits (libwebm cannot handle them).
|
||||||
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid rolling over pos when very close to LONG_LONG_MAX.
|
||||||
|
const unsigned long long rollover_check =
|
||||||
|
static_cast<unsigned long long>(pos) + len;
|
||||||
|
if (rollover_check > LONG_LONG_MAX)
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
pos += len; // consume length of size
|
pos += len; // consume length of size
|
||||||
|
|
||||||
// pos now designates payload
|
// pos now designates payload
|
||||||
|
|
||||||
if ((stop >= 0) && ((pos + size) > stop))
|
if (stop >= 0 && pos >= stop)
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
return 0; // success
|
return 0; // success
|
||||||
|
|||||||
Reference in New Issue
Block a user