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

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

Issue 138803012: Fix use-after-free in WebstoreInstaller (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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 "chrome/browser/extensions/webstore_installer.h" 5 #include "chrome/browser/extensions/webstore_installer.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 237
238 WebstoreInstaller::Approval::~Approval() {} 238 WebstoreInstaller::Approval::~Approval() {}
239 239
240 const WebstoreInstaller::Approval* WebstoreInstaller::GetAssociatedApproval( 240 const WebstoreInstaller::Approval* WebstoreInstaller::GetAssociatedApproval(
241 const DownloadItem& download) { 241 const DownloadItem& download) {
242 return static_cast<const Approval*>(download.GetUserData(kApprovalKey)); 242 return static_cast<const Approval*>(download.GetUserData(kApprovalKey));
243 } 243 }
244 244
245 WebstoreInstaller::WebstoreInstaller(Profile* profile, 245 WebstoreInstaller::WebstoreInstaller(Profile* profile,
246 Delegate* delegate, 246 Delegate* delegate,
247 NavigationController* controller, 247 content::WebContents* web_contents,
248 const std::string& id, 248 const std::string& id,
249 scoped_ptr<Approval> approval, 249 scoped_ptr<Approval> approval,
250 InstallSource source) 250 InstallSource source)
251 : profile_(profile), 251 : content::WebContentsObserver(web_contents),
252 profile_(profile),
252 delegate_(delegate), 253 delegate_(delegate),
253 controller_(controller),
254 id_(id), 254 id_(id),
255 install_source_(source), 255 install_source_(source),
256 download_item_(NULL), 256 download_item_(NULL),
257 approval_(approval.release()), 257 approval_(approval.release()),
258 total_modules_(0), 258 total_modules_(0),
259 download_started_(false) { 259 download_started_(false) {
260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
261 DCHECK(controller_); 261 DCHECK(web_contents);
262 262
263 registrar_.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE, 263 registrar_.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE,
264 content::NotificationService::AllSources()); 264 content::NotificationService::AllSources());
265 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, 265 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
266 content::Source<Profile>(profile->GetOriginalProfile())); 266 content::Source<Profile>(profile->GetOriginalProfile()));
267 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, 267 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
268 content::Source<CrxInstaller>(NULL)); 268 content::Source<CrxInstaller>(NULL));
269 } 269 }
270 270
271 void WebstoreInstaller::Start() { 271 void WebstoreInstaller::Start() {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 void WebstoreInstaller::InvalidateDelegate() { 399 void WebstoreInstaller::InvalidateDelegate() {
400 delegate_ = NULL; 400 delegate_ = NULL;
401 } 401 }
402 402
403 void WebstoreInstaller::SetDownloadDirectoryForTests( 403 void WebstoreInstaller::SetDownloadDirectoryForTests(
404 base::FilePath* directory) { 404 base::FilePath* directory) {
405 g_download_directory_for_tests = directory; 405 g_download_directory_for_tests = directory;
406 } 406 }
407 407
408 WebstoreInstaller::~WebstoreInstaller() { 408 WebstoreInstaller::~WebstoreInstaller() {
409 controller_ = NULL;
410 if (download_item_) { 409 if (download_item_) {
411 download_item_->RemoveObserver(this); 410 download_item_->RemoveObserver(this);
412 download_item_ = NULL; 411 download_item_ = NULL;
413 } 412 }
414 } 413 }
415 414
416 void WebstoreInstaller::OnDownloadStarted( 415 void WebstoreInstaller::OnDownloadStarted(
417 DownloadItem* item, 416 DownloadItem* item,
418 content::DownloadInterruptReason interrupt_reason) { 417 content::DownloadInterruptReason interrupt_reason) {
419 if (!item) { 418 if (!item) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 // http://crbug.com/126013 550 // http://crbug.com/126013
552 // The current working theory is that one of the many pointers dereferenced in 551 // The current working theory is that one of the many pointers dereferenced in
553 // here is occasionally deleted before all of its referers are nullified, 552 // here is occasionally deleted before all of its referers are nullified,
554 // probably in a callback race. After this comment is released, the crash 553 // probably in a callback race. After this comment is released, the crash
555 // reports should narrow down exactly which pointer it is. Collapsing all the 554 // reports should narrow down exactly which pointer it is. Collapsing all the
556 // early-returns into a single branch makes it hard to see exactly which pointer 555 // early-returns into a single branch makes it hard to see exactly which pointer
557 // it is. 556 // it is.
558 void WebstoreInstaller::StartDownload(const base::FilePath& file) { 557 void WebstoreInstaller::StartDownload(const base::FilePath& file) {
559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
560 559
561 DownloadManager* download_manager =
562 BrowserContext::GetDownloadManager(profile_);
563 if (file.empty()) { 560 if (file.empty()) {
564 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 561 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
565 return; 562 return;
566 } 563 }
564
565 DownloadManager* download_manager =
566 BrowserContext::GetDownloadManager(profile_);
567 if (!download_manager) { 567 if (!download_manager) {
568 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 568 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
569 return; 569 return;
570 } 570 }
571 if (!controller_) { 571
572 content::WebContents* contents = web_contents();
573 if (!contents) {
572 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 574 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
573 return; 575 return;
574 } 576 }
575 if (!controller_->GetWebContents()) { 577 if (!contents->GetRenderProcessHost()) {
576 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 578 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
577 return; 579 return;
578 } 580 }
579 if (!controller_->GetWebContents()->GetRenderProcessHost()) { 581 if (!contents->GetRenderViewHost()) {
580 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 582 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
581 return; 583 return;
582 } 584 }
583 if (!controller_->GetWebContents()->GetRenderViewHost()) { 585
586 content::NavigationController& controller = contents->GetController();
587 if (!controller.GetBrowserContext()) {
584 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 588 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
585 return; 589 return;
586 } 590 }
587 if (!controller_->GetBrowserContext()) { 591 if (!controller.GetBrowserContext()->GetResourceContext()) {
588 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER); 592 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
589 return; 593 return;
590 } 594 }
591 if (!controller_->GetBrowserContext()->GetResourceContext()) {
592 ReportFailure(kDownloadDirectoryError, FAILURE_REASON_OTHER);
593 return;
594 }
595 595
596 // The download url for the given extension is contained in |download_url_|. 596 // The download url for the given extension is contained in |download_url_|.
597 // We will navigate the current tab to this url to start the download. The 597 // We will navigate the current tab to this url to start the download. The
598 // download system will then pass the crx to the CrxInstaller. 598 // download system will then pass the crx to the CrxInstaller.
599 RecordDownloadSource(DOWNLOAD_INITIATED_BY_WEBSTORE_INSTALLER); 599 RecordDownloadSource(DOWNLOAD_INITIATED_BY_WEBSTORE_INSTALLER);
600 int render_process_host_id = 600 int render_process_host_id = contents->GetRenderProcessHost()->GetID();
601 controller_->GetWebContents()->GetRenderProcessHost()->GetID();
602 int render_view_host_routing_id = 601 int render_view_host_routing_id =
603 controller_->GetWebContents()->GetRenderViewHost()->GetRoutingID(); 602 contents->GetRenderViewHost()->GetRoutingID();
604 content::ResourceContext* resource_context = 603 content::ResourceContext* resource_context =
605 controller_->GetBrowserContext()->GetResourceContext(); 604 controller.GetBrowserContext()->GetResourceContext();
606 scoped_ptr<DownloadUrlParameters> params(new DownloadUrlParameters( 605 scoped_ptr<DownloadUrlParameters> params(new DownloadUrlParameters(
607 download_url_, 606 download_url_,
608 render_process_host_id, 607 render_process_host_id,
609 render_view_host_routing_id , 608 render_view_host_routing_id ,
610 resource_context)); 609 resource_context));
611 params->set_file_path(file); 610 params->set_file_path(file);
612 if (controller_->GetVisibleEntry()) 611 if (controller.GetVisibleEntry())
613 params->set_referrer( 612 params->set_referrer(
614 content::Referrer(controller_->GetVisibleEntry()->GetURL(), 613 content::Referrer(controller.GetVisibleEntry()->GetURL(),
615 blink::WebReferrerPolicyDefault)); 614 blink::WebReferrerPolicyDefault));
616 params->set_callback(base::Bind(&WebstoreInstaller::OnDownloadStarted, this)); 615 params->set_callback(base::Bind(&WebstoreInstaller::OnDownloadStarted, this));
617 download_manager->DownloadUrl(params.Pass()); 616 download_manager->DownloadUrl(params.Pass());
618 } 617 }
619 618
620 void WebstoreInstaller::ReportFailure(const std::string& error, 619 void WebstoreInstaller::ReportFailure(const std::string& error,
621 FailureReason reason) { 620 FailureReason reason) {
622 if (delegate_) { 621 if (delegate_) {
623 delegate_->OnExtensionInstallFailure(id_, error, reason); 622 delegate_->OnExtensionInstallFailure(id_, error, reason);
624 delegate_ = NULL; 623 delegate_ = NULL;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 1, 660 1,
662 kMaxSizeKb, 661 kMaxSizeKb,
663 kNumBuckets); 662 kNumBuckets);
664 } 663 }
665 UMA_HISTOGRAM_BOOLEAN( 664 UMA_HISTOGRAM_BOOLEAN(
666 "Extensions.WebstoreDownload.InterruptTotalSizeUnknown", 665 "Extensions.WebstoreDownload.InterruptTotalSizeUnknown",
667 total_bytes <= 0); 666 total_bytes <= 0);
668 } 667 }
669 668
670 } // namespace extensions 669 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/webstore_installer.h ('k') | chrome/browser/extensions/webstore_standalone_installer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698