Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 | 341 |
| 342 DISALLOW_COPY_AND_ASSIGN(UDIFBlockChunkReadStream); | 342 DISALLOW_COPY_AND_ASSIGN(UDIFBlockChunkReadStream); |
| 343 }; | 343 }; |
| 344 | 344 |
| 345 } // namespace | 345 } // namespace |
| 346 | 346 |
| 347 UDIFParser::UDIFParser(ReadStream* stream) | 347 UDIFParser::UDIFParser(ReadStream* stream) |
| 348 : stream_(stream), | 348 : stream_(stream), |
| 349 partition_names_(), | 349 partition_names_(), |
| 350 blocks_(), | 350 blocks_(), |
| 351 block_size_(kSectorSize) { | 351 block_size_(kSectorSize), |
| 352 } | 352 trailer_(new UDIFResourceFile), |
| 353 trailer_successfully_parsed_(false) {} | |
| 353 | 354 |
| 354 UDIFParser::~UDIFParser() {} | 355 UDIFParser::~UDIFParser() {} |
| 355 | 356 |
| 356 bool UDIFParser::Parse() { | 357 bool UDIFParser::ParseTrailer() { |
| 357 if (!ParseBlkx()) | 358 // Makes sure that trailer is only ever parsed single time during execution of |
| 359 // constuctor, so position of ReadStream is not moved while parsing blocks. | |
| 360 if (trailer_successfully_parsed_) | |
| 361 return true; | |
| 362 | |
| 363 if (trailer_.get() == nullptr) | |
|
Robert Sesek
2017/06/12 20:52:34
This will never happen (Chromium terminates on OOM
mortonm
2017/06/12 21:39:49
I removed the null pointer check, but unless anyon
| |
| 358 return false; | 364 return false; |
| 359 | 365 |
| 366 off_t trailer_start = stream_->Seek(-sizeof(*trailer_), SEEK_END); | |
| 367 if (trailer_start == -1) | |
| 368 return false; | |
| 369 | |
| 370 if (!stream_->ReadType(trailer_.get())) { | |
| 371 DLOG(ERROR) << "Failed to read UDIFResourceFile"; | |
| 372 return false; | |
| 373 } | |
| 374 ConvertBigEndian(trailer_.get()); | |
| 375 | |
| 376 if (trailer_->signature != trailer_->kSignature) { | |
| 377 DLOG(ERROR) << "blkx signature does not match, is 0x" << std::hex | |
| 378 << trailer_->signature; | |
| 379 return false; | |
| 380 } | |
| 381 if (trailer_->version != trailer_->kVersion) { | |
| 382 DLOG(ERROR) << "blkx version does not match, is " << trailer_->version; | |
| 383 return false; | |
| 384 } | |
| 385 | |
| 386 auto plist_end = base::CheckedNumeric<size_t>(trailer_->plist_offset) + | |
| 387 trailer_->plist_length; | |
| 388 if (!plist_end.IsValid() || | |
| 389 plist_end.ValueOrDie() > base::checked_cast<size_t>(trailer_start)) { | |
| 390 DLOG(ERROR) << "blkx plist extends past UDIF trailer"; | |
| 391 return false; | |
| 392 } | |
| 393 | |
| 360 return true; | 394 return true; |
| 361 } | 395 } |
| 362 | 396 |
| 397 bool UDIFParser::Parse() { | |
| 398 // First parses trailer and then parses blocks. | |
| 399 trailer_successfully_parsed_ = ParseTrailer(); | |
| 400 return trailer_successfully_parsed_ && ParseBlkx(); | |
| 401 } | |
| 402 | |
| 363 size_t UDIFParser::GetNumberOfPartitions() { | 403 size_t UDIFParser::GetNumberOfPartitions() { |
| 364 return blocks_.size(); | 404 return blocks_.size(); |
| 365 } | 405 } |
| 366 | 406 |
| 367 std::string UDIFParser::GetPartitionName(size_t part_number) { | 407 std::string UDIFParser::GetPartitionName(size_t part_number) { |
| 368 DCHECK_LT(part_number, partition_names_.size()); | 408 DCHECK_LT(part_number, partition_names_.size()); |
| 369 return partition_names_[part_number]; | 409 return partition_names_[part_number]; |
| 370 } | 410 } |
| 371 | 411 |
| 372 std::string UDIFParser::GetPartitionType(size_t part_number) { | 412 std::string UDIFParser::GetPartitionType(size_t part_number) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 400 } | 440 } |
| 401 | 441 |
| 402 std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream( | 442 std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream( |
| 403 size_t part_number) { | 443 size_t part_number) { |
| 404 DCHECK_LT(part_number, blocks_.size()); | 444 DCHECK_LT(part_number, blocks_.size()); |
| 405 return base::MakeUnique<UDIFPartitionReadStream>(stream_, block_size_, | 445 return base::MakeUnique<UDIFPartitionReadStream>(stream_, block_size_, |
| 406 blocks_[part_number].get()); | 446 blocks_[part_number].get()); |
| 407 } | 447 } |
| 408 | 448 |
| 409 bool UDIFParser::ParseBlkx() { | 449 bool UDIFParser::ParseBlkx() { |
| 410 UDIFResourceFile trailer; | 450 if (!trailer_successfully_parsed_) |
| 411 off_t trailer_start = stream_->Seek(-sizeof(trailer), SEEK_END); | |
| 412 if (trailer_start == -1) | |
| 413 return false; | 451 return false; |
| 414 | 452 |
| 415 if (!stream_->ReadType(&trailer)) { | 453 std::vector<uint8_t> plist_bytes(trailer_->plist_length, 0); |
| 416 DLOG(ERROR) << "Failed to read UDIFResourceFile"; | |
| 417 return false; | |
| 418 } | |
| 419 ConvertBigEndian(&trailer); | |
| 420 | 454 |
| 421 if (trailer.signature != trailer.kSignature) { | 455 if (stream_->Seek(trailer_->plist_offset, SEEK_SET) == -1) |
| 422 DLOG(ERROR) << "blkx signature does not match, is 0x" | |
| 423 << std::hex << trailer.signature; | |
| 424 return false; | |
| 425 } | |
| 426 if (trailer.version != trailer.kVersion) { | |
| 427 DLOG(ERROR) << "blkx version does not match, is " << trailer.version; | |
| 428 return false; | |
| 429 } | |
| 430 | |
| 431 auto plist_end = base::CheckedNumeric<size_t>(trailer.plist_offset) + | |
| 432 trailer.plist_length; | |
| 433 if (!plist_end.IsValid() || | |
| 434 plist_end.ValueOrDie() > base::checked_cast<size_t>(trailer_start)) { | |
| 435 DLOG(ERROR) << "blkx plist extends past UDIF trailer"; | |
| 436 return false; | |
| 437 } | |
| 438 | |
| 439 std::vector<uint8_t> plist_bytes(trailer.plist_length, 0); | |
| 440 | |
| 441 if (stream_->Seek(trailer.plist_offset, SEEK_SET) == -1) | |
| 442 return false; | 456 return false; |
| 443 | 457 |
| 444 if (!stream_->ReadExact(&plist_bytes[0], trailer.plist_length)) { | 458 if (!stream_->ReadExact(&plist_bytes[0], trailer_->plist_length)) { |
| 445 DLOG(ERROR) << "Failed to read blkx plist data"; | 459 DLOG(ERROR) << "Failed to read blkx plist data"; |
| 446 return false; | 460 return false; |
| 447 } | 461 } |
| 448 | 462 |
| 449 base::ScopedCFTypeRef<CFDataRef> plist_data( | 463 base::ScopedCFTypeRef<CFDataRef> plist_data( |
| 450 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, | 464 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, |
| 451 &plist_bytes[0], plist_bytes.size(), kCFAllocatorNull)); | 465 &plist_bytes[0], plist_bytes.size(), kCFAllocatorNull)); |
| 452 if (!plist_data) { | 466 if (!plist_data) { |
| 453 DLOG(ERROR) << "Failed to create data from bytes"; | 467 DLOG(ERROR) << "Failed to create data from bytes"; |
| 454 return false; | 468 return false; |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 << chunk_->compressed_offset; | 879 << chunk_->compressed_offset; |
| 866 return false; | 880 return false; |
| 867 } | 881 } |
| 868 return true; | 882 return true; |
| 869 } | 883 } |
| 870 | 884 |
| 871 } // namespace | 885 } // namespace |
| 872 | 886 |
| 873 } // namespace dmg | 887 } // namespace dmg |
| 874 } // namespace safe_browsing | 888 } // namespace safe_browsing |
| OLD | NEW |