muxread,CreateInternal: fix riff size checks

previously when adjusting size down based on a smaller riff_size the
checks were insufficient to prevent 'size -= RIFF_HEADER_SIZE' from
rolling over causing ChunkVerifyAndAssign to over read. the new checks
are imported from demux.c.

BUG=webp:386

Change-Id: If863c4a9892977b9ade7dd894392a0ecae13775c
(cherry picked from commit 2c70ad76c9)
This commit is contained in:
James Zern 2018-06-14 00:03:34 -07:00
parent a0b85e4a36
commit 706ff9c325

View File

@ -187,7 +187,7 @@ WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
size = bitstream->size; size = bitstream->size;
if (data == NULL) return NULL; if (data == NULL) return NULL;
if (size < RIFF_HEADER_SIZE) return NULL; if (size < RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE) return NULL;
if (GetLE32(data + 0) != MKFOURCC('R', 'I', 'F', 'F') || if (GetLE32(data + 0) != MKFOURCC('R', 'I', 'F', 'F') ||
GetLE32(data + CHUNK_HEADER_SIZE) != MKFOURCC('W', 'E', 'B', 'P')) { GetLE32(data + CHUNK_HEADER_SIZE) != MKFOURCC('W', 'E', 'B', 'P')) {
return NULL; return NULL;
@ -196,8 +196,6 @@ WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
mux = WebPMuxNew(); mux = WebPMuxNew();
if (mux == NULL) return NULL; if (mux == NULL) return NULL;
if (size < RIFF_HEADER_SIZE + TAG_SIZE) goto Err;
tag = GetLE32(data + RIFF_HEADER_SIZE); tag = GetLE32(data + RIFF_HEADER_SIZE);
if (tag != kChunks[IDX_VP8].tag && if (tag != kChunks[IDX_VP8].tag &&
tag != kChunks[IDX_VP8L].tag && tag != kChunks[IDX_VP8L].tag &&
@ -206,12 +204,11 @@ WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
} }
riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE)); riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE));
if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) { if (riff_size < CHUNK_HEADER_SIZE) goto Err;
goto Err; if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) goto Err;
} else { // There's no point in reading past the end of the RIFF chunk.
if (riff_size < size) { // Redundant data after last chunk. if (size > riff_size + CHUNK_HEADER_SIZE) {
size = riff_size; // To make sure we don't read any data beyond mux_size. size = riff_size + CHUNK_HEADER_SIZE;
}
} }
end = data + size; end = data + size;