]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
linux: Add mseal syscall support
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 6 Dec 2024 17:37:49 +0000 (14:37 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 6 Mar 2025 13:13:46 +0000 (10:13 -0300)
It as added on Linux 6.10 (8be7258aad44b5e25977a98db136f677fa6f4370)
as way to block operations as unmaping, moving to another location,
shrinking the size, expanding the size, or modifying to a pre-existent
memory mapping.

Although the systecall only work on 64 bit CPU, the entrypoint was
added for all ABIs (since kernel might eventually implement it to
additional ones and/or the abi can execute on a 64 bit kernel).

Checked on x86_64-linux-gnu.

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 e2e40e141cc0501b0c52df4d3e66d37145f0cf86..4732ec2522000732489382b1d46d5ebfe59e39d5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,9 @@ Version 2.42
 
 Major new features:
 
-  [Add new features here]
+* On Linux, the mseal function has been added.  It allows to seal memory
+  mappings to avoid further change during process execution such as protection
+  permissions, unmapping, moving to another location, or shrinking the size.
 
 Deprecated and removed features, and other changes affecting compatibility:
 
index dc4621e2c51b38da8b6972b1382633dd68409a3f..f092ee4ce6afd184d8afc06f0bb2eb470b44a7a5 100644 (file)
@@ -3072,6 +3072,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, previous 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 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 associate 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 address range.
+
+The @var{flags} is currently ununsed.
+
+The @code{mseal} function returns @math{0} on sucess 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 CPUs (the sealing is currently supported only on
+64-bit CPUs, although 32 bit binaries running on 64 bit kernel is
+supported).
+
+@item ENOMEM
+Either the @var{address} is not allocated, or the end address is not within the
+allocation, or there is an unallocated memory between start and end address.
+
+@item ENOSYS
+The kernel does not support the @code{mseal} syscall.
+
+@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}.
+
+@end table
+@end deftypefun
+
 @subsection Memory Protection Keys
 
 @cindex memory protection key
index 395d2d65938d33de6747264a63b73915003281e6..ae46e0726d6d6183b0d7df996ddd32c9ee712ca1 100644 (file)
@@ -213,6 +213,8 @@ tests += \
   tst-misalign-clone \
   tst-mlock2 \
   tst-mount \
+  tst-mseal \
+  tst-mseal-pkey \
   tst-ntp_adjtime \
   tst-ntp_gettime \
   tst-ntp_gettimex \
index 55d565545ab3b601d30c330bc63be324fd5d681e..e5d226165e9ea47975167372dac13a97ab87706d 100644 (file)
@@ -332,6 +332,9 @@ libc {
     sched_getattr;
     sched_setattr;
   }
