Re: git: bdb561843e86 - main - linux: implement pkey_alloc, pkey_free and pkey_mprotect

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Sun, 16 Aug 2026 13:31:22 UTC

> On 16. Aug 2026, at 03:01, Devin Teske <dteske@FreeBSD.org> wrote:
> 
> The branch main has been updated by dteske:
> 
> URL: https://cgit.FreeBSD.org/src/commit/?id=bdb561843e865eaa5bbdc5394ed9d9c91136240c
> 
> commit bdb561843e865eaa5bbdc5394ed9d9c91136240c
> Author:     Devin Teske <dteske@FreeBSD.org>
> AuthorDate: 2026-08-16 00:58:19 +0000
> Commit:     Devin Teske <dteske@FreeBSD.org>
> CommitDate: 2026-08-16 00:58:43 +0000
> 
>    linux: implement pkey_alloc, pkey_free and pkey_mprotect
> 
>    Bridge the Linux memory protection key syscalls to FreeBSD's native
>    MPK support instead of returning ENOSYS. Modern Linux software
>    probes these at startup: Chromium-based browsers (found via
>    www/linux-brave) use protection keys for V8's heap and JIT
>    sandboxing, and glibc >= 2.27 exposes the full API.
> 
>    pkey_alloc() allocates from a per-process bitmap kept in the process
>    emuldata (key 0 implicitly allocated, matching Linux's
>    mm_pkey_allocation_map; ENOSPC once keys 1..15 are exhausted or when
>    PKU is absent, as Linux returns on such hardware) and applies the
>    requested initial access rights to the calling thread's PKRU, located
>    in the XSAVE area via xsave_area_offset(). pkey_free() is
>    bookkeeping only: as on Linux, freeing neither untags pages nor
>    updates PKRU. pkey_mprotect() performs the protection change and
>    tags the range through amd64_pkru_update(), factored out of
>    sysarch(2)'s AMD64_SET_PKRU/AMD64_CLEAR_PKRU implementation so that
>    both share the same argument checking and map read lock
>    synchronization with a parallel pmap_vmspace_copy() on fork; tags die
>    with the mapping, matching Linux VMA semantics. A pkey of -1
>    degrades to plain mprotect.
> 
>    The allocation map is inherited on fork and reset on exec. At exec
>    the Linux sysvecs initialize PKRU to 0x55555554, Linux's init_pkru
>    default (access disabled for keys 1..15), so memory tagged with a
>    not yet allocated key is inaccessible to threads that were never
>    granted rights -- the property V8's thread isolation relies on.
>    Setting PKRU at exec initializes the user FPU state slightly earlier
>    than the lazy first-use path; the state would be initialized moments
>    later in rtld/libc startup regardless. Protection key faults
>    already deliver SEGV_PKUERR through the existing siginfo
>    translation.
> 
>    The common code carries no architecture ifdefs. Machine-dependent
>    state lives in struct linux_pemuldata_md, embedded in the process
>    emuldata in the manner of struct mdthread, and common code calls
>    per-arch lifecycle hooks (linux_pemuldata_init_md/_exec_md) and pkey
>    back ends after performing the parameter validation Linux applies
>    regardless of hardware support. On amd64 the implementation lives
>    in sys/amd64/linux/linux_pkru.c, compiled into linux_common and
>    serving both the 64-bit and 32-bit Linux ABIs. Elsewhere (arm64,
>    i386) linux_emul_md.c provides stubs returning what Linux returns on
>    hardware without protection keys (ENOSPC from pkey_alloc;
>    pkey_mprotect with a pkey of -1 acts as plain mprotect), so
>    applications take their normal no-PKU fallback instead of the ENOSYS
>    path.
> 
>    PR:             297427
>    MFC after:      1 month
>    Reviewed by:    kib
>    Differential Revision:  https://reviews.freebsd.org/D58782
Hi Devin,

This breaks compilation for me on arm64. In sys/arm64/linux/linux_emul_md.c
the file compat/linux/linux_emul.h is included which needs an inclusion
of sys/imgact.h.

So

diff --git a/sys/arm64/linux/linux_emul_md.c b/sys/arm64/linux/linux_emul_md.c
index 9dd507ad4f49..e55d3b712056 100644
--- a/sys/arm64/linux/linux_emul_md.c
+++ b/sys/arm64/linux/linux_emul_md.c
@@ -7,6 +7,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
+#include <sys/imgact.h>
   #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_mmap.h>

fixes compilation for me.

Best regards
Michael