Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "chrome/browser/extensions/sandboxed_unpacker.h" | 5 #include "chrome/browser/extensions/sandboxed_unpacker.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/files/file_util_proxy.h" | 13 #include "base/files/file_util_proxy.h" |
| 14 #include "base/files/scoped_file.h" | 14 #include "base/files/scoped_file.h" |
| 15 #include "base/json/json_string_value_serializer.h" | 15 #include "base/json/json_string_value_serializer.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/numerics/safe_conversions.h" | 18 #include "base/numerics/safe_conversions.h" |
| 19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 20 #include "base/sequenced_task_runner.h" | 20 #include "base/sequenced_task_runner.h" |
| 21 #include "base/strings/string_number_conversions.h" | |
| 21 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 22 #include "base/threading/sequenced_worker_pool.h" | 23 #include "base/threading/sequenced_worker_pool.h" |
| 23 #include "chrome/browser/extensions/extension_service.h" | 24 #include "chrome/browser/extensions/extension_service.h" |
| 24 #include "chrome/common/chrome_paths.h" | 25 #include "chrome/common/chrome_paths.h" |
| 25 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
| 26 #include "chrome/common/chrome_utility_messages.h" | 27 #include "chrome/common/chrome_utility_messages.h" |
| 27 #include "chrome/common/extensions/chrome_utility_extensions_messages.h" | 28 #include "chrome/common/extensions/chrome_utility_extensions_messages.h" |
| 28 #include "chrome/grit/generated_resources.h" | 29 #include "chrome/grit/generated_resources.h" |
| 29 #include "components/crx_file/constants.h" | 30 #include "components/crx_file/constants.h" |
| 30 #include "components/crx_file/crx_file.h" | 31 #include "components/crx_file/crx_file.h" |
| 31 #include "components/crx_file/id_util.h" | 32 #include "components/crx_file/id_util.h" |
| 32 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 33 #include "content/public/browser/utility_process_host.h" | 34 #include "content/public/browser/utility_process_host.h" |
| 34 #include "content/public/common/common_param_traits.h" | 35 #include "content/public/common/common_param_traits.h" |
| 36 #include "crypto/secure_hash.h" | |
| 37 #include "crypto/sha2.h" | |
| 35 #include "crypto/signature_verifier.h" | 38 #include "crypto/signature_verifier.h" |
| 36 #include "extensions/common/constants.h" | 39 #include "extensions/common/constants.h" |
| 37 #include "extensions/common/extension.h" | 40 #include "extensions/common/extension.h" |
| 38 #include "extensions/common/extension_l10n_util.h" | 41 #include "extensions/common/extension_l10n_util.h" |
| 39 #include "extensions/common/extensions_client.h" | 42 #include "extensions/common/extensions_client.h" |
| 40 #include "extensions/common/file_util.h" | 43 #include "extensions/common/file_util.h" |
| 41 #include "extensions/common/manifest_constants.h" | 44 #include "extensions/common/manifest_constants.h" |
| 42 #include "extensions/common/manifest_handlers/icons_handler.h" | 45 #include "extensions/common/manifest_handlers/icons_handler.h" |
| 46 #include "extensions/common/switches.h" | |
| 43 #include "third_party/skia/include/core/SkBitmap.h" | 47 #include "third_party/skia/include/core/SkBitmap.h" |
| 44 #include "ui/base/l10n/l10n_util.h" | 48 #include "ui/base/l10n/l10n_util.h" |
| 45 #include "ui/gfx/codec/png_codec.h" | 49 #include "ui/gfx/codec/png_codec.h" |
| 46 | 50 |
| 47 using base::ASCIIToUTF16; | 51 using base::ASCIIToUTF16; |
| 48 using content::BrowserThread; | 52 using content::BrowserThread; |
| 49 using content::UtilityProcessHost; | 53 using content::UtilityProcessHost; |
| 50 using crx_file::CrxFile; | 54 using crx_file::CrxFile; |
| 51 | 55 |
| 52 // The following macro makes histograms that record the length of paths | 56 // The following macro makes histograms that record the length of paths |
| 53 // in this file much easier to read. | 57 // in this file much easier to read. |
| 54 // Windows has a short max path length. If the path length to a | 58 // Windows has a short max path length. If the path length to a |
| 55 // file being unpacked from a CRX exceeds the max length, we might | 59 // file being unpacked from a CRX exceeds the max length, we might |
| 56 // fail to install. To see if this is happening, see how long the | 60 // fail to install. To see if this is happening, see how long the |
| 57 // path to the temp unpack directory is. See crbug.com/69693 . | 61 // path to the temp unpack directory is. See crbug.com/69693 . |
| 58 #define PATH_LENGTH_HISTOGRAM(name, path) \ | 62 #define PATH_LENGTH_HISTOGRAM(name, path) \ |
| 59 UMA_HISTOGRAM_CUSTOM_COUNTS(name, path.value().length(), 0, 500, 100) | 63 UMA_HISTOGRAM_CUSTOM_COUNTS(name, path.value().length(), 0, 500, 100) |
| 60 | 64 |
| 61 // Record a rate (kB per second) at which extensions are unpacked. | 65 // Record a rate (kB per second) at which extensions are unpacked. |
| 62 // Range from 1kB/s to 100mB/s. | 66 // Range from 1kB/s to 100mB/s. |
| 63 #define UNPACK_RATE_HISTOGRAM(name, rate) \ | 67 #define UNPACK_RATE_HISTOGRAM(name, rate) \ |
| 64 UMA_HISTOGRAM_CUSTOM_COUNTS(name, rate, 1, 100000, 100); | 68 UMA_HISTOGRAM_CUSTOM_COUNTS(name, rate, 1, 100000, 100); |
| 65 | 69 |
| 70 // Record if the .crx hash sum is the same as in the updater manifest. | |
| 71 #define CRX_HASH_CHECK_HISTOGRAM(name, success) \ | |
| 72 UMA_HISTOGRAM_BOOLEAN(name, success) | |
| 73 | |
| 66 namespace extensions { | 74 namespace extensions { |
| 67 namespace { | 75 namespace { |
| 68 | 76 |
| 69 void RecordSuccessfulUnpackTimeHistograms( | 77 void RecordSuccessfulUnpackTimeHistograms( |
| 70 const base::FilePath& crx_path, const base::TimeDelta unpack_time) { | 78 const base::FilePath& crx_path, const base::TimeDelta unpack_time) { |
| 71 | 79 |
| 72 const int64 kBytesPerKb = 1024; | 80 const int64 kBytesPerKb = 1024; |
| 73 const int64 kBytesPerMb = 1024 * 1024; | 81 const int64 kBytesPerMb = 1024 * 1024; |
| 74 | 82 |
| 75 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackSuccessTime", unpack_time); | 83 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackSuccessTime", unpack_time); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 | 217 |
| 210 IPC::Message pickle(file_str.data(), file_str.size()); | 218 IPC::Message pickle(file_str.data(), file_str.size()); |
| 211 PickleIterator iter(pickle); | 219 PickleIterator iter(pickle); |
| 212 return IPC::ReadParam(&pickle, &iter, catalogs); | 220 return IPC::ReadParam(&pickle, &iter, catalogs); |
| 213 } | 221 } |
| 214 | 222 |
| 215 } // namespace | 223 } // namespace |
| 216 | 224 |
| 217 SandboxedUnpacker::SandboxedUnpacker( | 225 SandboxedUnpacker::SandboxedUnpacker( |
| 218 const base::FilePath& crx_path, | 226 const base::FilePath& crx_path, |
| 227 const std::string& package_hash, | |
| 219 Manifest::Location location, | 228 Manifest::Location location, |
| 220 int creation_flags, | 229 int creation_flags, |
| 221 const base::FilePath& extensions_dir, | 230 const base::FilePath& extensions_dir, |
| 222 const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner, | 231 const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner, |
| 223 SandboxedUnpackerClient* client) | 232 SandboxedUnpackerClient* client) |
| 224 : crx_path_(crx_path), | 233 : crx_path_(crx_path), |
| 234 package_hash_(package_hash), | |
| 235 check_crx_hash_(false), | |
| 225 client_(client), | 236 client_(client), |
| 226 extensions_dir_(extensions_dir), | 237 extensions_dir_(extensions_dir), |
| 227 got_response_(false), | 238 got_response_(false), |
| 228 location_(location), | 239 location_(location), |
| 229 creation_flags_(creation_flags), | 240 creation_flags_(creation_flags), |
| 230 unpacker_io_task_runner_(unpacker_io_task_runner) { | 241 unpacker_io_task_runner_(unpacker_io_task_runner) { |
| 242 if (!package_hash_.empty()) { | |
| 243 check_crx_hash_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 244 extensions::switches::kEnableCrxHashCheck); | |
| 245 } | |
| 231 } | 246 } |
| 232 | 247 |
| 233 bool SandboxedUnpacker::CreateTempDirectory() { | 248 bool SandboxedUnpacker::CreateTempDirectory() { |
| 234 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); | 249 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); |
| 235 | 250 |
| 236 base::FilePath temp_dir; | 251 base::FilePath temp_dir; |
| 237 if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) { | 252 if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) { |
| 238 ReportFailure( | 253 ReportFailure( |
| 239 COULD_NOT_GET_TEMP_DIRECTORY, | 254 COULD_NOT_GET_TEMP_DIRECTORY, |
| 240 l10n_util::GetStringFUTF16( | 255 l10n_util::GetStringFUTF16( |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 void SandboxedUnpacker::OnUnpackExtensionFailed(const base::string16& error) { | 430 void SandboxedUnpacker::OnUnpackExtensionFailed(const base::string16& error) { |
| 416 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); | 431 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); |
| 417 got_response_ = true; | 432 got_response_ = true; |
| 418 ReportFailure( | 433 ReportFailure( |
| 419 UNPACKER_CLIENT_FAILED, | 434 UNPACKER_CLIENT_FAILED, |
| 420 l10n_util::GetStringFUTF16( | 435 l10n_util::GetStringFUTF16( |
| 421 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, | 436 IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, |
| 422 error)); | 437 error)); |
| 423 } | 438 } |
| 424 | 439 |
| 440 static size_t fread_sha256(void* ptr, | |
| 441 size_t size, | |
| 442 size_t nmemb, | |
| 443 FILE* stream, | |
| 444 scoped_ptr<crypto::SecureHash>& hash) { | |
| 445 size_t len = fread(ptr, size, nmemb, stream); | |
| 446 if (len > 0 && hash) { | |
| 447 hash->Update(ptr, len * size); | |
| 448 } | |
| 449 return len; | |
| 450 } | |
| 451 | |
| 425 bool SandboxedUnpacker::ValidateSignature() { | 452 bool SandboxedUnpacker::ValidateSignature() { |
| 426 base::ScopedFILE file(base::OpenFile(crx_path_, "rb")); | 453 base::ScopedFILE file(base::OpenFile(crx_path_, "rb")); |
| 427 | 454 |
| 455 scoped_ptr<crypto::SecureHash> hash; | |
| 456 | |
| 457 if (!package_hash_.empty()) { | |
| 458 hash.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | |
| 459 } | |
| 460 | |
| 428 if (!file.get()) { | 461 if (!file.get()) { |
| 429 // Could not open crx file for reading. | 462 // Could not open crx file for reading. |
| 430 #if defined (OS_WIN) | 463 #if defined (OS_WIN) |
| 431 // On windows, get the error code. | 464 // On windows, get the error code. |
| 432 uint32 error_code = ::GetLastError(); | 465 uint32 error_code = ::GetLastError(); |
| 433 // TODO(skerner): Use this histogram to understand why so many | 466 // TODO(skerner): Use this histogram to understand why so many |
| 434 // windows users hit this error. crbug.com/69693 | 467 // windows users hit this error. crbug.com/69693 |
| 435 | 468 |
| 436 // Windows errors are unit32s, but all of likely errors are in | 469 // Windows errors are unit32s, but all of likely errors are in |
| 437 // [1, 1000]. See winerror.h for the meaning of specific values. | 470 // [1, 1000]. See winerror.h for the meaning of specific values. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 451 ASCIIToUTF16("CRX_FILE_NOT_READABLE"))); | 484 ASCIIToUTF16("CRX_FILE_NOT_READABLE"))); |
| 452 return false; | 485 return false; |
| 453 } | 486 } |
| 454 | 487 |
| 455 // Read and verify the header. | 488 // Read and verify the header. |
| 456 // TODO(erikkay): Yuck. I'm not a big fan of this kind of code, but it | 489 // TODO(erikkay): Yuck. I'm not a big fan of this kind of code, but it |
| 457 // appears that we don't have any endian/alignment aware serialization | 490 // appears that we don't have any endian/alignment aware serialization |
| 458 // code in the code base. So for now, this assumes that we're running | 491 // code in the code base. So for now, this assumes that we're running |
| 459 // on a little endian machine with 4 byte alignment. | 492 // on a little endian machine with 4 byte alignment. |
| 460 CrxFile::Header header; | 493 CrxFile::Header header; |
| 461 size_t len = fread(&header, 1, sizeof(header), file.get()); | 494 size_t len = fread_sha256(&header, 1, sizeof(header), file.get(), hash); |
| 462 if (len < sizeof(header)) { | 495 if (len < sizeof(header)) { |
| 463 // Invalid crx header | 496 // Invalid crx header |
| 464 ReportFailure( | 497 ReportFailure( |
| 465 CRX_HEADER_INVALID, | 498 CRX_HEADER_INVALID, |
| 466 l10n_util::GetStringFUTF16( | 499 l10n_util::GetStringFUTF16( |
| 467 IDS_EXTENSION_PACKAGE_ERROR_CODE, | 500 IDS_EXTENSION_PACKAGE_ERROR_CODE, |
| 468 ASCIIToUTF16("CRX_HEADER_INVALID"))); | 501 ASCIIToUTF16("CRX_HEADER_INVALID"))); |
| 469 return false; | 502 return false; |
| 470 } | 503 } |
| 471 | 504 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 l10n_util::GetStringFUTF16( | 545 l10n_util::GetStringFUTF16( |
| 513 IDS_EXTENSION_PACKAGE_ERROR_CODE, | 546 IDS_EXTENSION_PACKAGE_ERROR_CODE, |
| 514 ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH"))); | 547 ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH"))); |
| 515 break; | 548 break; |
| 516 } | 549 } |
| 517 return false; | 550 return false; |
| 518 } | 551 } |
| 519 | 552 |
| 520 std::vector<uint8> key; | 553 std::vector<uint8> key; |
| 521 key.resize(header.key_size); | 554 key.resize(header.key_size); |
| 522 len = fread(&key.front(), sizeof(uint8), header.key_size, file.get()); | 555 len = fread_sha256(&key.front(), sizeof(uint8), header.key_size, file.get(), |
| 556 hash); | |
| 523 if (len < header.key_size) { | 557 if (len < header.key_size) { |
| 524 // Invalid public key | 558 // Invalid public key |
| 525 ReportFailure( | 559 ReportFailure( |
| 526 CRX_PUBLIC_KEY_INVALID, | 560 CRX_PUBLIC_KEY_INVALID, |
| 527 l10n_util::GetStringFUTF16( | 561 l10n_util::GetStringFUTF16( |
| 528 IDS_EXTENSION_PACKAGE_ERROR_CODE, | 562 IDS_EXTENSION_PACKAGE_ERROR_CODE, |
| 529 ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID"))); | 563 ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID"))); |
| 530 return false; | 564 return false; |
| 531 } | 565 } |
| 532 | 566 |
| 533 std::vector<uint8> signature; | 567 std::vector<uint8> signature; |
| 534 signature.resize(header.signature_size); | 568 signature.resize(header.signature_size); |
| 535 len = fread(&signature.front(), sizeof(uint8), header.signature_size, | 569 len = fread_sha256(&signature.front(), sizeof(uint8), header.signature_size, |
| 536 file.get()); | 570 file.get(), hash); |
| 537 if (len < header.signature_size) { | 571 if (len < header.signature_size) { |
| 538 // Invalid signature | 572 // Invalid signature |
| 539 ReportFailure( | 573 ReportFailure( |
| 540 CRX_SIGNATURE_INVALID, | 574 CRX_SIGNATURE_INVALID, |
| 541 l10n_util::GetStringFUTF16( | 575 l10n_util::GetStringFUTF16( |
| 542 IDS_EXTENSION_PACKAGE_ERROR_CODE, | 576 IDS_EXTENSION_PACKAGE_ERROR_CODE, |
| 543 ASCIIToUTF16("CRX_SIGNATURE_INVALID"))); | 577 ASCIIToUTF16("CRX_SIGNATURE_INVALID"))); |
| 544 return false; | 578 return false; |
| 545 } | 579 } |
| 546 | 580 |
| 547 crypto::SignatureVerifier verifier; | 581 crypto::SignatureVerifier verifier; |
| 548 if (!verifier.VerifyInit(crx_file::kSignatureAlgorithm, | 582 if (!verifier.VerifyInit(crx_file::kSignatureAlgorithm, |
| 549 sizeof(crx_file::kSignatureAlgorithm), | 583 sizeof(crx_file::kSignatureAlgorithm), |
| 550 &signature.front(), | 584 &signature.front(), |
| 551 signature.size(), | 585 signature.size(), |
| 552 &key.front(), | 586 &key.front(), |
| 553 key.size())) { | 587 key.size())) { |
| 554 // Signature verification initialization failed. This is most likely | 588 // Signature verification initialization failed. This is most likely |
| 555 // caused by a public key in the wrong format (should encode algorithm). | 589 // caused by a public key in the wrong format (should encode algorithm). |
| 556 ReportFailure( | 590 ReportFailure( |
| 557 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED, | 591 CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED, |
| 558 l10n_util::GetStringFUTF16( | 592 l10n_util::GetStringFUTF16( |
| 559 IDS_EXTENSION_PACKAGE_ERROR_CODE, | 593 IDS_EXTENSION_PACKAGE_ERROR_CODE, |
| 560 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED"))); | 594 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED"))); |
| 561 return false; | 595 return false; |
| 562 } | 596 } |
| 563 | 597 |
| 564 unsigned char buf[1 << 12]; | 598 unsigned char buf[1 << 12]; |
| 565 while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0) | 599 while ((len = fread_sha256(buf, 1, sizeof(buf), file.get(), hash)) > 0) |
| 566 verifier.VerifyUpdate(buf, len); | 600 verifier.VerifyUpdate(buf, len); |
| 567 | 601 |
| 568 if (!verifier.VerifyFinal()) { | 602 if (!verifier.VerifyFinal()) { |
| 569 // Signature verification failed | 603 // Signature verification failed |
| 570 ReportFailure( | 604 ReportFailure( |
| 571 CRX_SIGNATURE_VERIFICATION_FAILED, | 605 CRX_SIGNATURE_VERIFICATION_FAILED, |
| 572 l10n_util::GetStringFUTF16( | 606 l10n_util::GetStringFUTF16( |
| 573 IDS_EXTENSION_PACKAGE_ERROR_CODE, | 607 IDS_EXTENSION_PACKAGE_ERROR_CODE, |
| 574 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED"))); | 608 ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED"))); |
| 575 return false; | 609 return false; |
| 576 } | 610 } |
| 577 | 611 |
| 612 if (hash) { | |
| 613 uint8 output3[crypto::kSHA256Length]; | |
|
Dmitry Polukhin
2015/01/15 12:45:13
Why so strange name 'output3'?
| |
| 614 hash->Finish(output3, sizeof(output3)); | |
| 615 if (base::StringToLowerASCII(base::HexEncode(output3, sizeof(output3))) | |
| 616 != package_hash_) { | |
| 617 // Package hash verification failed | |
| 618 CRX_HASH_CHECK_HISTOGRAM("Extensions.SandboxUnpackHashCheck", false); | |
| 619 if (check_crx_hash_) { | |
|
Dmitry Polukhin
2015/01/15 12:45:13
I would also print error message to log.
| |
| 620 ReportFailure( | |
| 621 CRX_HASH_VERIFICATION_FAILED, | |
| 622 l10n_util::GetStringFUTF16( | |
| 623 IDS_EXTENSION_PACKAGE_ERROR_CODE, | |
| 624 ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED"))); | |
| 625 return false; | |
| 626 } | |
| 627 } else { | |
| 628 CRX_HASH_CHECK_HISTOGRAM("Extensions.SandboxUnpackHashCheck", true); | |
| 629 } | |
| 630 } | |
| 631 | |
| 578 std::string public_key = | 632 std::string public_key = |
| 579 std::string(reinterpret_cast<char*>(&key.front()), key.size()); | 633 std::string(reinterpret_cast<char*>(&key.front()), key.size()); |
| 580 base::Base64Encode(public_key, &public_key_); | 634 base::Base64Encode(public_key, &public_key_); |
| 581 | 635 |
| 582 extension_id_ = crx_file::id_util::GenerateId(public_key); | 636 extension_id_ = crx_file::id_util::GenerateId(public_key); |
| 583 | 637 |
| 584 return true; | 638 return true; |
| 585 } | 639 } |
| 586 | 640 |
| 587 void SandboxedUnpacker::ReportFailure(FailureReason reason, | 641 void SandboxedUnpacker::ReportFailure(FailureReason reason, |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 831 | 885 |
| 832 void SandboxedUnpacker::Cleanup() { | 886 void SandboxedUnpacker::Cleanup() { |
| 833 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); | 887 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); |
| 834 if (!temp_dir_.Delete()) { | 888 if (!temp_dir_.Delete()) { |
| 835 LOG(WARNING) << "Can not delete temp directory at " | 889 LOG(WARNING) << "Can not delete temp directory at " |
| 836 << temp_dir_.path().value(); | 890 << temp_dir_.path().value(); |
| 837 } | 891 } |
| 838 } | 892 } |
| 839 | 893 |
| 840 } // namespace extensions | 894 } // namespace extensions |
| OLD | NEW |