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

Side by Side Diff: chrome/common/safe_browsing/zip_analyzer.cc

Issue 2961373002: Improve Zip File Scanning on Mac (Closed)
Patch Set: comments Created 3 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/common/safe_browsing/zip_analyzer.h" 5 #include "chrome/common/safe_browsing/zip_analyzer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
11 #include <set> 11 #include <set>
12 12
13 #include "base/i18n/streaming_utf8_validator.h" 13 #include "base/i18n/streaming_utf8_validator.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "build/build_config.h"
16 #include "chrome/common/safe_browsing/archive_analyzer_results.h" 17 #include "chrome/common/safe_browsing/archive_analyzer_results.h"
17 #include "chrome/common/safe_browsing/binary_feature_extractor.h" 18 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
18 #include "chrome/common/safe_browsing/download_protection_util.h" 19 #include "chrome/common/safe_browsing/download_protection_util.h"
19 #include "chrome/common/safe_browsing/file_type_policies.h" 20 #include "chrome/common/safe_browsing/file_type_policies.h"
21 #include "chrome/common/safe_browsing/mach_o_image_reader_mac.h"
Robert Sesek 2017/08/03 18:36:31 I think this will probably need to move after line
mortonm 2017/08/03 18:45:21 Done.
20 #include "components/safe_browsing/csd.pb.h" 22 #include "components/safe_browsing/csd.pb.h"
21 #include "crypto/secure_hash.h" 23 #include "crypto/secure_hash.h"
22 #include "crypto/sha2.h" 24 #include "crypto/sha2.h"
23 #include "third_party/zlib/google/zip_reader.h" 25 #include "third_party/zlib/google/zip_reader.h"
24 26
27 #if defined(OS_MACOSX)
28 #include <mach-o/fat.h>
29 #include <mach-o/loader.h>
30 #endif // OS_MACOSX
31
25 namespace safe_browsing { 32 namespace safe_browsing {
26 namespace zip_analyzer { 33 namespace zip_analyzer {
27 34
28 namespace { 35 namespace {
29 36
30 // A writer delegate that computes a SHA-256 hash digest over the data while 37 // A writer delegate that computes a SHA-256 hash digest over the data while
31 // writing it to a file. 38 // writing it to a file.
32 class HashingFileWriter : public zip::FileWriterDelegate { 39 class HashingFileWriter : public zip::FileWriterDelegate {
33 public: 40 public:
34 explicit HashingFileWriter(base::File* file); 41 explicit HashingFileWriter(base::File* file);
(...skipping 18 matching lines...) Expand all
53 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes)) 60 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes))
54 return false; 61 return false;
55 sha256_->Update(data, num_bytes); 62 sha256_->Update(data, num_bytes);
56 return true; 63 return true;
57 } 64 }
58 65
59 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) { 66 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) {
60 sha256_->Finish(digest, digest_length); 67 sha256_->Finish(digest, digest_length);
61 } 68 }
62 69
70 #if defined(OS_MACOSX)
71 bool StringIsMachOMagic(std::string bytes) {
72 if (bytes.length() < sizeof(uint32_t))
73 return false;
74
75 uint32_t magic;
76 memcpy(&magic, bytes.c_str(), sizeof(uint32_t));
77
78 return MachOImageReader::IsMachOMagicValue(magic);
79 }
80 #endif // OS_MACOSX
81
63 void AnalyzeContainedFile( 82 void AnalyzeContainedFile(
64 const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor, 83 const scoped_refptr<BinaryFeatureExtractor>& binary_feature_extractor,
65 const base::FilePath& file_path, 84 const base::FilePath& file_path,
66 zip::ZipReader* reader, 85 zip::ZipReader* reader,
67 base::File* temp_file, 86 base::File* temp_file,
68 ClientDownloadRequest::ArchivedBinary* archived_binary) { 87 ClientDownloadRequest::ArchivedBinary* archived_binary) {
69 std::string file_basename(file_path.BaseName().AsUTF8Unsafe()); 88 std::string file_basename(file_path.BaseName().AsUTF8Unsafe());
70 if (base::StreamingUtf8Validator::Validate(file_basename)) 89 if (base::StreamingUtf8Validator::Validate(file_basename))
71 archived_binary->set_file_basename(file_basename); 90 archived_binary->set_file_basename(file_basename);
72 archived_binary->set_download_type( 91 archived_binary->set_download_type(
73 download_protection_util::GetDownloadType(file_path)); 92 download_protection_util::GetDownloadType(file_path));
74 archived_binary->set_length(reader->current_entry_info()->original_size()); 93 archived_binary->set_length(reader->current_entry_info()->original_size());
75 HashingFileWriter writer(temp_file); 94 HashingFileWriter writer(temp_file);
76 if (reader->ExtractCurrentEntry(&writer)) { 95 if (reader->ExtractCurrentEntry(&writer,
96 std::numeric_limits<uint64_t>::max())) {
77 uint8_t digest[crypto::kSHA256Length]; 97 uint8_t digest[crypto::kSHA256Length];
78 writer.ComputeDigest(&digest[0], arraysize(digest)); 98 writer.ComputeDigest(&digest[0], arraysize(digest));
79 archived_binary->mutable_digests()->set_sha256(&digest[0], 99 archived_binary->mutable_digests()->set_sha256(&digest[0],
80 arraysize(digest)); 100 arraysize(digest));
81 if (!binary_feature_extractor->ExtractImageFeaturesFromFile( 101 if (!binary_feature_extractor->ExtractImageFeaturesFromFile(
82 temp_file->Duplicate(), 102 temp_file->Duplicate(),
83 BinaryFeatureExtractor::kDefaultOptions, 103 BinaryFeatureExtractor::kDefaultOptions,
84 archived_binary->mutable_image_headers(), 104 archived_binary->mutable_image_headers(),
85 archived_binary->mutable_signature()->mutable_signed_data())) { 105 archived_binary->mutable_signature()->mutable_signed_data())) {
86 archived_binary->clear_image_headers(); 106 archived_binary->clear_image_headers();
(...skipping 23 matching lines...) Expand all
110 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { 130 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) {
111 if (!advanced) { 131 if (!advanced) {
112 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; 132 DVLOG(1) << "Could not advance to next entry, aborting zip scan.";
113 return; 133 return;
114 } 134 }
115 if (!reader.OpenCurrentEntryInZip()) { 135 if (!reader.OpenCurrentEntryInZip()) {
116 DVLOG(1) << "Failed to open current entry in zip file"; 136 DVLOG(1) << "Failed to open current entry in zip file";
117 continue; 137 continue;
118 } 138 }
119 const base::FilePath& file = reader.current_entry_info()->file_path(); 139 const base::FilePath& file = reader.current_entry_info()->file_path();
140 bool current_entry_is_executable;
141 #if defined(OS_MACOSX)
142 std::string magic;
143 reader.ExtractCurrentEntryToString(sizeof(uint32_t), &magic);
144 current_entry_is_executable =
145 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file) ||
146 StringIsMachOMagic(magic);
147 #else
148 current_entry_is_executable =
149 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file);
150 #endif // OS_MACOSX
151
120 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) { 152 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) {
121 DVLOG(2) << "Downloaded a zipped archive: " << file.value(); 153 DVLOG(2) << "Downloaded a zipped archive: " << file.value();
122 results->has_archive = true; 154 results->has_archive = true;
123 archived_archive_filenames.insert(file.BaseName()); 155 archived_archive_filenames.insert(file.BaseName());
124 ClientDownloadRequest::ArchivedBinary* archived_archive = 156 ClientDownloadRequest::ArchivedBinary* archived_archive =
125 results->archived_binary.Add(); 157 results->archived_binary.Add();
126 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe()); 158 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe());
127 if (base::StreamingUtf8Validator::Validate(file_basename_utf8)) 159 if (base::StreamingUtf8Validator::Validate(file_basename_utf8))
128 archived_archive->set_file_basename(file_basename_utf8); 160 archived_archive->set_file_basename(file_basename_utf8);
129 archived_archive->set_download_type( 161 archived_archive->set_download_type(
130 ClientDownloadRequest::ZIPPED_ARCHIVE); 162 ClientDownloadRequest::ZIPPED_ARCHIVE);
131 } else if (FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file)) { 163 } else if (current_entry_is_executable) {
132 DVLOG(2) << "Downloaded a zipped executable: " << file.value(); 164 #if defined(OS_MACOSX)
133 results->has_executable = true; 165 // This check prevents running analysis on .app files since they are
134 AnalyzeContainedFile(binary_feature_extractor, file, &reader, &temp_file, 166 // really just directories and will cause binary feature extraction
135 results->archived_binary.Add()); 167 // to fail.
168 if (file.Extension().compare(".app") == 0) {
169 DVLOG(2) << "Downloaded a zipped .app directory: " << file.value();
170 } else {
171 #endif // OS_MACOSX
172 DVLOG(2) << "Downloaded a zipped executable: " << file.value();
173 results->has_executable = true;
174 AnalyzeContainedFile(binary_feature_extractor, file, &reader,
175 &temp_file, results->archived_binary.Add());
176 #if defined(OS_MACOSX)
177 }
178 #endif // OS_MACOSX
136 } else { 179 } else {
137 DVLOG(3) << "Ignoring non-binary file: " << file.value(); 180 DVLOG(3) << "Ignoring non-binary file: " << file.value();
138 } 181 }
139 } 182 }
140 results->archived_archive_filenames.assign(archived_archive_filenames.begin(), 183 results->archived_archive_filenames.assign(archived_archive_filenames.begin(),
141 archived_archive_filenames.end()); 184 archived_archive_filenames.end());
142 results->success = true; 185 results->success = true;
143 } 186 }
144 187
145 } // namespace zip_analyzer 188 } // namespace zip_analyzer
146 } // namespace safe_browsing 189 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc ('k') | chrome/test/data/safe_browsing/mach_o/Makefile » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698