aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorDominique Martinet <asmadeus@codewreck.org>2018-03-17 17:11:43 +0100
committerDominique Martinet <asmadeus@codewreck.org>2018-03-22 21:27:49 +0100
commitd5e14ab2470032a5f8152c685415724a4734b492 (patch)
treef122ffd148bc3faa3f42144ea2a00d05bf376cc8 /backend
parentb0c2bbebd1c4c50173a01175d049842b79ee7e1b (diff)
wayland backend: fix use-after free on output destroy
==12021==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000015698 at pc 0x7f1a9abe1c09 bp 0x7ffe9068f6b0 sp 0x7ffe9068f6a0 WRITE of size 4 at 0x617000015698 thread T0 #0 0x7f1a9abe1c08 in pointer_handle_leave ../backend/wayland/wl_seat.c:40 #1 0x7f1a96ae7d1d in ffi_call_unix64 (/lib64/libffi.so.6+0x5d1d) #2 0x7f1a96ae768e in ffi_call (/lib64/libffi.so.6+0x568e) #3 0x7f1a988e0d8a (/lib64/libwayland-client.so.0+0x8d8a) #4 0x7f1a988dd927 (/lib64/libwayland-client.so.0+0x5927) #5 0x7f1a988debe3 in wl_display_dispatch_queue_pending (/lib64/libwayland-client.so.0+0x6be3) #6 0x7f1a9abdd6d6 in dispatch_events ../backend/wayland/backend.c:28 #7 0x7f1a9a968c11 in wl_event_loop_dispatch (/lib64/libwayland-server.so.0+0x9c11) #8 0x7f1a9a967449 in wl_display_run (/lib64/libwayland-server.so.0+0x8449) #9 0x418dff in main ../rootston/main.c:81 #10 0x7f1a99b5ef29 in __libc_start_main (/lib64/libc.so.6+0x20f29) #11 0x4057c9 in _start (/home/shared/wayland/wlroots/build/rootston/rootston+0x4057c9) 0x617000015698 is located 664 bytes inside of 696-byte region [0x617000015400,0x6170000156b8) freed by thread T0 here: #0 0x7f1a9af754b8 in __interceptor_free (/lib64/libasan.so.4+0xde4b8) #1 0x7f1a9abe01ee in wlr_wl_output_destroy ../backend/wayland/output.c:194 #2 0x7f1a9ac12918 in wlr_output_destroy ../types/wlr_output.c:299 #3 0x7f1a9abe061b in xdg_toplevel_handle_close ../backend/wayland/output.c:255 #4 0x7f1a96ae7d1d in ffi_call_unix64 (/lib64/libffi.so.6+0x5d1d) #5 0x7f1a96ae768e in ffi_call (/lib64/libffi.so.6+0x568e) #6 0x7f1a988e0d8a (/lib64/libwayland-client.so.0+0x8d8a) #7 0x7f1a988dd927 (/lib64/libwayland-client.so.0+0x5927) #8 0x7f1a988debe3 in wl_display_dispatch_queue_pending (/lib64/libwayland-client.so.0+0x6be3) #9 0x7f1a9abdd6d6 in dispatch_events ../backend/wayland/backend.c:28 #10 0x7f1a9a968c11 in wl_event_loop_dispatch (/lib64/libwayland-server.so.0+0x9c11) #11 0x7f1a9a967449 in wl_display_run (/lib64/libwayland-server.so.0+0x8449) #12 0x418dff in main ../rootston/main.c:81 #13 0x7f1a99b5ef29 in __libc_start_main (/lib64/libc.so.6+0x20f29) #14 0x4057c9 in _start (/home/shared/wayland/wlroots/build/rootston/rootston+0x4057c9) previously allocated by thread T0 here: #0 0x7f1a9af75a38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38) #1 0x7f1a9abe0703 in wlr_wl_output_create ../backend/wayland/output.c:272 #2 0x7f1a9abdd8eb in wlr_wl_backend_start ../backend/wayland/backend.c:55 #3 0x7f1a9abbeb49 in wlr_backend_start ../backend/backend.c:28 #4 0x7f1a9abd8ce1 in multi_backend_start ../backend/multi/backend.c:24 #5 0x7f1a9abbeb49 in wlr_backend_start ../backend/backend.c:28 #6 0x418c32 in main ../rootston/main.c:58 #7 0x7f1a99b5ef29 in __libc_start_main (/lib64/libc.so.6+0x20f29) #8 0x4057c9 in _start (/home/shared/wayland/wlroots/build/rootston/rootston+0x4057c9)
Diffstat (limited to 'backend')
-rw-r--r--backend/wayland/wl_seat.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c
index 841e693d..6ca59130 100644
--- a/backend/wayland/wl_seat.c
+++ b/backend/wayland/wl_seat.c
@@ -26,6 +26,11 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
// GNOME sends a pointer enter when the surface is being destroyed
return;
}
+ if (wlr_wl_pointer->current_output) {
+ wl_list_remove(&wlr_wl_pointer->output_destroy_listener.link);
+ }
+ wl_signal_add(&output->wlr_output.events.destroy,
+ &wlr_wl_pointer->output_destroy_listener);
wlr_wl_pointer->current_output = output;
output->enter_serial = serial;
wlr_wl_output_update_cursor(output);
@@ -49,7 +54,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
struct wlr_wl_pointer *wlr_wl_pointer =
(struct wlr_wl_pointer *)dev->pointer;
if (!wlr_wl_pointer->current_output) {
- wlr_log(L_ERROR, "pointer motion event without current output");
+ wlr_log(L_DEBUG, "pointer motion event without current output");
return;
}
@@ -231,6 +236,14 @@ static struct wlr_input_device *allocate_device(struct wlr_wl_backend *backend,
return wlr_device;
}
+static void wlr_wl_pointer_handle_output_destroy(struct wl_listener *listener,
+ void *data) {
+ struct wlr_wl_pointer *wlr_wl_pointer =
+ wl_container_of(listener, wlr_wl_pointer, output_destroy_listener);
+ wlr_wl_pointer->current_output = NULL;
+ wl_list_remove(&wlr_wl_pointer->output_destroy_listener.link);
+}
+
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
enum wl_seat_capability caps) {
struct wlr_wl_backend *backend = data;
@@ -243,6 +256,8 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
wlr_log(L_ERROR, "Unable to allocate wlr_wl_pointer");
return;
}
+ wlr_wl_pointer->output_destroy_listener.notify =
+ wlr_wl_pointer_handle_output_destroy;
struct wlr_input_device *wlr_device;
if (!(wlr_device = allocate_device(backend, WLR_INPUT_DEVICE_POINTER))) {