+  GLIBC_2.42 {
+    mseal;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
index 38db77e4f7808c2070e0053b5c5bdabe2cd7a3ff..eab487fc76730333ebc0c37a8ef575d66560eaa6 100644 (file)
@@ -2750,3 +2750,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 637bfce9fbf4c3e18c5a925c48096d6aa2112720..d6d3464c4610c5903a8eeb9e7450bf410c600bbf 100644 (file)
@@ -3097,6 +3097,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 4a305cf7303f18113e94e2c8e5a77710227302a5..2c7aa2c939f65e02f5187a5161881aa1d7996e92 100644 (file)
@@ -2511,3 +2511,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 1d54f71b146d00a004926af01e12158a5b8e728b..54fd3d3a830963e2ae9599f640e79e21b72ec078 100644 (file)
@@ -2803,6 +2803,7 @@ GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index ff7e8bc40beb21de35f1706f0452b0cd329896a5..4231ef1ffde0534d5207ea3c17dddb386a5f1822 100644 (file)
@@ -2800,6 +2800,7 @@ GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 31590979b92c476d41eba2e55c010a6c2522dae3..b9892f62c2a2f316bd0bc34f422f415184ff17e9 100644 (file)
@@ -81,6 +81,14 @@ 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 remmap to
+   shrink or expand the VMA, change protection permission with mprotect,
+   unmap with munmap, destructive semantic such madvise with MADV_DONTNEED.
+   The address range must be valid VMA, withouth any gap (unallocated memory)
+   between start and end, and ADDR much 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 c3ed65467d14e729d693a503be84e6aba6cb9e3e..53265587caa43e955f7e6e1c0bd097596f8778f0 100644 (file)
@@ -2787,3 +2787,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 991475380ca51a11821247f0bacde69cf5acd4bb..2ad9eb1286b5b2abecd792a1e4111a00c7c5d742 100644 (file)
@@ -2824,6 +2824,7 @@ GLIBC_2.4 unshare F
 GLIBC_2.41 cacheflush F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 4fedf775d485f1a74d50d76c0fa83c32ab7ff6f4..f808d3f1109b39b1a98cc7d26bf5503df0e8ae0a 100644 (file)
@@ -3007,6 +3007,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 86b2d3ce512588c8823c11076c91116092836402..a44824991f95105956eb9492adbba0181a87e1e1 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 0024282289ffbee67ae570d5ef6d7ca55a2ca1ca..db7a5896ff1e3a7a430ceabf3a714bb996c593a7 100644 (file)
@@ -2271,3 +2271,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 142595eb3ed52656a159f38428972a57fe23ab75..91250faca5cf460d3656f2aea352bc4adc3b7089 100644 (file)
@@ -2783,6 +2783,7 @@ GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 85e7746c10a125b398c62e1e6136581418e909a4..f5f8c2d613b7ff348f7ff4d6f1e1b95277e9db97 100644 (file)
@@ -2950,6 +2950,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 91dc1b83785655a57ed05e74829a116de278c2b5..e505d338f4462b7149a441880a1c955b90c1ae9b 100644 (file)
@@ -2836,3 +2836,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 3440e90f6fda9abbe969df7bbc7b1c04fd6c8acd..c360b28fd178a0d00285fae4ab2d2b9bfe473656 100644 (file)
@@ -2833,3 +2833,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 5ee7b8c52fac1c935793fb37a46f3f6f0305e71f..fa09f9d9c9f34947acc662cc8353feb76cd5fa1a 100644 (file)
@@ -2911,6 +2911,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index ae7474c0f03e880b6e7faad3fa47a5efb3311ff1..1db4a115c8e91cc52ab1cbb6c27785adc120e86b 100644 (file)
@@ -2917,6 +2917,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index cdf040dec27b87736c025bc3388bc05e8a02189e..770fa9b04292a5968789dfa129ff0c7660a1ca05 100644 (file)
@@ -2819,6 +2819,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index c356a11b1ceafbc69a5f972ee01f75ac544d1861..c41f91db2871a30dc4bda2ebc370e78ce12aa9ba 100644 (file)
@@ -2261,3 +2261,4 @@ GLIBC_2.40 setcontext F
 GLIBC_2.40 swapcontext F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 7937f94cf092f6143f4cdb181641ac934ec7f25a..8eccaa5c92684a4d9662d5022e1ef7a6665b11c7 100644 (file)
@@ -3140,6 +3140,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index d6e35f31d248749053a7e845279c80407bec6b0e..f827f65615b3729cf722a12527b5fbf2674cbeb7 100644 (file)
@@ -3185,6 +3185,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 2268d6890d73a5cce9949d46f7fee58bcf6df05c..141186553dc203997b996a2d1159a2723fb62e8a 100644 (file)
@@ -2894,6 +2894,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 7f61b14bc8df2a165a3ff14fa34d1d7c095de9a4..7786c970725b270d2bb1b776c4e7cf9339e2cfdb 100644 (file)
@@ -2970,3 +2970,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 4187241f5030d411d225a5cfce94db53b98ff01c..090a8a3cc377af82dd25246fe3efdbcce2fb6385 100644 (file)
@@ -2514,3 +2514,4 @@ GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.40 __riscv_hwprobe F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index 8935beccac1a2c693e664f634aa27cd671dc852b..8f8daa10b26305ea423ad0fd7151fcfe6b77da2a 100644 (file)
@@ -2714,3 +2714,4 @@ GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.40 __riscv_hwprobe F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
index e69dc7ccf6952f895e04aedd80f19f5af28e14e6..68ad13d4d1e39287fd9c6921e9df47da02d2a1b3 100644 (file)
@@ -3138,6 +3138,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 7d860001d8a57160e8fe33ada27abb8875bea8c2..b07e767d442c22aa6d3e309a114f007771b89933 100644 (file)
@@ -2931,6 +2931,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index fcb8161841078f2bc6dcef904dd85a2d4b8a4a40..841da24118010bf63f5dede5503153c0434df83b 100644 (file)
@@ -2830,6 +2830,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 3fd078d1257bf8d93b990cf2c10bfe4091ac8d56..2a8cba719ee9f632378e3e0cb4f12666f8e622ee 100644 (file)
@@ -2827,6 +2827,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 1ce1fe9da7180b4fa65ceab1983b66e7876e70d9..8f9031f344fe793d0e56b4be9fe803bbd2211681 100644 (file)
@@ -3159,6 +3159,7 @@ GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 07507b86f6bd506c7549cd2e47eee2c6df815b4f..e5abc49fce58b0f8771a72958e2d571ea66643c8 100644 (file)
@@ -2795,6 +2795,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find 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..d194fba
--- /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_EXIT (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..0aff1e9
--- /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_EXIT (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 5acf49dbe82a1a41c62df4fb8bfd178904225908..5a2265409586f7a521cdea80c4ef1da4241cca50 100644 (file)
@@ -2746,6 +2746,7 @@ GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
index 02d1bb97dca5f0a5d576d2dbaac9f844b4b5b6c2..d627f4fcce144a42fc4c1330e4c04e1827540d09 100644 (file)
@@ -2765,3 +2765,4 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
 GLIBC_2.41 sched_getattr F
 GLIBC_2.41 sched_setattr F
+GLIBC_2.42 mseal F