@@ -36,6 +36,10 @@ Major new features:
* On Linux, update epoll header to include epoll ioctl definitions and
related structure added in Linux kernel 6.9.
+* 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:
* Architectures which use a 32-bit seconds-since-epoch field in struct
@@ -3072,6 +3072,72 @@ 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 seals the memory range of
+@var{length} bytes, starting at @var{address}. The sealed memory is
+protection against further modifictions 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
+Expanding the size with @code{mremap}.
+
+@item
+Change the protection flags with @code{mprotect} or @code{pkey_mprotect}.
+
+@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 is unmodified
+without partion 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
+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 starts
+another one through @code{execve} function.
+
+@end table
+@end deftypefun
+
@subsection Memory Protection Keys
@cindex memory protection key
@@ -210,6 +210,7 @@ tests += \
tst-misalign-clone \
tst-mlock2 \
tst-mount \
+ tst-mseal \
tst-ntp_adjtime \
tst-ntp_gettime \
tst-ntp_gettimex \
@@ -328,6 +328,9 @@ libc {
posix_spawnattr_getcgroup_np;
posix_spawnattr_setcgroup_np;
}
+ GLIBC_2.40 {
+ mseal;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__syscall_rt_sigqueueinfo;
@@ -158,6 +158,7 @@
#define __NR_mq_timedsend 182
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2748,3 +2748,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -190,6 +190,7 @@
#define __NR_mq_unlink 433
#define __NR_mremap 341
#define __NR_msgctl 200
+#define __NR_mseal 572
#define __NR_msgget 201
#define __NR_msgrcv 202
#define __NR_msgsnd 203
@@ -3095,6 +3095,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -161,6 +161,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2509,3 +2509,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -205,6 +205,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 275
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 304
#define __NR_msgget 303
#define __NR_msgrcv 302
@@ -2801,6 +2801,7 @@ GLIBC_2.4 xdrstdio_create F
GLIBC_2.4 xencrypt F
GLIBC_2.4 xprt_register F
GLIBC_2.4 xprt_unregister F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2798,6 +2798,7 @@ GLIBC_2.4 xdrstdio_create F
GLIBC_2.4 xencrypt F
GLIBC_2.4 xprt_register F
GLIBC_2.4 xprt_unregister F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -80,6 +80,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 */
@@ -168,6 +168,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2785,3 +2785,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -197,6 +197,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 230
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 191
#define __NR_msgget 190
#define __NR_msgrcv 189
@@ -2821,6 +2821,7 @@ GLIBC_2.4 sys_errlist D 0x400
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -222,6 +222,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 278
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -3005,6 +3005,7 @@ GLIBC_2.4 sys_errlist D 0x210
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -257,4 +257,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 */
new file mode 100644
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ Copyright (C) 2024 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/>. */
+
+int foo (void) { return 42; }
@@ -155,6 +155,7 @@
#define __NR_mq_timedsend 182
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2269,3 +2269,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -213,6 +213,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 272
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -2781,6 +2781,7 @@ GLIBC_2.4 xdrstdio_create F
GLIBC_2.4 xencrypt F
GLIBC_2.4 xprt_register F
GLIBC_2.4 xprt_unregister F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2948,6 +2948,7 @@ GLIBC_2.4 sys_errlist D 0x210
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -221,6 +221,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 278
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 331
#define __NR_msgget 332
#define __NR_msgrcv 333
@@ -2834,3 +2834,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -2831,3 +2831,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -211,6 +211,7 @@
#define __NR_mq_timedsend_time64 4418
#define __NR_mq_unlink 4272
#define __NR_mremap 4167
+#define __NR_mseal 4462
#define __NR_msgctl 4402
#define __NR_msgget 4399
#define __NR_msgrcv 4401
@@ -2909,6 +2909,7 @@ GLIBC_2.4 renameat F
GLIBC_2.4 symlinkat F
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -194,6 +194,7 @@
#define __NR_mq_timedsend_time64 6418
#define __NR_mq_unlink 6235
#define __NR_mremap 6024
+#define __NR_mseal 6462
#define __NR_msgctl 6069
#define __NR_msgget 6066
#define __NR_msgrcv 6068
@@ -2915,6 +2915,7 @@ GLIBC_2.4 renameat F
GLIBC_2.4 symlinkat F
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -183,6 +183,7 @@
#define __NR_mq_timedsend 5232
#define __NR_mq_unlink 5231
#define __NR_mremap 5024
+#define __NR_mseal 5462
#define __NR_msgctl 5069
#define __NR_msgget 5066
#define __NR_msgrcv 5068
@@ -2817,6 +2817,7 @@ GLIBC_2.4 renameat F
GLIBC_2.4 symlinkat F
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -167,6 +167,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2873,3 +2873,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -167,6 +167,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2257,5 +2257,6 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 getcontext F
GLIBC_2.40 makecontext F
+GLIBC_2.40 mseal F
GLIBC_2.40 setcontext F
GLIBC_2.40 swapcontext F
@@ -211,6 +211,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 263
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -3138,6 +3138,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3183,6 +3183,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -195,6 +195,7 @@
#define __NR_mq_timedsend 264
#define __NR_mq_unlink 263
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -2892,6 +2892,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2968,3 +2968,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F
@@ -153,6 +153,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2512,3 +2512,4 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
+GLIBC_2.40 mseal F
@@ -158,6 +158,7 @@
#define __NR_mq_timedsend 182
#define __NR_mq_unlink 181
#define __NR_mremap 216
+#define __NR_mseal 462
#define __NR_msgctl 187
#define __NR_msgget 186
#define __NR_msgrcv 188
@@ -2712,3 +2712,4 @@ GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
+GLIBC_2.40 mseal F
@@ -214,6 +214,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 272
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -3136,6 +3136,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -185,6 +185,7 @@
#define __NR_mq_timedsend 273
#define __NR_mq_unlink 272
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -2929,6 +2929,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -206,6 +206,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 278
#define __NR_mremap 163
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -2828,6 +2828,7 @@ GLIBC_2.4 sys_errlist D 0x210
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2825,6 +2825,7 @@ GLIBC_2.4 sys_errlist D 0x210
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -211,6 +211,7 @@
#define __NR_mq_timedsend_time64 418
#define __NR_mq_unlink 274
#define __NR_mremap 250
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -3157,6 +3157,7 @@ GLIBC_2.4 wcstold F
GLIBC_2.4 wcstold_l F
GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -192,6 +192,7 @@
#define __NR_mq_timedsend 275
#define __NR_mq_unlink 274
#define __NR_mremap 250
+#define __NR_mseal 462
#define __NR_msgctl 402
#define __NR_msgget 399
#define __NR_msgrcv 401
@@ -2793,6 +2793,7 @@ GLIBC_2.4 sys_errlist D 0x430
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -287,6 +287,7 @@ mq_timedsend
mq_timedsend_time64
mq_unlink
mremap
+mseal
msgctl
msgget
msgrcv
@@ -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
new file mode 100644
@@ -0,0 +1,67 @@
+/* Basic tests for mseal.
+ Copyright (C) 2024 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)
+ 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>
@@ -189,6 +189,7 @@
#define __NR_mq_timedsend 242
#define __NR_mq_unlink 241
#define __NR_mremap 25
+#define __NR_mseal 462
#define __NR_msgctl 71
#define __NR_msgget 68
#define __NR_msgrcv 70
@@ -2744,6 +2744,7 @@ GLIBC_2.4 sys_errlist D 0x420
GLIBC_2.4 sys_nerr D 0x4
GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
+GLIBC_2.40 mseal F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -182,6 +182,7 @@
#define __NR_mq_timedsend 1073742066
#define __NR_mq_unlink 1073742065
#define __NR_mremap 1073741849
+#define __NR_mseal 1073742286
#define __NR_msgctl 1073741895
#define __NR_msgget 1073741892
#define __NR_msgrcv 1073741894
@@ -2763,3 +2763,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
GLIBC_2.39 stdc_trailing_zeros_ul F
GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 mseal F