libwebp: validate chunk size in ParseOptionalChunks

the max wasn't checked leading to a rollover case, possibly exploitable.
additionally check the RIFF size early, to avoid similar issues.

pulled from chromium:
 http://codereview.chromium.org/11229048/

Change-Id: Ifebc712bf3d3de0129b76ca4c57c68e062abc429
This commit is contained in:
James Zern 2012-10-22 21:57:59 -07:00
parent 704818980f
commit 30763333f3

View File

@ -76,6 +76,9 @@ static VP8StatusCode ParseRIFF(const uint8_t** const data,
if (size < TAG_SIZE + CHUNK_HEADER_SIZE) { if (size < TAG_SIZE + CHUNK_HEADER_SIZE) {
return VP8_STATUS_BITSTREAM_ERROR; return VP8_STATUS_BITSTREAM_ERROR;
} }
if (size > MAX_CHUNK_PAYLOAD) {
return VP8_STATUS_BITSTREAM_ERROR;
}
// We have a RIFF container. Skip it. // We have a RIFF container. Skip it.
*riff_size = size; *riff_size = size;
*data += RIFF_HEADER_SIZE; *data += RIFF_HEADER_SIZE;
@ -177,6 +180,9 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
} }
chunk_size = get_le32(buf + TAG_SIZE); chunk_size = get_le32(buf + TAG_SIZE);
if (chunk_size > MAX_CHUNK_PAYLOAD) {
return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
}
// For odd-sized chunk-payload, there's one byte padding at the end. // For odd-sized chunk-payload, there's one byte padding at the end.
disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1; disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
total_size += disk_chunk_size; total_size += disk_chunk_size;