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

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

Issue 2697463002: Convert utility process extension Unpacker IPC to mojo (Closed)
Patch Set: Use MakeUnique when creating the utility mojo client. Created 3 years, 10 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 "extensions/browser/sandboxed_unpacker.h" 5 #include "extensions/browser/sandboxed_unpacker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <set> 10 #include <set>
11 #include <tuple> 11 #include <tuple>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
16 #include "base/json/json_string_value_serializer.h" 16 #include "base/json/json_string_value_serializer.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
19 #include "base/numerics/safe_conversions.h"
20 #include "base/path_service.h" 18 #include "base/path_service.h"
21 #include "base/sequenced_task_runner.h" 19 #include "base/sequenced_task_runner.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
24 #include "base/threading/sequenced_worker_pool.h"
25 #include "build/build_config.h" 21 #include "build/build_config.h"
26 #include "components/crx_file/crx_file.h" 22 #include "components/crx_file/crx_file.h"
27 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/utility_process_host.h"
29 #include "content/public/common/common_param_traits.h"
30 #include "extensions/common/constants.h" 24 #include "extensions/common/constants.h"
31 #include "extensions/common/extension.h" 25 #include "extensions/common/extension.h"
32 #include "extensions/common/extension_l10n_util.h" 26 #include "extensions/common/extension_l10n_util.h"
33 #include "extensions/common/extension_utility_messages.h" 27 #include "extensions/common/extension_utility_messages.h"
28 #include "extensions/common/extension_utility_types.h"
34 #include "extensions/common/extensions_client.h" 29 #include "extensions/common/extensions_client.h"
35 #include "extensions/common/file_util.h" 30 #include "extensions/common/file_util.h"
36 #include "extensions/common/manifest_constants.h" 31 #include "extensions/common/manifest_constants.h"
37 #include "extensions/common/manifest_handlers/icons_handler.h" 32 #include "extensions/common/manifest_handlers/icons_handler.h"
38 #include "extensions/common/switches.h" 33 #include "extensions/common/switches.h"
39 #include "grit/extensions_strings.h" 34 #include "grit/extensions_strings.h"
40 #include "third_party/skia/include/core/SkBitmap.h" 35 #include "third_party/skia/include/core/SkBitmap.h"
41 #include "ui/base/l10n/l10n_util.h" 36 #include "ui/base/l10n/l10n_util.h"
42 #include "ui/gfx/codec/png_codec.h" 37 #include "ui/gfx/codec/png_codec.h"
43 38
44 using base::ASCIIToUTF16; 39 using base::ASCIIToUTF16;
45 using content::BrowserThread; 40 using content::BrowserThread;
46 using content::UtilityProcessHost;
47 using crx_file::CrxFile; 41 using crx_file::CrxFile;
48 42
49 // The following macro makes histograms that record the length of paths 43 // The following macro makes histograms that record the length of paths
50 // in this file much easier to read. 44 // in this file much easier to read.
51 // Windows has a short max path length. If the path length to a 45 // Windows has a short max path length. If the path length to a
52 // file being unpacked from a CRX exceeds the max length, we might 46 // file being unpacked from a CRX exceeds the max length, we might
53 // fail to install. To see if this is happening, see how long the 47 // fail to install. To see if this is happening, see how long the
54 // path to the temp unpack directory is. See crbug.com/69693 . 48 // path to the temp unpack directory is. See crbug.com/69693 .
55 #define PATH_LENGTH_HISTOGRAM(name, path) \ 49 #define PATH_LENGTH_HISTOGRAM(name, path) \
56 UMA_HISTOGRAM_CUSTOM_COUNTS(name, path.value().length(), 1, 500, 100) 50 UMA_HISTOGRAM_CUSTOM_COUNTS(name, path.value().length(), 1, 500, 100)
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 } 211 }
218 212
219 SandboxedUnpacker::SandboxedUnpacker( 213 SandboxedUnpacker::SandboxedUnpacker(
220 Manifest::Location location, 214 Manifest::Location location,
221 int creation_flags, 215 int creation_flags,
222 const base::FilePath& extensions_dir, 216 const base::FilePath& extensions_dir,
223 const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner, 217 const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner,
224 SandboxedUnpackerClient* client) 218 SandboxedUnpackerClient* client)
225 : client_(client), 219 : client_(client),
226 extensions_dir_(extensions_dir), 220 extensions_dir_(extensions_dir),
227 got_response_(false),
228 location_(location), 221 location_(location),
229 creation_flags_(creation_flags), 222 creation_flags_(creation_flags),
230 unpacker_io_task_runner_(unpacker_io_task_runner), 223 unpacker_io_task_runner_(unpacker_io_task_runner) {}
231 utility_wrapper_(new UtilityHostWrapper) {}
232 224
233 bool SandboxedUnpacker::CreateTempDirectory() { 225 bool SandboxedUnpacker::CreateTempDirectory() {
234 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 226 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
235 227
236 base::FilePath temp_dir; 228 base::FilePath temp_dir;
237 if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) { 229 if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) {
238 ReportFailure(COULD_NOT_GET_TEMP_DIRECTORY, 230 ReportFailure(COULD_NOT_GET_TEMP_DIRECTORY,
239 l10n_util::GetStringFUTF16( 231 l10n_util::GetStringFUTF16(
240 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 232 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
241 ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"))); 233 ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY")));
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 LOG(ERROR) << "Could not get the normalized path of " 298 LOG(ERROR) << "Could not get the normalized path of "
307 << temp_crx_path.value(); 299 << temp_crx_path.value();
308 ReportFailure(COULD_NOT_GET_SANDBOX_FRIENDLY_PATH, 300 ReportFailure(COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
309 l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED)); 301 l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
310 return; 302 return;
311 } 303 }
312 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength", 304 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength",
313 link_free_crx_path); 305 link_free_crx_path);
314 306
315 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 307 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
316 base::Bind(&SandboxedUnpacker::StartUnzipOnIOThread, 308 base::Bind(&SandboxedUnpacker::UnzipOnIOThread, this,
317 this, link_free_crx_path)); 309 link_free_crx_path));
318 } 310 }
319 311
320 void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id, 312 void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id,
321 const std::string& public_key, 313 const std::string& public_key,
322 const base::FilePath& directory) { 314 const base::FilePath& directory) {
323 extension_id_ = extension_id; 315 extension_id_ = extension_id;
324 public_key_ = public_key; 316 public_key_ = public_key;
325 if (!CreateTempDirectory()) 317 if (!CreateTempDirectory())
326 return; // ReportFailure() already called. 318 return; // ReportFailure() already called.
327 319
328 extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName); 320 extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName);
329 321
330 if (!base::Move(directory, extension_root_)) { 322 if (!base::Move(directory, extension_root_)) {
331 LOG(ERROR) << "Could not move " << directory.value() << " to " 323 LOG(ERROR) << "Could not move " << directory.value() << " to "
332 << extension_root_.value(); 324 << extension_root_.value();
333 ReportFailure( 325 ReportFailure(
334 DIRECTORY_MOVE_FAILED, 326 DIRECTORY_MOVE_FAILED,
335 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 327 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
336 ASCIIToUTF16("DIRECTORY_MOVE_FAILED"))); 328 ASCIIToUTF16("DIRECTORY_MOVE_FAILED")));
337 return; 329 return;
338 } 330 }
339 331
340 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 332 BrowserThread::PostTask(
341 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, 333 BrowserThread::IO, FROM_HERE,
342 this, extension_root_)); 334 base::Bind(&SandboxedUnpacker::UnpackOnIOThread, this, extension_root_));
343 } 335 }
344 336
345 SandboxedUnpacker::~SandboxedUnpacker() { 337 SandboxedUnpacker::~SandboxedUnpacker() {
346 // To avoid blocking shutdown, don't delete temporary directory here if it 338 // To avoid blocking shutdown, don't delete temporary directory here if it
347 // hasn't been cleaned up or passed on to another owner yet. 339 // hasn't been cleaned up or passed on to another owner yet.
348 temp_dir_.Take(); 340 temp_dir_.Take();
349 } 341 }
350 342
351 bool SandboxedUnpacker::OnMessageReceived(const IPC::Message& message) { 343 void SandboxedUnpacker::StartUtilityProcess(const base::FilePath& dir) {
352 bool handled = true; 344 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
353 IPC_BEGIN_MESSAGE_MAP(SandboxedUnpacker, message) 345 DCHECK(!dir.empty());
354 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnzipToDir_Succeeded, 346
355 OnUnzipToDirSucceeded) 347 if (utility_process_mojo_client_)
Devlin 2017/02/14 17:24:59 Should this happen? It looks like we're clearing
Noel Gordon 2017/02/15 17:28:08 Yes it will happen. We clear it on failures [1],
356 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnzipToDir_Failed, 348 return;
357 OnUnzipToDirFailed) 349
358 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnpackExtension_Succeeded, 350 utility_process_mojo_client_ = base::MakeUnique<
359 OnUnpackExtensionSucceeded) 351 content::UtilityProcessMojoClient<extensions::mojom::ExtensionUnpacker>>(
360 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnpackExtension_Failed, 352 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EXTENSION_UNPACKER_NAME));
361 OnUnpackExtensionFailed) 353 utility_process_mojo_client_->set_error_callback(
362 IPC_MESSAGE_UNHANDLED(handled = false) 354 base::Bind(&SandboxedUnpacker::UtilityProcessCrashed, this));
363 IPC_END_MESSAGE_MAP() 355 utility_process_mojo_client_->set_exposed_directory(dir);
364 return handled; 356
357 utility_process_mojo_client_->Start();
365 } 358 }
366 359
367 void SandboxedUnpacker::OnProcessCrashed(int exit_code) { 360 void SandboxedUnpacker::UtilityProcessCrashed() {
368 // Don't report crashes if they happen after we got a response. 361 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
369 if (got_response_)
370 return;
371 362
372 // Utility process crashed while trying to install. 363 utility_process_mojo_client_.reset();
364
373 ReportFailure( 365 ReportFailure(
374 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, 366 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
375 l10n_util::GetStringFUTF16( 367 l10n_util::GetStringFUTF16(
376 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 368 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
377 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + 369 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) +
378 ASCIIToUTF16(". ") + 370 ASCIIToUTF16(". ") +
379 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); 371 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED));
380 } 372 }
381 373
382 void SandboxedUnpacker::StartUnzipOnIOThread(const base::FilePath& crx_path) { 374 void SandboxedUnpacker::UnzipOnIOThread(const base::FilePath& crx_path) {
383 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, 375 DCHECK_CURRENTLY_ON(BrowserThread::IO);
384 unpacker_io_task_runner_)) { 376
385 ReportFailure( 377 StartUtilityProcess(temp_dir_.GetPath());
386 COULD_NOT_START_UTILITY_PROCESS, 378
387 l10n_util::GetStringFUTF16(
388 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
389 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS)));
390 return;
391 }
392 DCHECK(crx_path.DirName() == temp_dir_.GetPath()); 379 DCHECK(crx_path.DirName() == temp_dir_.GetPath());
393 base::FilePath unzipped_dir = 380 base::FilePath unzipped_dir =
394 crx_path.DirName().AppendASCII(kTempExtensionName); 381 crx_path.DirName().AppendASCII(kTempExtensionName);
395 utility_wrapper_->host()->Send( 382
396 new ExtensionUtilityMsg_UnzipToDir(crx_path, unzipped_dir)); 383 utility_process_mojo_client_->service()->Unzip(
384 crx_path, unzipped_dir,
385 base::Bind(&SandboxedUnpacker::UnzipDone, this, unzipped_dir));
397 } 386 }
398 387
399 void SandboxedUnpacker::StartUnpackOnIOThread( 388 void SandboxedUnpacker::UnzipDone(const base::FilePath& directory,
400 const base::FilePath& directory_path) { 389 bool success) {
401 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, 390 DCHECK_CURRENTLY_ON(BrowserThread::IO);
402 unpacker_io_task_runner_)) { 391
403 ReportFailure( 392 if (!success) {
404 COULD_NOT_START_UTILITY_PROCESS, 393 utility_process_mojo_client_.reset();
405 l10n_util::GetStringFUTF16( 394 ReportFailure(UNZIP_FAILED,
406 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 395 l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR));
407 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS)));
408 return; 396 return;
409 } 397 }
410 DCHECK(directory_path.DirName() == temp_dir_.GetPath()); 398
411 utility_wrapper_->host()->Send(new ExtensionUtilityMsg_UnpackExtension( 399 BrowserThread::PostTask(
412 directory_path, extension_id_, location_, creation_flags_)); 400 BrowserThread::IO, FROM_HERE,
401 base::Bind(&SandboxedUnpacker::UnpackOnIOThread, this, directory));
413 } 402 }
414 403
415 void SandboxedUnpacker::OnUnzipToDirSucceeded(const base::FilePath& directory) { 404 void SandboxedUnpacker::UnpackOnIOThread(const base::FilePath& directory) {
416 BrowserThread::PostTask( 405 DCHECK_CURRENTLY_ON(BrowserThread::IO);
417 BrowserThread::IO, FROM_HERE, 406
418 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, this, directory)); 407 StartUtilityProcess(temp_dir_.GetPath());
408
409 DCHECK(directory.DirName() == temp_dir_.GetPath());
410
411 utility_process_mojo_client_->service()->Unpack(
412 directory, extension_id_, location_, creation_flags_,
413 base::Bind(&SandboxedUnpacker::UnpackDone, this));
419 } 414 }
420 415
421 void SandboxedUnpacker::OnUnzipToDirFailed(const std::string& error) { 416 void SandboxedUnpacker::UnpackDone(
422 got_response_ = true; 417 const base::string16& error,
423 utility_wrapper_ = nullptr; 418 std::unique_ptr<base::DictionaryValue> manifest) {
424 ReportFailure(UNZIP_FAILED, 419 DCHECK_CURRENTLY_ON(BrowserThread::IO);
425 l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR)); 420
421 utility_process_mojo_client_.reset();
422
423 if (!error.empty()) {
424 unpacker_io_task_runner_->PostTask(
425 FROM_HERE,
426 base::Bind(&SandboxedUnpacker::UnpackExtensionFailed, this, error));
427 return;
428 }
429
430 unpacker_io_task_runner_->PostTask(
431 FROM_HERE, base::Bind(&SandboxedUnpacker::UnpackExtensionSucceeded, this,
432 base::Passed(&manifest)));
426 } 433 }
427 434
428 void SandboxedUnpacker::OnUnpackExtensionSucceeded( 435 void SandboxedUnpacker::UnpackExtensionSucceeded(
429 const base::DictionaryValue& manifest) { 436 std::unique_ptr<base::DictionaryValue> manifest) {
430 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 437 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
431 got_response_ = true;
432 utility_wrapper_ = nullptr;
433 438
434 std::unique_ptr<base::DictionaryValue> final_manifest( 439 std::unique_ptr<base::DictionaryValue> final_manifest(
435 RewriteManifestFile(manifest)); 440 RewriteManifestFile(*manifest.get()));
Devlin 2017/02/14 17:24:59 *foo.get() is redundant. Prefer just *foo.
Noel Gordon 2017/02/15 17:28:08 Done.
436 if (!final_manifest) 441 if (!final_manifest)
437 return; 442 return;
438 443
439 // Create an extension object that refers to the temporary location the 444 // Create an extension object that refers to the temporary location the
440 // extension was unpacked to. We use this until the extension is finally 445 // extension was unpacked to. We use this until the extension is finally
441 // installed. For example, the install UI shows images from inside the 446 // installed. For example, the install UI shows images from inside the
442 // extension. 447 // extension.
443 448
444 // Localize manifest now, so confirm UI gets correct extension name. 449 // Localize manifest now, so confirm UI gets correct extension name.
445 450
(...skipping 19 matching lines...) Expand all
465 return; 470 return;
466 } 471 }
467 472
468 SkBitmap install_icon; 473 SkBitmap install_icon;
469 if (!RewriteImageFiles(&install_icon)) 474 if (!RewriteImageFiles(&install_icon))
470 return; 475 return;
471 476
472 if (!RewriteCatalogFiles()) 477 if (!RewriteCatalogFiles())
473 return; 478 return;
474 479
475 ReportSuccess(manifest, install_icon); 480 ReportSuccess(std::move(manifest), install_icon);
476 } 481 }
477 482
478 void SandboxedUnpacker::OnUnpackExtensionFailed(const base::string16& error) { 483 void SandboxedUnpacker::UnpackExtensionFailed(const base::string16& error) {
479 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 484 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
480 got_response_ = true; 485
481 utility_wrapper_ = nullptr;
482 ReportFailure( 486 ReportFailure(
483 UNPACKER_CLIENT_FAILED, 487 UNPACKER_CLIENT_FAILED,
484 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error)); 488 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error));
485 } 489 }
486 490
487 base::string16 SandboxedUnpacker::FailureReasonToString16( 491 base::string16 SandboxedUnpacker::FailureReasonToString16(
488 FailureReason reason) { 492 FailureReason reason) {
489 switch (reason) { 493 switch (reason) {
490 case COULD_NOT_GET_TEMP_DIRECTORY: 494 case COULD_NOT_GET_TEMP_DIRECTORY:
491 return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"); 495 return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY");
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 case ERROR_SAVING_CATALOG: 564 case ERROR_SAVING_CATALOG:
561 return ASCIIToUTF16("ERROR_SAVING_CATALOG"); 565 return ASCIIToUTF16("ERROR_SAVING_CATALOG");
562 566
563 case CRX_HASH_VERIFICATION_FAILED: 567 case CRX_HASH_VERIFICATION_FAILED:
564 return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED"); 568 return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED");
565 569
566 case UNZIP_FAILED: 570 case UNZIP_FAILED:
567 return ASCIIToUTF16("UNZIP_FAILED"); 571 return ASCIIToUTF16("UNZIP_FAILED");
568 case DIRECTORY_MOVE_FAILED: 572 case DIRECTORY_MOVE_FAILED:
569 return ASCIIToUTF16("DIRECTORY_MOVE_FAILED"); 573 return ASCIIToUTF16("DIRECTORY_MOVE_FAILED");
570 case COULD_NOT_START_UTILITY_PROCESS:
571 return ASCIIToUTF16("COULD_NOT_START_UTILITY_PROCESS");
572 574
573 case NUM_FAILURE_REASONS: 575 case NUM_FAILURE_REASONS:
574 NOTREACHED(); 576 NOTREACHED();
575 return base::string16(); 577 return base::string16();
576 } 578 }
579
577 NOTREACHED(); 580 NOTREACHED();
578 return base::string16(); 581 return base::string16();
579 } 582 }
580 583
581 void SandboxedUnpacker::FailWithPackageError(FailureReason reason) { 584 void SandboxedUnpacker::FailWithPackageError(FailureReason reason) {
582 ReportFailure(reason, 585 ReportFailure(reason,
583 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, 586 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE,
584 FailureReasonToString16(reason))); 587 FailureReasonToString16(reason)));
585 } 588 }
586 589
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 CHECK(!expected_hash.empty()); 639 CHECK(!expected_hash.empty());
637 UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false); 640 UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false);
638 FailWithPackageError(CRX_HASH_VERIFICATION_FAILED); 641 FailWithPackageError(CRX_HASH_VERIFICATION_FAILED);
639 break; 642 break;
640 } 643 }
641 return false; 644 return false;
642 } 645 }
643 646
644 void SandboxedUnpacker::ReportFailure(FailureReason reason, 647 void SandboxedUnpacker::ReportFailure(FailureReason reason,
645 const base::string16& error) { 648 const base::string16& error) {
646 utility_wrapper_ = nullptr;
647 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason, 649 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason,
648 NUM_FAILURE_REASONS); 650 NUM_FAILURE_REASONS);
649 if (!crx_unpack_start_time_.is_null()) 651 if (!crx_unpack_start_time_.is_null())
650 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", 652 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime",
651 base::TimeTicks::Now() - crx_unpack_start_time_); 653 base::TimeTicks::Now() - crx_unpack_start_time_);
652 Cleanup(); 654 Cleanup();
653 655
654 CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED 656 CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED
655 ? CrxInstallError::ERROR_HASH_MISMATCH 657 ? CrxInstallError::ERROR_HASH_MISMATCH
656 : CrxInstallError::ERROR_OTHER, 658 : CrxInstallError::ERROR_OTHER,
657 error); 659 error);
658 660
659 client_->OnUnpackFailure(error_info); 661 client_->OnUnpackFailure(error_info);
660 } 662 }
661 663
662 void SandboxedUnpacker::ReportSuccess( 664 void SandboxedUnpacker::ReportSuccess(
663 const base::DictionaryValue& original_manifest, 665 std::unique_ptr<base::DictionaryValue> original_manifest,
664 const SkBitmap& install_icon) { 666 const SkBitmap& install_icon) {
665 utility_wrapper_ = nullptr;
666 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); 667 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1);
667 668
668 if (!crx_unpack_start_time_.is_null()) 669 if (!crx_unpack_start_time_.is_null())
669 RecordSuccessfulUnpackTimeHistograms( 670 RecordSuccessfulUnpackTimeHistograms(
670 crx_path_for_histograms_, 671 crx_path_for_histograms_,
671 base::TimeTicks::Now() - crx_unpack_start_time_); 672 base::TimeTicks::Now() - crx_unpack_start_time_);
672 DCHECK(!temp_dir_.GetPath().empty()); 673 DCHECK(!temp_dir_.GetPath().empty());
673 674
674 // Client takes ownership of temporary directory and extension. 675 // Client takes ownership of temporary directory and extension.
675 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_, 676 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_,
676 &original_manifest, extension_.get(), install_icon); 677 original_manifest.get(), extension_.get(),
Noel Gordon 2017/02/15 17:28:08 Perhaps client_->OnUnpackSuccess could take owners
678 install_icon);
677 extension_ = NULL; 679 extension_ = NULL;
678 } 680 }
679 681
680 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( 682 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile(
681 const base::DictionaryValue& manifest) { 683 const base::DictionaryValue& manifest) {
682 // Add the public key extracted earlier to the parsed manifest and overwrite 684 // Add the public key extracted earlier to the parsed manifest and overwrite
683 // the original manifest. We do this to ensure the manifest doesn't contain an 685 // the original manifest. We do this to ensure the manifest doesn't contain an
684 // exploitable bug that could be used to compromise the browser. 686 // exploitable bug that could be used to compromise the browser.
685 DCHECK(!public_key_.empty()); 687 DCHECK(!public_key_.empty());
686 std::unique_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy()); 688 std::unique_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy());
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 } 888 }
887 889
888 void SandboxedUnpacker::Cleanup() { 890 void SandboxedUnpacker::Cleanup() {
889 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 891 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
890 if (!temp_dir_.Delete()) { 892 if (!temp_dir_.Delete()) {
891 LOG(WARNING) << "Can not delete temp directory at " 893 LOG(WARNING) << "Can not delete temp directory at "
892 << temp_dir_.GetPath().value(); 894 << temp_dir_.GetPath().value();
893 } 895 }
894 } 896 }
895 897
896 SandboxedUnpacker::UtilityHostWrapper::UtilityHostWrapper() {}
897
898 bool SandboxedUnpacker::UtilityHostWrapper::StartIfNeeded(
899 const base::FilePath& exposed_dir,
900 const scoped_refptr<UtilityProcessHostClient>& client,
901 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner) {
902 DCHECK_CURRENTLY_ON(BrowserThread::IO);
903 if (!utility_host_) {
904 utility_host_ =
905 UtilityProcessHost::Create(client, client_task_runner)->AsWeakPtr();
906 utility_host_->SetName(
907 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EXTENSION_UNPACKER_NAME));
908
909 // Grant the subprocess access to our temp dir so it can write out files.
910 DCHECK(!exposed_dir.empty());
911 utility_host_->SetExposedDir(exposed_dir);
912 if (!utility_host_->StartBatchMode()) {
913 utility_host_.reset();
914 return false;
915 }
916 }
917 return true;
918 }
919
920 content::UtilityProcessHost* SandboxedUnpacker::UtilityHostWrapper::host()
921 const {
922 DCHECK_CURRENTLY_ON(BrowserThread::IO);
923 return utility_host_.get();
924 }
925
926 SandboxedUnpacker::UtilityHostWrapper::~UtilityHostWrapper() {
927 DCHECK_CURRENTLY_ON(BrowserThread::IO);
928 if (utility_host_) {
929 utility_host_->EndBatchMode();
930 utility_host_.reset();
931 }
932 }
933
934 } // namespace extensions 898 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698