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

Side by Side Diff: google_apis/gaia/oauth2_token_service_request.cc

Issue 458753006: Fix use after free bug by calling GetTokenService in Core's ctor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update TSP comment (CANDIDATE). Created 6 years, 4 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "google_apis/gaia/oauth2_token_service_request.h" 5 #include "google_apis/gaia/oauth2_token_service_request.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
(...skipping 22 matching lines...) Expand all
33 // 4. Stop() is called on owner thread, which calls StopOnTokenServiceThread() 33 // 4. Stop() is called on owner thread, which calls StopOnTokenServiceThread()
34 // on token service thread. 34 // on token service thread.
35 // 35 //
36 // 5. Core is destroyed on owner thread. 36 // 5. Core is destroyed on owner thread.
37 class OAuth2TokenServiceRequest::Core 37 class OAuth2TokenServiceRequest::Core
38 : public base::NonThreadSafe, 38 : public base::NonThreadSafe,
39 public base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core> { 39 public base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core> {
40 public: 40 public:
41 // Note the thread where an instance of Core is constructed is referred to as 41 // Note the thread where an instance of Core is constructed is referred to as
42 // the "owner thread" here. 42 // the "owner thread" here.
43 Core(OAuth2TokenServiceRequest* owner, TokenServiceProvider* provider); 43 Core(OAuth2TokenServiceRequest* owner,
44 const scoped_refptr<TokenServiceProvider>& provider);
44 45
45 // Starts the core. Must be called on the owner thread. 46 // Starts the core. Must be called on the owner thread.
46 void Start(); 47 void Start();
47 48
48 // Stops the core. Must be called on the owner thread. 49 // Stops the core. Must be called on the owner thread.
49 void Stop(); 50 void Stop();
50 51
51 // Returns true if this object has been stopped. Must be called on the owner 52 // Returns true if this object has been stopped. Must be called on the owner
52 // thread. 53 // thread.
53 bool IsStopped() const; 54 bool IsStopped() const;
(...skipping 14 matching lines...) Expand all
68 OAuth2TokenService* token_service(); 69 OAuth2TokenService* token_service();
69 OAuth2TokenServiceRequest* owner(); 70 OAuth2TokenServiceRequest* owner();
70 71
71 private: 72 private:
72 friend class base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core>; 73 friend class base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core>;
73 74
74 void DoNothing(); 75 void DoNothing();
75 76
76 scoped_refptr<base::SingleThreadTaskRunner> token_service_task_runner_; 77 scoped_refptr<base::SingleThreadTaskRunner> token_service_task_runner_;
77 OAuth2TokenServiceRequest* owner_; 78 OAuth2TokenServiceRequest* owner_;
78 TokenServiceProvider* provider_; 79
80 // It is important that provider_ is destroyed on the owner thread, not the
blundell 2014/08/13 06:58:05 This comment is puzzling. Since |provider_| is a r
maniscalco 2014/08/13 16:13:03 You're right, this comment is incorrect. The clas
81 // token_service_task_runner_ thread.
82 scoped_refptr<TokenServiceProvider> provider_;
83
79 DISALLOW_COPY_AND_ASSIGN(Core); 84 DISALLOW_COPY_AND_ASSIGN(Core);
80 }; 85 };
81 86
82 OAuth2TokenServiceRequest::Core::Core(OAuth2TokenServiceRequest* owner, 87 OAuth2TokenServiceRequest::Core::Core(
83 TokenServiceProvider* provider) 88 OAuth2TokenServiceRequest* owner,
89 const scoped_refptr<TokenServiceProvider>& provider)
84 : owner_(owner), provider_(provider) { 90 : owner_(owner), provider_(provider) {
85 DCHECK(owner_); 91 DCHECK(owner_);
86 DCHECK(provider_); 92 DCHECK(provider_);
87 token_service_task_runner_ = provider_->GetTokenServiceTaskRunner(); 93 token_service_task_runner_ = provider_->GetTokenServiceTaskRunner();
88 DCHECK(token_service_task_runner_); 94 DCHECK(token_service_task_runner_);
89 } 95 }
90 96
91 OAuth2TokenServiceRequest::Core::~Core() { 97 OAuth2TokenServiceRequest::Core::~Core() {
92 } 98 }
93 99
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 DCHECK(CalledOnValidThread()); 148 DCHECK(CalledOnValidThread());
143 } 149 }
144 150
145 namespace { 151 namespace {
146 152
147 // An implementation of Core for getting an access token. 153 // An implementation of Core for getting an access token.
148 class RequestCore : public OAuth2TokenServiceRequest::Core, 154 class RequestCore : public OAuth2TokenServiceRequest::Core,
149 public OAuth2TokenService::Consumer { 155 public OAuth2TokenService::Consumer {
150 public: 156 public:
151 RequestCore(OAuth2TokenServiceRequest* owner, 157 RequestCore(OAuth2TokenServiceRequest* owner,
152 OAuth2TokenServiceRequest::TokenServiceProvider* provider, 158 const scoped_refptr<
159 OAuth2TokenServiceRequest::TokenServiceProvider>& provider,
153 OAuth2TokenService::Consumer* consumer, 160 OAuth2TokenService::Consumer* consumer,
154 const std::string& account_id, 161 const std::string& account_id,
155 const OAuth2TokenService::ScopeSet& scopes); 162 const OAuth2TokenService::ScopeSet& scopes);
156 163
157 // OAuth2TokenService::Consumer. Must be called on the token service thread. 164 // OAuth2TokenService::Consumer. Must be called on the token service thread.
158 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 165 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
159 const std::string& access_token, 166 const std::string& access_token,
160 const base::Time& expiration_time) OVERRIDE; 167 const base::Time& expiration_time) OVERRIDE;
161 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 168 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
162 const GoogleServiceAuthError& error) OVERRIDE; 169 const GoogleServiceAuthError& error) OVERRIDE;
(...skipping 19 matching lines...) Expand all
182 189
183 // OAuth2TokenService request for fetching OAuth2 access token; it should be 190 // OAuth2TokenService request for fetching OAuth2 access token; it should be
184 // created, reset and accessed only on the token service thread. 191 // created, reset and accessed only on the token service thread.
185 scoped_ptr<OAuth2TokenService::Request> request_; 192 scoped_ptr<OAuth2TokenService::Request> request_;
186 193
187 DISALLOW_COPY_AND_ASSIGN(RequestCore); 194 DISALLOW_COPY_AND_ASSIGN(RequestCore);
188 }; 195 };
189 196
190 RequestCore::RequestCore( 197 RequestCore::RequestCore(
191 OAuth2TokenServiceRequest* owner, 198 OAuth2TokenServiceRequest* owner,
192 OAuth2TokenServiceRequest::TokenServiceProvider* provider, 199 const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
200 provider,
193 OAuth2TokenService::Consumer* consumer, 201 OAuth2TokenService::Consumer* consumer,
194 const std::string& account_id, 202 const std::string& account_id,
195 const OAuth2TokenService::ScopeSet& scopes) 203 const OAuth2TokenService::ScopeSet& scopes)
196 : OAuth2TokenServiceRequest::Core(owner, provider), 204 : OAuth2TokenServiceRequest::Core(owner, provider),
197 OAuth2TokenService::Consumer("oauth2_token_service"), 205 OAuth2TokenService::Consumer("oauth2_token_service"),
198 owner_task_runner_(base::ThreadTaskRunnerHandle::Get()), 206 owner_task_runner_(base::ThreadTaskRunnerHandle::Get()),
199 consumer_(consumer), 207 consumer_(consumer),
200 account_id_(account_id), 208 account_id_(account_id),
201 scopes_(scopes) { 209 scopes_(scopes) {
202 DCHECK(consumer_); 210 DCHECK(consumer_);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 DCHECK(CalledOnValidThread()); 261 DCHECK(CalledOnValidThread());
254 if (!IsStopped()) { 262 if (!IsStopped()) {
255 consumer_->OnGetTokenFailure(owner(), error); 263 consumer_->OnGetTokenFailure(owner(), error);
256 } 264 }
257 } 265 }
258 266
259 // An implementation of Core for invalidating an access token. 267 // An implementation of Core for invalidating an access token.
260 class InvalidateCore : public OAuth2TokenServiceRequest::Core { 268 class InvalidateCore : public OAuth2TokenServiceRequest::Core {
261 public: 269 public:
262 InvalidateCore(OAuth2TokenServiceRequest* owner, 270 InvalidateCore(OAuth2TokenServiceRequest* owner,
263 OAuth2TokenServiceRequest::TokenServiceProvider* provider, 271 const scoped_refptr<
272 OAuth2TokenServiceRequest::TokenServiceProvider>& provider,
264 const std::string& access_token, 273 const std::string& access_token,
265 const std::string& account_id, 274 const std::string& account_id,
266 const OAuth2TokenService::ScopeSet& scopes); 275 const OAuth2TokenService::ScopeSet& scopes);
267 276
268 private: 277 private:
269 friend class base::RefCountedThreadSafe<InvalidateCore>; 278 friend class base::RefCountedThreadSafe<InvalidateCore>;
270 279
271 // Must be destroyed on the owner thread. 280 // Must be destroyed on the owner thread.
272 virtual ~InvalidateCore(); 281 virtual ~InvalidateCore();
273 282
274 // Core implementation. 283 // Core implementation.
275 virtual void StartOnTokenServiceThread() OVERRIDE; 284 virtual void StartOnTokenServiceThread() OVERRIDE;
276 virtual void StopOnTokenServiceThread() OVERRIDE; 285 virtual void StopOnTokenServiceThread() OVERRIDE;
277 286
278 std::string access_token_; 287 std::string access_token_;
279 std::string account_id_; 288 std::string account_id_;
280 OAuth2TokenService::ScopeSet scopes_; 289 OAuth2TokenService::ScopeSet scopes_;
281 290
282 DISALLOW_COPY_AND_ASSIGN(InvalidateCore); 291 DISALLOW_COPY_AND_ASSIGN(InvalidateCore);
283 }; 292 };
284 293
285 InvalidateCore::InvalidateCore( 294 InvalidateCore::InvalidateCore(
286 OAuth2TokenServiceRequest* owner, 295 OAuth2TokenServiceRequest* owner,
287 OAuth2TokenServiceRequest::TokenServiceProvider* provider, 296 const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
297 provider,
288 const std::string& access_token, 298 const std::string& access_token,
289 const std::string& account_id, 299 const std::string& account_id,
290 const OAuth2TokenService::ScopeSet& scopes) 300 const OAuth2TokenService::ScopeSet& scopes)
291 : OAuth2TokenServiceRequest::Core(owner, provider), 301 : OAuth2TokenServiceRequest::Core(owner, provider),
292 access_token_(access_token), 302 access_token_(access_token),
293 account_id_(account_id), 303 account_id_(account_id),
294 scopes_(scopes) { 304 scopes_(scopes) {
295 DCHECK(!access_token_.empty()); 305 DCHECK(!access_token_.empty());
296 DCHECK(!account_id_.empty()); 306 DCHECK(!account_id_.empty());
297 DCHECK(!scopes.empty()); 307 DCHECK(!scopes.empty());
298 } 308 }
299 309
300 InvalidateCore::~InvalidateCore() { 310 InvalidateCore::~InvalidateCore() {
301 } 311 }
302 312
303 void InvalidateCore::StartOnTokenServiceThread() { 313 void InvalidateCore::StartOnTokenServiceThread() {
304 DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 314 DCHECK(token_service_task_runner()->BelongsToCurrentThread());
305 token_service()->InvalidateToken(account_id_, scopes_, access_token_); 315 token_service()->InvalidateToken(account_id_, scopes_, access_token_);
306 } 316 }
307 317
308 void InvalidateCore::StopOnTokenServiceThread() { 318 void InvalidateCore::StopOnTokenServiceThread() {
309 DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 319 DCHECK(token_service_task_runner()->BelongsToCurrentThread());
310 // Nothing to do. 320 // Nothing to do.
311 } 321 }
312 322
313 } // namespace 323 } // namespace
314 324
315 // static 325 // static
316 scoped_ptr<OAuth2TokenServiceRequest> OAuth2TokenServiceRequest::CreateAndStart( 326 scoped_ptr<OAuth2TokenServiceRequest> OAuth2TokenServiceRequest::CreateAndStart(
317 TokenServiceProvider* provider, 327 const scoped_refptr<TokenServiceProvider>& provider,
318 const std::string& account_id, 328 const std::string& account_id,
319 const OAuth2TokenService::ScopeSet& scopes, 329 const OAuth2TokenService::ScopeSet& scopes,
320 OAuth2TokenService::Consumer* consumer) { 330 OAuth2TokenService::Consumer* consumer) {
321 scoped_ptr<OAuth2TokenServiceRequest> request( 331 scoped_ptr<OAuth2TokenServiceRequest> request(
322 new OAuth2TokenServiceRequest(account_id)); 332 new OAuth2TokenServiceRequest(account_id));
323 scoped_refptr<Core> core( 333 scoped_refptr<Core> core(
324 new RequestCore(request.get(), provider, consumer, account_id, scopes)); 334 new RequestCore(request.get(), provider, consumer, account_id, scopes));
325 request->StartWithCore(core); 335 request->StartWithCore(core);
326 return request.Pass(); 336 return request.Pass();
327 } 337 }
328 338
329 // static 339 // static
330 void OAuth2TokenServiceRequest::InvalidateToken( 340 void OAuth2TokenServiceRequest::InvalidateToken(
331 OAuth2TokenServiceRequest::TokenServiceProvider* provider, 341 const scoped_refptr<TokenServiceProvider>& provider,
332 const std::string& account_id, 342 const std::string& account_id,
333 const OAuth2TokenService::ScopeSet& scopes, 343 const OAuth2TokenService::ScopeSet& scopes,
334 const std::string& access_token) { 344 const std::string& access_token) {
335 scoped_ptr<OAuth2TokenServiceRequest> request( 345 scoped_ptr<OAuth2TokenServiceRequest> request(
336 new OAuth2TokenServiceRequest(account_id)); 346 new OAuth2TokenServiceRequest(account_id));
337 scoped_refptr<Core> core(new InvalidateCore( 347 scoped_refptr<Core> core(new InvalidateCore(
338 request.get(), provider, access_token, account_id, scopes)); 348 request.get(), provider, access_token, account_id, scopes));
339 request->StartWithCore(core); 349 request->StartWithCore(core);
340 } 350 }
341 351
342 OAuth2TokenServiceRequest::~OAuth2TokenServiceRequest() { 352 OAuth2TokenServiceRequest::~OAuth2TokenServiceRequest() {
343 core_->Stop(); 353 core_->Stop();
344 } 354 }
345 355
346 std::string OAuth2TokenServiceRequest::GetAccountId() const { 356 std::string OAuth2TokenServiceRequest::GetAccountId() const {
347 return account_id_; 357 return account_id_;
348 } 358 }
349 359
350 OAuth2TokenServiceRequest::OAuth2TokenServiceRequest( 360 OAuth2TokenServiceRequest::OAuth2TokenServiceRequest(
351 const std::string& account_id) 361 const std::string& account_id)
352 : account_id_(account_id) { 362 : account_id_(account_id) {
353 DCHECK(!account_id_.empty()); 363 DCHECK(!account_id_.empty());
354 } 364 }
355 365
356 void OAuth2TokenServiceRequest::StartWithCore(const scoped_refptr<Core>& core) { 366 void OAuth2TokenServiceRequest::StartWithCore(const scoped_refptr<Core>& core) {
357 DCHECK(core); 367 DCHECK(core);
358 core_ = core; 368 core_ = core;
359 core_->Start(); 369 core_->Start();
360 } 370 }
OLDNEW
« no previous file with comments | « google_apis/gaia/oauth2_token_service_request.h ('k') | google_apis/gaia/oauth2_token_service_request_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698