mkvparser: Segment::ParseHeaders() avoid rollover and bad int sizes.
BUG=23226908 Change-Id: I177fc75684daa3c0282b63ec270d095251a70881
This commit is contained in:
parent
f250aceeaa
commit
39a315f8c1
@ -793,6 +793,11 @@ long long Segment::ParseHeaders() {
|
|||||||
long long pos = m_pos;
|
long long pos = m_pos;
|
||||||
const long long element_start = pos;
|
const long long element_start = pos;
|
||||||
|
|
||||||
|
// Avoid rolling over pos when very close to LONG_LONG_MAX.
|
||||||
|
unsigned long long rollover_check = pos + 1ULL;
|
||||||
|
if (rollover_check > LONG_LONG_MAX)
|
||||||
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
if ((pos + 1) > available)
|
if ((pos + 1) > available)
|
||||||
return (pos + 1);
|
return (pos + 1);
|
||||||
|
|
||||||
@ -802,8 +807,10 @@ long long Segment::ParseHeaders() {
|
|||||||
if (result < 0) // error
|
if (result < 0) // error
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (result > 0) // underflow (weird)
|
if (result > 0) {
|
||||||
|
// MkvReader doesn't have enough data to satisfy this read attempt.
|
||||||
return (pos + 1);
|
return (pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((segment_stop >= 0) && ((pos + len) > segment_stop))
|
if ((segment_stop >= 0) && ((pos + len) > segment_stop))
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
@ -814,8 +821,13 @@ long long Segment::ParseHeaders() {
|
|||||||
const long long idpos = pos;
|
const long long idpos = pos;
|
||||||
const long long id = ReadUInt(m_pReader, idpos, len);
|
const long long id = ReadUInt(m_pReader, idpos, len);
|
||||||
|
|
||||||
if (id < 0) // error
|
if (id < 0 || len < 1 || len > 4) {
|
||||||
|
// TODO(tomfinegan): A helper that is intended for reading IDs would be
|
||||||
|
// handy; even better if its aware of the max ID size from the EBML
|
||||||
|
// header. It could easily enforce the rules here, instead of duping this
|
||||||
|
// check everytime an ID is read.
|
||||||
return id;
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
if (id == 0x0F43B675) // Cluster ID
|
if (id == 0x0F43B675) // Cluster ID
|
||||||
break;
|
break;
|
||||||
@ -831,8 +843,10 @@ long long Segment::ParseHeaders() {
|
|||||||
if (result < 0) // error
|
if (result < 0) // error
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (result > 0) // underflow (weird)
|
if (result > 0) {
|
||||||
|
// MkvReader doesn't have enough data to satisfy this read attempt.
|
||||||
return (pos + 1);
|
return (pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((segment_stop >= 0) && ((pos + len) > segment_stop))
|
if ((segment_stop >= 0) && ((pos + len) > segment_stop))
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
@ -842,11 +856,19 @@ long long Segment::ParseHeaders() {
|
|||||||
|
|
||||||
const long long size = ReadUInt(m_pReader, pos, len);
|
const long long size = ReadUInt(m_pReader, pos, len);
|
||||||
|
|
||||||
if (size < 0) // error
|
if (size < 0 || len < 1 || len > 8) {
|
||||||
|
// TODO(tomfinegan): ReadUInt should return an error when len is < 1 or
|
||||||
|
// len > 8 is true instead of checking this _everywhere_.
|
||||||
return size;
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
pos += len; // consume length of size of element
|
pos += len; // consume length of size of element
|
||||||
|
|
||||||
|
// Avoid rolling over pos when very close to LONG_LONG_MAX.
|
||||||
|
rollover_check = static_cast<unsigned long long>(pos) + size;
|
||||||
|
if (rollover_check > LONG_LONG_MAX)
|
||||||
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
const long long element_size = size + pos - element_start;
|
const long long element_size = size + pos - element_start;
|
||||||
|
|
||||||
// Pos now points to start of payload
|
// Pos now points to start of payload
|
||||||
|
Loading…
x
Reference in New Issue
Block a user