diff options
author | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 00:26:58 +0000 |
---|---|---|
committer | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 00:26:58 +0000 |
commit | e263ba7490f1c8ec0fb017b1e8e8392ca1356f87 (patch) | |
tree | 47a09ae7ef60a059b3b4f6fc8b298d17da1270fe | |
parent | 6cf58a0487f8ae5a768d5c4338a05e8a262a85d8 (diff) | |
download | chromium_src-e263ba7490f1c8ec0fb017b1e8e8392ca1356f87.zip chromium_src-e263ba7490f1c8ec0fb017b1e8e8392ca1356f87.tar.gz chromium_src-e263ba7490f1c8ec0fb017b1e8e8392ca1356f87.tar.bz2 |
Attempt to fix use-after-free in VersionUpdaterWin.
I've been unable to repro the crash, but perhaps there's a way for
VersionUpdaterWin::OnReportResults to be invoked twice. This change
detaches the VersionUpdaterWin instance from the GoogleUpdate instance
when it releases its reference.
BUG=236413,242895
R=mad@chromium.org
Review URL: https://chromiumcodereview.appspot.com/15649007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202707 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/webui/help/version_updater_win.cc | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/chrome/browser/ui/webui/help/version_updater_win.cc b/chrome/browser/ui/webui/help/version_updater_win.cc index 2df0593..a3b1b8f 100644 --- a/chrome/browser/ui/webui/help/version_updater_win.cc +++ b/chrome/browser/ui/webui/help/version_updater_win.cc @@ -59,8 +59,11 @@ class VersionUpdaterWin : public VersionUpdater, // result case can now be completeb on the UI thread. void GotInstalledVersion(const Version& version); - // Little helper function to reset google_updater_. - void SetGoogleUpdater(); + // Little helper function to create google_updater_. + void CreateGoogleUpdater(); + + // Helper function to clear google_updater_. + void ClearGoogleUpdater(); // Returns a window that can be used for elevation. HWND GetElevationParent(); @@ -121,14 +124,13 @@ class VersionReader VersionUpdaterWin::VersionUpdaterWin() : weak_factory_(this) { - SetGoogleUpdater(); + CreateGoogleUpdater(); } VersionUpdaterWin::~VersionUpdaterWin() { // The Google Updater will hold a pointer to the listener until it reports // status, so that pointer must be cleared when the listener is destoyed. - if (google_updater_) - google_updater_->set_status_listener(NULL); + ClearGoogleUpdater(); } void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) { @@ -144,7 +146,7 @@ void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) { !base::win::UserAccountControlIsEnabled())) { // This could happen if the page got refreshed after results were returned. if (!google_updater_) - SetGoogleUpdater(); + CreateGoogleUpdater(); UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR, string16()); // Specify false to not upgrade yet. google_updater_->CheckForUpdate(false, GetElevationParent()); @@ -159,7 +161,7 @@ void VersionUpdaterWin::OnReportResults( GoogleUpdateUpgradeResult result, GoogleUpdateErrorCode error_code, const string16& error_message, const string16& version) { // Drop the last reference to the object so that it gets cleaned up here. - google_updater_ = NULL; + ClearGoogleUpdater(); UpdateStatus(result, error_code, error_message); } @@ -188,7 +190,7 @@ void VersionUpdaterWin::UpdateStatus(GoogleUpdateUpgradeResult result, content::RecordAction( UserMetricsAction("UpgradeCheck_UpgradeIsAvailable")); DCHECK(!google_updater_); // Should have been nulled out already. - SetGoogleUpdater(); + CreateGoogleUpdater(); UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR, string16()); // Specify true to upgrade now. google_updater_->CheckForUpdate(true, GetElevationParent()); @@ -256,11 +258,19 @@ void VersionUpdaterWin::GotInstalledVersion(const Version& version) { } } -void VersionUpdaterWin::SetGoogleUpdater() { +void VersionUpdaterWin::CreateGoogleUpdater() { + ClearGoogleUpdater(); google_updater_ = new GoogleUpdate(); google_updater_->set_status_listener(this); } +void VersionUpdaterWin::ClearGoogleUpdater() { + if (google_updater_) { + google_updater_->set_status_listener(NULL); + google_updater_ = NULL; + } +} + BOOL CALLBACK WindowEnumeration(HWND window, LPARAM param) { if (IsWindowVisible(window)) { HWND* returned_window = reinterpret_cast<HWND*>(param); |