| Index: chrome/utility/safe_browsing/mac/udif.cc
|
| diff --git a/chrome/utility/safe_browsing/mac/udif.cc b/chrome/utility/safe_browsing/mac/udif.cc
|
| index 9a48efa50023474d0912d0cc2bc151048be8d1e9..22d66c0453dd1ae22a215a9a24ce8c070866bcc8 100644
|
| --- a/chrome/utility/safe_browsing/mac/udif.cc
|
| +++ b/chrome/utility/safe_browsing/mac/udif.cc
|
| @@ -190,7 +190,14 @@ class UDIFBlock {
|
| public:
|
| UDIFBlock() : block_() {}
|
|
|
| - bool ParseBlockData(const UDIFBlockData* block_data, uint16_t sector_size) {
|
| + bool ParseBlockData(const UDIFBlockData* block_data,
|
| + size_t block_data_size,
|
| + uint16_t sector_size) {
|
| + if (block_data_size < sizeof(block_)) {
|
| + DLOG(ERROR) << "UDIF block data is smaller than expected";
|
| + return false;
|
| + }
|
| +
|
| block_ = *block_data;
|
| ConvertBigEndian(&block_);
|
|
|
| @@ -202,6 +209,19 @@ class UDIFBlock {
|
| return false;
|
| }
|
|
|
| + // Make sure the block data contains the reported number of chunks.
|
| + auto block_and_chunks_size =
|
| + (base::CheckedNumeric<size_t>(sizeof(UDIFBlockChunk)) *
|
| + block_.chunk_count) +
|
| + sizeof(block_);
|
| + if (!block_and_chunks_size.IsValid() ||
|
| + block_data_size < block_and_chunks_size.ValueOrDie()) {
|
| + DLOG(ERROR) << "UDIF block does not contain reported number of chunks, "
|
| + << block_and_chunks_size.ValueOrDie() << " bytes expected, "
|
| + << "got " << block_data_size;
|
| + return false;
|
| + }
|
| +
|
| // Make sure that the chunk data isn't larger than the block reports.
|
| base::CheckedNumeric<size_t> chunk_sectors(0);
|
| for (uint32_t i = 0; i < block_.chunk_count; ++i) {
|
| @@ -486,6 +506,7 @@ bool UDIFParser::ParseBlkx() {
|
| std::unique_ptr<UDIFBlock> block(new UDIFBlock());
|
| if (!block->ParseBlockData(
|
| reinterpret_cast<const UDIFBlockData*>(CFDataGetBytePtr(data)),
|
| + base::checked_cast<size_t>(CFDataGetLength(data)),
|
| block_size_)) {
|
| DLOG(ERROR) << "Failed to parse UDIF block data";
|
| return false;
|
|
|