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

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

Issue 2697463002: Convert utility process extension Unpacker IPC to mojo (Closed)
Patch Set: Add it again (from a different machine). 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" 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_utility_messages.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 "grit/extensions_strings.h" 35 #include "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 225
233 bool SandboxedUnpacker::CreateTempDirectory() { 226 bool SandboxedUnpacker::CreateTempDirectory() {
234 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 227 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
235 228
236 base::FilePath temp_dir; 229 base::FilePath temp_dir;
237 if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) { 230 if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) {
238 ReportFailure(COULD_NOT_GET_TEMP_DIRECTORY, 231 ReportFailure(COULD_NOT_GET_TEMP_DIRECTORY,
239 l10n_util::GetStringFUTF16( 232 l10n_util::GetStringFUTF16(
240 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 233 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
241 ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"))); 234 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 " 299 LOG(ERROR) << "Could not get the normalized path of "
307 << temp_crx_path.value(); 300 << temp_crx_path.value();
308 ReportFailure(COULD_NOT_GET_SANDBOX_FRIENDLY_PATH, 301 ReportFailure(COULD_NOT_GET_SANDBOX_FRIENDLY_PATH,
309 l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED)); 302 l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED));
310 return; 303 return;
311 } 304 }
312 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength", 305 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackLinkFreeCrxPathLength",
313 link_free_crx_path); 306 link_free_crx_path);
314 307
315 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 308 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
316 base::Bind(&SandboxedUnpacker::StartUnzipOnIOThread, 309 base::Bind(&SandboxedUnpacker::UnzipOnIOThread, this,
317 this, link_free_crx_path)); 310 link_free_crx_path));
318 } 311 }
319 312
320 void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id, 313 void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id,
321 const std::string& public_key, 314 const std::string& public_key,
322 const base::FilePath& directory) { 315 const base::FilePath& directory) {
323 extension_id_ = extension_id; 316 extension_id_ = extension_id;
324 public_key_ = public_key; 317 public_key_ = public_key;
325 if (!CreateTempDirectory()) 318 if (!CreateTempDirectory())
326 return; // ReportFailure() already called. 319 return; // ReportFailure() already called.
327 320
328 extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName); 321 extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName);
329 322
330 if (!base::Move(directory, extension_root_)) { 323 if (!base::Move(directory, extension_root_)) {
331 LOG(ERROR) << "Could not move " << directory.value() << " to " 324 LOG(ERROR) << "Could not move " << directory.value() << " to "
332 << extension_root_.value(); 325 << extension_root_.value();
333 ReportFailure( 326 ReportFailure(
334 DIRECTORY_MOVE_FAILED, 327 DIRECTORY_MOVE_FAILED,
335 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 328 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
336 ASCIIToUTF16("DIRECTORY_MOVE_FAILED"))); 329 ASCIIToUTF16("DIRECTORY_MOVE_FAILED")));
337 return; 330 return;
338 } 331 }
339 332
340 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 333 BrowserThread::PostTask(
341 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, 334 BrowserThread::IO, FROM_HERE,
342 this, extension_root_)); 335 base::Bind(&SandboxedUnpacker::UnpackOnIOThread, this, extension_root_));
343 } 336 }
344 337
345 SandboxedUnpacker::~SandboxedUnpacker() { 338 SandboxedUnpacker::~SandboxedUnpacker() {
346 // To avoid blocking shutdown, don't delete temporary directory here if it 339 // 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. 340 // hasn't been cleaned up or passed on to another owner yet.
348 temp_dir_.Take(); 341 temp_dir_.Take();
349 } 342 }
350 343
351 bool SandboxedUnpacker::OnMessageReceived(const IPC::Message& message) { 344 void SandboxedUnpacker::StartUtilityProcess(const base::FilePath& dir) {
Devlin 2017/02/17 15:53:56 Given both instances of this call it with temp_dir
Noel Gordon 2017/02/27 11:47:50 Done.
352 bool handled = true; 345 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
353 IPC_BEGIN_MESSAGE_MAP(SandboxedUnpacker, message) 346 DCHECK(!dir.empty());
354 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnzipToDir_Succeeded, 347
355 OnUnzipToDirSucceeded) 348 if (utility_process_mojo_client_)
356 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnzipToDir_Failed, 349 return;
357 OnUnzipToDirFailed) 350
358 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnpackExtension_Succeeded, 351 utility_process_mojo_client_ = base::MakeUnique<
359 OnUnpackExtensionSucceeded) 352 content::UtilityProcessMojoClient<extensions::mojom::ExtensionUnpacker>>(
360 IPC_MESSAGE_HANDLER(ExtensionUtilityHostMsg_UnpackExtension_Failed, 353 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_EXTENSION_UNPACKER_NAME));
361 OnUnpackExtensionFailed) 354 utility_process_mojo_client_->set_error_callback(
362 IPC_MESSAGE_UNHANDLED(handled = false) 355 base::Bind(&SandboxedUnpacker::UtilityProcessCrashed, this));
363 IPC_END_MESSAGE_MAP() 356
364 return handled; 357 utility_process_mojo_client_->set_exposed_directory(dir);
358
359 utility_process_mojo_client_->Start();
365 } 360 }
366 361
367 void SandboxedUnpacker::OnProcessCrashed(int exit_code) { 362 void SandboxedUnpacker::UtilityProcessCrashed() {
368 // Don't report crashes if they happen after we got a response. 363 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
369 if (got_response_)
370 return;
371 364
372 // Utility process crashed while trying to install. 365 utility_process_mojo_client_.reset();
366
373 ReportFailure( 367 ReportFailure(
374 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, 368 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL,
375 l10n_util::GetStringFUTF16( 369 l10n_util::GetStringFUTF16(
376 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 370 IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
377 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + 371 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) +
378 ASCIIToUTF16(". ") + 372 ASCIIToUTF16(". ") +
379 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); 373 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED));
380 } 374 }
381 375
382 void SandboxedUnpacker::StartUnzipOnIOThread(const base::FilePath& crx_path) { 376 void SandboxedUnpacker::UnzipOnIOThread(const base::FilePath& crx_path) {
383 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, 377 DCHECK_CURRENTLY_ON(BrowserThread::IO);
384 unpacker_io_task_runner_)) { 378
385 ReportFailure( 379 StartUtilityProcess(temp_dir_.GetPath());
386 COULD_NOT_START_UTILITY_PROCESS, 380
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()); 381 DCHECK(crx_path.DirName() == temp_dir_.GetPath());
393 base::FilePath unzipped_dir = 382 base::FilePath unzipped_dir =
394 crx_path.DirName().AppendASCII(kTempExtensionName); 383 crx_path.DirName().AppendASCII(kTempExtensionName);
395 utility_wrapper_->host()->Send( 384
396 new ExtensionUtilityMsg_UnzipToDir(crx_path, unzipped_dir)); 385 utility_process_mojo_client_->service()->Unzip(
386 crx_path, unzipped_dir,
387 base::Bind(&SandboxedUnpacker::UnzipDone, this, unzipped_dir));
397 } 388 }
398 389
399 void SandboxedUnpacker::StartUnpackOnIOThread( 390 void SandboxedUnpacker::UnzipDone(const base::FilePath& directory,
400 const base::FilePath& directory_path) { 391 bool success) {
401 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, 392 DCHECK_CURRENTLY_ON(BrowserThread::IO);
402 unpacker_io_task_runner_)) { 393
403 ReportFailure( 394 if (!success) {
404 COULD_NOT_START_UTILITY_PROCESS, 395 utility_process_mojo_client_.reset();
405 l10n_util::GetStringFUTF16( 396 ReportFailure(UNZIP_FAILED,
406 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, 397 l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR));
407 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS)));
408 return; 398 return;
409 } 399 }
410 DCHECK(directory_path.DirName() == temp_dir_.GetPath()); 400
411 utility_wrapper_->host()->Send(new ExtensionUtilityMsg_UnpackExtension( 401 BrowserThread::PostTask(
412 directory_path, extension_id_, location_, creation_flags_)); 402 BrowserThread::IO, FROM_HERE,
403 base::Bind(&SandboxedUnpacker::UnpackOnIOThread, this, directory));
413 } 404 }
414 405
415 void SandboxedUnpacker::OnUnzipToDirSucceeded(const base::FilePath& directory) { 406 void SandboxedUnpacker::UnpackOnIOThread(const base::FilePath& directory) {
416 BrowserThread::PostTask( 407 DCHECK_CURRENTLY_ON(BrowserThread::IO);
417 BrowserThread::IO, FROM_HERE, 408
418 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, this, directory)); 409 StartUtilityProcess(temp_dir_.GetPath());
410
411 DCHECK(directory.DirName() == temp_dir_.GetPath());
412
413 utility_process_mojo_client_->service()->Unpack(
414 directory, extension_id_, location_, creation_flags_,
415 base::Bind(&SandboxedUnpacker::UnpackDone, this));
419 } 416 }
420 417
421 void SandboxedUnpacker::OnUnzipToDirFailed(const std::string& error) { 418 void SandboxedUnpacker::UnpackDone(
422 got_response_ = true; 419 const base::string16& error,
423 utility_wrapper_ = nullptr; 420 std::unique_ptr<base::DictionaryValue> manifest) {
424 ReportFailure(UNZIP_FAILED, 421 DCHECK_CURRENTLY_ON(BrowserThread::IO);
425 l10n_util::GetStringUTF16(IDS_EXTENSION_PACKAGE_UNZIP_ERROR)); 422
423 utility_process_mojo_client_.reset();
424
425 if (!error.empty()) {
426 unpacker_io_task_runner_->PostTask(
427 FROM_HERE,
428 base::Bind(&SandboxedUnpacker::UnpackExtensionFailed, this, error));
429 return;
430 }
431
432 unpacker_io_task_runner_->PostTask(
433 FROM_HERE, base::Bind(&SandboxedUnpacker::UnpackExtensionSucceeded, this,
434 base::Passed(&manifest)));
426 } 435 }
427 436
428 void SandboxedUnpacker::OnUnpackExtensionSucceeded( 437 void SandboxedUnpacker::UnpackExtensionSucceeded(
429 const base::DictionaryValue& manifest) { 438 std::unique_ptr<base::DictionaryValue> manifest) {
430 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 439 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
431 got_response_ = true;
432 utility_wrapper_ = nullptr;
433 440
434 std::unique_ptr<base::DictionaryValue> final_manifest( 441 std::unique_ptr<base::DictionaryValue> final_manifest(
435 RewriteManifestFile(manifest)); 442 RewriteManifestFile(*manifest));
436 if (!final_manifest) 443 if (!final_manifest)
437 return; 444 return;
438 445
439 // Create an extension object that refers to the temporary location the 446 // Create an extension object that refers to the temporary location the
440 // extension was unpacked to. We use this until the extension is finally 447 // extension was unpacked to. We use this until the extension is finally
441 // installed. For example, the install UI shows images from inside the 448 // installed. For example, the install UI shows images from inside the
442 // extension. 449 // extension.
443 450
444 // Localize manifest now, so confirm UI gets correct extension name. 451 // Localize manifest now, so confirm UI gets correct extension name.
445 452
(...skipping 19 matching lines...) Expand all
465 return; 472 return;
466 } 473 }
467 474
468 SkBitmap install_icon; 475 SkBitmap install_icon;
469 if (!RewriteImageFiles(&install_icon)) 476 if (!RewriteImageFiles(&install_icon))
470 return; 477 return;
471 478
472 if (!RewriteCatalogFiles()) 479 if (!RewriteCatalogFiles())
473 return; 480 return;
474 481
475 ReportSuccess(manifest, install_icon); 482 ReportSuccess(std::move(manifest), install_icon);
476 } 483 }
477 484
478 void SandboxedUnpacker::OnUnpackExtensionFailed(const base::string16& error) { 485 void SandboxedUnpacker::UnpackExtensionFailed(const base::string16& error) {
479 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 486 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
480 got_response_ = true; 487
481 utility_wrapper_ = nullptr;
482 ReportFailure( 488 ReportFailure(
483 UNPACKER_CLIENT_FAILED, 489 UNPACKER_CLIENT_FAILED,
484 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error)); 490 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error));
485 } 491 }
486 492
487 base::string16 SandboxedUnpacker::FailureReasonToString16( 493 base::string16 SandboxedUnpacker::FailureReasonToString16(
488 FailureReason reason) { 494 FailureReason reason) {
489 switch (reason) { 495 switch (reason) {
490 case COULD_NOT_GET_TEMP_DIRECTORY: 496 case COULD_NOT_GET_TEMP_DIRECTORY:
491 return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY"); 497 return ASCIIToUTF16("COULD_NOT_GET_TEMP_DIRECTORY");
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 case ERROR_SAVING_CATALOG: 566 case ERROR_SAVING_CATALOG:
561 return ASCIIToUTF16("ERROR_SAVING_CATALOG"); 567 return ASCIIToUTF16("ERROR_SAVING_CATALOG");
562 568
563 case CRX_HASH_VERIFICATION_FAILED: 569 case CRX_HASH_VERIFICATION_FAILED:
564 return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED"); 570 return ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED");
565 571
566 case UNZIP_FAILED: 572 case UNZIP_FAILED:
567 return ASCIIToUTF16("UNZIP_FAILED"); 573 return ASCIIToUTF16("UNZIP_FAILED");
568 case DIRECTORY_MOVE_FAILED: 574 case DIRECTORY_MOVE_FAILED:
569 return ASCIIToUTF16("DIRECTORY_MOVE_FAILED"); 575 return ASCIIToUTF16("DIRECTORY_MOVE_FAILED");
570 case COULD_NOT_START_UTILITY_PROCESS:
571 return ASCIIToUTF16("COULD_NOT_START_UTILITY_PROCESS");
572 576
573 case NUM_FAILURE_REASONS: 577 case NUM_FAILURE_REASONS:
574 NOTREACHED(); 578 NOTREACHED();
575 return base::string16(); 579 return base::string16();
576 } 580 }
581
577 NOTREACHED(); 582 NOTREACHED();
578 return base::string16(); 583 return base::string16();
579 } 584 }
580 585
581 void SandboxedUnpacker::FailWithPackageError(FailureReason reason) { 586 void SandboxedUnpacker::FailWithPackageError(FailureReason reason) {
582 ReportFailure(reason, 587 ReportFailure(reason,
583 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE, 588 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_CODE,
584 FailureReasonToString16(reason))); 589 FailureReasonToString16(reason)));
585 } 590 }
586 591
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 CHECK(!expected_hash.empty()); 641 CHECK(!expected_hash.empty());
637 UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false); 642 UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", false);
638 FailWithPackageError(CRX_HASH_VERIFICATION_FAILED); 643 FailWithPackageError(CRX_HASH_VERIFICATION_FAILED);
639 break; 644 break;
640 } 645 }
641 return false; 646 return false;
642 } 647 }
643 648
644 void SandboxedUnpacker::ReportFailure(FailureReason reason, 649 void SandboxedUnpacker::ReportFailure(FailureReason reason,
645 const base::string16& error) { 650 const base::string16& error) {
646 utility_wrapper_ = nullptr;
647 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason, 651 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", reason,
648 NUM_FAILURE_REASONS); 652 NUM_FAILURE_REASONS);
649 if (!crx_unpack_start_time_.is_null()) 653 if (!crx_unpack_start_time_.is_null())
650 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", 654 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime",
651 base::TimeTicks::Now() - crx_unpack_start_time_); 655 base::TimeTicks::Now() - crx_unpack_start_time_);
652 Cleanup(); 656 Cleanup();
653 657
654 CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED 658 CrxInstallError error_info(reason == CRX_HASH_VERIFICATION_FAILED
655 ? CrxInstallError::ERROR_HASH_MISMATCH 659 ? CrxInstallError::ERROR_HASH_MISMATCH
656 : CrxInstallError::ERROR_OTHER, 660 : CrxInstallError::ERROR_OTHER,
657 error); 661 error);
658 662
659 client_->OnUnpackFailure(error_info); 663 client_->OnUnpackFailure(error_info);
660 } 664 }
661 665
662 void SandboxedUnpacker::ReportSuccess( 666 void SandboxedUnpacker::ReportSuccess(
663 const base::DictionaryValue& original_manifest, 667 std::unique_ptr<base::DictionaryValue> original_manifest,
664 const SkBitmap& install_icon) { 668 const SkBitmap& install_icon) {
665 utility_wrapper_ = nullptr;
666 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); 669 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1);
667 670
668 if (!crx_unpack_start_time_.is_null()) 671 if (!crx_unpack_start_time_.is_null())
669 RecordSuccessfulUnpackTimeHistograms( 672 RecordSuccessfulUnpackTimeHistograms(
670 crx_path_for_histograms_, 673 crx_path_for_histograms_,
671 base::TimeTicks::Now() - crx_unpack_start_time_); 674 base::TimeTicks::Now() - crx_unpack_start_time_);
672 DCHECK(!temp_dir_.GetPath().empty()); 675 DCHECK(!temp_dir_.GetPath().empty());
673 676
674 // Client takes ownership of temporary directory and extension. 677 // Client takes ownership of temporary directory and extension.
675 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_, 678 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_,
676 &original_manifest, extension_.get(), install_icon); 679 original_manifest.get(), extension_.get(),
680 install_icon);
677 extension_ = NULL; 681 extension_ = NULL;
678 } 682 }
679 683
680 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( 684 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile(
681 const base::DictionaryValue& manifest) { 685 const base::DictionaryValue& manifest) {
682 // Add the public key extracted earlier to the parsed manifest and overwrite 686 // 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 687 // 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. 688 // exploitable bug that could be used to compromise the browser.
685 DCHECK(!public_key_.empty()); 689 DCHECK(!public_key_.empty());
686 std::unique_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy()); 690 std::unique_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy());
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 } 890 }
887 891
888 void SandboxedUnpacker::Cleanup() { 892 void SandboxedUnpacker::Cleanup() {
889 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); 893 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread());
890 if (!temp_dir_.Delete()) { 894 if (!temp_dir_.Delete()) {
891 LOG(WARNING) << "Can not delete temp directory at " 895 LOG(WARNING) << "Can not delete temp directory at "
892 << temp_dir_.GetPath().value(); 896 << temp_dir_.GetPath().value();
893 } 897 }
894 } 898 }
895 899
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 900 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698