From 385647d3576c812e8d2decb4d0551b006b7f4130 Mon Sep 17 00:00:00 2001 From: Leandro Ribeiro Date: Mon, 2 Feb 2026 13:34:12 -0300 Subject: [PATCH] xdg-shell: avoid leaving dangling pointers on resource creation failure Currently if weston_desktop_surface_add_resource() fails to create a wl_resource, it disconnects the client and destroys the desktop surface that we pass. It is odd to do that, callers should be responsible for destroying the desktop surface when it is reasonable to do so. This is dangerous and can leave dangling pointers. Besides that, in many cases callers should not even destroy the desktop surface, as they are not the owners of it. When we are giving the role of toplevel/popup to a xdg_surface and we fail to do so, client gets disconnected and the base desktop surface will get destroyed by the destructor of the xdg_surface resource. This commit fixes these issues, bringing a more consistent behavior. Signed-off-by: Leandro Ribeiro --- libweston/desktop/surface.c | 1 - libweston/desktop/xdg-shell-v6.c | 7 ++++++- libweston/desktop/xdg-shell.c | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libweston/desktop/surface.c b/libweston/desktop/surface.c index d6d0188f9..c93f16113 100644 --- a/libweston/desktop/surface.c +++ b/libweston/desktop/surface.c @@ -330,7 +330,6 @@ weston_desktop_surface_add_resource(struct weston_desktop_surface *surface, id); if (resource == NULL) { wl_client_post_no_memory(wl_client); - weston_desktop_surface_destroy(surface); return NULL; } if (destroy == NULL) diff --git a/libweston/desktop/xdg-shell-v6.c b/libweston/desktop/xdg-shell-v6.c index 9b62727d9..b3473c2a4 100644 --- a/libweston/desktop/xdg-shell-v6.c +++ b/libweston/desktop/xdg-shell-v6.c @@ -1492,13 +1492,18 @@ weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client, &zxdg_surface_v6_interface, &weston_desktop_xdg_surface_implementation, id, weston_desktop_xdg_surface_resource_destroy); - if (surface->resource == NULL) + if (surface->resource == NULL) { + weston_desktop_surface_destroy(surface->desktop_surface); + free(surface); return; + } if (weston_surface_has_content(wsurface)) { wl_resource_post_error(surface->resource, ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER, "xdg_surface must not have a buffer at creation"); + weston_desktop_surface_destroy(surface->desktop_surface); + free(surface); return; } } diff --git a/libweston/desktop/xdg-shell.c b/libweston/desktop/xdg-shell.c index 818345569..3c025d3f6 100644 --- a/libweston/desktop/xdg-shell.c +++ b/libweston/desktop/xdg-shell.c @@ -2087,8 +2087,11 @@ weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client, &xdg_surface_interface, &weston_desktop_xdg_surface_implementation, id, weston_desktop_xdg_surface_resource_destroy); - if (surface->resource == NULL) + if (surface->resource == NULL) { + weston_desktop_surface_destroy(surface->desktop_surface); + free(surface); return; + } } static void