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

Side by Side Diff: chrome/browser/ui/webui/help/version_updater_win.cc

Issue 15649007: Attempt to fix use-after-free in VersionUpdaterWin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Set -> Create Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 (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 "base/memory/ref_counted.h" 5 #include "base/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h" 6 #include "base/memory/scoped_ptr.h"
7 #include "base/memory/weak_ptr.h" 7 #include "base/memory/weak_ptr.h"
8 #include "base/string16.h" 8 #include "base/string16.h"
9 #include "base/version.h" 9 #include "base/version.h"
10 #include "base/win/windows_version.h" 10 #include "base/win/windows_version.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 // Update the UI to show the status of the upgrade. 53 // Update the UI to show the status of the upgrade.
54 void UpdateStatus(GoogleUpdateUpgradeResult result, 54 void UpdateStatus(GoogleUpdateUpgradeResult result,
55 GoogleUpdateErrorCode error_code, 55 GoogleUpdateErrorCode error_code,
56 const string16& error_message); 56 const string16& error_message);
57 57
58 // Got the intalled version so the handling of the UPGRADE_ALREADY_UP_TO_DATE 58 // Got the intalled version so the handling of the UPGRADE_ALREADY_UP_TO_DATE
59 // result case can now be completeb on the UI thread. 59 // result case can now be completeb on the UI thread.
60 void GotInstalledVersion(const Version& version); 60 void GotInstalledVersion(const Version& version);
61 61
62 // Little helper function to reset google_updater_. 62 // Little helper function to create google_updater_.
63 void SetGoogleUpdater(); 63 void CreateGoogleUpdater();
64
65 // Helper function to clear google_updater_.
66 void ClearGoogleUpdater();
64 67
65 // Returns a window that can be used for elevation. 68 // Returns a window that can be used for elevation.
66 HWND GetElevationParent(); 69 HWND GetElevationParent();
67 70
68 // The class that communicates with Google Update to find out if an update is 71 // The class that communicates with Google Update to find out if an update is
69 // available and asks it to start an upgrade. 72 // available and asks it to start an upgrade.
70 scoped_refptr<GoogleUpdate> google_updater_; 73 scoped_refptr<GoogleUpdate> google_updater_;
71 74
72 // Used for callbacks. 75 // Used for callbacks.
73 base::WeakPtrFactory<VersionUpdaterWin> weak_factory_; 76 base::WeakPtrFactory<VersionUpdaterWin> weak_factory_;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 // We use a weak pointer in case the updater gets destroyed while waiting. 117 // We use a weak pointer in case the updater gets destroyed while waiting.
115 base::WeakPtr<VersionUpdaterWin> version_updater_; 118 base::WeakPtr<VersionUpdaterWin> version_updater_;
116 119
117 // This is the version that gets read in the FILE thread and set on the 120 // This is the version that gets read in the FILE thread and set on the
118 // the updater in the UI thread. 121 // the updater in the UI thread.
119 Version installed_version_; 122 Version installed_version_;
120 }; 123 };
121 124
122 VersionUpdaterWin::VersionUpdaterWin() 125 VersionUpdaterWin::VersionUpdaterWin()
123 : weak_factory_(this) { 126 : weak_factory_(this) {
124 SetGoogleUpdater(); 127 CreateGoogleUpdater();
125 } 128 }
126 129
127 VersionUpdaterWin::~VersionUpdaterWin() { 130 VersionUpdaterWin::~VersionUpdaterWin() {
128 // The Google Updater will hold a pointer to the listener until it reports 131 // The Google Updater will hold a pointer to the listener until it reports
129 // status, so that pointer must be cleared when the listener is destoyed. 132 // status, so that pointer must be cleared when the listener is destoyed.
130 if (google_updater_) 133 ClearGoogleUpdater();
131 google_updater_->set_status_listener(NULL);
132 } 134 }
133 135
134 void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) { 136 void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) {
135 callback_ = callback; 137 callback_ = callback;
136 138
137 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned 139 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
138 // off. So, in this case, the version updater must not mention 140 // off. So, in this case, the version updater must not mention
139 // on-demand updates. Silent updates (in the background) should still 141 // on-demand updates. Silent updates (in the background) should still
140 // work as before - enabling UAC or installing the latest service pack 142 // work as before - enabling UAC or installing the latest service pack
141 // for Vista is another option. 143 // for Vista is another option.
142 if (!(base::win::GetVersion() == base::win::VERSION_VISTA && 144 if (!(base::win::GetVersion() == base::win::VERSION_VISTA &&
143 (base::win::OSInfo::GetInstance()->service_pack().major == 0) && 145 (base::win::OSInfo::GetInstance()->service_pack().major == 0) &&
144 !base::win::UserAccountControlIsEnabled())) { 146 !base::win::UserAccountControlIsEnabled())) {
145 // This could happen if the page got refreshed after results were returned. 147 // This could happen if the page got refreshed after results were returned.
146 if (!google_updater_) 148 if (!google_updater_)
147 SetGoogleUpdater(); 149 CreateGoogleUpdater();
148 UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR, string16()); 150 UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR, string16());
149 // Specify false to not upgrade yet. 151 // Specify false to not upgrade yet.
150 google_updater_->CheckForUpdate(false, GetElevationParent()); 152 google_updater_->CheckForUpdate(false, GetElevationParent());
151 } 153 }
152 } 154 }
153 155
154 void VersionUpdaterWin::RelaunchBrowser() const { 156 void VersionUpdaterWin::RelaunchBrowser() const {
155 chrome::AttemptRestart(); 157 chrome::AttemptRestart();
156 } 158 }
157 159
158 void VersionUpdaterWin::OnReportResults( 160 void VersionUpdaterWin::OnReportResults(
159 GoogleUpdateUpgradeResult result, GoogleUpdateErrorCode error_code, 161 GoogleUpdateUpgradeResult result, GoogleUpdateErrorCode error_code,
160 const string16& error_message, const string16& version) { 162 const string16& error_message, const string16& version) {
161 // Drop the last reference to the object so that it gets cleaned up here. 163 // Drop the last reference to the object so that it gets cleaned up here.
162 google_updater_ = NULL; 164 ClearGoogleUpdater();
163 UpdateStatus(result, error_code, error_message); 165 UpdateStatus(result, error_code, error_message);
164 } 166 }
165 167
166 void VersionUpdaterWin::UpdateStatus(GoogleUpdateUpgradeResult result, 168 void VersionUpdaterWin::UpdateStatus(GoogleUpdateUpgradeResult result,
167 GoogleUpdateErrorCode error_code, 169 GoogleUpdateErrorCode error_code,
168 const string16& error_message) { 170 const string16& error_message) {
169 // For Chromium builds it would show an error message. 171 // For Chromium builds it would show an error message.
170 // But it looks weird because in fact there is no error, 172 // But it looks weird because in fact there is no error,
171 // just the update server is not available for non-official builds. 173 // just the update server is not available for non-official builds.
172 #if defined(GOOGLE_CHROME_BUILD) 174 #if defined(GOOGLE_CHROME_BUILD)
173 Status status = UPDATED; 175 Status status = UPDATED;
174 string16 message; 176 string16 message;
175 177
176 switch (result) { 178 switch (result) {
177 case UPGRADE_CHECK_STARTED: { 179 case UPGRADE_CHECK_STARTED: {
178 content::RecordAction(UserMetricsAction("UpgradeCheck_Started")); 180 content::RecordAction(UserMetricsAction("UpgradeCheck_Started"));
179 status = CHECKING; 181 status = CHECKING;
180 break; 182 break;
181 } 183 }
182 case UPGRADE_STARTED: { 184 case UPGRADE_STARTED: {
183 content::RecordAction(UserMetricsAction("Upgrade_Started")); 185 content::RecordAction(UserMetricsAction("Upgrade_Started"));
184 status = UPDATING; 186 status = UPDATING;
185 break; 187 break;
186 } 188 }
187 case UPGRADE_IS_AVAILABLE: { 189 case UPGRADE_IS_AVAILABLE: {
188 content::RecordAction( 190 content::RecordAction(
189 UserMetricsAction("UpgradeCheck_UpgradeIsAvailable")); 191 UserMetricsAction("UpgradeCheck_UpgradeIsAvailable"));
190 DCHECK(!google_updater_); // Should have been nulled out already. 192 DCHECK(!google_updater_); // Should have been nulled out already.
191 SetGoogleUpdater(); 193 CreateGoogleUpdater();
192 UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR, string16()); 194 UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR, string16());
193 // Specify true to upgrade now. 195 // Specify true to upgrade now.
194 google_updater_->CheckForUpdate(true, GetElevationParent()); 196 google_updater_->CheckForUpdate(true, GetElevationParent());
195 return; 197 return;
196 } 198 }
197 case UPGRADE_ALREADY_UP_TO_DATE: { 199 case UPGRADE_ALREADY_UP_TO_DATE: {
198 // Google Update reported that Chrome is up-to-date. 200 // Google Update reported that Chrome is up-to-date.
199 // To confirm the updated version is running, the reading 201 // To confirm the updated version is running, the reading
200 // must be done on the file thread. The rest of this case 202 // must be done on the file thread. The rest of this case
201 // will be handled within GotInstalledVersion. 203 // will be handled within GotInstalledVersion.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (!version.IsValid() || version.CompareTo(running_version) <= 0) { 251 if (!version.IsValid() || version.CompareTo(running_version) <= 0) {
250 content::RecordAction( 252 content::RecordAction(
251 UserMetricsAction("UpgradeCheck_AlreadyUpToDate")); 253 UserMetricsAction("UpgradeCheck_AlreadyUpToDate"));
252 callback_.Run(UPDATED, 0, string16()); 254 callback_.Run(UPDATED, 0, string16());
253 } else { 255 } else {
254 content::RecordAction(UserMetricsAction("UpgradeCheck_AlreadyUpgraded")); 256 content::RecordAction(UserMetricsAction("UpgradeCheck_AlreadyUpgraded"));
255 callback_.Run(NEARLY_UPDATED, 0, string16()); 257 callback_.Run(NEARLY_UPDATED, 0, string16());
256 } 258 }
257 } 259 }
258 260
259 void VersionUpdaterWin::SetGoogleUpdater() { 261 void VersionUpdaterWin::CreateGoogleUpdater() {
262 ClearGoogleUpdater();
260 google_updater_ = new GoogleUpdate(); 263 google_updater_ = new GoogleUpdate();
261 google_updater_->set_status_listener(this); 264 google_updater_->set_status_listener(this);
262 } 265 }
263 266
267 void VersionUpdaterWin::ClearGoogleUpdater() {
268 if (google_updater_) {
269 google_updater_->set_status_listener(NULL);
270 google_updater_ = NULL;
271 }
272 }
273
264 BOOL CALLBACK WindowEnumeration(HWND window, LPARAM param) { 274 BOOL CALLBACK WindowEnumeration(HWND window, LPARAM param) {
265 if (IsWindowVisible(window)) { 275 if (IsWindowVisible(window)) {
266 HWND* returned_window = reinterpret_cast<HWND*>(param); 276 HWND* returned_window = reinterpret_cast<HWND*>(param);
267 *returned_window = window; 277 *returned_window = window;
268 return FALSE; 278 return FALSE;
269 } 279 }
270 return TRUE; 280 return TRUE;
271 } 281 }
272 282
273 HWND VersionUpdaterWin::GetElevationParent() { 283 HWND VersionUpdaterWin::GetElevationParent() {
(...skipping 10 matching lines...) Expand all
284 << GetCurrentThreadId(); 294 << GetCurrentThreadId();
285 #endif 295 #endif
286 return window; 296 return window;
287 } 297 }
288 298
289 } // namespace 299 } // namespace
290 300
291 VersionUpdater* VersionUpdater::Create() { 301 VersionUpdater* VersionUpdater::Create() {
292 return new VersionUpdaterWin; 302 return new VersionUpdaterWin;
293 } 303 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698