aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-02-23 10:20:53 +0100
committeremersion <contact@emersion.fr>2018-02-23 10:20:53 +0100
commitb1e2718dd72ec4526d862a3ab059b7d37aeb9af8 (patch)
tree42799c487a9538379161d0e5e051a8e7f9e9cc1f
parentbd9583a7e8108ab4fd31fc5ab6f7c1552258fa6e (diff)
xwayland: fix some use-after-free in xwm
-rw-r--r--include/wlr/types/wlr_compositor.h1
-rw-r--r--include/wlr/xwm.h3
-rw-r--r--types/wlr_compositor.c2
-rw-r--r--xwayland/xwm.c26
4 files changed, 25 insertions, 7 deletions
diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h
index 8481c590..5919b934 100644
--- a/include/wlr/types/wlr_compositor.h
+++ b/include/wlr/types/wlr_compositor.h
@@ -14,6 +14,7 @@ struct wlr_compositor {
struct {
struct wl_signal new_surface;
+ struct wl_signal destroy;
} events;
};
diff --git a/include/wlr/xwm.h b/include/wlr/xwm.h
index 242ff9cc..65681607 100644
--- a/include/wlr/xwm.h
+++ b/include/wlr/xwm.h
@@ -93,7 +93,8 @@ struct wlr_xwm {
const xcb_query_extension_reply_t *xfixes;
- struct wl_listener compositor_surface_create;
+ struct wl_listener compositor_new_surface;
+ struct wl_listener compositor_destroy;
struct wl_listener seat_selection;
struct wl_listener seat_primary_selection;
};
diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c
index 008f2e51..f27655c0 100644
--- a/types/wlr_compositor.c
+++ b/types/wlr_compositor.c
@@ -90,6 +90,7 @@ void wlr_compositor_destroy(struct wlr_compositor *compositor) {
if (compositor == NULL) {
return;
}
+ wlr_signal_emit_safe(&compositor->events.destroy, compositor);
wl_list_remove(&compositor->display_destroy.link);
wl_global_destroy(compositor->wl_global);
free(compositor);
@@ -195,6 +196,7 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
wl_list_init(&compositor->wl_resources);
wl_list_init(&compositor->surfaces);
wl_signal_init(&compositor->events.new_surface);
+ wl_signal_init(&compositor->events.destroy);
compositor->display_destroy.notify = handle_display_destroy;
wl_display_add_destroy_listener(display, &compositor->display_destroy);
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index 94dfdaab..0d957260 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -1019,11 +1019,11 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) {
return count;
}
-static void handle_compositor_surface_create(struct wl_listener *listener,
+static void handle_compositor_new_surface(struct wl_listener *listener,
void *data) {
- struct wlr_surface *surface = data;
struct wlr_xwm *xwm =
- wl_container_of(listener, xwm, compositor_surface_create);
+ wl_container_of(listener, xwm, compositor_new_surface);
+ struct wlr_surface *surface = data;
if (wl_resource_get_client(surface->resource) != xwm->xwayland->client) {
return;
}
@@ -1043,6 +1043,16 @@ static void handle_compositor_surface_create(struct wl_listener *listener,
}
}
+static void handle_compositor_destroy(struct wl_listener *listener,
+ void *data) {
+ struct wlr_xwm *xwm =
+ wl_container_of(listener, xwm, compositor_destroy);
+ wl_list_remove(&xwm->compositor_new_surface.link);
+ wl_list_remove(&xwm->compositor_destroy.link);
+ wl_list_init(&xwm->compositor_new_surface.link);
+ wl_list_init(&xwm->compositor_destroy.link);
+}
+
void wlr_xwayland_surface_activate(struct wlr_xwayland_surface *xsurface,
bool activated) {
struct wlr_xwayland_surface *focused = xsurface->xwm->focus_surface;
@@ -1124,7 +1134,8 @@ void xwm_destroy(struct wlr_xwm *xwm) {
wl_list_for_each_safe(xsurface, tmp, &xwm->unpaired_surfaces, link) {
wlr_xwayland_surface_destroy(xsurface);
}
- wl_list_remove(&xwm->compositor_surface_create.link);
+ wl_list_remove(&xwm->compositor_new_surface.link);
+ wl_list_remove(&xwm->compositor_destroy.link);
xcb_disconnect(xwm->xcb_conn);
free(xwm);
@@ -1407,9 +1418,12 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) {
xwm_selection_init(xwm);
- xwm->compositor_surface_create.notify = handle_compositor_surface_create;
+ xwm->compositor_new_surface.notify = handle_compositor_new_surface;
wl_signal_add(&wlr_xwayland->compositor->events.new_surface,
- &xwm->compositor_surface_create);
+ &xwm->compositor_new_surface);
+ xwm->compositor_destroy.notify = handle_compositor_destroy;
+ wl_signal_add(&wlr_xwayland->compositor->events.destroy,
+ &xwm->compositor_destroy);
xwm_create_wm_window(xwm);