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

Side by Side Diff: chrome/browser/safe_browsing/certificate_reporting_service.cc

Issue 2601203002: Fix crash during CertificateReportingService shutdown (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « chrome/browser/safe_browsing/certificate_reporting_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "chrome/browser/safe_browsing/certificate_reporting_service.h" 4 #include "chrome/browser/safe_browsing/certificate_reporting_service.h"
5 5
6 #include "base/bind_helpers.h" 6 #include "base/bind_helpers.h"
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "base/metrics/sparse_histogram.h" 8 #include "base/metrics/sparse_histogram.h"
9 #include "base/time/clock.h" 9 #include "base/time/clock.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
(...skipping 17 matching lines...) Expand all
28 const CertificateReportingService::Report& item2) { 28 const CertificateReportingService::Report& item2) {
29 return item1.creation_time > item2.creation_time; 29 return item1.creation_time > item2.creation_time;
30 } 30 }
31 31
32 // Records an UMA histogram of the net errors when certificate reports 32 // Records an UMA histogram of the net errors when certificate reports
33 // fail to send. 33 // fail to send.
34 void RecordUMAOnFailure(int net_error) { 34 void RecordUMAOnFailure(int net_error) {
35 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error); 35 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error);
36 } 36 }
37 37
38 void CleanupOnIOThread(
39 std::unique_ptr<CertificateReportingService::Reporter> reporter) {
40 reporter.reset();
41 }
42
38 } // namespace 43 } // namespace
39 44
40 CertificateReportingService::BoundedReportList::BoundedReportList( 45 CertificateReportingService::BoundedReportList::BoundedReportList(
41 size_t max_size) 46 size_t max_size)
42 : max_size_(max_size) { 47 : max_size_(max_size) {
43 CHECK(max_size <= 20) 48 CHECK(max_size <= 20)
44 << "Current implementation is not efficient for a large list."; 49 << "Current implementation is not efficient for a large list.";
45 DCHECK(thread_checker_.CalledOnValidThread()); 50 DCHECK(thread_checker_.CalledOnValidThread());
46 } 51 }
47 52
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 CertificateReportingService::CertificateReportingService( 162 CertificateReportingService::CertificateReportingService(
158 safe_browsing::SafeBrowsingService* safe_browsing_service, 163 safe_browsing::SafeBrowsingService* safe_browsing_service,
159 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, 164 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
160 Profile* profile, 165 Profile* profile,
161 uint8_t server_public_key[/* 32 */], 166 uint8_t server_public_key[/* 32 */],
162 uint32_t server_public_key_version, 167 uint32_t server_public_key_version,
163 size_t max_queued_report_count, 168 size_t max_queued_report_count,
164 base::TimeDelta max_report_age, 169 base::TimeDelta max_report_age,
165 base::Clock* clock) 170 base::Clock* clock)
166 : pref_service_(*profile->GetPrefs()), 171 : pref_service_(*profile->GetPrefs()),
167 enabled_(true),
168 url_request_context_(nullptr), 172 url_request_context_(nullptr),
169 max_queued_report_count_(max_queued_report_count), 173 max_queued_report_count_(max_queued_report_count),
170 max_report_age_(max_report_age), 174 max_report_age_(max_report_age),
171 clock_(clock), 175 clock_(clock),
172 server_public_key_(server_public_key), 176 server_public_key_(server_public_key),
173 server_public_key_version_(server_public_key_version) { 177 server_public_key_version_(server_public_key_version) {
174 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 178 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
175 DCHECK(clock_); 179 DCHECK(clock_);
176 // Subscribe to SafeBrowsing shutdown notifications. 180 // Subscribe to SafeBrowsing shutdown notifications.
177 safe_browsing_service_shutdown_subscription_ = 181 safe_browsing_service_shutdown_subscription_ =
178 safe_browsing_service->RegisterShutdownCallback(base::Bind( 182 safe_browsing_service->RegisterShutdownCallback(base::Bind(
179 &CertificateReportingService::Shutdown, base::Unretained(this))); 183 &CertificateReportingService::Shutdown, base::Unretained(this)));
180 184
181 // Subscribe to SafeBrowsing preference change notifications. 185 // Subscribe to SafeBrowsing preference change notifications.
182 safe_browsing_state_subscription_ = 186 safe_browsing_state_subscription_ =
183 safe_browsing_service->RegisterStateCallback( 187 safe_browsing_service->RegisterStateCallback(
184 base::Bind(&CertificateReportingService::OnPreferenceChanged, 188 base::Bind(&CertificateReportingService::OnPreferenceChanged,
185 base::Unretained(this))); 189 base::Unretained(this)));
186 190
187 content::BrowserThread::PostTask( 191 content::BrowserThread::PostTask(
188 content::BrowserThread::IO, FROM_HERE, 192 content::BrowserThread::IO, FROM_HERE,
189 base::Bind(&CertificateReportingService::InitializeOnIOThread, 193 base::Bind(&CertificateReportingService::InitializeOnIOThread,
190 base::Unretained(this), enabled_, url_request_context_getter, 194 base::Unretained(this), true, url_request_context_getter,
191 max_queued_report_count_, max_report_age_, clock_, 195 max_queued_report_count_, max_report_age_, clock_,
192 server_public_key_, server_public_key_version_)); 196 server_public_key_, server_public_key_version_));
193 } 197 }
194 198
195 CertificateReportingService::~CertificateReportingService() { 199 CertificateReportingService::~CertificateReportingService() {
196 DCHECK(!reporter_); 200 DCHECK(!reporter_);
197 } 201 }
198 202
199 void CertificateReportingService::Shutdown() { 203 void CertificateReportingService::Shutdown() {
200 // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once 204 // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once
201 // when all KeyedServices shut down. All calls after the first one are no-op. 205 // when all KeyedServices shut down. All calls after the first one are no-op.
202 enabled_ = false; 206 url_request_context_ = nullptr;
203 Reset(); 207 content::BrowserThread::PostTask(
208 content::BrowserThread::IO, FROM_HERE,
209 base::Bind(&CleanupOnIOThread, base::Passed(std::move(reporter_))));
204 } 210 }
205 211
206 void CertificateReportingService::Send(const std::string& serialized_report) { 212 void CertificateReportingService::Send(const std::string& serialized_report) {
207 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 213 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
208 if (!reporter_) { 214 if (!reporter_) {
209 return; 215 return;
210 } 216 }
211 content::BrowserThread::PostTask( 217 content::BrowserThread::PostTask(
212 content::BrowserThread::IO, FROM_HERE, 218 content::BrowserThread::IO, FROM_HERE,
213 base::Bind(&CertificateReportingService::Reporter::Send, 219 base::Bind(&CertificateReportingService::Reporter::Send,
(...skipping 22 matching lines...) Expand all
236 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 242 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
237 DCHECK(!url_request_context_); 243 DCHECK(!url_request_context_);
238 url_request_context_ = url_request_context_getter->GetURLRequestContext(); 244 url_request_context_ = url_request_context_getter->GetURLRequestContext();
239 ResetOnIOThread(enabled, url_request_context_, max_queued_report_count, 245 ResetOnIOThread(enabled, url_request_context_, max_queued_report_count,
240 max_report_age, clock, server_public_key, 246 max_report_age, clock, server_public_key,
241 server_public_key_version); 247 server_public_key_version);
242 } 248 }
243 249
244 void CertificateReportingService::SetEnabled(bool enabled) { 250 void CertificateReportingService::SetEnabled(bool enabled) {
245 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 251 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
246 enabled_ = enabled; 252 // Don't reset if the service is already shut down.
247 Reset(); 253 if (!url_request_context_)
254 return;
255
256 content::BrowserThread::PostTask(
257 content::BrowserThread::IO, FROM_HERE,
258 base::Bind(&CertificateReportingService::ResetOnIOThread,
259 base::Unretained(this), enabled, url_request_context_,
260 max_queued_report_count_, max_report_age_, clock_,
261 server_public_key_, server_public_key_version_));
248 } 262 }
249 263
250 CertificateReportingService::Reporter* 264 CertificateReportingService::Reporter*
251 CertificateReportingService::GetReporterForTesting() const { 265 CertificateReportingService::GetReporterForTesting() const {
252 return reporter_.get(); 266 return reporter_.get();
253 } 267 }
254 268
255 // static 269 // static
256 GURL CertificateReportingService::GetReportingURLForTesting() { 270 GURL CertificateReportingService::GetReportingURLForTesting() {
257 return GURL(kExtendedReportingUploadUrl); 271 return GURL(kExtendedReportingUploadUrl);
258 } 272 }
259 273
260 void CertificateReportingService::Reset() {
261 content::BrowserThread::PostTask(
262 content::BrowserThread::IO, FROM_HERE,
263 base::Bind(&CertificateReportingService::ResetOnIOThread,
264 base::Unretained(this), enabled_, url_request_context_,
265 max_queued_report_count_, max_report_age_, clock_,
266 server_public_key_, server_public_key_version_));
267 }
268
269 void CertificateReportingService::ResetOnIOThread( 274 void CertificateReportingService::ResetOnIOThread(
270 bool enabled, 275 bool enabled,
271 net::URLRequestContext* url_request_context, 276 net::URLRequestContext* url_request_context,
272 size_t max_queued_report_count, 277 size_t max_queued_report_count,
273 base::TimeDelta max_report_age, 278 base::TimeDelta max_report_age,
274 base::Clock* clock, 279 base::Clock* clock,
275 uint8_t* const server_public_key, 280 uint8_t* const server_public_key,
276 uint32_t server_public_key_version) { 281 uint32_t server_public_key_version) {
277 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 282 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
278 // url_request_context_ is null during shutdown. 283 // url_request_context_ is null during shutdown.
279 if (!enabled || !url_request_context) { 284 if (!enabled || !url_request_context) {
280 reporter_.reset(nullptr); 285 reporter_.reset();
281 return; 286 return;
282 } 287 }
283 std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter; 288 std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter;
284 if (server_public_key) { 289 if (server_public_key) {
285 // Only used in tests. 290 // Only used in tests.
286 std::unique_ptr<net::ReportSender> report_sender(new net::ReportSender( 291 std::unique_ptr<net::ReportSender> report_sender(new net::ReportSender(
287 url_request_context, net::ReportSender::DO_NOT_SEND_COOKIES)); 292 url_request_context, net::ReportSender::DO_NOT_SEND_COOKIES));
288 error_reporter.reset(new certificate_reporting::ErrorReporter( 293 error_reporter.reset(new certificate_reporting::ErrorReporter(
289 GURL(kExtendedReportingUploadUrl), server_public_key, 294 GURL(kExtendedReportingUploadUrl), server_public_key,
290 server_public_key_version, std::move(report_sender))); 295 server_public_key_version, std::move(report_sender)));
291 } else { 296 } else {
292 error_reporter.reset(new certificate_reporting::ErrorReporter( 297 error_reporter.reset(new certificate_reporting::ErrorReporter(
293 url_request_context, GURL(kExtendedReportingUploadUrl), 298 url_request_context, GURL(kExtendedReportingUploadUrl),
294 net::ReportSender::DO_NOT_SEND_COOKIES)); 299 net::ReportSender::DO_NOT_SEND_COOKIES));
295 } 300 }
296
297 reporter_.reset( 301 reporter_.reset(
298 new Reporter(std::move(error_reporter), 302 new Reporter(std::move(error_reporter),
299 std::unique_ptr<BoundedReportList>( 303 std::unique_ptr<BoundedReportList>(
300 new BoundedReportList(max_queued_report_count)), 304 new BoundedReportList(max_queued_report_count)),
301 clock, max_report_age, true /* retries_enabled */)); 305 clock, max_report_age, true /* retries_enabled */));
302 } 306 }
303 307
304 void CertificateReportingService::OnPreferenceChanged() { 308 void CertificateReportingService::OnPreferenceChanged() {
305 safe_browsing::SafeBrowsingService* safe_browsing_service_ = 309 safe_browsing::SafeBrowsingService* safe_browsing_service_ =
306 g_browser_process->safe_browsing_service(); 310 g_browser_process->safe_browsing_service();
307 const bool enabled = safe_browsing_service_ && 311 const bool enabled = safe_browsing_service_ &&
308 safe_browsing_service_->enabled_by_prefs() && 312 safe_browsing_service_->enabled_by_prefs() &&
309 safe_browsing::IsExtendedReportingEnabled(pref_service_); 313 safe_browsing::IsExtendedReportingEnabled(pref_service_);
310 SetEnabled(enabled); 314 SetEnabled(enabled);
311 } 315 }
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/certificate_reporting_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698