From 3d52fd274e9cfc74d90786672d927ca82cb40abd Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 10 Nov 2025 15:03:05 -0300 Subject: [PATCH] linux: Add mseal syscall support It has been added on Linux 6.10 (8be7258aad44b5e25977a98db136f677fa6f4370) as a way to block operations such as mapping, moving to another location, shrinking the size, expanding the size, or modifying it to a pre-existing memory mapping. Although the system only works on 64-bit CPUs, the entrypoint was added for all ABIs (since the kernel might eventually implement it for additional ones and/or the ABI can execute on a 64-bit kernel). Checked on x86_64-linux-gnu and aarch64-linux-gnu. Reviewed-by: Collin Funk --- NEWS | 5 ++ manual/memory.texi | 69 +++++++++++++++ sysdeps/unix/sysv/linux/Makefile | 2 + sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/mman-shared.h | 10 +++ sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/kernel-features.h | 8 ++ .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/syscalls.list | 1 + sysdeps/unix/sysv/linux/tst-mseal-pkey.c | 84 +++++++++++++++++++ sysdeps/unix/sysv/linux/tst-mseal.c | 67 +++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 40 files changed, 280 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/tst-mseal-pkey.c create mode 100644 sysdeps/unix/sysv/linux/tst-mseal.c diff --git a/NEWS b/NEWS index 0f01b751f9..0f03f97834 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,11 @@ Major new features: platforms supporting _Float128) _Float128_t, introduced in TS 18661-3:2015, have been added to . +* On Linux, the mseal function has been added. It allows for sealing + memory mappings to prevent further changes during process execution, + such as changes to protection permissions, unmapping, relocation to + another location, or shrinking the size. + Deprecated and removed features, and other changes affecting compatibility: * Support for dumped heaps has been removed - malloc_set_state() now always diff --git a/manual/memory.texi b/manual/memory.texi index dd6c7f9996..fb14a34de0 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -3126,6 +3126,75 @@ process memory, no matter how it was allocated. However, portable use of the function requires that it is only used with memory regions returned by @code{mmap} or @code{mmap64}. +@deftypefun int mseal (void *@var{address}, size_t @var{length}, unsigned long @var{flags}) +@standards{Linux, sys/mman.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + +A successful call to the @code {mseal} function protects the memory +range @var{address} of @var{length} bytes, previously allocated with +@code{mmap} or @code{mremap}, against further metadata changes, such +as: + +@itemize @bullet +@item +Unmapping, moving to another location, extending or shrinking the size, +via @code{munmap} and @code{mremap}. + +@item +Moving or expanding a different VMA into the current location, via +@code{mremap}. + +@item +Modifying the memory range with @code{mmap} along with the flag @code{MAP_FIXED}. + +@item +Change the protection flags with @code{mprotect} or @code{pkey_mprotect}. Also +for certain destructive @code{madvise} behaviours (@code{MADV_DONTNEED}, +@code{MADV_FREE}, @code{MADV_DONTNEED_LOCKED}, and @code{MADV_WIPEONFORK}), +@code{mseal} only blocks the operation if the protection key associated with +the memory denies write. + +@item +Destructive behaviors on anonymous memory, such as @code{madvice} with +@code{MADV_DONTNEED}. +@end itemize + +The @var{address} must be an allocated virtual memory done by @code{mmap} +or @code{mremap}, and it must be page-aligned. The end address (@var{address} +plus @var{length}) must be within an allocated virtual memory range. There +should be no unallocated memory between the start and end of the address range. + +The @var{flags} is currently unused. + +The @code{mseal} function returns @math{0} on success and @math{-1} on +failure. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EPERM +The system blocked the operation, and the given address range is unmodified +without a partial update. This error is also returned when @code{mseal} is +issued on a 32-bit CPU (sealing is currently supported only on 64-bit CPUs, +although 32-bit binaries running on a 64-bit kernel are supported). + +@item ENOMEM +Either the @var{address} is not allocated, or the end address is not within the +allocation, or there is unallocated memory between the start and end address. + +@item ENOSYS +The kernel does not support the @code{mseal} syscall. + +@end table +@end deftypefun + +@strong{NB:} The memory sealing changes the lifetime of a mapping, where the +sealing memory could not be unmapped until the process terminates or replaces +the process image through @code{execve} function. The sealed mappings are +inherited through @code{fork}. + + @subsection Memory Protection Keys @cindex memory protection key diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 193798e2ae..199031da64 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -205,6 +205,8 @@ tests += \ tst-misalign-clone \ tst-mlock2 \ tst-mount \ + tst-mseal \ + tst-mseal-pkey \ tst-ntp_adjtime \ tst-ntp_gettime \ tst-ntp_gettimex \ diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 585dec7689..8f4d71ad7f 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -339,6 +339,9 @@ libc { cfsetispeed; cfsetspeed; } + GLIBC_2.43 { + mseal; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index ecb1be5bb4..2f049a4b41 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2770,4 +2770,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 55c22da87f..bebfad9de2 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -3117,6 +3117,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index b1e5855b5d..d6341e98e7 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2531,4 +2531,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 1ac00b8303..a9076eb320 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -2823,6 +2823,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index cf92ab4ada..d3be53ea25 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -2820,6 +2820,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/bits/mman-shared.h b/sysdeps/unix/sysv/linux/bits/mman-shared.h index 0be4b471bf..39851c965c 100644 --- a/sysdeps/unix/sysv/linux/bits/mman-shared.h +++ b/sysdeps/unix/sysv/linux/bits/mman-shared.h @@ -80,6 +80,16 @@ int pkey_free (int __key) __THROW; range. */ int pkey_mprotect (void *__addr, size_t __len, int __prot, int __pkey) __THROW; +/* Seal the address range to avoid further modifications, such as remapping to + shrink or expand the VMA, changing protection permission with mprotect, + unmap with munmap, or destructive semantics such as madvise with + MADV_DONTNEED. + + The address range must be a valid VMA, without any gaps (unallocated + memory) between the start and end, and ADDR must be page-aligned (LEN will + be page-aligned implicitly). */ +int mseal (void *__addr, size_t __len, unsigned long flags) __THROW; + __END_DECLS #endif /* __USE_GNU */ diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 5d00604da5..e110766976 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2807,4 +2807,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 4011dc5cc0..a079e7d1a0 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2844,6 +2844,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 3757e41e6f..421b3c742b 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -3027,6 +3027,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index a49a9159cf..79191695b4 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -261,4 +261,12 @@ # define __ASSUME_FCHMODAT2 0 #endif +/* The mseal system call was introduced across all architectures in Linux 6.10 + (although only supported on 64-bit CPUs). */ +#if __LINUX_KERNEL_VERSION >= 0x060A00 +# define __ASSUME_MSEAL 1 +#else +# define __ASSUME_MSEAL 0 +#endif + #endif /* kernel-features.h */ diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 8bbb950386..1d7a1de570 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2291,4 +2291,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 74b36e84b6..b512384ed0 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -2803,6 +2803,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index b5cf2998c3..223e4825ab 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2970,6 +2970,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 547e21eb66..f314f55e1f 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2856,4 +2856,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index f98407da28..8a33db2cb2 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2853,4 +2853,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 1e207c97c3..3f704bd87d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2933,6 +2933,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index d44b0c41c0..8b8e5af806 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2939,6 +2939,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index bdcde50165..f45d5075fd 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2841,6 +2841,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index f2117e1dcc..96b056d14a 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2281,4 +2281,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 6e887bcca4..6420f23d06 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -3160,6 +3160,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 247cbc2c8d..9a2a258e02 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -3205,6 +3205,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 70fe1f2de8..6a20d8d031 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2914,6 +2914,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 8f82f6c648..c0fa82e6a2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2990,4 +2990,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 57b5790914..5c46dcacdc 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2534,4 +2534,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index faeaebc500..4ce2007c56 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2734,4 +2734,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 62a71df101..9a672c6a4c 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -3158,6 +3158,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 01681666e8..1926e675ca 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2951,6 +2951,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index b93a621870..b3510af9ef 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2850,6 +2850,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index fb41f72160..fc1fea412a 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2847,6 +2847,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index cbe10bb14c..fce9f948b7 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -3181,6 +3181,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 480dc5e8cd..9d4721c16e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2817,6 +2817,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index f1cfe8dc13..424bf43868 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -39,6 +39,7 @@ mlockall - mlockall i:i mlockall mount EXTRA mount i:sssUp __mount mount mount_setattr EXTRA mount_setattr i:isUpU mount_setattr move_mount EXTRA move_mount i:isisU move_mount +mseal EXTRA mseal i:bUU __mseal mseal munlock - munlock i:aU munlock munlockall - munlockall i: munlockall nfsservctl EXTRA nfsservctl i:ipp __compat_nfsservctl nfsservctl@GLIBC_2.0:GLIBC_2.28 diff --git a/sysdeps/unix/sysv/linux/tst-mseal-pkey.c b/sysdeps/unix/sysv/linux/tst-mseal-pkey.c new file mode 100644 index 0000000000..dfe12d04f8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-mseal-pkey.c @@ -0,0 +1,84 @@ +/* Basic tests for mseal and pkey. + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +static int +do_test (void) +{ + TEST_VERIFY (mseal (MAP_FAILED, 0, 0) == -1); + if (errno == ENOSYS || errno == EPERM) + FAIL_UNSUPPORTED ("kernel does not support mseal"); + TEST_COMPARE (errno, EINVAL); + + int key = pkey_alloc (0, 0); + if (key < 0) + { + if (errno == ENOSYS) + FAIL_UNSUPPORTED + ("kernel does not support memory protection keys"); + if (errno == EINVAL) + FAIL_UNSUPPORTED + ("CPU does not support memory protection keys: %m"); + if (errno == ENOSPC) + FAIL_UNSUPPORTED + ("no keys available or kernel does not support memory" + " protection keys"); + FAIL_EXIT1 ("pkey_alloc: %m"); + } + + long pagesize = xsysconf (_SC_PAGESIZE); + + void *page = xmmap (NULL, pagesize, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1); + + TEST_COMPARE (pkey_mprotect (page, pagesize, PROT_READ | PROT_WRITE, + key), 0); + + TEST_VERIFY_EXIT (mseal (page, pagesize, 0) == 0); + + /* For certain destructive madvise behaviours (MADV_DONTNEED, + MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK), mseal + only blocks the operation if the PKRU denies write. */ + TEST_VERIFY_EXIT (pkey_set (key, 0) == 0); + TEST_COMPARE (madvise (page, pagesize, MADV_DONTNEED), 0); + + /* The other mapping operation change are always blocked, + regardless of PKRU state. */ + TEST_COMPARE (pkey_mprotect (page, pagesize, PROT_READ, key), -1); + TEST_COMPARE (errno, EPERM); + + TEST_COMPARE (mprotect (page, pagesize, PROT_READ), -1); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (pkey_set (key, PKEY_DISABLE_WRITE) == 0); + TEST_COMPARE (madvise (page, pagesize, MADV_DONTNEED), -1); + TEST_COMPARE (errno, EPERM); + + TEST_COMPARE (mprotect (page, pagesize, PROT_READ), -1); + TEST_COMPARE (errno, EPERM); + TEST_COMPARE (munmap (page, pagesize),-1); + TEST_COMPARE (errno, EPERM); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/tst-mseal.c b/sysdeps/unix/sysv/linux/tst-mseal.c new file mode 100644 index 0000000000..fccef9313c --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-mseal.c @@ -0,0 +1,67 @@ +/* Basic tests for mseal. + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +static int +do_test (void) +{ + TEST_VERIFY (mseal (MAP_FAILED, 0, 0) == -1); + if (errno == ENOSYS || errno == EPERM) + FAIL_UNSUPPORTED ("kernel does not support mseal"); + TEST_COMPARE (errno, EINVAL); + + size_t pagesize = getpagesize (); + void *p = xmmap (NULL, 4 * pagesize, PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1); + xmunmap (p + 2 * pagesize, pagesize); + + /* Unaligned address. */ + TEST_VERIFY_EXIT (mseal (p + 1, pagesize, 0) == -1); + TEST_COMPARE (errno, EINVAL); + + /* Length too big. */ + TEST_VERIFY_EXIT (mseal (p, 3 * pagesize, 0) == -1); + TEST_COMPARE (errno, ENOMEM); + + TEST_VERIFY_EXIT (mseal (p, pagesize, 0) == 0); + /* Apply the same seal should be idempotent. */ + TEST_VERIFY_EXIT (mseal (p, pagesize, 0) == 0); + + TEST_VERIFY_EXIT (mprotect (p, pagesize, PROT_WRITE) == -1); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (munmap (p, pagesize) == -1); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (mremap (p, pagesize, 2 * pagesize, 0) == MAP_FAILED); + TEST_COMPARE (errno, EPERM); + + TEST_VERIFY_EXIT (madvise (p, pagesize, MADV_DONTNEED) == -1); + TEST_COMPARE (errno, EPERM); + + xmunmap (p + pagesize, pagesize); + xmunmap (p + 3 * pagesize, pagesize); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index e46f66efdf..a836a57426 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2766,6 +2766,7 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index a6edf8778a..aecce5bbc5 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2785,4 +2785,5 @@ GLIBC_2.42 ullabs F GLIBC_2.43 __memset_explicit_chk F GLIBC_2.43 memalignment F GLIBC_2.43 memset_explicit F +GLIBC_2.43 mseal F GLIBC_2.43 umaxabs F