| 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_successfully_parsed_(false) {} |
| 353 | 353 |
| 354 UDIFParser::~UDIFParser() {} | 354 UDIFParser::~UDIFParser() {} |
| 355 | 355 |
| 356 bool UDIFParser::ParseTrailer() { |
| 357 // Makes sure that trailer is only ever parsed single time during execution of |
| 358 // constuctor, so position of ReadStream is not moved after constructor runs. |
| 359 if (trailer_successfully_parsed_) |
| 360 return true; |
| 361 |
| 362 UDIFResourceFile trailer; |
| 363 |
| 364 off_t trailer_start = stream_->Seek(-sizeof(trailer), SEEK_END); |
| 365 if (trailer_start == -1) |
| 366 return false; |
| 367 |
| 368 if (!stream_->ReadType(&trailer)) { |
| 369 DLOG(ERROR) << "Failed to read UDIFResourceFile"; |
| 370 return false; |
| 371 } |
| 372 ConvertBigEndian(&trailer); |
| 373 |
| 374 if (trailer.signature != trailer.kSignature) { |
| 375 DLOG(ERROR) << "blkx signature does not match, is 0x" << std::hex |
| 376 << trailer.signature; |
| 377 return false; |
| 378 } |
| 379 if (trailer.version != trailer.kVersion) { |
| 380 DLOG(ERROR) << "blkx version does not match, is " << trailer.version; |
| 381 return false; |
| 382 } |
| 383 |
| 384 auto plist_end = |
| 385 base::CheckedNumeric<size_t>(trailer.plist_offset) + trailer.plist_length; |
| 386 if (!plist_end.IsValid() || |
| 387 plist_end.ValueOrDie() > base::checked_cast<size_t>(trailer_start)) { |
| 388 DLOG(ERROR) << "blkx plist extends past UDIF trailer"; |
| 389 return false; |
| 390 } |
| 391 |
| 392 trailer_signature_ = trailer.signature; |
| 393 plist_length_ = trailer.plist_length; |
| 394 plist_offset_ = trailer.plist_offset; |
| 395 return true; |
| 396 } |
| 397 |
| 356 bool UDIFParser::Parse() { | 398 bool UDIFParser::Parse() { |
| 357 if (!ParseBlkx()) | 399 // First parses trailer and then parses blocks. |
| 400 trailer_successfully_parsed_ = ParseTrailer(); |
| 401 if (!trailer_successfully_parsed_ || !ParseBlkx()) |
| 358 return false; | 402 return false; |
| 359 | 403 |
| 360 return true; | 404 return true; |
| 361 } | 405 } |
| 362 | 406 |
| 363 size_t UDIFParser::GetNumberOfPartitions() { | 407 size_t UDIFParser::GetNumberOfPartitions() { |
| 364 return blocks_.size(); | 408 return blocks_.size(); |
| 365 } | 409 } |
| 366 | 410 |
| 367 std::string UDIFParser::GetPartitionName(size_t part_number) { | 411 std::string UDIFParser::GetPartitionName(size_t part_number) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 } | 444 } |
| 401 | 445 |
| 402 std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream( | 446 std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream( |
| 403 size_t part_number) { | 447 size_t part_number) { |
| 404 DCHECK_LT(part_number, blocks_.size()); | 448 DCHECK_LT(part_number, blocks_.size()); |
| 405 return base::MakeUnique<UDIFPartitionReadStream>(stream_, block_size_, | 449 return base::MakeUnique<UDIFPartitionReadStream>(stream_, block_size_, |
| 406 blocks_[part_number].get()); | 450 blocks_[part_number].get()); |
| 407 } | 451 } |
| 408 | 452 |
| 409 bool UDIFParser::ParseBlkx() { | 453 bool UDIFParser::ParseBlkx() { |
| 410 UDIFResourceFile trailer; | 454 if (!trailer_successfully_parsed_) |
| 411 off_t trailer_start = stream_->Seek(-sizeof(trailer), SEEK_END); | |
| 412 if (trailer_start == -1) | |
| 413 return false; | 455 return false; |
| 414 | 456 |
| 415 if (!stream_->ReadType(&trailer)) { | 457 std::vector<uint8_t> plist_bytes(plist_length_, 0); |
| 416 DLOG(ERROR) << "Failed to read UDIFResourceFile"; | |
| 417 return false; | |
| 418 } | |
| 419 ConvertBigEndian(&trailer); | |
| 420 | 458 |
| 421 if (trailer.signature != trailer.kSignature) { | 459 if (stream_->Seek(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; | 460 return false; |
| 443 | 461 |
| 444 if (!stream_->ReadExact(&plist_bytes[0], trailer.plist_length)) { | 462 if (!stream_->ReadExact(&plist_bytes[0], plist_length_)) { |
| 445 DLOG(ERROR) << "Failed to read blkx plist data"; | 463 DLOG(ERROR) << "Failed to read blkx plist data"; |
| 446 return false; | 464 return false; |
| 447 } | 465 } |
| 448 | 466 |
| 449 base::ScopedCFTypeRef<CFDataRef> plist_data( | 467 base::ScopedCFTypeRef<CFDataRef> plist_data( |
| 450 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, | 468 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, |
| 451 &plist_bytes[0], plist_bytes.size(), kCFAllocatorNull)); | 469 &plist_bytes[0], plist_bytes.size(), kCFAllocatorNull)); |
| 452 if (!plist_data) { | 470 if (!plist_data) { |
| 453 DLOG(ERROR) << "Failed to create data from bytes"; | 471 DLOG(ERROR) << "Failed to create data from bytes"; |
| 454 return false; | 472 return false; |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 << chunk_->compressed_offset; | 883 << chunk_->compressed_offset; |
| 866 return false; | 884 return false; |
| 867 } | 885 } |
| 868 return true; | 886 return true; |
| 869 } | 887 } |
| 870 | 888 |
| 871 } // namespace | 889 } // namespace |
| 872 | 890 |
| 873 } // namespace dmg | 891 } // namespace dmg |
| 874 } // namespace safe_browsing | 892 } // namespace safe_browsing |
| OLD | NEW |