Commit 9fd701ec authored by meacer's avatar meacer Committed by Commit bot

Fix crash during CertificateReportingService shutdown

CertificateReportingService::ShutDown posts a task to the IO thread to
delete reporter_. If the service's destructor is already run, this will
cause a crash during shutdown. Instead, delete reporter_ using a static
method and without referencing CertificateReportingService's |this|.

BUG=677329

Review-Url: https://codereview.chromium.org/2601203002
Cr-Commit-Position: refs/heads/master@{#440933}
parent 350e4751
...@@ -35,6 +35,11 @@ void RecordUMAOnFailure(int net_error) { ...@@ -35,6 +35,11 @@ void RecordUMAOnFailure(int net_error) {
UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error); UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error);
} }
void CleanupOnIOThread(
std::unique_ptr<CertificateReportingService::Reporter> reporter) {
reporter.reset();
}
} // namespace } // namespace
CertificateReportingService::BoundedReportList::BoundedReportList( CertificateReportingService::BoundedReportList::BoundedReportList(
...@@ -164,7 +169,6 @@ CertificateReportingService::CertificateReportingService( ...@@ -164,7 +169,6 @@ CertificateReportingService::CertificateReportingService(
base::TimeDelta max_report_age, base::TimeDelta max_report_age,
base::Clock* clock) base::Clock* clock)
: pref_service_(*profile->GetPrefs()), : pref_service_(*profile->GetPrefs()),
enabled_(true),
url_request_context_(nullptr), url_request_context_(nullptr),
max_queued_report_count_(max_queued_report_count), max_queued_report_count_(max_queued_report_count),
max_report_age_(max_report_age), max_report_age_(max_report_age),
...@@ -187,7 +191,7 @@ CertificateReportingService::CertificateReportingService( ...@@ -187,7 +191,7 @@ CertificateReportingService::CertificateReportingService(
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE, content::BrowserThread::IO, FROM_HERE,
base::Bind(&CertificateReportingService::InitializeOnIOThread, base::Bind(&CertificateReportingService::InitializeOnIOThread,
base::Unretained(this), enabled_, url_request_context_getter, base::Unretained(this), true, url_request_context_getter,
max_queued_report_count_, max_report_age_, clock_, max_queued_report_count_, max_report_age_, clock_,
server_public_key_, server_public_key_version_)); server_public_key_, server_public_key_version_));
} }
...@@ -199,8 +203,10 @@ CertificateReportingService::~CertificateReportingService() { ...@@ -199,8 +203,10 @@ CertificateReportingService::~CertificateReportingService() {
void CertificateReportingService::Shutdown() { void CertificateReportingService::Shutdown() {
// Shutdown will be called twice: Once after SafeBrowsing shuts down, and once // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once
// when all KeyedServices shut down. All calls after the first one are no-op. // when all KeyedServices shut down. All calls after the first one are no-op.
enabled_ = false; url_request_context_ = nullptr;
Reset(); content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&CleanupOnIOThread, base::Passed(std::move(reporter_))));
} }
void CertificateReportingService::Send(const std::string& serialized_report) { void CertificateReportingService::Send(const std::string& serialized_report) {
...@@ -243,8 +249,16 @@ void CertificateReportingService::InitializeOnIOThread( ...@@ -243,8 +249,16 @@ void CertificateReportingService::InitializeOnIOThread(
void CertificateReportingService::SetEnabled(bool enabled) { void CertificateReportingService::SetEnabled(bool enabled) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
enabled_ = enabled; // Don't reset if the service is already shut down.
Reset(); if (!url_request_context_)
return;
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&CertificateReportingService::ResetOnIOThread,
base::Unretained(this), enabled, url_request_context_,
max_queued_report_count_, max_report_age_, clock_,
server_public_key_, server_public_key_version_));
} }
CertificateReportingService::Reporter* CertificateReportingService::Reporter*
...@@ -257,15 +271,6 @@ GURL CertificateReportingService::GetReportingURLForTesting() { ...@@ -257,15 +271,6 @@ GURL CertificateReportingService::GetReportingURLForTesting() {
return GURL(kExtendedReportingUploadUrl); return GURL(kExtendedReportingUploadUrl);
} }
void CertificateReportingService::Reset() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&CertificateReportingService::ResetOnIOThread,
base::Unretained(this), enabled_, url_request_context_,
max_queued_report_count_, max_report_age_, clock_,
server_public_key_, server_public_key_version_));
}
void CertificateReportingService::ResetOnIOThread( void CertificateReportingService::ResetOnIOThread(
bool enabled, bool enabled,
net::URLRequestContext* url_request_context, net::URLRequestContext* url_request_context,
...@@ -277,7 +282,7 @@ void CertificateReportingService::ResetOnIOThread( ...@@ -277,7 +282,7 @@ void CertificateReportingService::ResetOnIOThread(
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
// url_request_context_ is null during shutdown. // url_request_context_ is null during shutdown.
if (!enabled || !url_request_context) { if (!enabled || !url_request_context) {
reporter_.reset(nullptr); reporter_.reset();
return; return;
} }
std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter; std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter;
...@@ -293,7 +298,6 @@ void CertificateReportingService::ResetOnIOThread( ...@@ -293,7 +298,6 @@ void CertificateReportingService::ResetOnIOThread(
url_request_context, GURL(kExtendedReportingUploadUrl), url_request_context, GURL(kExtendedReportingUploadUrl),
net::ReportSender::DO_NOT_SEND_COOKIES)); net::ReportSender::DO_NOT_SEND_COOKIES));
} }
reporter_.reset( reporter_.reset(
new Reporter(std::move(error_reporter), new Reporter(std::move(error_reporter),
std::unique_ptr<BoundedReportList>( std::unique_ptr<BoundedReportList>(
......
...@@ -104,7 +104,7 @@ class CertificateReportingService : public KeyedService { ...@@ -104,7 +104,7 @@ class CertificateReportingService : public KeyedService {
Reporter( Reporter(
std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter_, std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter_,
std::unique_ptr<BoundedReportList> retry_list, std::unique_ptr<BoundedReportList> retry_list,
base::Clock* clock, base::Clock* const clock,
base::TimeDelta report_ttl, base::TimeDelta report_ttl,
bool retries_enabled); bool retries_enabled);
~Reporter(); ~Reporter();
...@@ -129,7 +129,7 @@ class CertificateReportingService : public KeyedService { ...@@ -129,7 +129,7 @@ class CertificateReportingService : public KeyedService {
std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter_; std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter_;
std::unique_ptr<BoundedReportList> retry_list_; std::unique_ptr<BoundedReportList> retry_list_;
base::Clock* clock_; base::Clock* const clock_;
// Maximum age of a queued report. Reports older than this are discarded in // Maximum age of a queued report. Reports older than this are discarded in
// the next SendPending() call. // the next SendPending() call.
const base::TimeDelta report_ttl_; const base::TimeDelta report_ttl_;
...@@ -176,14 +176,12 @@ class CertificateReportingService : public KeyedService { ...@@ -176,14 +176,12 @@ class CertificateReportingService : public KeyedService {
static GURL GetReportingURLForTesting(); static GURL GetReportingURLForTesting();
private: private:
void Reset();
void InitializeOnIOThread( void InitializeOnIOThread(
bool enabled, bool enabled,
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
size_t max_queued_report_count, size_t max_queued_report_count,
base::TimeDelta max_report_age, base::TimeDelta max_report_age,
base::Clock* clock, base::Clock* const clock,
uint8_t* server_public_key, uint8_t* server_public_key,
uint32_t server_public_key_version); uint32_t server_public_key_version);
...@@ -196,18 +194,13 @@ class CertificateReportingService : public KeyedService { ...@@ -196,18 +194,13 @@ class CertificateReportingService : public KeyedService {
net::URLRequestContext* url_request_context, net::URLRequestContext* url_request_context,
size_t max_queued_report_count, size_t max_queued_report_count,
base::TimeDelta max_report_age, base::TimeDelta max_report_age,
base::Clock* clock, base::Clock* const clock,
uint8_t* server_public_key, uint8_t* server_public_key,
uint32_t server_public_key_version); uint32_t server_public_key_version);
void OnPreferenceChanged(); void OnPreferenceChanged();
const PrefService& pref_service_; const PrefService& pref_service_;
// If true, reporting is enabled. When SafeBrowsing preferences change, this
// might be set to false.
bool enabled_;
net::URLRequestContext* url_request_context_; net::URLRequestContext* url_request_context_;
std::unique_ptr<Reporter> reporter_; std::unique_ptr<Reporter> reporter_;
...@@ -224,14 +217,14 @@ class CertificateReportingService : public KeyedService { ...@@ -224,14 +217,14 @@ class CertificateReportingService : public KeyedService {
safe_browsing_state_subscription_; safe_browsing_state_subscription_;
// Maximum number of reports to be queued for retry. // Maximum number of reports to be queued for retry.
size_t max_queued_report_count_; const size_t max_queued_report_count_;
// Maximum age of the reports to be queued for retry, from the time the // Maximum age of the reports to be queued for retry, from the time the
// certificate error was first encountered by the user. Any report older than // certificate error was first encountered by the user. Any report older than
// this age is ignored and is not re-uploaded. // this age is ignored and is not re-uploaded.
base::TimeDelta max_report_age_; const base::TimeDelta max_report_age_;
base::Clock* clock_; base::Clock* const clock_;
// Encryption parameters. // Encryption parameters.
uint8_t* server_public_key_; uint8_t* server_public_key_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment