diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2024-07-08 16:38:10 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2024-07-31 17:02:05 -0300 |
commit | 52ddeb99b2db8247a7095ae1354acb3ca3e4ea4a (patch) | |
tree | 483786f0c7d72de96b718a3902e493ec26eb2dfe /sysdeps/unix/sysv | |
parent | 8d2a331b64c8d299d11826058c43d29643cf6b86 (diff) | |
download | glibc-azanella/mseal.tar.gz glibc-azanella/mseal.tar.xz glibc-azanella/mseal.zip |
elf: Add support for GNU_PROPERTY_NO_MEMORY_SEAL azanella/mseal
The GNU_PROPERTY_NO_MEMORY_SEAL is a GNU property per module instructing the glibc not to seal the object PT_LOAD. It can be used for any reason the modules require to seal not to be enabled (i.e., on Firefox hack to bypass the dynamic loader and enable DT_RELR on older glibc [1]). In this case, it is up to the module to apply memory sealing itself. The sealing is applied by default, and it is always enforced with glibc.rtld.seal=2. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and powerpc64le-linux-gnu. [1] https://glandium.org/blog/?p=4297
Diffstat (limited to 'sysdeps/unix/sysv')
11 files changed, 230 insertions, 5 deletions
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 3161363db1..c82aeb3403 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -685,6 +685,52 @@ $(objpfx)tst-dl_mseal-dlopen-2.so: $(objpfx)tst-dl_mseal-dlopen-2-1.so LDFLAGS-tst-dl_mseal-dlopen-2.so = -Wl,--no-as-needed tst-dl_mseal-static-ARGS = -- $(host-test-program-cmd) + +ifeq ($(have-z-no-memory-seal),yes) +tests-static += \ + tst-dl_mseal-static-no-memory-seal \ + # tests-static + +tests += \ + tst-dl_mseal-no-memory-seal \ + tst-dl_mseal-static-no-memory-seal \ + # tests + +modules-names += \ + tst-dl_mseal-dlopen-no-memory-seal-2 \ + tst-dl_mseal-dlopen-no-memory-seal-2-1 \ + tst-dl_mseal-mod-no-memory-seal-1 \ + tst-dl_mseal-mod-no-memory-seal-2 \ + tst-dl_mseal-no-memory-seal-auditmod \ + tst-dl_mseal-no-memory-seal-preload \ + # modules-names + +$(objpfx)tst-dl_mseal-no-memory-seal.out: \ + $(objpfx)tst-dl_mseal-no-memory-seal-auditmod.so \ + $(objpfx)tst-dl_mseal-no-memory-seal-preload.so \ + $(objpfx)tst-dl_mseal-mod-no-memory-seal-1.so \ + $(objpfx)tst-dl_mseal-mod-no-memory-seal-2.so \ + $(objpfx)tst-dl_mseal-dlopen-1.so \ + $(objpfx)tst-dl_mseal-dlopen-1-1.so \ + $(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2.so \ + $(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2-1.so + +tst-dl_mseal-no-memory-seal-ARGS = -- $(host-test-program-cmd) + +LDFLAGS-tst-dl_mseal-no-memory-seal-preload.so = -Wl,-z,no-memory-seal + +LDFLAGS-tst-dl_mseal-no-memory-seal-auditmod.so = -Wl,-z,no-memory-seal +$(objpfx)tst-dl_mseal-no-memory-seal: $(objpfx)tst-dl_mseal-mod-no-memory-seal-1.so +LDFLAGS-tst-dl_mseal-no-memory-seal = -Wl,-z,no-memory-seal -Wl,--no-as-needed +$(objpfx)tst-dl_mseal-mod-no-memory-seal-1.so: $(objpfx)tst-dl_mseal-mod-no-memory-seal-2.so +LDFLAGS-tst-dl_mseal-mod-no-memory-seal-1.so = -Wl,--no-as-needed +LDFLAGS-tst-dl_mseal-mod-no-memory-seal-2.so = -Wl,-z,no-memory-seal -Wl,--no-as-needed +$(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2.so: $(objpfx)tst-dl_mseal-dlopen-no-memory-seal-2-1.so +LDFLAGS-tst-dl_mseal-dlopen-no-memory-seal-2.so = -Wl,--no-as-needed -Wl,-z,no-memory-seal + +LDFLAGS-tst-dl_mseal-static-no-memory-seal = -Wl,-z,no-memory-seal +tst-dl_mseal-static-no-memory-seal-ARGS = -- $(host-test-program-cmd) +endif endif ifeq ($(subdir),rt) diff --git a/sysdeps/unix/sysv/linux/dl-mseal.h b/sysdeps/unix/sysv/linux/dl-mseal.h index 89b19e33c4..25e3f724dc 100644 --- a/sysdeps/unix/sysv/linux/dl-mseal.h +++ b/sysdeps/unix/sysv/linux/dl-mseal.h @@ -25,5 +25,3 @@ Return 0 in case of success or a negative value otherwise (a negative errno). */ int _dl_mseal (void *addr, size_t len) attribute_hidden; - -#define SUPPORT_MSEAL lt_seal_toseal diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-2-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-2-1.c new file mode 100644 index 0000000000..0cd647de46 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-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-no-memory-seal-2.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-2.c new file mode 100644 index 0000000000..f719dd3cba --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-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-no-memory-seal-1.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-1.c new file mode 100644 index 0000000000..3bd188efe8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-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-no-memory-seal-2.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-2.c new file mode 100644 index 0000000000..636e9777af --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-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-no-memory-seal-auditmod.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-auditmod.c new file mode 100644 index 0000000000..a5b257d05e --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-auditmod.c @@ -0,0 +1 @@ +#include "tst-dl_mseal-auditmod.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-preload.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-preload.c new file mode 100644 index 0000000000..32b4153e79 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-preload.c @@ -0,0 +1 @@ +#include "tst-dl_mseal-preload.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal.c new file mode 100644 index 0000000000..014a8e76c7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal.c @@ -0,0 +1,65 @@ +/* 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_NO_MEMORY_SEAL handling on multiple + places: + + - On the binary itself. + - On a LD_PRELOAD library. + - On a depedency module (tst-dl_mseal-mod-no-memory-seal-2.so). + - On a audit modules (tst-dl_mseal-no-memory-seal-auditmod.so). + - On a dlopen dependency opened with RTLD_NODELET + (tst-dl_mseal-dlopen-no-memory-seal-2.so). +*/ + +#define LIB_PRELOAD "tst-dl_mseal-no-memory-seal-preload.so" +#define GLIBC_RTLD_SEAL "1" + +#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-no-memory-seal-2.so" +#define LIB_DLOPEN_NODELETE_DEP "tst-dl_mseal-dlopen-no-memory-seal-2-1.so" + +#define LIB_AUDIT "tst-dl_mseal-no-memory-seal-auditmod.so" + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_libs[] = +{ + "libc.so", + "ld.so", + "tst-dl_mseal-mod-no-memory-seal-1.so", + LIB_DLOPEN_NODELETE_DEP, + LIBGCC_S_SO, +}; + +/* Expected non sealed libraries. */ +static const char *expected_non_sealed_libs[] = +{ + "[vdso]", + "tst-dl_mseal-no-memory-seal", + LIB_PRELOAD, + LIB_AUDIT, + "tst-dl_mseal-mod-no-memory-seal-2.so", + LIB_DLOPEN_DEFAULT, + LIB_DLOPEN_DEFAULT_DEP, + LIB_DLOPEN_NODELETE, +}; + +#include "tst-dl_mseal-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c index fbf18d9b7c..6c77b14d86 100644 --- a/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c @@ -1,4 +1,4 @@ -/* Basic tests for sealing. Static version. +/* Basic tests for sealing. Copyright (C) 2024 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -198,7 +198,7 @@ handle_restart (void) /* Also check if all the expected sealed maps were found. */ for (int i = 0; i < array_length (expected_sealed_libs); i++) - if (!found_expected[i]) + if (expected_sealed_libs[i][0] && !found_expected[i]) FAIL_EXIT1 ("expected VMA %s not sealed\n", expected_sealed_libs[i]); return 0; @@ -239,7 +239,7 @@ do_test (int argc, char *argv[]) spargv[i] = NULL; char *envvarss[4]; - envvarss[0] = (char *) "GLIBC_TUNABLES=glibc.rtld.seal=2"; + envvarss[0] = (char *) "GLIBC_TUNABLES=glibc.rtld.seal=" GLIBC_RTLD_SEAL; #ifndef TEST_STATIC envvarss[1] = (char *) "LD_PRELOAD=" LIB_PRELOAD; envvarss[2] = (char *) "LD_AUDIT=" LIB_AUDIT, diff --git a/sysdeps/unix/sysv/linux/tst-dl_mseal-static-no-memory-seal.c b/sysdeps/unix/sysv/linux/tst-dl_mseal-static-no-memory-seal.c new file mode 100644 index 0000000000..257500ea47 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-dl_mseal-static-no-memory-seal.c @@ -0,0 +1,38 @@ +/* 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_NO_MEMORY_SEAL handling on a statically + built binary. In this case only the vDSO (if existent) will be sealed. */ + +#define GLIBC_RTLD_SEAL "1" +#define TEST_STATIC 1 + +/* Expected libraries that loader will seal. */ +static const char *expected_sealed_libs[] = +{ + "", +}; + +/* Expected non sealed libraries. */ +static const char *expected_non_sealed_libs[] = +{ + "[vdso]", + "tst-dl_mseal-static-no-memory-seal", +}; + +#include "tst-dl_mseal-skeleton.c" |