Skip to content

wayland-shm: Check the size of sealed memory if ignoring SIGBUS handlers to avoid a crash

Duncan McIntosh requested to merge duncanm/wayland:fix-sigbus-crash into main

If an application gives the compositor a shared memory region that's marked F_SEAL_SHRINK, then the compositor won't worry about setting up the SIGBUS handler (11623e8f). This works fine most of the time, unless the application lies about the length of the region. Then, the compositor will get a SIGBUS and crash; the region can't shrink, but it's smaller than what the compositor is told!

I've made a proof of concept (build with libwayland-client and xdg-shell.{c,h}) that triggers the crash by creating a memfd with zero bytes, and then tries to display it on a xdg-shell toplevel. I've tested it with GNOME, Sway, and Weston with the latest Debian sid versions and libwayland-server0 1.19.0-2, and they crash (although Weston needed some changes to the test program). Interestingly, KWin doesn't crash, but rather just makes the toplevel window with no contents; not sure why.

One possible fix is to just always set the signal handler. However, it seems that fstat is able to determine the size of a memfd, and thus that can be used to determine the size is in the right range. If the size makes sense, F_SEAL_SHRINK is already set so the region can never shrink, and thus SIGBUS is (...should be) impossible. If the size is too small, it will set the SIGBUS handler.

The best solution for this would likely be MAP_NOSIGBUS, since could theoretically remove all the SIGBUS handling, but that won't help on systems with older kernels or on systems that support memfd sealing but not MAP_NOSIGBUS (if such systems exist).

Edited by Duncan McIntosh

Merge request reports