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>
This commit is contained in:
6t8k 2023-10-14 23:25:48 +02:00
parent c5d145a602
commit 03e304544b
No known key found for this signature in database

View file

@ -40,6 +40,11 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
/* Fallback to no flag when missing the definition */
#ifndef MFD_NOEXEC_SEAL
#define MFD_NOEXEC_SEAL 0
#endif
#include "os-compatibility.h" #include "os-compatibility.h"
#ifndef HAVE_MKOSTEMP #ifndef HAVE_MKOSTEMP
@ -124,7 +129,21 @@ os_create_anonymous_file(off_t size)
int fd; int fd;
#ifdef HAVE_MEMFD_CREATE #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) { if (fd >= 0) {
/* We can add this seal before calling posix_fallocate(), as /* We can add this seal before calling posix_fallocate(), as
* the file is currently zero-sized anyway. * the file is currently zero-sized anyway.