]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
linux: Add mseal syscall support
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 10 Nov 2025 18:03:05 +0000 (15:03 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 12 Nov 2025 18:27:28 +0000 (15:27 -0300)
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 <collin.funk1@gmail.com>
40 files changed:
NEWS
manual/memory.texi
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/Versions
sysdeps/unix/sysv/linux/aarch64/libc.abilist
sysdeps/unix/sysv/linux/alpha/libc.abilist
sysdeps/unix/sysv/linux/arc/libc.abilist
sysdeps/unix/sysv/linux/arm/be/libc.abilist
sysdeps/unix/sysv/linux/arm/le/libc.abilist
sysdeps/unix/sysv/linux/bits/mman-shared.h
sysdeps/unix/sysv/linux/csky/libc.abilist
sysdeps/unix/sysv/linux/hppa/libc.abilist
sysdeps/unix/sysv/linux/i386/libc.abilist
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
sysdeps/unix/sysv/linux/or1k/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
sysdeps/unix/sysv/linux/sh/be/libc.abilist
sysdeps/unix/sysv/linux/sh/le/libc.abilist
sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
sysdeps/unix/sysv/linux/syscalls.list
sysdeps/unix/sysv/linux/tst-mseal-pkey.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/tst-mseal.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

diff --git a/NEWS b/NEWS
index 0f01b751f988795cbd823c00f7653121cd6df38e..0f03f97834227d6f714cf8efa3f7cd7d84e40ecc 100644 (file)
--- 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 <math.h>.
 
+* 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
index dd6c7f99960d1863a80c71e68b95ab3dc3eaf660..fb14a34de0de4e835bdbce4bf1e7efe14053c498 100644 (file)
@@ -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
index 193798e2ae69954aa82d505870bb097984f1d348..199031da64a12e39e63445ac838d348fe0c2e775 100644 (file)
@@ -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 \
index 585dec7689e72028e064e2f52c77505af073758e..8f4d71ad7fe00a73c1577a8711383b711ccae33f 100644 (file)
@@ -339,6 +339,9 @@ libc {
     cfsetispeed;
     cfsetspeed;
   }
+  GLIBC_2.43 {
+    mseal;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
index ecb1be5bb494f4e5521b4889aa64d9a9a9488759..2f049a4b41032e9641e09409ce99bda84dbc8890 100644 (file)
@@ -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
index 55c22da87f3aeeab73ff5fa7f952c861e68568ce..bebfad9de2cd7546b392a80d6ee386bc5429248a 100644 (file)
@@ -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
index b1e5855b5dd2cc74bad75ddee8e3d1272d2c7988..d6341e98e7bac55c78aeece80392390f0d564329 100644 (file)
@@ -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
index 1ac00b8303f7973a54081d1013639eba526335e7..a9076eb3207b6254e6a694460e7196d66a64e9c7 100644 (file)
@@ -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
index cf92ab4adae72e06adf46ed95bdebdb043f2ed4e..d3be53ea257c0d5c178877c7c165db0616043562 100644 (file)
@@ -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
index 0be4b471bff0f959aebc6e58058717c387539f62..39851c965c2d5c837d29166d7933bd6271a02278 100644 (file)
@@ -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 */
index 5d00604da52f747bb3783a700450d123153ed9f7..e1107669767dcd1343725b3762df60be420d3e4d 100644 (file)
@@ -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
index 4011dc5cc09de32ac3bcbe9d8d8fbd69e7f136ad..a079e7d1a01ac1d9ff8a9502d99a2009ac03c271 100644 (file)
@@ -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
index 3757e41e6f4d7568f91f063f4fadf0c6d6404bdb..421b3c742beaca21321c433fded8c8535faf0e99 100644 (file)
@@ -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
index a49a9159cfa7d4496395581e64a2a7ad2d8b99a8..79191695b4f5283c5eead0c070863f80105ea185 100644 (file)
 # 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 */
index 8bbb9503862b640cf0fe8e50f66a077a9928f5ac..1d7a1de570c635b80895eeec4f2ada3a230959e1 100644 (file)
@@ -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
index 74b36e84b6f1814c3b27d07abfbce7e225296ed6..b512384ed01f037dc53689cf502c352d39956240 100644 (file)
@@ -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
index b5cf2998c36ff7936db3dc47387c669cbaea47e4..223e4825ab270c1514aa707194db4fb7bd69755e 100644 (file)
@@ -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
index 547e21eb66cf94a5f03abf4b557ecc45ac0032fe..f314f55e1fa04a709b7d349ab84fa1384fb9a30e 100644 (file)
@@ -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
index f98407da281301dba5664c45927bfa96dc9c3af7..8a33db2cb2aac165e4f538f391c460e6263e72de 100644 (file)
@@ -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
index 1e207c97c339172c505e78294dabb4a00b73f91a..3f704bd87de7b402e74939234df1d99e405988ec 100644 (file)
@@ -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
index d44b0c41c0df509bed727dec4b73800fc48f1602..8b8e5af806a25215b4ab1322a52c2e31fdcdaef1 100644 (file)
@@ -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
index bdcde501656400c4a3630726869ca90ae3c1c000..f45d5075fdf2890161b68487b7ca4f68d0de4393 100644 (file)
@@ -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
index f2117e1dcc013f0ef57cdd5adc66f165e6ac2031..96b056d14a0689766af497c6f424b543931fc712 100644 (file)
@@ -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
index 6e887bcca485c22b94f2b0181acd46cdda1826f7..6420f23d068f7269ffcd9fbec362b42c58638668 100644 (file)
@@ -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
index 247cbc2c8d82c04e6bcce0c75c2dab970492e716..9a2a258e02420b16e9580f0d52f682a2278ed078 100644 (file)
@@ -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
index 70fe1f2de82be45f422567959bb6f475e00c7d3a..6a20d8d031adba86eb7711b0d8226e839c3a3924 100644 (file)
@@ -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
index 8f82f6c648049de61bb26925234a0df772183a8f..c0fa82e6a2ae98b64d714ad070e2b72acad501a7 100644 (file)
@@ -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
index 57b5790914d2422f12397e6217cc665817653a00..5c46dcacdcec1ff886f4ae8ccc64986c03012a12 100644 (file)
@@ -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
index faeaebc5003d62069ffe10c1c996b1df1bc464a9..4ce2007c56d2c98def1d6b8b565c3d3031ad5441 100644 (file)
@@ -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
index 62a71df101371bb191fca416222600f4f2302164..9a672c6a4c37da9d5d5a92ddf176f4b544879546 100644 (file)
@@ -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
index 01681666e8568514362413359dd2f5fcc8b67a82..1926e675ca972f1bfff11a97c528f02dc27684c2 100644 (file)
@@ -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
index b93a621870a585c5497ee3423ef2c0a1f5ae16f1..b3510af9ef76edd34ddec10e5ae2d037bd71dc66 100644 (file)
@@ -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
index fb41f72160b14b0bc6f5afe089f9cd03ab12e6f5..fc1fea412a50dda68c8e25ed4a5e24f81ed0e256 100644 (file)
@@ -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
index cbe10bb14c745fa0b2015c4abe248c9a57109b47..fce9f948b799e780da22f58d1608071538d80b2c 100644 (file)
@@ -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
index 480dc5e8cd8b2a2222d2464390cde93d393312a5..9d4721c16ebfcdfecc7cf98cf813c05ba86f0c00 100644 (file)
@@ -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
index f1cfe8dc139e56d43f0d2b55941666795f7697e2..424bf43868f0bc9c5f93b5a9767c3d63aa4ce7e1 100644 (file)
@@ -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 (file)
index 0000000..dfe12d0
--- /dev/null
@@ -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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+
+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 <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/tst-mseal.c b/sysdeps/unix/sysv/linux/tst-mseal.c
new file mode 100644 (file)
index 0000000..fccef93
--- /dev/null
@@ -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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+
+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 <support/test-driver.c>
index e46f66efdf7654f2ccb6ea4602e3cb2c3e9f80ac..a836a574266c944349c8b5f27c5ea307e1e5da17 100644 (file)
@@ -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
index a6edf8778abb8f14cefcfcbb1021a9e450cdbdf5..aecce5bbc5e167aa0abee1ced80340233a7a0e34 100644 (file)
@@ -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