From 582ae5385bd5e27845872b6b1218a20c796bdd26 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Tue, 9 Dec 2025 16:12:52 +0200 Subject: [PATCH] xwayland: Fix some memory leaks on compositor shutdown path While exiting, on the shutdown compositor path, for instance if we don't have permission access to create a lock file we will end up reporting some memory leaks/use-after-free. This patch addresses of all them: - api->listen returns NULL and we do not property free wet_xwayland struct - we don't remove the signal handler causing a use-after-free (signal handler gets called by the main object has been freed) - we don't remove/destroy the debug scope causing a mem-leak - on the same path check for valid event source to avoid deref invalid pointers. Add a simple wrapper which we can call in other call sites. Signed-off-by: Marius Vlad --- frontend/xwayland.c | 4 +++- xwayland/launcher.c | 28 ++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/frontend/xwayland.c b/frontend/xwayland.c index 8d80a048b..844698f84 100644 --- a/frontend/xwayland.c +++ b/frontend/xwayland.c @@ -260,8 +260,10 @@ wet_load_xwayland(struct weston_compositor *comp) wxw->compositor = comp; wxw->api = api; wxw->xwayland = xwayland; - if (api->listen(xwayland, wxw, spawn_xserver) < 0) + if (api->listen(xwayland, wxw, spawn_xserver) < 0) { + free(wxw); return NULL; + } return wxw; } diff --git a/xwayland/launcher.c b/xwayland/launcher.c index dd4ecdc8a..a79d24fd4 100644 --- a/xwayland/launcher.c +++ b/xwayland/launcher.c @@ -86,8 +86,10 @@ weston_xserver_shutdown(struct weston_xserver *wxs) wl_client_destroy(wxs->client); wxs->client = NULL; } else { - wl_event_source_remove(wxs->abstract_source); - wl_event_source_remove(wxs->unix_source); + if (wxs->abstract_source) + wl_event_source_remove(wxs->abstract_source); + if (wxs->unix_source) + wl_event_source_remove(wxs->unix_source); } close(wxs->abstract_fd); close(wxs->unix_fd); @@ -233,11 +235,8 @@ create_lockfile(int display, char *lockfile, size_t lsize) } static void -weston_xserver_destroy(struct wl_listener *l, void *data) +weston_xserver_destroy(struct weston_xserver *wxs) { - struct weston_xserver *wxs = - container_of(l, struct weston_xserver, compositor_destroy_listener); - wl_list_remove(&wxs->compositor_destroy_listener.link); if (wxs->loop) @@ -248,6 +247,15 @@ weston_xserver_destroy(struct wl_listener *l, void *data) free(wxs); } +static void +weston_xserver_destroy_handler(struct wl_listener *l, void *data) +{ + struct weston_xserver *wxs = + container_of(l, struct weston_xserver, compositor_destroy_listener); + + weston_xserver_destroy(wxs); +} + static struct weston_xwayland * weston_xwayland_get(struct weston_compositor *compositor) { @@ -255,7 +263,7 @@ weston_xwayland_get(struct weston_compositor *compositor) struct weston_xserver *wxs; listener = wl_signal_get(&compositor->destroy_signal, - weston_xserver_destroy); + weston_xserver_destroy_handler); if (!listener) return NULL; @@ -281,7 +289,7 @@ retry: wxs->display++; goto retry; } else { - free(wxs); + weston_xserver_destroy(wxs); return -1; } } @@ -297,7 +305,7 @@ retry: if (wxs->unix_fd < 0) { unlink(lockfile); close(wxs->abstract_fd); - free(wxs); + weston_xserver_destroy(wxs); return -1; } @@ -380,7 +388,7 @@ weston_module_init(struct weston_compositor *compositor) if (!weston_compositor_add_destroy_listener_once(compositor, &wxs->compositor_destroy_listener, - weston_xserver_destroy)) { + weston_xserver_destroy_handler)) { free(wxs); return 0; }