aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2024-12-06 14:37:56 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2025-03-07 08:46:49 -0300
commit815beee47c1c42e1b7bd5a1ce7b6a34c2013d3dc (patch)
treef3d76eb25b1d2db31216b101b17db01c9f9f6242
parent7fec24327c3aae29bdbc2d82c186b0d06bf33c9a (diff)
downloadglibc-815beee47c1c42e1b7bd5a1ce7b6a34c2013d3dc.tar.xz
glibc-815beee47c1c42e1b7bd5a1ce7b6a34c2013d3dc.zip
linux: Add memory sealing tests
The new tests added are: 1. tst-dl_mseal: check memory sealing is applied for statically linked binaries. 2. tst-dl_mseal-static: memory sealing is not applied if there is no gnu attribute for statically linked binaries. 3. tst-dl-mseal: check memory sealing works as expected on multiples places: - On the binary itself. - On a LD_PRELOAD library. - On a depedency modules (tst-dl_mseal-mod-{1,2}.so). - On a audit modules (tst-dl_mseal-auditmod.so). - On a dlopen dependency opened with RTLD_NODELETE). - On the libgcc_s Aopened by thread unwind. 4. tst-dl-mseal-noseal: check if mixing object with and without memory sealing works as expected. Checked on x86_64-linux-gnu and aarch64-linux-gnu.
-rw-r--r--sysdeps/unix/sysv/linux/Makefile78
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c23
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-common.h29
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c90
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c263
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c59
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-static.c56
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal.c92
15 files changed, 823 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index a72635e340..8fe74be95f 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -687,6 +687,84 @@ tests-special += \
$(objpfx)tst-nolink-libc-2.out \
# tests-special
endif
+
+ifeq ($(have-z-memory-seal),yes)
+tests-static += \
+ tst-dl_mseal-static \
+ tst-dl_mseal-static-noseal \
+ # tests-static
+
+tests += \
+ $(tests-static) \
+ tst-dl_mseal \
+ tst-dl_mseal-noseal \
+ # tests
+
+modules-names += \
+ tst-dl_mseal-auditmod \
+ tst-dl_mseal-dlopen-1 \
+ tst-dl_mseal-dlopen-1-1 \
+ tst-dl_mseal-dlopen-2 \
+ tst-dl_mseal-dlopen-2-1 \
+ tst-dl_mseal-mod-1 \
+ tst-dl_mseal-mod-2 \
+ tst-dl_mseal-preload \
+ # modules-names
+
+$(objpfx)tst-dl_mseal.out: \
+ $(objpfx)tst-dl_mseal-auditmod.so \
+ $(objpfx)tst-dl_mseal-preload.so \
+ $(objpfx)tst-dl_mseal-mod-1.so \
+ $(objpfx)tst-dl_mseal-mod-2.so \
+ $(objpfx)tst-dl_mseal-dlopen-1.so \
+ $(objpfx)tst-dl_mseal-dlopen-1-1.so \
+ $(objpfx)tst-dl_mseal-dlopen-2.so \
+ $(objpfx)tst-dl_mseal-dlopen-2-1.so
+
+$(objpfx)tst-dl_mseal-noseal.out: \
+ $(objpfx)tst-dl_mseal-auditmod.so \
+ $(objpfx)tst-dl_mseal-preload.so \
+ $(objpfx)tst-dl_mseal-mod-1.so \
+ $(objpfx)tst-dl_mseal-mod-2.so \
+ $(objpfx)tst-dl_mseal-dlopen-1.so \
+ $(objpfx)tst-dl_mseal-dlopen-1-1.so \
+ $(objpfx)tst-dl_mseal-dlopen-2.so \
+ $(objpfx)tst-dl_mseal-dlopen-2-1.so
+
+ifeq ($(enable-memory-seal),yes)
+CFLAGS-tst-dl_mseal.c += -DDEFAULT_MEMORY_SEAL
+CFLAGS-tst-dl_mseal-noseal.c += -DDEFAULT_MEMORY_SEAL
+endif
+
+LDFLAGS-tst-dl_mseal = -Wl,--no-as-needed -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-static = -Wl,--no-as-needed -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-mod-1.so = -Wl,--no-as-needed -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-mod-2.so = -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-dlopen-1.so = -Wl,--no-as-needed
+LDFLAGS-tst-dl_mseal-dlopen-2.so = -Wl,--no-as-needed -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-preload.so = -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-auditmod.so = -Wl,-z,memory-seal
+
+tst-dl_mseal-noseal-no-memory-seal = yes
+tst-dl_mseal-dlopen-1-1.so-no-memory-seal = yes
+tst-dl_mseal-dlopen-2-1.so-no-memory-seal = yes
+
+$(objpfx)tst-dl_mseal: $(objpfx)tst-dl_mseal-mod-1.so
+$(objpfx)tst-dl_mseal-noseal: $(objpfx)tst-dl_mseal-mod-1.so
+$(objpfx)tst-dl_mseal-mod-1.so: $(objpfx)tst-dl_mseal-mod-2.so
+$(objpfx)tst-dl_mseal-dlopen-1.so: $(objpfx)tst-dl_mseal-dlopen-1-1.so
+$(objpfx)tst-dl_mseal-dlopen-2.so: $(objpfx)tst-dl_mseal-dlopen-2-1.so
+
+LDFLAGS-tst-dl_mseal-noseal = -Wl,--no-as-needed
+
+tst-dl_mseal-static-noseal-no-memory-seal = yes
+
+tst-dl_mseal-ARGS = -- $(host-test-program-cmd)
+tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd)
+tst-dl_mseal-noseal-ARGS = -- $(host-test-program-cmd)
+tst-dl_mseal-static-noseal-ARGS = -- $(host-test-program-cmd)
+endif
+
endif # $(subdir) == elf
ifeq ($(subdir),rt)
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c
new file mode 100644
index 0000000000..7767620456
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c
@@ -0,0 +1,23 @@
+/* Audit module for tst-dl_mseal test.
+ 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/>. */
+
+unsigned int
+la_version (unsigned int v)
+{
+ return v;
+}
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-common.h b/sysdeps/unix/sysv/linux/tst-dl_mseal-common.h
new file mode 100644
index 0000000000..4e2461b889
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-common.h
@@ -0,0 +1,29 @@
+/* Basic tests for sealing.
+ 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/>. */
+
+#define LIB_PRELOAD "tst-dl_mseal-preload.so"
+
+#define LIB_AUDIT "tst-dl_mseal-auditmod.so"
+
+#define LIB_MODULE1 "tst-dl_mseal-mod-1.so"
+#define LIB_MODULE1_DEP "tst-dl_mseal-mod-2.so"
+
+#define LIB_DLOPEN_DEFAULT "tst-dl_mseal-dlopen-1.so"
+#define LIB_DLOPEN_DEFAULT_DEP "tst-dl_mseal-dlopen-1-1.so"
+#define LIB_DLOPEN_NODELETE "tst-dl_mseal-dlopen-2.so"
+#define LIB_DLOPEN_NODELETE_DEP "tst-dl_mseal-dlopen-2-1.so"
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c
new file mode 100644
index 0000000000..fd116536ee
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int foo2_1 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c
new file mode 100644
index 0000000000..aa7a18390e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int foo2 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c
new file mode 100644
index 0000000000..dc3d832343
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int bar2_1 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c
new file mode 100644
index 0000000000..6be7ce4d3d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int bar2 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c
new file mode 100644
index 0000000000..e8e42de5bf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int foo1 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c
new file mode 100644
index 0000000000..05226a443d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int bar1 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c
new file mode 100644
index 0000000000..686347c86e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c
@@ -0,0 +1,90 @@
+/* Basic tests for sealing.
+ 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 <support/xdlfcn.h>
+#include <support/xthread.h>
+#include <gnu/lib-names.h>
+
+/* Check if memory sealing is not applied if program does not have the
+ GNU_PROPERTY_MEMORY_SEAL attribute. It included:
+ - On the binary itself.
+ - On a LD_PRELOAD library.
+ - On a dependency modules (tst-dl_mseal-mod-{1,2}.so).
+ - On a audit modules (tst-dl_mseal-auditmod.so).
+ - On a dlopen dependency opened with RTLD_NODELETE
+ (tst-dl_mseal-dlopen-{2,2-1}.so).
+ - On the libgcc_s opened by thread unwind. */
+
+#include "tst-dl_mseal-common.h"
+
+/* Expected libraries that loader will seal. */
+static const char *expected_sealed_vmas[] =
+{
+ "",
+};
+
+/* Expected non sealed libraries. */
+static const char *expected_non_sealed_vmas[] =
+{
+ "libc.so",
+ "ld.so",
+ "tst-dl_mseal-noseal",
+ LIB_PRELOAD,
+ LIB_AUDIT,
+ LIB_MODULE1,
+ LIB_MODULE1_DEP,
+ LIB_DLOPEN_NODELETE,
+ LIB_DLOPEN_NODELETE_DEP,
+ LIB_DLOPEN_DEFAULT,
+ LIB_DLOPEN_DEFAULT_DEP,
+ /* Auxiliary pages mapped by the kernel. */
+ "[vdso]",
+ "[sigpage]",
+};
+
+/* Special pages, either Auxiliary kernel pages where permission can not be
+ changed or auxiliary libs that we can know prior hand that sealing is
+ enabled. */
+static const char *expected_non_sealed_special[] =
+{
+ LIBGCC_S_SO,
+ "[vectors]",
+};
+
+static void *
+tf (void *closure)
+{
+ pthread_exit (NULL);
+ return NULL;
+}
+
+static void
+run_extra_steps (void)
+{
+ /* dlopen should work even if the modules contains the sealing attribute. */
+ xdlopen (LIB_DLOPEN_NODELETE, RTLD_NOW | RTLD_NODELETE);
+ xdlopen (LIB_DLOPEN_DEFAULT, RTLD_NOW);
+
+ /* pthread_exit will load LIBGCC_S_SO. */
+ xpthread_join (xpthread_create (NULL, tf, NULL));
+}
+
+#define LD_PRELOAD LIB_PRELOAD
+#define LD_AUDIT LIB_AUDIT
+
+#include "tst-dl_mseal-skeleton.c"
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c
new file mode 100644
index 0000000000..414c8c7295
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c
@@ -0,0 +1,19 @@
+/* Additional module for tst-dl_mseal test.
+ 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/>. */
+
+int foo (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c
new file mode 100644
index 0000000000..570a0a867d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c
@@ -0,0 +1,263 @@
+/* Basic tests for memory sealing.
+ 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 <array_length.h>
+#include <errno.h>
+#include <getopt.h>
+#include <inttypes.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xstdio.h>
+
+#if UINTPTR_MAX == UINT64_MAX
+# define PTR_FMT "#018" PRIxPTR
+#else
+# define PTR_FMT "#010" PRIxPTR
+#endif
+
+static int
+new_flags (const char flags[4])
+{
+ bool read_flag = flags[0] == 'r';
+ bool write_flag = flags[1] == 'w';
+ bool exec_flag = flags[2] == 'x';
+
+ write_flag = !write_flag;
+
+ return (read_flag ? PROT_READ : 0)
+ | (write_flag ? PROT_WRITE : 0)
+ | (exec_flag ? PROT_EXEC : 0);
+}
+
+/* Libraries/VMA that could not be sealed, and that checking for sealing
+ does not work (kernel does not allow changing protection). */
+static const char *non_sealed_vmas[] =
+{
+ ".", /* basename value for empty string anonymous
+ mappings. */
+ "[heap]",
+ "[vsyscall]",
+ "[vvar]",
+ "[stack]",
+ "[vvar_vclock]",
+ "zero", /* /dev/zero */
+};
+
+static int
+is_in_string_list (const char *s, const char *const list[], size_t len)
+{
+ for (size_t i = 0; i != len; i++)
+ if (strcmp (s, list[i]) == 0)
+ return i;
+ return -1;
+}
+#define IS_IN_STRING_LIST(__s, __list) \
+ is_in_string_list (__s, __list, array_length (__list))
+
+static int
+handle_restart