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

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

Issue 2961373002: Improve Zip File Scanning on Mac (Closed)
Patch Set: refactoring in zip_reader Created 3 years, 5 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 #if defined(OS_MACOSX)
14 #include <mach-o/fat.h>
15 #include <mach-o/loader.h>
16 #endif // OS_MACOSX
17
13 #include "base/i18n/streaming_utf8_validator.h" 18 #include "base/i18n/streaming_utf8_validator.h"
14 #include "base/logging.h" 19 #include "base/logging.h"
15 #include "base/macros.h" 20 #include "base/macros.h"
21 #include "build/build_config.h"
16 #include "chrome/common/safe_browsing/archive_analyzer_results.h" 22 #include "chrome/common/safe_browsing/archive_analyzer_results.h"
17 #include "chrome/common/safe_browsing/binary_feature_extractor.h" 23 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
18 #include "chrome/common/safe_browsing/download_protection_util.h" 24 #include "chrome/common/safe_browsing/download_protection_util.h"
19 #include "chrome/common/safe_browsing/file_type_policies.h" 25 #include "chrome/common/safe_browsing/file_type_policies.h"
20 #include "components/safe_browsing/csd.pb.h" 26 #include "components/safe_browsing/csd.pb.h"
21 #include "crypto/secure_hash.h" 27 #include "crypto/secure_hash.h"
22 #include "crypto/sha2.h" 28 #include "crypto/sha2.h"
23 #include "third_party/zlib/google/zip_reader.h" 29 #include "third_party/zlib/google/zip_reader.h"
24 30
25 namespace safe_browsing { 31 namespace safe_browsing {
(...skipping 27 matching lines...) Expand all
53 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes)) 59 if (!zip::FileWriterDelegate::WriteBytes(data, num_bytes))
54 return false; 60 return false;
55 sha256_->Update(data, num_bytes); 61 sha256_->Update(data, num_bytes);
56 return true; 62 return true;
57 } 63 }
58 64
59 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) { 65 void HashingFileWriter::ComputeDigest(uint8_t* digest, size_t digest_length) {
60 sha256_->Finish(digest, digest_length); 66 sha256_->Finish(digest, digest_length);
61 } 67 }
62 68
69 #if defined(OS_MACOSX)
70 bool StringIsMachOMagic(std::string bytes) {
71 if (bytes.length() < sizeof(uint32_t))
72 return false;
73
74 uint32_t magic;
75 memcpy(&magic, bytes.c_str(), sizeof(uint32_t));
76
77 return magic == FAT_MAGIC || magic == FAT_CIGAM || magic == MH_MAGIC ||
78 magic == MH_CIGAM || magic == MH_MAGIC_64 || magic == MH_CIGAM_64;
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(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 bool advanced = true; 128 bool advanced = true;
110 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) { 129 for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) {
111 if (!advanced) { 130 if (!advanced) {
112 DVLOG(1) << "Could not advance to next entry, aborting zip scan."; 131 DVLOG(1) << "Could not advance to next entry, aborting zip scan.";
113 return; 132 return;
114 } 133 }
115 if (!reader.OpenCurrentEntryInZip()) { 134 if (!reader.OpenCurrentEntryInZip()) {
116 DVLOG(1) << "Failed to open current entry in zip file"; 135 DVLOG(1) << "Failed to open current entry in zip file";
117 continue; 136 continue;
118 } 137 }
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.ExtractFromBeginningOfCurrentEntryToString(sizeof(uint32_t), false,
satorux1 2017/07/21 05:27:02 Sorry for not taking a look at the caller earlier,
mortonm 2017/07/21 16:29:56 In this case, we only want to read the first 4 byt
satorux1 2017/07/21 23:00:09 My bad. sizeof(uint32_t) is of course 4, not 4GB.
mortonm 2017/07/24 17:51:43 Done. Required adding an extra parameter to each o
144 &magic);
145 current_entry_is_executable =
146 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file) ||
147 StringIsMachOMagic(magic);
148 #else
149 current_entry_is_executable =
150 FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file);
151 #endif // OS_MACOSX
152
120 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) { 153 if (FileTypePolicies::GetInstance()->IsArchiveFile(file)) {
121 DVLOG(2) << "Downloaded a zipped archive: " << file.value(); 154 DVLOG(2) << "Downloaded a zipped archive: " << file.value();
122 results->has_archive = true; 155 results->has_archive = true;
123 archived_archive_filenames.insert(file.BaseName()); 156 archived_archive_filenames.insert(file.BaseName());
124 ClientDownloadRequest::ArchivedBinary* archived_archive = 157 ClientDownloadRequest::ArchivedBinary* archived_archive =
125 results->archived_binary.Add(); 158 results->archived_binary.Add();
126 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe()); 159 std::string file_basename_utf8(file.BaseName().AsUTF8Unsafe());
127 if (base::StreamingUtf8Validator::Validate(file_basename_utf8)) 160 if (base::StreamingUtf8Validator::Validate(file_basename_utf8))
128 archived_archive->set_file_basename(file_basename_utf8); 161 archived_archive->set_file_basename(file_basename_utf8);
129 archived_archive->set_download_type( 162 archived_archive->set_download_type(
130 ClientDownloadRequest::ZIPPED_ARCHIVE); 163 ClientDownloadRequest::ZIPPED_ARCHIVE);
131 } else if (FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file)) { 164 } else if (current_entry_is_executable) {
132 DVLOG(2) << "Downloaded a zipped executable: " << file.value(); 165 #if defined(OS_MACOSX)
133 results->has_executable = true; 166 // This check prevents running analysis on .app files since they are
134 AnalyzeContainedFile(binary_feature_extractor, file, &reader, &temp_file, 167 // really just directories and will cause binary feature extraction
135 results->archived_binary.Add()); 168 // to fail.
169 if (file.Extension().compare(".app") == 0) {
170 DVLOG(2) << "Downloaded a zipped .app directory: " << file.value();
171 } else {
172 #endif // OS_MACOSX
173 DVLOG(2) << "Downloaded a zipped executable: " << file.value();
174 results->has_executable = true;
175 AnalyzeContainedFile(binary_feature_extractor, file, &reader,
176 &temp_file, results->archived_binary.Add());
177 #if defined(OS_MACOSX)
178 }
179 #endif // OS_MACOSX
136 } else { 180 } else {
137 DVLOG(3) << "Ignoring non-binary file: " << file.value(); 181 DVLOG(3) << "Ignoring non-binary file: " << file.value();
138 } 182 }
139 } 183 }
140 results->archived_archive_filenames.assign(archived_archive_filenames.begin(), 184 results->archived_archive_filenames.assign(archived_archive_filenames.begin(),
141 archived_archive_filenames.end()); 185 archived_archive_filenames.end());
142 results->success = true; 186 results->success = true;
143 } 187 }
144 188
145 } // namespace zip_analyzer 189 } // namespace zip_analyzer
146 } // namespace safe_browsing 190 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698