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

Side by Side Diff: chrome/browser/extensions/chrome_content_verifier_delegate.cc

Issue 2790823004: Retry reinstallation of corrupted policy extensions. (Closed)
Patch Set: fix compile Created 3 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/chrome_content_verifier_delegate.h" 5 #include "chrome/browser/extensions/chrome_content_verifier_delegate.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/base_switches.h" 12 #include "base/base_switches.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/metrics/field_trial.h" 15 #include "base/metrics/field_trial.h"
16 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
17 #include "base/strings/string_piece.h" 17 #include "base/strings/string_piece.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/syslog_logging.h" 19 #include "base/syslog_logging.h"
20 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
21 #include "base/version.h" 21 #include "base/version.h"
22 #include "build/build_config.h" 22 #include "build/build_config.h"
23 #include "chrome/browser/extensions/extension_service.h" 23 #include "chrome/browser/extensions/extension_service.h"
24 #include "chrome/browser/extensions/policy_extension_reinstaller.h"
24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/extensions/extension_constants.h" 26 #include "chrome/common/extensions/extension_constants.h"
27 #include "content/public/browser/browser_thread.h"
26 #include "extensions/browser/extension_prefs.h" 28 #include "extensions/browser/extension_prefs.h"
27 #include "extensions/browser/extension_registry.h" 29 #include "extensions/browser/extension_registry.h"
28 #include "extensions/browser/extension_system.h" 30 #include "extensions/browser/extension_system.h"
29 #include "extensions/browser/management_policy.h" 31 #include "extensions/browser/management_policy.h"
30 #include "extensions/common/constants.h" 32 #include "extensions/common/constants.h"
31 #include "extensions/common/extension.h" 33 #include "extensions/common/extension.h"
32 #include "extensions/common/extension_urls.h" 34 #include "extensions/common/extension_urls.h"
33 #include "extensions/common/extensions_client.h" 35 #include "extensions/common/extensions_client.h"
34 #include "extensions/common/manifest.h" 36 #include "extensions/common/manifest.h"
35 #include "extensions/common/manifest_url_handlers.h" 37 #include "extensions/common/manifest_url_handlers.h"
36 #include "net/base/backoff_entry.h" 38 #include "net/base/backoff_entry.h"
37 #include "net/base/escape.h" 39 #include "net/base/escape.h"
38 40
39 #if defined(OS_CHROMEOS) 41 #if defined(OS_CHROMEOS)
40 #include "chrome/browser/extensions/extension_assets_manager_chromeos.h" 42 #include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
41 #endif 43 #endif
42 44
43 namespace { 45 namespace {
44 46
45 const char kContentVerificationExperimentName[] = 47 const char kContentVerificationExperimentName[] =
46 "ExtensionContentVerification"; 48 "ExtensionContentVerification";
47 49
48 const net::BackoffEntry::Policy kPolicyReinstallBackoffPolicy = {
49 // num_errors_to_ignore
50 1,
51
52 // initial_delay_ms (note that we set 'always_use_initial_delay' to false
53 // below)
54 100,
55
56 // multiply_factor
57 2,
58
59 // jitter_factor
60 0.1,
61
62 // maximum_backoff_ms (30 minutes)
63 1000 * 60 * 30,
64
65 // entry_lifetime_ms (6 hours)
66 1000 * 60 * 60 * 6,
67
68 // always_use_initial_delay
69 false,
70 };
71
72 base::Callback<void(base::TimeDelta delay)>* g_reinstall_action_for_test =
73 nullptr;
74 50
75 } // namespace 51 } // namespace
76 52
77 namespace extensions { 53 namespace extensions {
78 54
79 // static 55 // static
80 ContentVerifierDelegate::Mode ChromeContentVerifierDelegate::GetDefaultMode() { 56 ContentVerifierDelegate::Mode ChromeContentVerifierDelegate::GetDefaultMode() {
81 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 57 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
82 58
83 Mode experiment_value; 59 Mode experiment_value;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 104 }
129 105
130 // We don't want to allow the command-line flags to eg disable enforcement 106 // We don't want to allow the command-line flags to eg disable enforcement
131 // if the experiment group says it should be on, or malware may just modify 107 // if the experiment group says it should be on, or malware may just modify
132 // the command line flags. So return the more restrictive of the 2 values. 108 // the command line flags. So return the more restrictive of the 2 values.
133 return std::max(experiment_value, cmdline_value); 109 return std::max(experiment_value, cmdline_value);
134 } 110 }
135 111
136 ChromeContentVerifierDelegate::ChromeContentVerifierDelegate( 112 ChromeContentVerifierDelegate::ChromeContentVerifierDelegate(
137 content::BrowserContext* context) 113 content::BrowserContext* context)
138 : context_(context), default_mode_(GetDefaultMode()) {} 114 : context_(context),
115 default_mode_(GetDefaultMode()),
116 policy_extension_reinstaller_(
117 base::MakeUnique<PolicyExtensionReinstaller>(context_)) {}
139 118
140 ChromeContentVerifierDelegate::~ChromeContentVerifierDelegate() { 119 ChromeContentVerifierDelegate::~ChromeContentVerifierDelegate() {
141 } 120 }
142 121
143 ContentVerifierDelegate::Mode ChromeContentVerifierDelegate::ShouldBeVerified( 122 ContentVerifierDelegate::Mode ChromeContentVerifierDelegate::ShouldBeVerified(
144 const Extension& extension) { 123 const Extension& extension) {
145 #if defined(OS_CHROMEOS) 124 #if defined(OS_CHROMEOS)
146 if (ExtensionAssetsManagerChromeOS::IsSharedInstall(&extension)) 125 if (ExtensionAssetsManagerChromeOS::IsSharedInstall(&extension))
147 return ContentVerifierDelegate::ENFORCE_STRICT; 126 return ContentVerifierDelegate::ENFORCE_STRICT;
148 #endif 127 #endif
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (system->management_policy()->MustRemainEnabled(extension, NULL)) { 188 if (system->management_policy()->MustRemainEnabled(extension, NULL)) {
210 PendingExtensionManager* pending_manager = 189 PendingExtensionManager* pending_manager =
211 service->pending_extension_manager(); 190 service->pending_extension_manager();
212 if (pending_manager->IsPolicyReinstallForCorruptionExpected(extension_id)) 191 if (pending_manager->IsPolicyReinstallForCorruptionExpected(extension_id))
213 return; 192 return;
214 SYSLOG(WARNING) << "Corruption detected in policy extension " 193 SYSLOG(WARNING) << "Corruption detected in policy extension "
215 << extension_id << " installed at: " 194 << extension_id << " installed at: "
216 << extension->path().value(); 195 << extension->path().value();
217 pending_manager->ExpectPolicyReinstallForCorruption(extension_id); 196 pending_manager->ExpectPolicyReinstallForCorruption(extension_id);
218 service->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED); 197 service->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED);
219 198 // Attempt to reinstall.
220 net::BackoffEntry* backoff_entry = nullptr; 199 policy_extension_reinstaller_->NotifyExtensionDisabledDueToCorruption();
221 auto iter = policy_reinstall_backoff_.find(extension_id);
222 if (iter != policy_reinstall_backoff_.end()) {
223 backoff_entry = iter->second.get();
224 } else {
225 auto new_backoff_entry =
226 base::MakeUnique<net::BackoffEntry>(&kPolicyReinstallBackoffPolicy);
227 backoff_entry = new_backoff_entry.get();
228 policy_reinstall_backoff_[extension_id] = std::move(new_backoff_entry);
229 }
230 backoff_entry->InformOfRequest(false);
231
232 base::TimeDelta reinstall_delay = backoff_entry->GetTimeUntilRelease();
233 if (g_reinstall_action_for_test) {
234 g_reinstall_action_for_test->Run(reinstall_delay);
235 } else {
236 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
237 FROM_HERE, base::Bind(&ExtensionService::CheckForExternalUpdates,
238 service->AsWeakPtr()),
239 reinstall_delay);
240 }
241 return; 200 return;
242 } 201 }
243 DLOG(WARNING) << "Disabling extension " << extension_id << " ('" 202 DLOG(WARNING) << "Disabling extension " << extension_id << " ('"
244 << extension->name() 203 << extension->name()
245 << "') due to content verification failure. In tests you " 204 << "') due to content verification failure. In tests you "
246 << "might want to use a ScopedIgnoreContentVerifierForTest " 205 << "might want to use a ScopedIgnoreContentVerifierForTest "
247 << "instance to prevent this."; 206 << "instance to prevent this.";
248 service->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED); 207 service->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED);
249 ExtensionPrefs::Get(context_)->IncrementCorruptedDisableCount(); 208 ExtensionPrefs::Get(context_)->IncrementCorruptedDisableCount();
250 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionBecameDisabled", true); 209 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionBecameDisabled", true);
251 UMA_HISTOGRAM_ENUMERATION("Extensions.CorruptExtensionDisabledReason", 210 UMA_HISTOGRAM_ENUMERATION("Extensions.CorruptExtensionDisabledReason",
252 reason, ContentVerifyJob::FAILURE_REASON_MAX); 211 reason, ContentVerifyJob::FAILURE_REASON_MAX);
253 } else if (!base::ContainsKey(would_be_disabled_ids_, extension_id)) { 212 } else if (!base::ContainsKey(would_be_disabled_ids_, extension_id)) {
254 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionWouldBeDisabled", true); 213 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionWouldBeDisabled", true);
255 would_be_disabled_ids_.insert(extension_id); 214 would_be_disabled_ids_.insert(extension_id);
256 } 215 }
257 } 216 }
258 217
259 // static 218 void ChromeContentVerifierDelegate::Shutdown() {
260 void ChromeContentVerifierDelegate::set_policy_reinstall_action_for_test( 219 policy_extension_reinstaller_.reset();
Devlin 2017/04/01 03:00:53 Document why this is important
lazyboy 2017/04/03 18:13:04 Done.
261 base::Callback<void(base::TimeDelta delay)>* action) {
262 g_reinstall_action_for_test = action;
263 } 220 }
264 221
265 } // namespace extensions 222 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698