diff options
author | 6t8k <6t8k@noreply.codeberg.org> | 2023-10-14 23:25:48 +0200 |
---|---|---|
committer | 6t8k <6t8k@noreply.codeberg.org> | 2024-04-21 19:17:46 +0200 |
commit | 03e304544b9b01c175813215f5930a07152be448 (patch) | |
tree | 30b174757b831c0a46bd45815518db266750e853 | |
parent | c5d145a602581ee70f3ee87566ccb5cf1ff6cce8 (diff) |
cursor: memfd_create: try MFD_NOEXEC_SEAL
Effective from Linux 6.3 onward, this creates the memfd without execute
permissions and prevents that setting from ever being changed. A
run-time fallback is made to not using MFD_NOEXEC_SEAL when a
libwayland-cursor compiled on Linux >= 6.3 is run on Linux < 6.3.
This is a defense-in-depth security measure and silences a respective
kernel warning; see: https://lwn.net/Articles/918106/
This implementation is adopted from dnkl's `foot` terminal emulator.
Signed-off-by: 6t8k <6t8k@noreply.codeberg.org>
-rw-r--r-- | cursor/os-compatibility.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/cursor/os-compatibility.c b/cursor/os-compatibility.c index f2445ce..2b54bae 100644 --- a/cursor/os-compatibility.c +++ b/cursor/os-compatibility.c @@ -40,6 +40,11 @@ #include <sys/mman.h> #endif +/* Fallback to no flag when missing the definition */ +#ifndef MFD_NOEXEC_SEAL +#define MFD_NOEXEC_SEAL 0 +#endif + #include "os-compatibility.h" #ifndef HAVE_MKOSTEMP @@ -124,7 +129,21 @@ os_create_anonymous_file(off_t size) int fd; #ifdef HAVE_MEMFD_CREATE - fd = memfd_create("wayland-cursor", MFD_CLOEXEC | MFD_ALLOW_SEALING); + /* + * Linux kernels older than 6.3 reject MFD_NOEXEC_SEAL with EINVAL. + * Try first *with* it, and if that fails, try again *without* it. + */ + errno = 0; + fd = memfd_create( + "wayland-cursor", + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); + + if (fd < 0 && errno == EINVAL && MFD_NOEXEC_SEAL != 0) { + fd = memfd_create( + "wayland-cursor", + MFD_CLOEXEC | MFD_ALLOW_SEALING); + } + if (fd >= 0) { /* We can add this seal before calling posix_fallocate(), as * the file is currently zero-sized anyway. |