Skip to content

Dangling raw_ptr in ChildWindowDelegate when closing child window browser (Chrome Views) #4147

@ohaggmyr

Description

@ohaggmyr

CEF version: 144.0.15+g72717cf (Chromium 144.0.7559.172)
OS: Linux x86_64 (Ubuntu)
Runtime style: Chrome (default)

Description:

Calling CefBrowserHost::CloseBrowser() on a browser created as a child window via CefWindowInfo::SetAsChild() triggers a dangling raw_ptr detection, resulting in a SIGTRAP crash when PartitionAllocBackupRefPtr and PartitionAllocDanglingPtr are enabled in their default (crash) mode.

The issue is a destruction ordering problem between two internally-posted tasks:

  1. ChromeBrowserHostImpl::DestroyBrowser() runs first and destroys CefBrowserPlatformDelegateChromeChildWindow, which frees memory via its unique_ptr members.
  2. The Widget/View teardown runs second, eventually destroying the ChildWindowDelegate (defined in chrome_child_window.cc:40). Its destructor releases a raw_ptr that points to memory already freed in step 1.

The pointer is not dereferenced after the free — it is only detected during raw_ptr release in the destructor. This is a benign dangling pointer (no actual use-after-free), but it crashes the process when dangling pointer detection is in crash mode.

Steps to reproduce:

  1. Create a parent window and a browser via CefBrowserHost::CreateBrowser() using CefWindowInfo::SetAsChild(parentWindow, rect)
  2. Close the child browser via browserHost->CloseBrowser(false) (or true — both reproduce)
  3. Run with --enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr (crash mode, the default)

Workaround:

Disable PartitionAllocDanglingPtr:

--disable-features=PartitionAllocDanglingPtr

Stack traces:

Memory freed at (DestroyBrowser path):

#4 CefBrowserPlatformDelegateChromeViews::~CefBrowserPlatformDelegateChromeViews() [unique_ptr.h:74]
#5 CefBrowserPlatformDelegateChromeChildWindow::~CefBrowserPlatformDelegateChromeChildWindow() [browser_platform_delegate_chrome_child_window.h:11]
#6 CefBrowserHostBase::DestroyBrowser() [unique_ptr.h:74]
#7 ChromeBrowserHostImpl::DestroyBrowser() [chrome_browser_host_impl.cc:579]

Dangling raw_ptr released at (ChildWindowDelegate destruction):

#4 ChildWindowDelegate::~ChildWindowDelegate() [raw_ptr_backup_ref_impl.h:194]
#5 ChildWindowDelegate::~ChildWindowDelegate() [chrome_child_window.cc:40]
#6 ChildWindowDelegate::Release() [chrome_child_window.cc:152]
#7 CefWindowImpl::~CefWindowImpl() [scoped_refptr.h:392]
...
#15 CefViewView<>::~CefViewView() [view_view.h:47]
#16 CefWindowView::~CefWindowView() [window_view.cc:505]
...
#21 views::Widget::~Widget() [[widget.cc:297](http://widget.cc:297/)]
#22 BrowserWidget::~BrowserWidget() [browser_widget.cc:161]
#23 ChromeBrowserWidget::~ChromeBrowserWidget() [chrome_browser_widget.cc:28]

Task trace linking both to CloseBrowser:

#0 ChromeBrowserHostImpl::OnWebContentsDestroyed() [chrome_browser_host_impl.cc:145]
#1 ChromeBrowserHostImpl::CloseBrowser() [chrome_browser_host_impl.cc:186]

Suggested fix area:

The ChildWindowDelegate in cef/libcef/browser/chrome/views/chrome_child_window.cc likely needs to either:

  • Clear its raw_ptr member before DestroyBrowser() frees the target, or
  • Have its destruction sequenced before the platform delegate teardown in DestroyBrowser()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug reporthas fixA fix has been proposed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions