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

From: Devin Teske <dteske_at_freebsd.org>
Date: Sun, 16 Aug 2026 23:46:04 UTC

> On Aug 16, 2026, at 6:31 AM, Michael Tuexen <tuexen@FreeBSD.org> wrote:
> 
> 
> 
>> 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

Thank you, Michael.

Fixed-up
— 
Devin