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

Side by Side Diff: extensions/browser/sandboxed_unpacker.h

Issue 2697463002: Convert utility process extension Unpacker IPC to mojo (Closed)
Patch Set: Set the IPC enum traits limit to extensions::Manifest::NUM_LOCATIONS - 1. Created 3 years, 9 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
« no previous file with comments | « extensions/browser/extensions_test.cc ('k') | extensions/browser/sandboxed_unpacker.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #ifndef EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_ 5 #ifndef EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_
6 #define EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_ 6 #define EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_
7 7
8 #include <string> 8 #include <string>
9 9
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h" 11 #include "base/files/scoped_temp_dir.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ref_counted_delete_on_sequence.h" 13 #include "base/memory/ref_counted_delete_on_sequence.h"
14 #include "base/memory/weak_ptr.h" 14 #include "base/memory/weak_ptr.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/utility_process_mojo_client.h"
17 #include "content/public/browser/utility_process_host_client.h"
18 #include "extensions/browser/crx_file_info.h" 17 #include "extensions/browser/crx_file_info.h"
19 #include "extensions/browser/install/crx_install_error.h" 18 #include "extensions/browser/install/crx_install_error.h"
20 #include "extensions/common/manifest.h" 19 #include "extensions/common/manifest.h"
21 20
22 class SkBitmap; 21 class SkBitmap;
23 22
24 namespace base { 23 namespace base {
25 class DictionaryValue; 24 class DictionaryValue;
26 class SequencedTaskRunner; 25 class SequencedTaskRunner;
27 } 26 }
28 27
29 namespace content {
30 class UtilityProcessHost;
31 }
32
33 namespace extensions { 28 namespace extensions {
34 class Extension; 29 class Extension;
35 30
31 namespace mojom {
32 class ExtensionUnpacker;
33 }
34
36 class SandboxedUnpackerClient 35 class SandboxedUnpackerClient
37 : public base::RefCountedDeleteOnSequence<SandboxedUnpackerClient> { 36 : public base::RefCountedDeleteOnSequence<SandboxedUnpackerClient> {
38 public: 37 public:
39 // Initialize the ref-counted base to always delete on the UI thread. Note 38 // Initialize the ref-counted base to always delete on the UI thread. Note
40 // the constructor call must also happen on the UI thread. 39 // the constructor call must also happen on the UI thread.
41 SandboxedUnpackerClient(); 40 SandboxedUnpackerClient();
42 41
43 // temp_dir - A temporary directory containing the results of the extension 42 // temp_dir - A temporary directory containing the results of the extension
44 // unpacking. The client is responsible for deleting this directory. 43 // unpacking. The client is responsible for deleting this directory.
45 // 44 //
(...skipping 10 matching lines...) Expand all
56 const base::FilePath& extension_root, 55 const base::FilePath& extension_root,
57 const base::DictionaryValue* original_manifest, 56 const base::DictionaryValue* original_manifest,
58 const Extension* extension, 57 const Extension* extension,
59 const SkBitmap& install_icon) = 0; 58 const SkBitmap& install_icon) = 0;
60 virtual void OnUnpackFailure(const CrxInstallError& error) = 0; 59 virtual void OnUnpackFailure(const CrxInstallError& error) = 0;
61 60
62 protected: 61 protected:
63 friend class base::RefCountedDeleteOnSequence<SandboxedUnpackerClient>; 62 friend class base::RefCountedDeleteOnSequence<SandboxedUnpackerClient>;
64 friend class base::DeleteHelper<SandboxedUnpackerClient>; 63 friend class base::DeleteHelper<SandboxedUnpackerClient>;
65 64
66 virtual ~SandboxedUnpackerClient() {} 65 virtual ~SandboxedUnpackerClient() = default;
67 }; 66 };
68 67
69 // SandboxedUnpacker does work to optionally unpack and then validate/sanitize 68 // SandboxedUnpacker does work to optionally unpack and then validate/sanitize
70 // an extension, either starting from a crx file or an already unzipped 69 // an extension, either starting from a crx file, or else an already unzipped
71 // directory (eg from differential update). This is done in a sandboxed 70 // directory (eg., from a differential update). This is done in a sandboxed
72 // subprocess to protect the browser process from parsing complex formats like 71 // subprocess to protect the browser process from parsing complex data formats
73 // JPEG or JSON from untrusted sources. 72 // like JPEG or JSON from untrusted sources.
74 // 73 //
75 // Unpacking an extension using this class makes minor changes to its source, 74 // Unpacking an extension using this class makes changes to its source, such as
76 // such as transcoding all images to PNG, parsing all message catalogs 75 // transcoding all images to PNG, parsing all message catalogs, and rewriting
77 // and rewriting the manifest JSON. As such, it should not be used when the 76 // the manifest JSON. As such, it should not be used when the output is not
78 // output is not intended to be given back to the author. 77 // intended to be given back to the author.
79 //
80 // 78 //
81 // Lifetime management: 79 // Lifetime management:
82 // 80 //
83 // This class is ref-counted by each call it makes to itself on another thread, 81 // This class is ref-counted by each call it makes to itself on another thread,
84 // and by UtilityProcessHost. 82 // and by UtilityProcessMojoClient.
85 // 83 //
86 // Additionally, we hold a reference to our own client so that it lives at least 84 // Additionally, we hold a reference to our own client so that the client lives
87 // long enough to receive the result of unpacking. 85 // long enough to receive the result of unpacking.
88 // 86 //
87 // NOTE: This class should only be used on the FILE thread.
89 // 88 //
90 // NOTE: This class should only be used on the file thread. 89 class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> {
91 class SandboxedUnpacker : public content::UtilityProcessHostClient {
92 public: 90 public:
93 // Creates a SanboxedUnpacker that will do work to unpack an extension, 91 // Creates a SanboxedUnpacker that will do work to unpack an extension,
94 // passing the |location| and |creation_flags| to Extension::Create. The 92 // passing the |location| and |creation_flags| to Extension::Create. The
95 // |extensions_dir| parameter should specify the directory under which we'll 93 // |extensions_dir| parameter should specify the directory under which we'll
96 // create a subdirectory to write the unpacked extension contents. 94 // create a subdirectory to write the unpacked extension contents.
97 SandboxedUnpacker( 95 SandboxedUnpacker(
98 Manifest::Location location, 96 Manifest::Location location,
99 int creation_flags, 97 int creation_flags,
100 const base::FilePath& extensions_dir, 98 const base::FilePath& extensions_dir,
101 const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner, 99 const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner,
102 SandboxedUnpackerClient* client); 100 SandboxedUnpackerClient* client);
103 101
104 // Start processing the extension, either from a CRX file or already unzipped 102 // Start processing the extension, either from a CRX file or already unzipped
105 // in a directory. The client is called with the results. The directory form 103 // in a directory. The client is called with the results. The directory form
106 // requires the id and base64-encoded public key (for insertion into the 104 // requires the id and base64-encoded public key (for insertion into the
107 // 'key' field of the manifest.json file). 105 // 'key' field of the manifest.json file).
108 void StartWithCrx(const CRXFileInfo& crx_info); 106 void StartWithCrx(const CRXFileInfo& crx_info);
109 void StartWithDirectory(const std::string& extension_id, 107 void StartWithDirectory(const std::string& extension_id,
110 const std::string& public_key_base64, 108 const std::string& public_key_base64,
111 const base::FilePath& directory); 109 const base::FilePath& directory);
112 110
113 private: 111 private:
114 class ProcessHostClient; 112 friend class base::RefCountedThreadSafe<SandboxedUnpacker>;
115 113
116 // Enumerate all the ways unpacking can fail. Calls to ReportFailure() 114 // Enumerate all the ways unpacking can fail. Calls to ReportFailure()
117 // take a failure reason as an argument, and put it in histogram 115 // take a failure reason as an argument, and put it in histogram
118 // Extensions.SandboxUnpackFailureReason. 116 // Extensions.SandboxUnpackFailureReason.
119 enum FailureReason { 117 enum FailureReason {
120 // SandboxedUnpacker::CreateTempDirectory() 118 // SandboxedUnpacker::CreateTempDirectory()
121 COULD_NOT_GET_TEMP_DIRECTORY, 119 COULD_NOT_GET_TEMP_DIRECTORY,
122 COULD_NOT_CREATE_TEMP_DIRECTORY, 120 COULD_NOT_CREATE_TEMP_DIRECTORY,
123 121
124 // SandboxedUnpacker::Start() 122 // SandboxedUnpacker::Start()
125 FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY, 123 FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY,
126 COULD_NOT_GET_SANDBOX_FRIENDLY_PATH, 124 COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
127 125
128 // SandboxedUnpacker::OnUnpackExtensionSucceeded() 126 // SandboxedUnpacker::UnpackExtensionSucceeded()
129 COULD_NOT_LOCALIZE_EXTENSION, 127 COULD_NOT_LOCALIZE_EXTENSION,
130 INVALID_MANIFEST, 128 INVALID_MANIFEST,
131 129
132 // SandboxedUnpacker::OnUnpackExtensionFailed() 130 // SandboxedUnpacker::UnpackExtensionFailed()
133 UNPACKER_CLIENT_FAILED, 131 UNPACKER_CLIENT_FAILED,
134 132
135 // SandboxedUnpacker::OnProcessCrashed() 133 // SandboxedUnpacker::UtilityProcessCrashed()
136 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, 134 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
137 135
138 // SandboxedUnpacker::ValidateSignature() 136 // SandboxedUnpacker::ValidateSignature()
139 CRX_FILE_NOT_READABLE, 137 CRX_FILE_NOT_READABLE,
140 CRX_HEADER_INVALID, 138 CRX_HEADER_INVALID,
141 CRX_MAGIC_NUMBER_INVALID, 139 CRX_MAGIC_NUMBER_INVALID,
142 CRX_VERSION_NUMBER_INVALID, 140 CRX_VERSION_NUMBER_INVALID,
143 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE, 141 CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE,
144 CRX_ZERO_KEY_LENGTH, 142 CRX_ZERO_KEY_LENGTH,
145 CRX_ZERO_SIGNATURE_LENGTH, 143 CRX_ZERO_SIGNATURE_LENGTH,
(...skipping 21 matching lines...) Expand all
167 INVALID_CATALOG_DATA, 165 INVALID_CATALOG_DATA,
168 INVALID_PATH_FOR_CATALOG, 166 INVALID_PATH_FOR_CATALOG,
169 ERROR_SERIALIZING_CATALOG, 167 ERROR_SERIALIZING_CATALOG,
170 ERROR_SAVING_CATALOG, 168 ERROR_SAVING_CATALOG,
171 169
172 // SandboxedUnpacker::ValidateSignature() 170 // SandboxedUnpacker::ValidateSignature()
173 CRX_HASH_VERIFICATION_FAILED, 171 CRX_HASH_VERIFICATION_FAILED,
174 172
175 UNZIP_FAILED, 173 UNZIP_FAILED,
176 DIRECTORY_MOVE_FAILED, 174 DIRECTORY_MOVE_FAILED,
177 COULD_NOT_START_UTILITY_PROCESS,
178 175
179 NUM_FAILURE_REASONS 176 NUM_FAILURE_REASONS
180 }; 177 };
181 178
182 friend class ProcessHostClient;
183 friend class SandboxedUnpackerTest; 179 friend class SandboxedUnpackerTest;
184 180
185 ~SandboxedUnpacker() override; 181 ~SandboxedUnpacker();
186 182
187 // Set |temp_dir_| as a temporary directory to unpack the extension in. 183 // Create |temp_dir_| used to unzip or unpack the extension in.
188 // Return true on success. 184 bool CreateTempDirectory();
189 virtual bool CreateTempDirectory();
190 185
191 // Helper functions to simplify calls to ReportFailure. 186 // Helper functions to simplify calling ReportFailure.
192 base::string16 FailureReasonToString16(FailureReason reason); 187 base::string16 FailureReasonToString16(FailureReason reason);
193 void FailWithPackageError(FailureReason reason); 188 void FailWithPackageError(FailureReason reason);
194 189
195 // Validates the signature of the extension and extract the key to 190 // Validates the signature of the extension and extract the key to
196 // |public_key_|. Returns true if the signature validates, false otherwise. 191 // |public_key_|. True if the signature validates, false otherwise.
197 bool ValidateSignature(const base::FilePath& crx_path, 192 bool ValidateSignature(const base::FilePath& crx_path,
198 const std::string& expected_hash); 193 const std::string& expected_hash);
199 194
200 void StartUnzipOnIOThread(const base::FilePath& crx_path); 195 // Ensures the utility process is created.
201 void StartUnpackOnIOThread(const base::FilePath& directory_path); 196 void StartUtilityProcessIfNeeded();
202 197
203 // UtilityProcessHostClient 198 // Utility process crashed or failed while trying to install.
204 bool OnMessageReceived(const IPC::Message& message) override; 199 void UtilityProcessCrashed();
205 void OnProcessCrashed(int exit_code) override;
206 200
207 // IPC message handlers. 201 // Unzips the extension into directory.
208 void OnUnzipToDirSucceeded(const base::FilePath& directory); 202 void Unzip(const base::FilePath& crx_path);
209 void OnUnzipToDirFailed(const std::string& error); 203 void UnzipDone(const base::FilePath& directory, bool success);
210 void OnUnpackExtensionSucceeded(const base::DictionaryValue& manifest);
211 void OnUnpackExtensionFailed(const base::string16& error_message);
212 204
213 void ReportFailure(FailureReason reason, const base::string16& message); 205 // Unpacks the extension in directory and returns the manifest.
214 void ReportSuccess(const base::DictionaryValue& original_manifest, 206 void Unpack(const base::FilePath& directory);
207 void UnpackDone(const base::string16& error,
208 std::unique_ptr<base::DictionaryValue> manifest);
209 void UnpackExtensionSucceeded(
210 std::unique_ptr<base::DictionaryValue> manifest);
211 void UnpackExtensionFailed(const base::string16& error);
212
213 // Reports unpack success or failure, or unzip failure.
214 void ReportSuccess(std::unique_ptr<base::DictionaryValue> original_manifest,
215 const SkBitmap& install_icon); 215 const SkBitmap& install_icon);
216 void ReportFailure(FailureReason reason, const base::string16& error);
216 217
217 // Overwrites original manifest with safe result from utility process. 218 // Overwrites original manifest with safe result from utility process.
218 // Returns NULL on error. Caller owns the returned object. 219 // Returns NULL on error. Caller owns the returned object.
219 base::DictionaryValue* RewriteManifestFile( 220 base::DictionaryValue* RewriteManifestFile(
220 const base::DictionaryValue& manifest); 221 const base::DictionaryValue& manifest);
221 222
222 // Overwrites original files with safe results from utility process. 223 // Overwrites original files with safe results from utility process.
223 // Reports error and returns false if it fails. 224 // Reports error and returns false if it fails.
224 bool RewriteImageFiles(SkBitmap* install_icon); 225 bool RewriteImageFiles(SkBitmap* install_icon);
225 bool RewriteCatalogFiles(); 226 bool RewriteCatalogFiles();
226 227
227 // Cleans up temp directory artifacts. 228 // Cleans up temp directory artifacts.
228 void Cleanup(); 229 void Cleanup();
229 230
230 // This is a helper class to make it easier to keep track of the lifecycle of 231 // If we unpacked a CRX file, we hold on to the path name for use
231 // a UtilityProcessHost, including automatic begin and end of batch mode. 232 // in various histograms.
232 class UtilityHostWrapper : public base::RefCountedThreadSafe<
233 UtilityHostWrapper,
234 content::BrowserThread::DeleteOnIOThread> {
235 public:
236 UtilityHostWrapper();
237
238 // Start up the utility process if it is not already started, putting it
239 // into batch mode and giving it access to |exposed_dir|. This should only
240 // be called on the IO thread. Returns false if there was an error starting
241 // the utility process or putting it into batch mode.
242 bool StartIfNeeded(
243 const base::FilePath& exposed_dir,
244 const scoped_refptr<UtilityProcessHostClient>& client,
245 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner);
246
247 // This should only be called on the IO thread.
248 content::UtilityProcessHost* host() const;
249
250 private:
251 friend struct content::BrowserThread::DeleteOnThread<
252 content::BrowserThread::IO>;
253 friend class base::DeleteHelper<UtilityHostWrapper>;
254 ~UtilityHostWrapper();
255
256 // Should only be used on the IO thread.
257 base::WeakPtr<content::UtilityProcessHost> utility_host_;
258
259 DISALLOW_COPY_AND_ASSIGN(UtilityHostWrapper);
260 };
261
262 // If we unpacked a crx file, we hold on to the path for use in various
263 // histograms.
264 base::FilePath crx_path_for_histograms_; 233 base::FilePath crx_path_for_histograms_;
265 234
266 // Our client. 235 // Our unpacker client.
267 scoped_refptr<SandboxedUnpackerClient> client_; 236 scoped_refptr<SandboxedUnpackerClient> client_;
268 237
269 // The Extensions directory inside the profile. 238 // The Extensions directory inside the profile.
270 base::FilePath extensions_dir_; 239 base::FilePath extensions_dir_;
271 240
272 // A temporary directory to use for unpacking. 241 // Temporary directory to use for unpacking.
273 base::ScopedTempDir temp_dir_; 242 base::ScopedTempDir temp_dir_;
274 243
275 // The root directory of the unpacked extension. This is a child of temp_dir_. 244 // Root directory of the unpacked extension (a child of temp_dir_).
276 base::FilePath extension_root_; 245 base::FilePath extension_root_;
277 246
278 // Represents the extension we're unpacking. 247 // Represents the extension we're unpacking.
279 scoped_refptr<Extension> extension_; 248 scoped_refptr<Extension> extension_;
280 249
281 // Whether we've received a response from the utility process yet.
282 bool got_response_;
283
284 // The public key that was extracted from the CRX header. 250 // The public key that was extracted from the CRX header.
285 std::string public_key_; 251 std::string public_key_;
286 252
287 // The extension's ID. This will be calculated from the public key in the crx 253 // The extension's ID. This will be calculated from the public key
288 // header. 254 // in the CRX header.
289 std::string extension_id_; 255 std::string extension_id_;
290 256
291 // If we unpacked a .crx file, the time at which unpacking started. Used to 257 // If we unpacked a CRX file, the time at which unpacking started.
292 // compute the time unpacking takes. 258 // Used to compute the time unpacking takes.
293 base::TimeTicks crx_unpack_start_time_; 259 base::TimeTicks crx_unpack_start_time_;
294 260
295 // Location to use for the unpacked extension. 261 // Location to use for the unpacked extension.
296 Manifest::Location location_; 262 Manifest::Location location_;
297 263
298 // Creation flags to use for the extension. These flags will be used 264 // Creation flags to use for the extension. These flags will be used
299 // when calling Extenion::Create() by the crx installer. 265 // when calling Extenion::Create() by the CRX installer.
300 int creation_flags_; 266 int creation_flags_;
301 267
302 // Sequenced task runner where file I/O operations will be performed at. 268 // Sequenced task runner where file I/O operations will be performed.
303 scoped_refptr<base::SequencedTaskRunner> unpacker_io_task_runner_; 269 scoped_refptr<base::SequencedTaskRunner> unpacker_io_task_runner_;
304 270
305 // Used for sending tasks to the utility process. 271 // Utility client used for sending tasks to the utility process.
306 scoped_refptr<UtilityHostWrapper> utility_wrapper_; 272 std::unique_ptr<content::UtilityProcessMojoClient<mojom::ExtensionUnpacker>>
273 utility_process_mojo_client_;
307 274
308 DISALLOW_COPY_AND_ASSIGN(SandboxedUnpacker); 275 DISALLOW_COPY_AND_ASSIGN(SandboxedUnpacker);
309 }; 276 };
310 277
311 } // namespace extensions 278 } // namespace extensions
312 279
313 #endif // EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_ 280 #endif // EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_
OLDNEW
« no previous file with comments | « extensions/browser/extensions_test.cc ('k') | extensions/browser/sandboxed_unpacker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698