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 <marius.vlad@collabora.com>
This commit is contained in:
Marius Vlad 2025-12-09 16:12:52 +02:00 committed by Pekka Paalanen
parent 119ce40714
commit 582ae5385b
2 changed files with 21 additions and 11 deletions

View file

@ -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;
}

View file

@ -86,7 +86,9 @@ weston_xserver_shutdown(struct weston_xserver *wxs)
wl_client_destroy(wxs->client);
wxs->client = NULL;
} else {
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);
@ -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;
}