Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: chrome/utility/safe_browsing/mac/udif.cc

Issue 2314883002: Validate that UDIFBlock data length matches the size and reported number of chunks. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/utility/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/utility/safe_browsing/mac/udif.h" 5 #include "chrome/utility/safe_browsing/mac/udif.h"
6 6
7 #include <CoreFoundation/CoreFoundation.h> 7 #include <CoreFoundation/CoreFoundation.h>
8 #include <bzlib.h> 8 #include <bzlib.h>
9 #include <libkern/OSByteOrder.h> 9 #include <libkern/OSByteOrder.h>
10 #include <uuid/uuid.h> 10 #include <uuid/uuid.h>
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 ConvertBigEndian(&block->chunk_count); 183 ConvertBigEndian(&block->chunk_count);
184 // Note: This deliberately does not swap the chunks themselves. 184 // Note: This deliberately does not swap the chunks themselves.
185 } 185 }
186 186
187 // UDIFBlock takes a raw, big-endian block data pointer and stores, in host 187 // UDIFBlock takes a raw, big-endian block data pointer and stores, in host
188 // endian, the data for both the block and the chunk. 188 // endian, the data for both the block and the chunk.
189 class UDIFBlock { 189 class UDIFBlock {
190 public: 190 public:
191 UDIFBlock() : block_() {} 191 UDIFBlock() : block_() {}
192 192
193 bool ParseBlockData(const UDIFBlockData* block_data, uint16_t sector_size) { 193 bool ParseBlockData(const UDIFBlockData* block_data,
194 size_t block_data_size,
195 uint16_t sector_size) {
196 if (block_data_size < sizeof(block_)) {
197 DLOG(ERROR) << "UDIF block data is smaller than expected";
198 return false;
199 }
200
194 block_ = *block_data; 201 block_ = *block_data;
195 ConvertBigEndian(&block_); 202 ConvertBigEndian(&block_);
196 203
197 // Make sure the number of sectors doesn't overflow. 204 // Make sure the number of sectors doesn't overflow.
198 auto block_size = base::CheckedNumeric<size_t>(sector_count()) * 205 auto block_size = base::CheckedNumeric<size_t>(sector_count()) *
199 sector_size; 206 sector_size;
200 if (!block_size.IsValid()) { 207 if (!block_size.IsValid()) {
201 DLOG(ERROR) << "UDIF block size overflows"; 208 DLOG(ERROR) << "UDIF block size overflows";
202 return false; 209 return false;
203 } 210 }
204 211
212 // Make sure the block data contains the reported number of chunks.
213 auto block_and_chunks_size =
214 (base::CheckedNumeric<size_t>(sizeof(UDIFBlockChunk)) *
215 block_.chunk_count) +
216 sizeof(block_);
217 if (!block_and_chunks_size.IsValid() ||
218 block_data_size < block_and_chunks_size.ValueOrDie()) {
219 DLOG(ERROR) << "UDIF block does not contain reported number of chunks, "
220 << block_and_chunks_size.ValueOrDie() << " bytes expected, "
221 << "got " << block_data_size;
222 return false;
223 }
224
205 // Make sure that the chunk data isn't larger than the block reports. 225 // Make sure that the chunk data isn't larger than the block reports.
206 base::CheckedNumeric<size_t> chunk_sectors(0); 226 base::CheckedNumeric<size_t> chunk_sectors(0);
207 for (uint32_t i = 0; i < block_.chunk_count; ++i) { 227 for (uint32_t i = 0; i < block_.chunk_count; ++i) {
208 chunks_.push_back(block_data->chunks[i]); 228 chunks_.push_back(block_data->chunks[i]);
209 UDIFBlockChunk* chunk = &chunks_[i]; 229 UDIFBlockChunk* chunk = &chunks_[i];
210 ConvertBigEndian(chunk); 230 ConvertBigEndian(chunk);
211 231
212 chunk_sectors += chunk->sector_count; 232 chunk_sectors += chunk->sector_count;
213 if (!chunk_sectors.IsValid() || 233 if (!chunk_sectors.IsValid() ||
214 chunk_sectors.ValueOrDie() > sector_count()) { 234 chunk_sectors.ValueOrDie() > sector_count()) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 if (!data) { 499 if (!data) {
480 DLOG(ERROR) << "Skipping block " << i 500 DLOG(ERROR) << "Skipping block " << i
481 << " because it has no Data section"; 501 << " because it has no Data section";
482 continue; 502 continue;
483 } 503 }
484 504
485 // Copy the block table out of the plist. 505 // Copy the block table out of the plist.
486 std::unique_ptr<UDIFBlock> block(new UDIFBlock()); 506 std::unique_ptr<UDIFBlock> block(new UDIFBlock());
487 if (!block->ParseBlockData( 507 if (!block->ParseBlockData(
488 reinterpret_cast<const UDIFBlockData*>(CFDataGetBytePtr(data)), 508 reinterpret_cast<const UDIFBlockData*>(CFDataGetBytePtr(data)),
509 base::checked_cast<size_t>(CFDataGetLength(data)),
489 block_size_)) { 510 block_size_)) {
490 DLOG(ERROR) << "Failed to parse UDIF block data"; 511 DLOG(ERROR) << "Failed to parse UDIF block data";
491 return false; 512 return false;
492 } 513 }
493 514
494 if (block->signature() != UDIFBlockData::kSignature) { 515 if (block->signature() != UDIFBlockData::kSignature) {
495 DLOG(ERROR) << "Skipping block " << i << " because its signature does not" 516 DLOG(ERROR) << "Skipping block " << i << " because its signature does not"
496 << " match, is 0x" << std::hex << block->signature(); 517 << " match, is 0x" << std::hex << block->signature();
497 continue; 518 continue;
498 } 519 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 << chunk_->compressed_offset; 857 << chunk_->compressed_offset;
837 return false; 858 return false;
838 } 859 }
839 return true; 860 return true;
840 } 861 }
841 862
842 } // namespace 863 } // namespace
843 864
844 } // namespace dmg 865 } // namespace dmg
845 } // namespace safe_browsing 866 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/utility/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698