Fix potential UAF of CefBPDNativeAura::window_widget_

This commit is contained in:
Marshall Greenblatt 2023-02-06 15:43:00 -08:00
parent adfa59f690
commit f34406c57d
6 changed files with 48 additions and 10 deletions

View File

@ -216,6 +216,12 @@ gfx::Vector2d CefBrowserPlatformDelegateNativeAura::GetUiWheelEventOffset(
return gfx::Vector2d(deltaX, deltaY);
}
base::OnceClosure
CefBrowserPlatformDelegateNativeAura::GetWidgetDeleteCallback() {
return base::BindOnce(&CefBrowserPlatformDelegateNativeAura::WidgetDeleted,
weak_ptr_factory_.GetWeakPtr());
}
// static
base::TimeTicks CefBrowserPlatformDelegateNativeAura::GetEventTimeStamp() {
return base::TimeTicks::Now();
@ -279,6 +285,11 @@ int CefBrowserPlatformDelegateNativeAura::TranslateUiChangedButtonFlags(
return result;
}
void CefBrowserPlatformDelegateNativeAura::WidgetDeleted() {
DCHECK(window_widget_);
window_widget_ = nullptr;
}
content::RenderWidgetHostViewAura*
CefBrowserPlatformDelegateNativeAura::GetHostView() const {
if (!web_contents_) {

View File

@ -7,6 +7,7 @@
#include "libcef/browser/native/browser_platform_delegate_native.h"
#include "base/memory/weak_ptr.h"
#include "ui/events/event.h"
namespace content {
@ -71,6 +72,8 @@ class CefBrowserPlatformDelegateNativeAura
virtual gfx::Vector2d GetUiWheelEventOffset(int deltaX, int deltaY) const;
protected:
base::OnceClosure GetWidgetDeleteCallback();
static base::TimeTicks GetEventTimeStamp();
static int TranslateUiEventModifiers(uint32 cef_modifiers);
static int TranslateUiChangedButtonFlags(uint32 cef_modifiers);
@ -80,7 +83,14 @@ class CefBrowserPlatformDelegateNativeAura
views::Widget* window_widget_ = nullptr;
private:
// Will only be called if the Widget is deleted before
// CefBrowserHostBase::DestroyBrowser() is called.
void WidgetDeleted();
content::RenderWidgetHostViewAura* GetHostView() const;
base::WeakPtrFactory<CefBrowserPlatformDelegateNativeAura> weak_ptr_factory_{
this};
};
#endif // CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_

View File

@ -79,7 +79,7 @@ bool CefBrowserPlatformDelegateNativeLinux::CreateHostWindow() {
CefWindowDelegateView* delegate_view = new CefWindowDelegateView(
GetBackgroundColor(), window_x11_->TopLevelAlwaysOnTop(),
GetBoundsChangedCallback());
GetBoundsChangedCallback(), GetWidgetDeleteCallback());
delegate_view->Init(static_cast<gfx::AcceleratedWidget>(window_info_.window),
web_contents_, gfx::Rect(gfx::Point(), rect.size()));

View File

@ -284,7 +284,8 @@ bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() {
(top_level_window_ex_styles & WS_EX_TOPMOST) == WS_EX_TOPMOST;
CefWindowDelegateView* delegate_view = new CefWindowDelegateView(
GetBackgroundColor(), always_on_top, GetBoundsChangedCallback());
GetBackgroundColor(), always_on_top, GetBoundsChangedCallback(),
GetWidgetDeleteCallback());
delegate_view->Init(window_info_.window, web_contents_,
gfx::Rect(0, 0, dip_rect.width(), dip_rect.height()));

View File

@ -15,11 +15,12 @@
CefWindowDelegateView::CefWindowDelegateView(
SkColor background_color,
bool always_on_top,
base::RepeatingClosure on_bounds_changed)
base::RepeatingClosure on_bounds_changed,
base::OnceClosure on_delete)
: background_color_(background_color),
web_view_(nullptr),
always_on_top_(always_on_top),
on_bounds_changed_(on_bounds_changed) {}
on_bounds_changed_(std::move(on_bounds_changed)),
on_delete_(std::move(on_delete)) {}
void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
content::WebContents* web_contents,
@ -64,6 +65,10 @@ void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
DCHECK(widget->is_top_level());
// |widget| must be activatable for focus handling to work correctly.
DCHECK(widget->widget_delegate()->CanActivate());
// WidgetDelegate::DeleteDelegate() will execute the registered callback.
RegisterDeleteDelegateCallback(base::BindOnce(
&CefWindowDelegateView::DeleteDelegate, base::Unretained(this)));
}
void CefWindowDelegateView::InitContent() {
@ -72,6 +77,12 @@ void CefWindowDelegateView::InitContent() {
AddChildView(web_view_);
}
void CefWindowDelegateView::DeleteDelegate() {
if (!on_delete_.is_null()) {
std::move(on_delete_).Run();
}
}
void CefWindowDelegateView::ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) {
if (details.is_add && details.child == this) {

View File

@ -22,7 +22,8 @@ class CefWindowDelegateView : public views::WidgetDelegateView {
public:
CefWindowDelegateView(SkColor background_color,
bool always_on_top,
base::RepeatingClosure on_bounds_changed);
base::RepeatingClosure on_bounds_changed,
base::OnceClosure on_delete);
CefWindowDelegateView(const CefWindowDelegateView&) = delete;
CefWindowDelegateView& operator=(const CefWindowDelegateView&) = delete;
@ -36,6 +37,8 @@ class CefWindowDelegateView : public views::WidgetDelegateView {
// Initialize the Widget's content.
void InitContent();
void DeleteDelegate();
// WidgetDelegateView methods:
bool CanMaximize() const override { return true; }
View* GetContentsView() override { return this; }
@ -46,10 +49,12 @@ class CefWindowDelegateView : public views::WidgetDelegateView {
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
private:
SkColor background_color_;
views::WebView* web_view_;
bool always_on_top_;
const SkColor background_color_;
const bool always_on_top_;
base::RepeatingClosure on_bounds_changed_;
base::OnceClosure on_delete_;
views::WebView* web_view_ = nullptr;
};
#endif // CEF_LIBCEF_BROWSER_NATIVE_WINDOW_DELEGATE_VIEW_H_