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-01-17 16:54:06 -0300
commitf432aca665be33bef98c42b450c1f1402430cabd (patch)
treee0c9ae6a04f94483337d44ee93097f9ab030d5ba
parente6800f0ee428173402c5cca991e4504193e22bdf (diff)
downloadglibc-azanella/memory-seal-v5.zip
glibc-azanella/memory-seal-v5.tar.gz
glibc-azanella/memory-seal-v5.tar.bz2
linux: Add memory sealing testsazanella/memory-seal-v5
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/Makefile97
-rw-r--r--sysdeps/unix/sysv/linux/dl-mseal.c2
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod-noseal.c1
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c23
-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-noseal.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-noseal.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-noseal.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-noseal.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.c80
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-preload-noseal.c1
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c19
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c276
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c45
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal-static.c42
-rw-r--r--sysdeps/unix/sysv/linux/tst-dl_mseal.c78
21 files changed, 853 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index ac67b98..670ed45 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -685,6 +685,103 @@ tests-special += \
$(objpfx)tst-nolink-libc-1.out \
$(objpfx)tst-nolink-libc-2.out \
# tests-special
+
+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-auditmod-noseal \
+ 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-dlopen-2-1-noseal \
+ tst-dl_mseal-dlopen-2-noseal \
+ tst-dl_mseal-mod-1 \
+ tst-dl_mseal-mod-1-noseal \
+ tst-dl_mseal-mod-2 \
+ tst-dl_mseal-mod-2-noseal \
+ tst-dl_mseal-preload \
+ tst-dl_mseal-preload-noseal \
+ # 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-noseal.so \
+ $(objpfx)tst-dl_mseal-preload-noseal.so \
+ $(objpfx)tst-dl_mseal-mod-1-noseal.so \
+ $(objpfx)tst-dl_mseal-mod-2-noseal.so \
+ $(objpfx)tst-dl_mseal-dlopen-1.so \
+ $(objpfx)tst-dl_mseal-dlopen-1-1.so \
+ $(objpfx)tst-dl_mseal-dlopen-2-noseal.so \
+ $(objpfx)tst-dl_mseal-dlopen-2-1-noseal.so
+
+ifeq ($(default-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-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-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
+
+tst-dl_mseal-noseal-no-memory-seal = yes
+tst-dl_mseal-preload-noseal.so-no-memory-seal = yes
+tst-dl_mseal-auditmod-noseal.so-no-memory-seal = yes
+tst-dl_mseal-mod-2-noseal.so-no-memory-seal = yes
+tst-dl_mseal-dlopen-2-noseal.so-no-memory-seal =yes
+
+LDFLAGS-tst-dl_mseal-noseal = -Wl,--no-as-needed
+LDFLAGS-tst-dl_mseal-mod-1-noseal.so = -Wl,--no-as-needed -Wl,-z,memory-seal
+LDFLAGS-tst-dl_mseal-mod-2-noseal.so = -Wl,--no-as-needed
+LDFLAGS-tst-dl_mseal-dlopen-2-noseal.so = -Wl,--no-as-needed
+
+tst-dl_mseal-dlopen-2-1-noseal.so-no-memory-seal = yes
+
+$(objpfx)tst-dl_mseal-noseal: $(objpfx)tst-dl_mseal-mod-1-noseal.so
+$(objpfx)tst-dl_mseal-mod-1-noseal.so: $(objpfx)tst-dl_mseal-mod-2-noseal.so
+$(objpfx)tst-dl_mseal-dlopen-2-noseal.so: $(objpfx)tst-dl_mseal-dlopen-2-1-noseal.so
+
+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
endif # $(subdir) == elf
diff --git a/sysdeps/unix/sysv/linux/dl-mseal.c b/sysdeps/unix/sysv/linux/dl-mseal.c
index 2c2b430..b4098a8 100644
--- a/sysdeps/unix/sysv/linux/dl-mseal.c
+++ b/sysdeps/unix/sysv/linux/dl-mseal.c
@@ -46,6 +46,6 @@ _dl_mseal (void *addr, size_t len, const char *object)
{
static const char errstring[] = N_("\
cannot apply memory sealing");
- _dl_signal_error (-r, object, NULL, errstring);
+ _dl_signal_error (-r, DSO_FILENAME (object), NULL, errstring);
}
}
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod-noseal.c
new file mode 100644
index 0000000..a5b257d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod-noseal.c
@@ -0,0 +1 @@
+#include "tst-dl_mseal-auditmod.c"
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 0000000..d909a15
--- /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) 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/>. */
+
+unsigned int
+la_version (unsigned int v)
+{
+ return v;
+}
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 0000000..ef1372f
--- /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) 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 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 0000000..3c2cbe6
--- /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) 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 foo2 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1-noseal.c
new file mode 100644
index 0000000..0cd647d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1-noseal.c
@@ -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 bar2_1 (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 0000000..0cd647d
--- /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) 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 bar2_1 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-noseal.c
new file mode 100644
index 0000000..f719dd3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-noseal.c
@@ -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 bar2 (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 0000000..f719dd3
--- /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) 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 bar2 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1-noseal.c
new file mode 100644
index 0000000..3bd188e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1-noseal.c
@@ -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 foo1 (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 0000000..3bd188e
--- /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) 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 foo1 (void) { return 42; }
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2-noseal.c
new file mode 100644
index 0000000..636e977
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2-noseal.c
@@ -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 bar1 (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 0000000..636e977
--- /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) 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 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 0000000..cf3add4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-noseal.c
@@ -0,0 +1,80 @@
+/* Basic tests for sealing.
+ 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 <gnu/lib-names.h>
+
+/* This test checks the GNU_PROPERTY_MEMORY_SEAL handling on multiple
+ places:
+
+ - On the binary itself.
+ - On a LD_PRELOAD library.
+ - On a depedency module (tst-dl_mseal-mod-2-noseal.so).
+ - On a audit modules (tst-dl_mseal-auditmod-noeal.so).
+ - On a dlopen dependency opened with RTLD_NODELET
+ (tst-dl_mseal-dlopen-2-noseal.so).
+*/
+
+#define LIB_PRELOAD "tst-dl_mseal-preload-noseal.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-noseal.so"
+#define LIB_DLOPEN_NODELETE_DEP "tst-dl_mseal-dlopen-2-1-noseal.so"
+
+#define LIB_AUDIT "tst-dl_mseal-auditmod-noseal.so"
+
+/* Expected libraries that loader will seal. */
+static const char *expected_sealed_vmas[] =
+{
+#ifdef DEFAULT_MEMORY_SEAL
+ "libc.so",
+ "ld.so",
+#endif
+ "tst-dl_mseal-mod-1-noseal.so",
+};
+
+/* Expected non sealed libraries. */
+static const char *expected_non_sealed_vmas[] =
+{
+#ifndef DEFAULT_MEMORY_SEAL
+ "libc.so",
+ "ld.so",
+#endif
+ "tst-dl_mseal-noseal",
+ LIB_PRELOAD,
+ LIB_AUDIT,
+ "tst-dl_mseal-mod-2-noseal.so",
+ LIB_DLOPEN_NODELETE,
+ LIB_DLOPEN_NODELETE_DEP,
+ LIB_DLOPEN_DEFAULT,
+ LIB_DLOPEN_DEFAULT_DEP,
+ /* Auxiary 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]",
+};
+
+#include "tst-dl_mseal-skeleton.c"
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-preload-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-preload-noseal.c
new file mode 100644
index 0000000..32b4153
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-preload-noseal.c
@@ -0,0 +1 @@
+#include "tst-dl_mseal-preload.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 0000000..7831608
--- /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) 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; }
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 0000000..07cc18d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c
@@ -0,0 +1,276 @@
+/* Basic tests for sealing.
+ 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 <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/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xthread.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 void *
+tf (void *closure)
+{
+ pthread_exit (NULL);
+ return NULL;
+}
+
+static int
+handle_restart (void)
+{
+#ifndef TEST_STATIC
+ xdlopen (LIB_DLOPEN_NODELETE, RTLD_NOW | RTLD_NODELETE);
+ xdlopen (LIB_DLOPEN_DEFAULT, RTLD_NOW);
+#endif
+
+ /* pthread_exit will load LIBGCC_S_SO. */
+ xpthread_join (xpthread_create (NULL, tf, NULL));
+
+ FILE *fp = xfopen ("/proc/self/maps", "r");
+ char *line = NULL;
+ size_t linesiz = 0;
+
+ unsigned long pagesize = getpagesize ();
+
+ bool found_expected[array_length(expected_sealed_vmas)] = { false };
+ while (xgetline (&line, &linesiz, fp) > 0)
+ {
+ uintptr_t start;
+ uintptr_t end;
+ char flags[5] = { 0 };
+ char name[256] = { 0 };
+ int idx;
+
+ /* The line is in the form:
+ start-end flags offset dev inode pathname */
+ int r = sscanf (line,
+ "%" SCNxPTR "-%" SCNxPTR " %4s %*s %*s %*s %256s",
+ &start,
+ &end,
+ flags,
+ name);
+ TEST_VERIFY_EXIT (r == 3 || r == 4);
+
+ int found = false;
+
+ const char *libname = basename (name);
+ if ((idx = IS_IN_STRING_LIST (libname, expected_sealed_vmas))
+ != -1)
+ {
+ /* Check if we can change the protection flags of the segment. */
+ int new_prot = new_flags (flags);
+ TEST_VERIFY_EXIT (mprotect ((void *) start, end - start,
+ new_prot) == -1);
+ TEST_VERIFY_EXIT (errno == EPERM);
+
+ /* Also checks trying to map over the sealed libraries. */
+ {
+ char *p = mmap ((void *) start, pagesize, new_prot,
+ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ TEST_VERIFY_EXIT (p == MAP_FAILED);
+ TEST_VERIFY_EXIT (errno == EPERM);
+ }
+
+ /* And if remap is also blocked. */
+ {
+ char *p = mremap ((void *) start, end - start, end - start, 0);
+ TEST_VERIFY_EXIT (p == MAP_FAILED);
+ TEST_VERIFY_EXIT (errno == EPERM);
+ }
+
+ printf ("sealed: vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n",
+ start,
+ end,
+ flags,
+ name);
+
+ found_expected[idx] = true;
+ found = true;
+ }
+ else if ((idx = IS_IN_STRING_LIST (libname, expected_non_sealed_vmas))
+ != -1)
+ {
+ /* Check if expected non-sealed segments protection can indeed be
+ changed. The idea is to use something that would not break
+ process execution, so just try to mprotect with all protection
+ bits. */
+ int new_prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+ TEST_VERIFY_EXIT (mprotect ((void *) start, end - start, new_prot)
+ == 0);
+
+ printf ("not-sealed: vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n",
+ start,
+ end,
+ flags,
+ name);
+
+ found = true;
+ }
+ else if (IS_IN_STRING_LIST (libname, expected_non_sealed_special) != -1)
+ {
+ /* These pages protection can no be changed. */
+ found = true;
+ }
+
+ if (!found)
+ {
+ if (IS_IN_STRING_LIST (libname, non_sealed_vmas) != -1)
+ printf ("not-sealed: vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n",
+ start,
+ end,
+ flags,
+ name);
+ else
+ FAIL_EXIT1 ("unexpected vma: %" PTR_FMT "-%" PTR_FMT " %s %s\n",
+ start,
+ end,
+ flags,
+ name);
+ }
+ }
+ xfclose (fp);
+
+ printf ("\n");
+
+ /* Also check if all the expected sealed maps were found. */
+ for (int i = 0; i < array_length (expected_sealed_vmas); i++)
+ if (expected_sealed_vmas[i][0] && !found_expected[i])
+ FAIL_EXIT1 ("expected VMA %s not sealed\n", expected_sealed_vmas[i]);
+
+ return 0;
+}
+
+static int restart;
+#define CMDLINE_OPTIONS \
+ { "restart", no_argument, &restart, 1 },
+
+static int
+do_test (int argc, char *argv[])
+{
+ /* We must have either:
+ - One or four parameters left if called initially:
+ + path to ld.so optional
+ + "--library-path" optional
+ + the library path optional
+ + the application name */
+ if (restart)
+ return handle_restart ();
+
+ /* Check the test requirements. */
+ {
+ int r = mseal (NULL, 0, 0);
+ if (r == -1 && (errno == ENOSYS || errno == EPERM))
+ FAIL_UNSUPPORTED ("mseal is not supported by the kernel");
+ else
+ TEST_VERIFY_EXIT (r == 0);
+ }
+ support_need_proc ("Reads /proc/self/maps to get stack names.");
+
+ char *spargv[9];
+ int i = 0;
+ for (; i < argc - 1; i++)
+ spargv[i] = argv[i + 1];
+ spargv[i++] = (char *) "--direct";
+ spargv[i++] = (char *) "--restart";
+ spargv[i] = NULL;
+
+ char *envvarss[] = {
+#ifndef TEST_STATIC
+ (char *) "LD_PRELOAD=" LIB_PRELOAD,
+ (char *) "LD_AUDIT=" LIB_AUDIT,
+#endif
+ NULL
+ };
+
+ struct support_capture_subprocess result =
+ support_capture_subprogram (spargv[0], spargv, envvarss);
+ support_capture_subprocess_check (&result, "tst-dl_mseal", 0,
+ sc_allow_stdout);
+
+ {
+ FILE *out = fmemopen (result.out.buffer, result.out.length, "r");
+ TEST_VERIFY (out != NULL);
+ char *line = NULL;
+ size_t linesz = 0;
+ while (xgetline (&line, &linesz, out))
+ printf ("%s", line);
+ fclose (out);
+ }
+
+ support_capture_subprocess_free (&result);
+
+ return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c
new file mode 100644
index 0000000..3a52ee2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-static-noseal.c
@@ -0,0 +1,45 @@
+/* Basic tests for sealing. Static version.
+ 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/>. */
+
+/* This test checks the GNU_PROPERTY_MEMORY_SEAL handling on a statically
+ built binary. In this case only the vDSO (if existent) will be sealed. */
+
+#define TEST_STATIC 1
+
+/* Expected libraries that loader will seal. */
+static const char *expected_sealed_vmas[] =
+{
+ "",
+};
+
+/* Expected non sealed libraries. */
+static const char *expected_non_sealed_vmas[] =
+{
+ "tst-dl_mseal-static-noseal",
+ /* Auxiary pages mapped by the kernel. */
+ "[vdso]",
+ "[sigpage]",
+};
+
+/* Auxiliary kernel pages where permission can not be changed. */
+static const char *expected_non_sealed_special[] =
+{
+ "[vectors]",
+};
+
+#include "tst-dl_mseal-skeleton.c"
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-static.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-static.c
new file mode 100644
index 0000000..c0d82bc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-static.c
@@ -0,0 +1,42 @@
+/* Basic tests for sealing. Static version.
+ 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/>. */
+
+/* This test checks the memory sealing work on a statically built binary. */
+
+#define TEST_STATIC 1
+
+/* Expected libraries that loader will seal. */
+static const char *expected_sealed_vmas[] =
+{
+ "tst-dl_mseal-static",
+};
+
+/* Auxiliary pages mapped by the kernel. */
+static const char *expected_non_sealed_vmas[] =
+{
+ "[vdso]",
+ "[sigpage]",
+};
+
+/* Auxiliary kernel pages where permission can not be changed. */
+static const char *expected_non_sealed_special[] =
+{
+ "[vectors]",
+};
+
+#include "tst-dl_mseal-skeleton.c"
diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal.c
new file mode 100644
index 0000000..0c3b121
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-dl_mseal.c
@@ -0,0 +1,78 @@
+/* Basic tests for sealing.
+ 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 <gnu/lib-names.h>
+
+/* Check if 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_NODELET
+ (tst-dl_mseal-dlopen-{2,2-1}.so).
+ - On the libgcc_s opened by thread unwind.
+*/
+
+#define LIB_PRELOAD "tst-dl_mseal-preload.so"
+#define LIB_AUDIT "tst-dl_mseal-auditmod.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"
+
+/* Expected libraries that loader will seal. */
+static const char *expected_sealed_vmas[] =
+{
+#ifdef DEFAULT_MEMORY_SEAL
+ "libc.so",
+ "ld.so",
+#endif
+ "tst-dl_mseal",
+ "tst-dl_mseal-mod-1.so",
+ "tst-dl_mseal-mod-2.so",
+ LIB_PRELOAD,
+ LIB_AUDIT,
+ LIB_DLOPEN_NODELETE,
+};
+
+/* Expected non sealed libraries. */
+static const char *expected_non_sealed_vmas[] =
+{
+#ifndef DEFAULT_MEMORY_SEAL
+ "libc.so",
+ "ld.so",
+#endif
+ LIB_DLOPEN_DEFAULT,
+ LIB_DLOPEN_DEFAULT_DEP,
+ LIB_DLOPEN_NODELETE_DEP,
+ /* Auxiary 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]",
+};
+
+#include "tst-dl_mseal-skeleton.c"