From 7915a2ff59cac0ffc66a8640897c368560df49fa Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 4 Mar 2024 13:34:50 +0100 Subject: [PATCH] tinywl: fix wlr_seat use-after-free on exit When pressing the keybinding to shut down the compositor, the following use-after-free is triggered: ==1165966==ERROR: AddressSanitizer: heap-use-after-free on address 0x51800000ade0 at pc 0x7fa6728b4531 bp 0x7ffe540a6aa0 sp 0x7ffe540a6a90 READ of size 8 at 0x51800000ade0 thread T0 #0 0x7fa6728b4530 in wlr_seat_set_keyboard ../types/seat/wlr_seat_keyboard.c:124 #1 0x58a83fa7fd4e in keyboard_handle_key ../tinywl/tinywl.c:228 #2 0x7fa673a1901d in wl_signal_emit_mutable (/usr/lib/libwayland-server.so.0+0xa01d) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19) #3 0x7fa67295b4be in wlr_keyboard_notify_key ../types/wlr_keyboard.c:102 #4 0x7fa67295c791 in wlr_keyboard_finish ../types/wlr_keyboard.c:165 #5 0x7fa672848cb1 in destroy_wl_seat ../backend/wayland/seat.c:293 #6 0x7fa672833dca in backend_destroy ../backend/wayland/backend.c:493 #7 0x7fa6727b49e8 in wlr_backend_destroy ../backend/backend.c:67 #8 0x7fa67282d334 in multi_backend_destroy ../backend/multi/backend.c:59 #9 0x7fa67282da5a in handle_event_loop_destroy ../backend/multi/backend.c:110 #10 0x7fa673a18b98 in wl_event_loop_destroy (/usr/lib/libwayland-server.so.0+0x9b98) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19) #11 0x7fa673a1b43c in wl_display_destroy (/usr/lib/libwayland-server.so.0+0xc43c) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19) #12 0x58a83fa8ada1 in main ../tinywl/tinywl.c:1068 #13 0x7fa672043ccf (/usr/lib/libc.so.6+0x25ccf) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af) #14 0x7fa672043d89 in __libc_start_main (/usr/lib/libc.so.6+0x25d89) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af) #15 0x58a83fa7e7c4 in _start (/home/simon/src/wlroots/build/tinywl/tinywl+0x167c4) (BuildId: 1febf2a5a18bda0f6b67377a132484061875e248) 0x51800000ade0 is located 352 bytes inside of 880-byte region [0x51800000ac80,0x51800000aff0) freed by thread T0 here: #0 0x7fa6732dfdb2 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52 #1 0x7fa6728c6a1e in wlr_seat_destroy ../types/seat/wlr_seat.c:245 #2 0x7fa6728c6a7a in handle_display_destroy ../types/seat/wlr_seat.c:251 #3 0x7fa673a1b3c6 in wl_display_destroy (/usr/lib/libwayland-server.so.0+0xc3c6) (BuildId: d943a6a6069d1b5293dad7c842d26ce407ebdd19) previously allocated by thread T0 here: #0 0x7fa6732e0cc1 in __interceptor_calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7fa6728c6a9d in wlr_seat_create ../types/seat/wlr_seat.c:255 #2 0x58a83fa8a8d3 in main ../tinywl/tinywl.c:1024 #3 0x7fa672043ccf (/usr/lib/libc.so.6+0x25ccf) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af) This happens because the wlr_seat is destroyed before the wlr_keyboard. Destroying the wlr_keyboard has the side effect of implicitly releasing keys currently held down. Explicitly destroying the wlr_backend before the wl_display fixes this. Suggested-by: Isaac Freund --- tinywl/tinywl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c index bfdee90f..ac8b11e1 100644 --- a/tinywl/tinywl.c +++ b/tinywl/tinywl.c @@ -1065,6 +1065,7 @@ int main(int argc, char *argv[]) { wl_display_destroy_clients(server.wl_display); wlr_scene_node_destroy(&server.scene->tree.node); wlr_xcursor_manager_destroy(server.cursor_mgr); + wlr_backend_destroy(server.backend); wl_display_destroy(server.wl_display); return 0; }