mirror of
https://github.com/VirusTotal/yara.git
synced 2026-10-11 22:49:58 +00:00
bound tilde stream row-count read in dotnet_parse_tilde_2 (#2224)
dotnet_parse_tilde computes tilde_stream_end and checks each row-count read against it since #2196 (fits_in_pe was only checking the read against the whole PE buffer, not the #~ stream's own declared Size). dotnet_parse_tilde_2 is called right after with the same tilde_header and streams, but it independently re-reads the identical row-count array using the pre-#2196 fits_in_pe check - the #2196 fix never touched this function. tilde_stream_end is derived from streams->tilde->Offset and Size, which are read straight from the stream header with no bound against pe->data_size (dotnet_parse_stream_headers only validates the header struct itself fits in the PE, not the Offset/Size values it stores). So tilde_stream_end can point past the real buffer. dotnet_parse_tilde stays safe despite this because it first does a whole-array fits_in_pe(pe, row_offset, valid_count * sizeof(uint32_t)) before the loop, and only uses tilde_stream_end afterward as a secondary restriction on top of that already-verified range. dotnet_parse_tilde_2 has no such preceding fits_in_pe over the row array, so swapping its per-row fits_in_pe check for a tilde_stream_end-only check (as this PR did originally) would have made tilde_stream_end the sole bound on the read, which is unsafe since it's an unclamped, file-controlled pointer. Keep the fits_in_pe check and add the tilde_stream_end check on top, matching the two-layer approach dotnet_parse_tilde already uses. Built locally and ran make test-dotnet, passes clean.
This commit is contained in:
@@ -1917,6 +1917,10 @@ void dotnet_parse_tilde_2(
|
||||
const uint8_t* string_offset;
|
||||
const uint8_t* blob_offset;
|
||||
|
||||
const uint8_t* tilde_stream_end = pe->data + metadata_root +
|
||||
yr_le32toh(streams->tilde->Offset) +
|
||||
yr_le32toh(streams->tilde->Size);
|
||||
|
||||
uint32_t num_rows = 0;
|
||||
uint32_t valid_rows = 0;
|
||||
uint32_t* row_offset = NULL;
|
||||
@@ -1992,7 +1996,8 @@ void dotnet_parse_tilde_2(
|
||||
if (!((yr_le64toh(tilde_header->Valid) >> bit_check) & 0x01))
|
||||
continue;
|
||||
|
||||
if (!fits_in_pe(pe, row_offset + matched_bits, sizeof(uint32_t)))
|
||||
if (!fits_in_pe(pe, row_offset + matched_bits, sizeof(uint32_t)) ||
|
||||
(uint8_t*) (row_offset + matched_bits + 1) > tilde_stream_end)
|
||||
return;
|
||||
|
||||
num_rows = yr_le32toh(*(row_offset + matched_bits));
|
||||
|
||||
Reference in New Issue
Block a user