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)
This commit is contained in:
parent
b0c2bbebd1
commit
d5e14ab247
|
@ -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
|
// GNOME sends a pointer enter when the surface is being destroyed
|
||||||
return;
|
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;
|
wlr_wl_pointer->current_output = output;
|
||||||
output->enter_serial = serial;
|
output->enter_serial = serial;
|
||||||
wlr_wl_output_update_cursor(output);
|
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 *wlr_wl_pointer =
|
||||||
(struct wlr_wl_pointer *)dev->pointer;
|
(struct wlr_wl_pointer *)dev->pointer;
|
||||||
if (!wlr_wl_pointer->current_output) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +236,14 @@ static struct wlr_input_device *allocate_device(struct wlr_wl_backend *backend,
|
||||||
return wlr_device;
|
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,
|
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||||
enum wl_seat_capability caps) {
|
enum wl_seat_capability caps) {
|
||||||
struct wlr_wl_backend *backend = data;
|
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");
|
wlr_log(L_ERROR, "Unable to allocate wlr_wl_pointer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
wlr_wl_pointer->output_destroy_listener.notify =
|
||||||
|
wlr_wl_pointer_handle_output_destroy;
|
||||||
|
|
||||||
struct wlr_input_device *wlr_device;
|
struct wlr_input_device *wlr_device;
|
||||||
if (!(wlr_device = allocate_device(backend, WLR_INPUT_DEVICE_POINTER))) {
|
if (!(wlr_device = allocate_device(backend, WLR_INPUT_DEVICE_POINTER))) {
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct wlr_wl_pointer {
|
||||||
struct wlr_pointer wlr_pointer;
|
struct wlr_pointer wlr_pointer;
|
||||||
enum wlr_axis_source axis_source;
|
enum wlr_axis_source axis_source;
|
||||||
struct wlr_wl_backend_output *current_output;
|
struct wlr_wl_backend_output *current_output;
|
||||||
|
struct wl_listener output_destroy_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_wl_registry_poll(struct wlr_wl_backend *backend);
|
void wlr_wl_registry_poll(struct wlr_wl_backend *backend);
|
||||||
|
|
Loading…
Reference in New Issue