diff --git a/ui/ozone/platform/wayland/host/wayland_bubble.cc b/ui/ozone/platform/wayland/host/wayland_bubble.cc index ef876a70515d7..99379bf16a518 100644 --- a/ui/ozone/platform/wayland/host/wayland_bubble.cc +++ b/ui/ozone/platform/wayland/host/wayland_bubble.cc @@ -34,8 +34,15 @@ void WaylandBubble::Show(bool inactive) { return; } + auto weak_this = AsWeakPtr(); UpdateWindowScale(false); + if (!weak_this) { + return; + } AddToParentAsSubsurface(); + if (!weak_this) { + return; + } WaylandWindow::Show(inactive); } @@ -96,7 +103,11 @@ void WaylandBubble::Deactivate() { } void WaylandBubble::UpdateWindowScale(bool update_bounds) { + auto weak_this = AsWeakPtr(); WaylandWindow::UpdateWindowScale(update_bounds); + if (!weak_this) { + return; + } if (subsurface_) { SetSubsurfacePosition(); } @@ -131,7 +142,11 @@ void WaylandBubble::AddToParentAsSubsurface() { CHECK(parent_window()); // We need to make sure that window scale matches the parent window. + auto weak_this = AsWeakPtr(); UpdateWindowScale(true); + if (!weak_this) { + return; + } subsurface_ = root_surface()->CreateSubsurface(parent_window()->root_surface()); diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index 7701deda447bd..9a49a783694af 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc @@ -170,7 +170,11 @@ void WaylandWindow::UpdateWindowScale(bool update_bounds) { const auto window_scale = connection_->UsePerSurfaceScaling() ? GetPreferredScaleFactor() : GetScaleFactorFromEnteredOutputs(); + auto weak_this = AsWeakPtr(); SetWindowScale(window_scale.value_or(1.0f)); + if (!weak_this) { + return; + } // Propagate update to the popups. if (child_popup_) { diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index cca168290f53d..e59192ca7e32b 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc @@ -5502,6 +5502,44 @@ TEST_P(WaylandWindowTest, WaylandBubbleSetBoundsUaf) { wayland_bubble->SetBoundsInDIP(gfx::Rect(15, 15, 60, 60)); } +TEST_P(WaylandWindowTest, WaylandBubbleUpdateWindowScaleUaf) { + MockWaylandPlatformWindowDelegate bubble_delegate(connection_.get()); + gfx::Rect bubble_bounds(10, 10, 50, 50); + auto wayland_bubble = + CreateWaylandWindowWithParams(PlatformWindowType::kBubble, bubble_bounds, + &bubble_delegate, window_->GetWidget()); + ASSERT_TRUE(wayland_bubble); + + bubble_delegate.set_on_state_update_callback( + base::BindLambdaForTesting([&]() { + wayland_bubble.reset(); + return true; + })); + + // This should not crash if the fix is applied. + wayland_bubble->UpdateWindowScale(true); +} + +TEST_P(WaylandWindowTest, WaylandBubbleShowUaf) { + MockWaylandPlatformWindowDelegate bubble_delegate(connection_.get()); + PlatformWindowInitProperties properties; + properties.bounds = gfx::Rect(10, 10, 50, 50); + properties.type = PlatformWindowType::kBubble; + properties.parent_widget = window_->GetWidget(); + auto wayland_bubble = bubble_delegate.CreateWaylandWindow( + connection_.get(), std::move(properties)); + ASSERT_TRUE(wayland_bubble); + + bubble_delegate.set_on_state_update_callback( + base::BindLambdaForTesting([&]() { + wayland_bubble.reset(); + return true; + })); + + // This should not crash if the fix is applied. + wayland_bubble->Show(false); +} + INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest, WaylandWindowTest, Values(wl::ServerConfig{}));