diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index 7aea341d9dd14..edc806dccf3a2 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc @@ -483,6 +483,40 @@ TEST_P(WaylandWindowTest, DeleteWindowFromOnStateUpdate) { window_->SetBoundsInDIP(gfx::Rect(1024, 768)); } +// POC: ProcessPendingConfigureState UAF on freed |this| after +// RequestStateFromServer -> delegate()->OnStateUpdate() synchronously deletes +// the WaylandWindow. The inner weak guard in MaybeApplyLatestStateRequest +// returns early, but ProcessPendingConfigureState continues at :1329 writing to +// freed |this->pending_configure_state_| and dereferencing freed +// |this->root_surface_|. +TEST_P(WaylandWindowTest, DeleteWindowFromOnStateUpdateDuringSurfaceConfigure) { + // Arrange for the platform-window delegate to synchronously destroy the + // WaylandWindow inside OnStateUpdate(). In production this corresponds to a + // WidgetObserver calling Widget::CloseNow() from OnWidgetBoundsChanged -> + // DesktopWindowTreeHostPlatform::CloseNow -> SetPlatformWindow(nullptr). + delegate_.set_on_state_update_callback(base::BindLambdaForTesting([&]() { + window_.reset(); + return false; + })); + + // Simulate xdg_toplevel.configure with new bounds so the resulting + // ProcessPendingConfigureState() pushes a fresh in-flight request and reaches + // MaybeApplyLatestStateRequest -> delegate()->OnStateUpdate(). + WaylandWindow* window = window_.get(); + WaylandWindow::WindowStates window_states; + window_states.is_activated = true; + window->HandleToplevelConfigure(1024, 768, window_states); + + // Simulate xdg_surface.configure -> HandleSurfaceConfigure -> + // ProcessPendingConfigureState. |window_| is freed mid-call at + // wayland_window.cc:1599; control unwinds back to + // ProcessPendingConfigureState which then writes to freed + // |pending_configure_state_| at :1329 and reads freed members at :1335-1337. + window->HandleSurfaceConfigure(2); + + EXPECT_FALSE(window_); +} + TEST_P(WaylandWindowTest, SetTitle) { window_->SetTitle(u"hello"); PostToServerAndWait([id = surface_id_](wl::TestWaylandServerThread* server) {