Crash (NULL deref) when performing touchpad pointer gestures over some clients
Summary
When moving the mouse with the touchpad over some simple wayland clients (and performing gestures such as swipe, hold, or pinch gestures), wlroots
dereferences a NULL pointer inside wlr_seat_client_next_serial
because seat->pointer_state.focused_client
is NULL inside wlr_pointer_gestures_v1_send_hold_begin
.
This bug was discovered in sway (issue 6849), but might be a wlroots issue, though I have not yet managed to reproduce the bug in tinywl
(the same combination of clients and actions does not trigger the crash).
Clients that trigger the crash:
- wl-mirror
- The XDG-Shell example client from the Wayland Book (later referenced as
./client
) - maybe others as well
Details
Address Sanitizer Crash Report
==59504==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f45b1d156fc bp 0x61800000c528 sp 0x7ffedb6d6400 T0)
==59504==The signal is caused by a READ memory access.
==59504==Hint: address points to the zero page.
#0 0x7f45b1d156fc in wlr_seat_client_next_serial ../wlroots-asan-git/types/seat/wlr_seat.c:410
#1 0x7f45b1dadda0 in wlr_pointer_gestures_v1_send_hold_begin ../wlroots-asan-git/types/wlr_pointer_gestures_v1.c:293
#2 0x7f45b1dfcc50 in wlr_signal_emit_safe ../wlroots-asan-git/util/signal.c:29
#3 0x7f45b1dfcc50 in wlr_signal_emit_safe ../wlroots-asan-git/util/signal.c:29
#4 0x7f45b1c76903 in handle_pointer_hold_end ../wlroots-asan-git/backend/libinput/pointer.c:303
#5 0x7f45b1c76903 in handle_libinput_event ../wlroots-asan-git/backend/libinput/events.c:336
#6 0x7f45b1c76903 in handle_libinput_readable ../wlroots-asan-git/backend/libinput/backend.c:58
#7 0x7f45b22c21c9 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xb1c9)
#8 0x7f45b22bfd36 in wl_display_run (/usr/lib/libwayland-server.so.0+0x8d36)
#9 0x562e36991fdf in server_run ../sway/sway/server.c:307
#10 0x562e36991fdf in main ../sway/sway/main.c:431
#11 0x7f45b0c4a30f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)
#12 0x7f45b0c4a3c0 in __libc_start_main@GLIBC_2.2.5 (/usr/lib/libc.so.6+0x2d3c0)
#13 0x562e36996034 (/usr/bin/sway+0x393034)
How to reproduce:
- Start a wlroots-based compositor (e.g. sway)
- Start a simple application like the XDG-Shell example client
- Move your cursor over it with the laptop touch pad and move the cursor around a bit, lifting your finger sometimes
- (the compositor crashes reliably after only very few seconds)
Both clients that trigger the crash have in common that they do not use any toolkit and do not handle input. The crash does not happen with Gtk or Qt clients.
Analysis
The bug occurs because seat->pointer_state.focused_surface
is nonnull (which causes wlr_pointer_gestures_v1_send_hold_begin
to try to send the gesture event), but seat->pointer_state.focused_client
is null (which causes wlr_seat_client_next_serial
to crash).
Other parts of the seat codebase (e.g. types/seat/wlr_seat.c
) seem to check both focused_client
and focused_surface
for NULL, but the gesture codepaths only seem to check focused_surface
.
Manually treating the case where focused_client
is NULL the same as when focused_surface
is NULL (i.e., returning early) fixes the crash, though I do not know whether that is the appropriate behaviour in such a case. (see null-deref-hack-fix.patch)