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

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

Issue 2926473002: Mac Archive Type Sniffing (Closed)
Patch Set: simplified unit test since not parsing actual compressed data in DMGs Created 3 years, 6 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
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 10 matching lines...) Expand all
21 #include "base/strings/sys_string_conversions.h" 21 #include "base/strings/sys_string_conversions.h"
22 #include "chrome/utility/safe_browsing/mac/convert_big_endian.h" 22 #include "chrome/utility/safe_browsing/mac/convert_big_endian.h"
23 #include "chrome/utility/safe_browsing/mac/read_stream.h" 23 #include "chrome/utility/safe_browsing/mac/read_stream.h"
24 #include "third_party/zlib/zlib.h" 24 #include "third_party/zlib/zlib.h"
25 25
26 namespace safe_browsing { 26 namespace safe_browsing {
27 namespace dmg { 27 namespace dmg {
28 28
29 #pragma pack(push, 1) 29 #pragma pack(push, 1)
30 30
31 // The following structures come from the analysis provided by Jonathan Levin 31 // The following structures come from the analysis provided by Jonathan Levin
Jialiu Lin 2017/06/09 18:48:49 Remove line 31-34. Already in .h file.
mortonm 2017/06/09 19:47:21 Done.
32 // at <http://newosxbook.com/DMG.html>. 32 // at <http://newosxbook.com/DMG.html>.
33 // 33 //
34 // Note that all fields are stored in big endian. 34 // Note that all fields are stored in big endian.
35 35
36 struct UDIFChecksum {
37 uint32_t type;
38 uint32_t size;
39 uint32_t data[32];
40 };
41
42 static void ConvertBigEndian(UDIFChecksum* checksum) { 36 static void ConvertBigEndian(UDIFChecksum* checksum) {
43 ConvertBigEndian(&checksum->type); 37 ConvertBigEndian(&checksum->type);
44 ConvertBigEndian(&checksum->size); 38 ConvertBigEndian(&checksum->size);
45 for (size_t i = 0; i < arraysize(checksum->data); ++i) { 39 for (size_t i = 0; i < arraysize(checksum->data); ++i) {
46 ConvertBigEndian(&checksum->data[i]); 40 ConvertBigEndian(&checksum->data[i]);
47 } 41 }
48 } 42 }
49 43
50 // The trailer structure for a UDIF file.
51 struct UDIFResourceFile {
52 static const uint32_t kSignature = 'koly';
53 static const uint32_t kVersion = 4;
54
55 uint32_t signature;
56 uint32_t version;
57 uint32_t header_size; // Size of this structure.
58 uint32_t flags;
59 uint64_t running_data_fork_offset;
60 uint64_t data_fork_offset;
61 uint64_t data_fork_length;
62 uint64_t rsrc_fork_offset;
63 uint64_t rsrc_fork_length;
64 uint32_t segment_number;
65 uint32_t segment_count;
66 uuid_t segment_id;
67
68 UDIFChecksum data_checksum;
69
70 uint64_t plist_offset; // Offset and length of the blkx plist.
71 uint64_t plist_length;
72
73 uint8_t reserved1[64];
74
75 uint64_t code_signature_offset;
76 uint64_t code_signature_length;
77
78 uint8_t reserved2[40];
79
80 UDIFChecksum master_checksum;
81
82 uint32_t image_variant;
83 uint64_t sector_count;
84
85 uint32_t reserved3;
86 uint32_t reserved4;
87 uint32_t reserved5;
88 };
89
90 static void ConvertBigEndian(uuid_t* uuid) { 44 static void ConvertBigEndian(uuid_t* uuid) {
91 // UUID is never consulted, so do not swap. 45 // UUID is never consulted, so do not swap.
92 } 46 }
93 47
94 static void ConvertBigEndian(UDIFResourceFile* file) { 48 static void ConvertBigEndian(UDIFResourceFile* file) {
95 ConvertBigEndian(&file->signature); 49 ConvertBigEndian(&file->signature);
96 ConvertBigEndian(&file->version); 50 ConvertBigEndian(&file->version);
97 ConvertBigEndian(&file->flags); 51 ConvertBigEndian(&file->flags);
98 ConvertBigEndian(&file->header_size); 52 ConvertBigEndian(&file->header_size);
99 ConvertBigEndian(&file->running_data_fork_offset); 53 ConvertBigEndian(&file->running_data_fork_offset);
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 295
342 DISALLOW_COPY_AND_ASSIGN(UDIFBlockChunkReadStream); 296 DISALLOW_COPY_AND_ASSIGN(UDIFBlockChunkReadStream);
343 }; 297 };
344 298
345 } // namespace 299 } // namespace
346 300
347 UDIFParser::UDIFParser(ReadStream* stream) 301 UDIFParser::UDIFParser(ReadStream* stream)
348 : stream_(stream), 302 : stream_(stream),
349 partition_names_(), 303 partition_names_(),
350 blocks_(), 304 blocks_(),
351 block_size_(kSectorSize) { 305 block_size_(kSectorSize),
306 trailer_successfully_parsed_(false) {
307 trailer_successfully_parsed_ = ParseTrailer();
352 } 308 }
353 309
354 UDIFParser::~UDIFParser() {} 310 UDIFParser::~UDIFParser() {}
355 311
312 bool UDIFParser::ParseTrailer() {
313 off_t trailer_start = stream_->Seek(-sizeof(trailer_), SEEK_END);
314 if (trailer_start == -1)
315 return false;
316
317 if (!stream_->ReadType(&trailer_)) {
318 DLOG(ERROR) << "Failed to read UDIFResourceFile";
319 return false;
320 }
321 ConvertBigEndian(&trailer_);
322
323 if (trailer_.signature != trailer_.kSignature) {
324 DLOG(ERROR) << "blkx signature does not match, is 0x" << std::hex
325 << trailer_.signature;
326 return false;
327 }
328 if (trailer_.version != trailer_.kVersion) {
329 DLOG(ERROR) << "blkx version does not match, is " << trailer_.version;
330 return false;
331 }
332
333 auto plist_end = base::CheckedNumeric<size_t>(trailer_.plist_offset) +
334 trailer_.plist_length;
335 if (!plist_end.IsValid() ||
336 plist_end.ValueOrDie() > base::checked_cast<size_t>(trailer_start)) {
337 DLOG(ERROR) << "blkx plist extends past UDIF trailer";
338 return false;
339 }
340
341 return true;
342 }
343
344 UDIFResourceFile* UDIFParser::GetTrailer() {
345 if (!trailer_successfully_parsed_) {
346 return NULL;
347 } else {
348 return &trailer_;
349 }
350 }
351
356 bool UDIFParser::Parse() { 352 bool UDIFParser::Parse() {
357 if (!ParseBlkx()) 353 if (!ParseBlkx())
358 return false; 354 return false;
359 355
360 return true; 356 return true;
361 } 357 }
362 358
363 size_t UDIFParser::GetNumberOfPartitions() { 359 size_t UDIFParser::GetNumberOfPartitions() {
364 return blocks_.size(); 360 return blocks_.size();
365 } 361 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 } 396 }
401 397
402 std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream( 398 std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream(
403 size_t part_number) { 399 size_t part_number) {
404 DCHECK_LT(part_number, blocks_.size()); 400 DCHECK_LT(part_number, blocks_.size());
405 return base::MakeUnique<UDIFPartitionReadStream>(stream_, block_size_, 401 return base::MakeUnique<UDIFPartitionReadStream>(stream_, block_size_,
406 blocks_[part_number].get()); 402 blocks_[part_number].get());
407 } 403 }
408 404
409 bool UDIFParser::ParseBlkx() { 405 bool UDIFParser::ParseBlkx() {
410 UDIFResourceFile trailer; 406 if (!trailer_successfully_parsed_)
411 off_t trailer_start = stream_->Seek(-sizeof(trailer), SEEK_END);
412 if (trailer_start == -1)
413 return false; 407 return false;
414 408
415 if (!stream_->ReadType(&trailer)) { 409 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 410
421 if (trailer.signature != trailer.kSignature) { 411 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; 412 return false;
443 413
444 if (!stream_->ReadExact(&plist_bytes[0], trailer.plist_length)) { 414 if (!stream_->ReadExact(&plist_bytes[0], trailer_.plist_length)) {
445 DLOG(ERROR) << "Failed to read blkx plist data"; 415 DLOG(ERROR) << "Failed to read blkx plist data";
446 return false; 416 return false;
447 } 417 }
448 418
449 base::ScopedCFTypeRef<CFDataRef> plist_data( 419 base::ScopedCFTypeRef<CFDataRef> plist_data(
450 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, 420 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
451 &plist_bytes[0], plist_bytes.size(), kCFAllocatorNull)); 421 &plist_bytes[0], plist_bytes.size(), kCFAllocatorNull));
452 if (!plist_data) { 422 if (!plist_data) {
453 DLOG(ERROR) << "Failed to create data from bytes"; 423 DLOG(ERROR) << "Failed to create data from bytes";
454 return false; 424 return false;
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 << chunk_->compressed_offset; 835 << chunk_->compressed_offset;
866 return false; 836 return false;
867 } 837 }
868 return true; 838 return true;
869 } 839 }
870 840
871 } // namespace 841 } // namespace
872 842
873 } // namespace dmg 843 } // namespace dmg
874 } // namespace safe_browsing 844 } // namespace safe_browsing
OLDNEW
« chrome/utility/safe_browsing/mac/udif.h ('K') | « chrome/utility/safe_browsing/mac/udif.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698