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

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

Issue 2697463002: Convert utility process extension Unpacker IPC to mojo (Closed)
Patch Set: Add extensions::unpacker::TakeParsedManifest(). 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_)
356 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnzipToDir_Failed, 348 return;
357 OnUnzipToDirFailed) 349
358 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnpackExtension_Succeeded, 350 const base::string16 utility_process_name =
359 OnUnpackExtensionSucceeded) 351 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EXTENSION_UNPACKER_NAME);
360 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnpackExtension_Failed, 352
361 OnUnpackExtensionFailed) 353 utility_process_mojo_client_.reset(
Sam McNally 2017/02/14 05:41:52 utility_process_mojo_client_ = base::MakeUnique<co
Noel Gordon 2017/02/14 12:35:37 Done.
362 IPC_MESSAGE_UNHANDLED(handled = false) 354 new content::UtilityProcessMojoClient<
363 IPC_END_MESSAGE_MAP() 355 extensions::mojom::ExtensionUnpacker>(utility_process_name));
364 return handled; 356 utility_process_mojo_client_->set_error_callback(
357 base::Bind(&SandboxedUnpacker::UtilityProcessCrashed, this));
358
359 utility_process_mojo_client_->set_exposed_directory(dir);
360
361 utility_process_mojo_client_->Start();
365 } 362 }
366 363
367 void SandboxedUnpacker::OnProcessCrashed(int exit_code) { 364 void SandboxedUnpacker::UtilityProcessCrashed() {
368 // Don't report crashes if they happen after we got a response. 365 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
369 if (got_response_)
370 return;
371 366
372 // Utility process crashed while trying to install. 367 utility_process_mojo_client_.reset();
368
373 ReportFailure( 369 ReportFailure(
374 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, 370 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
375 l10n_util::GetStringFUTF16( 371 l10n_util::GetStringFUTF16(
376 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 372 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
377 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + 373 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) +
378 ASCIIToUTF16(". ") + 374 ASCIIToUTF16(". ") +
379 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); 375 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED));
380 } 376 }
381 377
382 void SandboxedUnpacker::StartUnzipOnIOThread(const base::FilePath& crx_path) { 378 void SandboxedUnpacker::UnzipOnIOThread(const base::FilePath& crx_path) {
383 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, 379 DCHECK_CURRENTLY_ON(BrowserThread::IO);
384 unpacker_io_task_runner_)) { 380
385 ReportFailure( 381 StartUtilityProcess(temp_dir_.GetPath());
386 COULD_NOT_START_UTILITY_PROCESS, 382
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()); 383 DCHECK(crx_path.DirName() == temp_dir_.GetPath());
393 base::FilePath unzipped_dir = 384 base::FilePath unzipped_dir =
394 crx_path.DirName().AppendASCII(kTempExtensionName); 385 crx_path.DirName().AppendASCII(kTempExtensionName);
395 utility_wrapper_->host()->Send( 386
396 new ExtensionUtilityMsg_UnzipToDir(crx_path, unzipped_dir)); 387 utility_process_mojo_client_->service()->Unzip(
388 crx_path, unzipped_dir,
389 base::Bind(&SandboxedUnpacker::UnzipDone, this, unzipped_dir));
397 } 390 }
398 391
399 void SandboxedUnpacker::StartUnpackOnIOThread( 392 void SandboxedUnpacker::UnzipDone(const base::FilePath& directory,
400 const base::FilePath& directory_path) { 393 bool success) {
401 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, 394 DCHECK_CURRENTLY_ON(BrowserThread::IO);
402 unpacker_io_task_runner_)) { 395
403 ReportFailure( 396 if (!success) {
404 COULD_NOT_START_UTILITY_PROCESS, 397 utility_process_mojo_client_.reset();
405 l10n_util::GetStringFUTF16( 398 ReportFailure(UNZIP_FAILED,
406 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 399 l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR));
407 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS)));
408 return; 400 return;
409 } 401 }
410 DCHECK(directory_path.DirName() == temp_dir_.GetPath()); 402
411 utility_wrapper_->host()->Send(new ExtensionUtilityMsg_UnpackExtension( 403 BrowserThread::PostTask(
412 directory_path, extension_id_, location_, creation_flags_)); 404 BrowserThread::IO, FROM_HERE,
405 base::Bind(&SandboxedUnpacker::UnpackOnIOThread, this, directory));
413 } 406 }
414 407
415 void SandboxedUnpacker::OnUnzipToDirSucceeded(const base::FilePath& directory) { 408 void SandboxedUnpacker::UnpackOnIOThread(const base::FilePath& directory) {
416 BrowserThread::PostTask( 409 DCHECK_CURRENTLY_ON(BrowserThread::IO);
417 BrowserThread::IO, FROM_HERE, 410
418 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, this, directory)); 411 StartUtilityProcess(temp_dir_.GetPath());
412
413 DCHECK(directory.DirName() == temp_dir_.GetPath());
414
415 utility_process_mojo_client_->service()->Unpack(
416 directory, extension_id_, location_, creation_flags_,
417 base::Bind(&SandboxedUnpacker::UnpackDone, this));
419 } 418 }
420 419
421 void SandboxedUnpacker::OnUnzipToDirFailed(const std::string& error) { 420 void SandboxedUnpacker::UnpackDone(
422 got_response_ = true; 421 const base::string16& error,
423 utility_wrapper_ = nullptr; 422 std::unique_ptr<base::DictionaryValue> manifest) {
424 ReportFailure(UNZIP_FAILED, 423 DCHECK_CURRENTLY_ON(BrowserThread::IO);
425 l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR)); 424
425 utility_process_mojo_client_.reset();
426
427 if (!error.empty()) {
428 unpacker_io_task_runner_->PostTask(
429 FROM_HERE,
430 base::Bind(&SandboxedUnpacker::UnpackExtensionFailed, this, error));
431 return;
432 }
433
434 unpacker_io_task_runner_->PostTask(
435 FROM_HERE, base::Bind(&SandboxedUnpacker::UnpackExtensionSucceeded, this,
436 base::Passed(&manifest)));
426 } 437 }
427 438
428 void SandboxedUnpacker::OnUnpackExtensionSucceeded( 439 void SandboxedUnpacker::UnpackExtensionSucceeded(
429 const base::DictionaryValue& manifest) { 440 std::unique_ptr<base::DictionaryValue> manifest) {
430 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 441 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
431 got_response_ = true;
432 utility_wrapper_ = nullptr;
433 442
434 std::unique_ptr<base::DictionaryValue> final_manifest( 443 std::unique_ptr<base::DictionaryValue> final_manifest(
435 RewriteManifestFile(manifest)); 444 RewriteManifestFile(*manifest.get()));
436 if (!final_manifest) 445 if (!final_manifest)
437 return; 446 return;
438 447
439 // Create an extension object that refers to the temporary location the 448 // Create an extension object that refers to the temporary location the
440 // extension was unpacked to. We use this until the extension is finally 449 // extension was unpacked to. We use this until the extension is finally
441 // installed. For example, the install UI shows images from inside the 450 // installed. For example, the install UI shows images from inside the
442 // extension. 451 // extension.
443 452
444 // Localize manifest now, so confirm UI gets correct extension name. 453 // Localize manifest now, so confirm UI gets correct extension name.
445 454
(...skipping 19 matching lines...) Expand all
465 return; 474 return;
466 } 475 }
467 476
468 SkBitmap install_icon; 477 SkBitmap install_icon;
469 if (!RewriteImageFiles(&install_icon)) 478 if (!RewriteImageFiles(&install_icon))
470 return; 479 return;
471 480
472 if (!RewriteCatalogFiles()) 481 if (!RewriteCatalogFiles())
473 return; 482 return;
474 483
475 ReportSuccess(manifest, install_icon); 484 ReportSuccess(std::move(manifest), install_icon);
476 } 485 }
477 486
478 void SandboxedUnpacker::OnUnpackExtensionFailed(const base::string16& error) { 487 void SandboxedUnpacker::UnpackExtensionFailed(const base::string16& error) {
479 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 488 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
480 got_response_ = true; 489
481 utility_wrapper_ = nullptr;
482 ReportFailure( 490 ReportFailure(
483 UNPACKER_CLIENT_FAILED, 491 UNPACKER_CLIENT_FAILED,
484 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error)); 492 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error));
485 } 493 }
486 494
487 base::string16 SandboxedUnpacker::FailureReasonToString16( 495 base::string16 SandboxedUnpacker::FailureReasonToString16(
488 FailureReason reason) { 496 FailureReason reason) {
489 switch (reason) { 497 switch (reason) {
490 case COULD_NOT_GET_TEMP_DIRECTORY: 498 case COULD_NOT_GET_TEMP_DIRECTORY:
491 return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"); 499 return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY");
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 case ERROR_SAVING_CATALOG: 568 case ERROR_SAVING_CATALOG:
561 return ASCIIToUTF16("ERROR_SAVING_CATALOG"); 569 return ASCIIToUTF16("ERROR_SAVING_CATALOG");
562 570
563 case CRX_HASH_VERIFICATION_FAILED: 571 case CRX_HASH_VERIFICATION_FAILED:
564 return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED"); 572 return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED");
565 573
566 case UNZIP_FAILED: 574 case UNZIP_FAILED:
567 return ASCIIToUTF16("UNZIP_FAILED"); 575 return ASCIIToUTF16("UNZIP_FAILED");
568 case DIRECTORY_MOVE_FAILED: 576 case DIRECTORY_MOVE_FAILED:
569 return ASCIIToUTF16("DIRECTORY_MOVE_FAILED"); 577 return ASCIIToUTF16("DIRECTORY_MOVE_FAILED");
570 case COULD_NOT_START_UTILITY_PROCESS:
571 return ASCIIToUTF16("COULD_NOT_START_UTILITY_PROCESS");
572 578
573 case NUM_FAILURE_REASONS: 579 case NUM_FAILURE_REASONS:
574 NOTREACHED(); 580 NOTREACHED();
575 return base::string16(); 581 return base::string16();
576 } 582 }
583
577 NOTREACHED(); 584 NOTREACHED();
578 return base::string16(); 585 return base::string16();
579 } 586 }
580 587
581 void SandboxedUnpacker::FailWithPackageError(FailureReason reason) { 588 void SandboxedUnpacker::FailWithPackageError(FailureReason reason) {
582 ReportFailure(reason, 589 ReportFailure(reason,
583 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, 590 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE,
584 FailureReasonToString16(reason))); 591 FailureReasonToString16(reason)));
585 } 592 }
586 593
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 CHECK(!expected_hash.empty()); 643 CHECK(!expected_hash.empty());
637 UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false); 644 UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false);
638 FailWithPackageError(CRX_HASH_VERIFICATION_FAILED); 645 FailWithPackageError(CRX_HASH_VERIFICATION_FAILED);
639 break; 646 break;
640 } 647 }
641 return false; 648 return false;
642 } 649 }
643 650
644 void SandboxedUnpacker::ReportFailure(FailureReason reason, 651 void SandboxedUnpacker::ReportFailure(FailureReason reason,
645 const base::string16& error) { 652 const base::string16& error) {
646 utility_wrapper_ = nullptr;
647 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason, 653 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason,
648 NUM_FAILURE_REASONS); 654 NUM_FAILURE_REASONS);
649 if (!crx_unpack_start_time_.is_null()) 655 if (!crx_unpack_start_time_.is_null())
650 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", 656 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime",
651 base::TimeTicks::Now() - crx_unpack_start_time_); 657 base::TimeTicks::Now() - crx_unpack_start_time_);
652 Cleanup(); 658 Cleanup();
653 659
654 CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED 660 CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED
655 ? CrxInstallError::ERROR_HASH_MISMATCH 661 ? CrxInstallError::ERROR_HASH_MISMATCH
656 : CrxInstallError::ERROR_OTHER, 662 : CrxInstallError::ERROR_OTHER,
657 error); 663 error);
658 664
659 client_->OnUnpackFailure(error_info); 665 client_->OnUnpackFailure(error_info);
660 } 666 }
661 667
662 void SandboxedUnpacker::ReportSuccess( 668 void SandboxedUnpacker::ReportSuccess(
663 const base::DictionaryValue& original_manifest, 669 std::unique_ptr<base::DictionaryValue> original_manifest,
664 const SkBitmap& install_icon) { 670 const SkBitmap& install_icon) {
665 utility_wrapper_ = nullptr;
666 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); 671 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1);
667 672
668 if (!crx_unpack_start_time_.is_null()) 673 if (!crx_unpack_start_time_.is_null())
669 RecordSuccessfulUnpackTimeHistograms( 674 RecordSuccessfulUnpackTimeHistograms(
670 crx_path_for_histograms_, 675 crx_path_for_histograms_,
671 base::TimeTicks::Now() - crx_unpack_start_time_); 676 base::TimeTicks::Now() - crx_unpack_start_time_);
672 DCHECK(!temp_dir_.GetPath().empty()); 677 DCHECK(!temp_dir_.GetPath().empty());
673 678
674 // Client takes ownership of temporary directory and extension. 679 // Client takes ownership of temporary directory and extension.
675 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_, 680 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_,
676 &original_manifest, extension_.get(), install_icon); 681 original_manifest.get(), extension_.get(),
682 install_icon);
677 extension_ = NULL; 683 extension_ = NULL;
678 } 684 }
679 685
680 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( 686 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile(
681 const base::DictionaryValue& manifest) { 687 const base::DictionaryValue& manifest) {
682 // Add the public key extracted earlier to the parsed manifest and overwrite 688 // 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 689 // 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. 690 // exploitable bug that could be used to compromise the browser.
685 DCHECK(!public_key_.empty()); 691 DCHECK(!public_key_.empty());
686 std::unique_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy()); 692 std::unique_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy());
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 } 892 }
887 893
888 void SandboxedUnpacker::Cleanup() { 894 void SandboxedUnpacker::Cleanup() {
889 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 895 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
890 if (!temp_dir_.Delete()) { 896 if (!temp_dir_.Delete()) {
891 LOG(WARNING) << "Can not delete temp directory at " 897 LOG(WARNING) << "Can not delete temp directory at "
892 << temp_dir_.GetPath().value(); 898 << temp_dir_.GetPath().value();
893 } 899 }
894 } 900 }
895 901
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 902 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698