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

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

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

Powered by Google App Engine
This is Rietveld 408576698