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 <ifreund@ifreund.xyz>
Stop trying to maintain a per-file _POSIX_C_SOURCE. Instead,
require POSIX.1-2008 globally. A lot of core source files depend
on that already.
Some care must be taken on a few select files where we need a bit
more than POSIX. Some files need XSI extensions (_XOPEN_SOURCE) and
some files need BSD extensions (_DEFAULT_SOURCE). In both cases,
these feature test macros imply _POSIX_C_SOURCE. Make sure to not
define both these macros and _POSIX_C_SOURCE explicitly to avoid
POSIX requirement conflicts (e.g. _POSIX_C_SOURCE says POSIX.1-2001
but _XOPEN_SOURCE says POSIX.1-2008).
Additionally, there is one special case in render/vulkan/vulkan.c.
That file needs major()/minor(), and these are system-specific.
On FreeBSD, _POSIX_C_SOURCE hides system-specific symbols so we need
to make sure it's not defined for this file. On Linux, we can
explicitly include <sys/sysmacros.h> and ensure that apart from
symbols defined there the file only uses POSIX toys.
Compositors now are expected to wait for an initial commit by checking
wlr_xdg_surface.initial_commit on every surface commit and send
(schedule) configure events manually.
This commit changes the behavior of `new_*` signals to better match
their names (see https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3608).
wlr_xdg_shell.events.new_surface is now emitted when an xdg_surface is
created, and wlr_xdg_shell.events.new_{toplevel,popup} events are
introduced to get notified when an xdg_{toplevel,popup} is created.
Same applies to
`wlr_xdg_decoration_manager_v1.events.new_toplevel_decoration`. As a
result, wlr_xdg_surface.added and wlr_xdg_toplevel_decoration_v1.added
are removed, as we no longer need to track whether the corresponding
event was emitted.
Additionally, this commit changes the behavior of
wlr_xdg_surface.events.destroy: it is now emitted when the xdg_surface
is destroyed, as the name suggests.
wlr_xdg_{toplevel,popup}.events.destroy events are added to get
notified when an xdg_{toplevel,popup} is destroyed.
"View" has been cargo-culted from Weston. In Weston, a view is not
even necessarily a toplevel -- it's just a way to draw an arbitrary
somewhere (a surface may be painted at multiple locations
simultaneously). The Weston concept has been misunderstood and then
was carried over to rootston, Sway, and tinywl.
Let's just use the official Wayland wording instead.
This changes the semantics of wlr_output_state. Instead of having
fields with uninitialized memory when missing from the committed
bitflag, all fields are always initialized (and maybe NULL/empty),
just like we do in wlr_surface_state. This reduces the chances of
footguns when reading a field, and removes the need to check for
the committed bitfield everywhere.
A new wlr_output_state_init() function takes care of initializing
the Pixman region.
Up until now, wlr_backend_autocreate() created the wlr_session and
then stuffed it into struct wlr_multi_backend so that compositors
can grab it later.
This is an abuse of wlr_multi_backend and the wlr_backend API:
wlr_backend_get_session() and wlr_multi_backend.session only exist
to accomodate the needs of wlr_backend_autocreate(). What's more,
the DRM and libinput backends don't implement
wlr_backend_impl.get_session.
Instead, return the struct wlr_session to the compositor in the
wlr_backend_autocreate() call. wlr_backend_get_session() will be
removed in the next commit.
With protocol additions such as [1], compositors currently have no
way to opt out of the version upgrade. The protocol upgrade will
always be backwards-compatible but may require new compositor
features.
The status quo doesn't make it possible to ship a protocol addition
without breaking the wlroots API. This will be an issue for API
stabilization [2].
To address this, let compositors provide a maximum version in the
function creating the global. We need to support all previous versions
of the interface anyways because of older clients.
This mechanism works the same way as Wayland clients passing a version
in wl_global.bind.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3514
[2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/1008
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3397
Running with WLR_BACKENDS=headless, there is no keyboard device.
Avoid crashes like so:
../tinywl/tinywl.c:136:2: runtime error: member access within null pointer of type 'struct wlr_keyboard'
../tinywl/tinywl.c:136:2: runtime error: member access within null pointer of type 'struct wlr_keyboard'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==331107==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000120 (pc 0x556ed03e4e99 bp 0x7ffce834bc10 sp 0x7ffce834bbb0 T0)
==331107==The signal is caused by a READ memory access.
==331107==Hint: address points to the zero page.
#0 0x556ed03e4e99 in focus_view ../tinywl/tinywl.c:136
#1 0x556ed03eb3be in xdg_toplevel_map ../tinywl/tinywl.c:603
#2 0x7f75d6f768db in wlr_signal_emit_safe ../util/signal.c:29
#3 0x7f75d6e9cac7 in xdg_surface_role_commit ../types/xdg_shell/wlr_xdg_surface.c:315
#4 0x7f75d6eb6944 in surface_commit_state ../types/wlr_compositor.c:466
#5 0x7f75d6eb7b02 in surface_handle_commit ../types/wlr_compositor.c:523
#6 0x7f75d5714d49 (/usr/lib/libffi.so.8+0x6d49)
#7 0x7f75d5714266 (/usr/lib/libffi.so.8+0x6266)
#8 0x7f75d68cb322 (/usr/lib/libwayland-server.so.0+0xd322)
#9 0x7f75d68c65cb (/usr/lib/libwayland-server.so.0+0x85cb)
#10 0x7f75d68c91c9 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xb1c9)
#11 0x7f75d68c6d36 in wl_display_run (/usr/lib/libwayland-server.so.0+0x8d36)
#12 0x556ed03eef55 in main ../tinywl/tinywl.c:905
#13 0x7f75d5d2330f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)
#14 0x7f75d5d233c0 in __libc_start_main@GLIBC_2.2.5 (/usr/lib/libc.so.6+0x2d3c0)
#15 0x556ed03e46e4 in _start (/home/simon/src/wlroots/build/tinywl/tinywl+0x136e4)