mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
chrome: Fix potential UAF of ChromeBrowserContext and Profile (see issue #2969)
This commit is contained in:
@@ -229,7 +229,9 @@ void CefBrowserContext::RemoveCefRequestContext(
|
|||||||
// Delete ourselves when the reference count reaches zero.
|
// Delete ourselves when the reference count reaches zero.
|
||||||
if (request_context_set_.empty()) {
|
if (request_context_set_.empty()) {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
delete this;
|
|
||||||
|
// Allow the current call stack to unwind before deleting |this|.
|
||||||
|
content::BrowserThread::DeleteSoon(CEF_UIT, FROM_HERE, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "base/sequenced_task_runner_helpers.h"
|
||||||
#include "chrome/common/plugin.mojom.h"
|
#include "chrome/common/plugin.mojom.h"
|
||||||
#include "services/network/public/mojom/network_context.mojom.h"
|
#include "services/network/public/mojom/network_context.mojom.h"
|
||||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||||
@@ -236,6 +237,9 @@ class CefBrowserContext {
|
|||||||
base::FilePath cache_path_;
|
base::FilePath cache_path_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// For DeleteSoon().
|
||||||
|
friend class base::DeleteHelper<CefBrowserContext>;
|
||||||
|
|
||||||
scoped_refptr<CefIOThreadState> iothread_state_;
|
scoped_refptr<CefIOThreadState> iothread_state_;
|
||||||
CookieableSchemes cookieable_schemes_;
|
CookieableSchemes cookieable_schemes_;
|
||||||
std::unique_ptr<CefMediaRouterManager> media_router_manager_;
|
std::unique_ptr<CefMediaRouterManager> media_router_manager_;
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "chrome/browser/browser_process.h"
|
#include "chrome/browser/browser_process.h"
|
||||||
#include "chrome/browser/profiles/off_the_record_profile_impl.h"
|
#include "chrome/browser/profiles/off_the_record_profile_impl.h"
|
||||||
|
#include "chrome/browser/profiles/profile_keep_alive_types.h"
|
||||||
|
#include "chrome/browser/profiles/scoped_profile_keep_alive.h"
|
||||||
|
|
||||||
ChromeBrowserContext::ChromeBrowserContext(
|
ChromeBrowserContext::ChromeBrowserContext(
|
||||||
const CefRequestContextSettings& settings)
|
const CefRequestContextSettings& settings)
|
||||||
@@ -16,15 +18,18 @@ ChromeBrowserContext::ChromeBrowserContext(
|
|||||||
ChromeBrowserContext::~ChromeBrowserContext() = default;
|
ChromeBrowserContext::~ChromeBrowserContext() = default;
|
||||||
|
|
||||||
content::BrowserContext* ChromeBrowserContext::AsBrowserContext() {
|
content::BrowserContext* ChromeBrowserContext::AsBrowserContext() {
|
||||||
|
CHECK(!destroyed_);
|
||||||
return profile_;
|
return profile_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Profile* ChromeBrowserContext::AsProfile() {
|
Profile* ChromeBrowserContext::AsProfile() {
|
||||||
|
CHECK(!destroyed_);
|
||||||
return profile_;
|
return profile_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChromeBrowserContext::IsInitialized() const {
|
bool ChromeBrowserContext::IsInitialized() const {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
|
CHECK(!destroyed_);
|
||||||
return !!profile_;
|
return !!profile_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,13 +78,21 @@ void ChromeBrowserContext::InitializeAsync(base::OnceClosure initialized_cb) {
|
|||||||
|
|
||||||
void ChromeBrowserContext::Shutdown() {
|
void ChromeBrowserContext::Shutdown() {
|
||||||
CefBrowserContext::Shutdown();
|
CefBrowserContext::Shutdown();
|
||||||
|
|
||||||
|
// Allow potential deletion of the Profile at some future point (controlled
|
||||||
|
// by ProfileManager).
|
||||||
|
profile_keep_alive_.reset();
|
||||||
|
|
||||||
// |g_browser_process| may be nullptr during shutdown.
|
// |g_browser_process| may be nullptr during shutdown.
|
||||||
if (should_destroy_ && g_browser_process) {
|
if (g_browser_process) {
|
||||||
|
if (should_destroy_) {
|
||||||
g_browser_process->profile_manager()
|
g_browser_process->profile_manager()
|
||||||
->GetPrimaryUserProfile()
|
->GetPrimaryUserProfile()
|
||||||
->DestroyOffTheRecordProfile(profile_);
|
->DestroyOffTheRecordProfile(profile_);
|
||||||
|
} else if (profile_) {
|
||||||
|
OnProfileWillBeDestroyed(profile_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
profile_ = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChromeBrowserContext::ProfileCreated(Profile* profile,
|
void ChromeBrowserContext::ProfileCreated(Profile* profile,
|
||||||
@@ -107,6 +120,9 @@ void ChromeBrowserContext::ProfileCreated(Profile* profile,
|
|||||||
// *CREATED isn't always sent for a disk-based profile that already
|
// *CREATED isn't always sent for a disk-based profile that already
|
||||||
// exists.
|
// exists.
|
||||||
profile_ = profile;
|
profile_ = profile;
|
||||||
|
profile_->AddObserver(this);
|
||||||
|
profile_keep_alive_.reset(new ScopedProfileKeepAlive(
|
||||||
|
profile_, ProfileKeepAliveOrigin::kAppWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
|
if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
|
||||||
@@ -128,3 +144,10 @@ void ChromeBrowserContext::ProfileCreated(Profile* profile,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChromeBrowserContext::OnProfileWillBeDestroyed(Profile* profile) {
|
||||||
|
CHECK_EQ(profile_, profile);
|
||||||
|
profile_->RemoveObserver(this);
|
||||||
|
profile_ = nullptr;
|
||||||
|
destroyed_ = true;
|
||||||
|
}
|
||||||
|
@@ -10,10 +10,13 @@
|
|||||||
|
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "chrome/browser/profiles/profile_manager.h"
|
#include "chrome/browser/profiles/profile_manager.h"
|
||||||
|
#include "chrome/browser/profiles/profile_observer.h"
|
||||||
|
|
||||||
|
class ScopedProfileKeepAlive;
|
||||||
|
|
||||||
// See CefBrowserContext documentation for usage. Only accessed on the UI thread
|
// See CefBrowserContext documentation for usage. Only accessed on the UI thread
|
||||||
// unless otherwise indicated.
|
// unless otherwise indicated.
|
||||||
class ChromeBrowserContext : public CefBrowserContext {
|
class ChromeBrowserContext : public CefBrowserContext, public ProfileObserver {
|
||||||
public:
|
public:
|
||||||
explicit ChromeBrowserContext(const CefRequestContextSettings& settings);
|
explicit ChromeBrowserContext(const CefRequestContextSettings& settings);
|
||||||
|
|
||||||
@@ -26,6 +29,9 @@ class ChromeBrowserContext : public CefBrowserContext {
|
|||||||
void StoreOrTriggerInitCallback(base::OnceClosure callback) override;
|
void StoreOrTriggerInitCallback(base::OnceClosure callback) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
|
|
||||||
|
// ProfileObserver overrides.
|
||||||
|
void OnProfileWillBeDestroyed(Profile* profile) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~ChromeBrowserContext() override;
|
~ChromeBrowserContext() override;
|
||||||
|
|
||||||
@@ -35,6 +41,9 @@ class ChromeBrowserContext : public CefBrowserContext {
|
|||||||
Profile* profile_ = nullptr;
|
Profile* profile_ = nullptr;
|
||||||
bool should_destroy_ = false;
|
bool should_destroy_ = false;
|
||||||
|
|
||||||
|
bool destroyed_ = false;
|
||||||
|
std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive_;
|
||||||
|
|
||||||
std::vector<base::OnceClosure> init_callbacks_;
|
std::vector<base::OnceClosure> init_callbacks_;
|
||||||
|
|
||||||
base::WeakPtrFactory<ChromeBrowserContext> weak_ptr_factory_;
|
base::WeakPtrFactory<ChromeBrowserContext> weak_ptr_factory_;
|
||||||
|
Reference in New Issue
Block a user