diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 16 | ||||
-rw-r--r-- | elf/dl-execstack-tunable.c | 39 | ||||
-rw-r--r-- | elf/dl-support.c | 4 | ||||
-rw-r--r-- | elf/dl-tunables.list | 2 | ||||
-rw-r--r-- | elf/elf.h | 3 | ||||
-rw-r--r-- | elf/rtld.c | 6 | ||||
-rw-r--r-- | elf/tst-execstack-prog-static-tunable.c | 1 | ||||
-rw-r--r-- | elf/tst-execstack-tunable.c | 1 | ||||
-rw-r--r-- | elf/tst-rtld-list-tunables.exp | 2 |
9 files changed, 64 insertions, 10 deletions
diff --git a/elf/Makefile b/elf/Makefile index 1282a5b..c3864ca 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -60,6 +60,7 @@ dl-routines = \ dl-deps \ dl-exception \ dl-execstack \ + dl-execstack-tunable \ dl-find_object \ dl-fini \ dl-init \ @@ -572,9 +573,11 @@ tests-execstack-yes = \ tst-execstack \ tst-execstack-needed \ tst-execstack-prog \ + tst-execstack-tunable \ # tests-execstack-yes tests-execstack-static-yes = \ - tst-execstack-prog-static + tst-execstack-prog-static \ + tst-execstack-prog-static-tunable \ # tests-execstack-static-yes ifeq (yes,$(run-built-tests)) tests-execstack-special-yes = \ @@ -2023,6 +2026,14 @@ LDFLAGS-tst-execstack-prog = -Wl,-z,execstack CFLAGS-tst-execstack-prog.c += -Wno-trampolines CFLAGS-tst-execstack-mod.c += -Wno-trampolines +# It expects loading a module with executable stack to work. +CFLAGS-tst-execstack-tunable.c += -DUSE_PTHREADS=0 -DDEFAULT_RWX_STACK=1 +$(objpfx)tst-execstack-tunable.out: $(objpfx)tst-execstack-mod.so +tst-execstack-tunable-ENV = GLIBC_TUNABLES=glibc.rtld.execstack=2 + +LDFLAGS-tst-execstack-prog-static-tunable = -Wl,-z,noexecstack +tst-execstack-prog-static-tunable-ENV = GLIBC_TUNABLES=glibc.rtld.execstack=2 + LDFLAGS-tst-execstack-prog-static = -Wl,-z,execstack ifeq ($(have-no-error-execstack),yes) LDFLAGS-tst-execstack-prog-static += -Wl,--no-error-execstack @@ -3453,7 +3464,8 @@ $(objpfx)tst-dlopen-constructor-null-mod2.so: \ CFLAGS-tst-origin.c += $(no-stack-protector) CFLAGS-liborigin-mod.c += $(no-stack-protector) # Link tst-origin with liborigin-mod.so, but without a full path. -LDFLAGS-tst-origin += -Wl,-rpath,\$$ORIGIN -L$(subst :, -L,$(rpath-link)) -lorigin-mod +LDFLAGS-tst-origin += -Wl,-rpath,\$$ORIGIN -L$(subst :, -L,$(rpath-link)) +LDLIBS-tst-origin += -lorigin-mod $(objpfx)tst-origin: +nolink-deps += $(objpfx)liborigin-mod.so $(objpfx)tst-origin: $(objpfx)liborigin-mod.so $(objpfx)tst-origin.out: tst-origin.sh $(objpfx)tst-origin diff --git a/elf/dl-execstack-tunable.c b/elf/dl-execstack-tunable.c new file mode 100644 index 0000000..6cef1a3 --- /dev/null +++ b/elf/dl-execstack-tunable.c @@ -0,0 +1,39 @@ +/* Stack executability handling for GNU dynamic linker. + 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 <ldsodefs.h> +#include <dl-tunables.h> + +void +_dl_handle_execstack_tunable (void) +{ + switch (TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL)) + { + case stack_tunable_mode_disable: + if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X)) + _dl_fatal_printf ( +"Fatal glibc error: executable stack is not allowed\n"); + break; + + case stack_tunable_mode_force: + if (_dl_make_stack_executable (&__libc_stack_end) != 0) + _dl_fatal_printf ( +"Fatal glibc error: cannot enable executable stack as tunable requires"); + break; + } +} diff --git a/elf/dl-support.c b/elf/dl-support.c index c7860f3..7b2a1c3 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -331,9 +331,7 @@ _dl_non_dynamic_init (void) break; } - if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X) - && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 0) - _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n"); + _dl_handle_execstack_tunable (); call_function_static_weak (_dl_find_object_init); diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 0b6721b..c03c996 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -138,7 +138,7 @@ glibc { execstack { type: INT_32 minval: 0 - maxval: 1 + maxval: 2 default: 1 } } @@ -837,12 +837,15 @@ typedef struct #define NT_ARM_ZT 0x40d /* ARM SME ZT registers. */ #define NT_ARM_FPMR 0x40e /* ARM floating point mode register. */ #define NT_ARM_POE 0x40f /* ARM POE registers. */ +#define NT_ARM_GCS 0x410 /* ARM GCS state. */ #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */ #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */ #define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */ #define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */ #define NT_RISCV_CSR 0x900 /* RISC-V Control and Status Registers */ #define NT_RISCV_VECTOR 0x901 /* RISC-V vector registers */ +#define NT_RISCV_TAGGED_ADDR_CTRL 0x902 /* RISC-V tagged + address control */ #define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers. */ #define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and status registers. */ @@ -1622,9 +1622,9 @@ dl_main (const ElfW(Phdr) *phdr, bool has_interp = rtld_setup_main_map (main_map); - if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X) - && TUNABLE_GET (glibc, rtld, execstack, int32_t, NULL) == 0) - _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n"); + /* Handle this after PT_GNU_STACK parse, because it updates dl_stack_flags + if required. */ + _dl_handle_execstack_tunable (); /* If the current libname is different from the SONAME, add the latter as well. */ diff --git a/elf/tst-execstack-prog-static-tunable.c b/elf/tst-execstack-prog-static-tunable.c new file mode 100644 index 0000000..88b0ca1 --- /dev/null +++ b/elf/tst-execstack-prog-static-tunable.c @@ -0,0 +1 @@ +#include <tst-execstack-prog-static.c> diff --git a/elf/tst-execstack-tunable.c b/elf/tst-execstack-tunable.c new file mode 100644 index 0000000..9f03b0f --- /dev/null +++ b/elf/tst-execstack-tunable.c @@ -0,0 +1 @@ +#include <tst-execstack.c> diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp index 9f5990f..8df6f59 100644 --- a/elf/tst-rtld-list-tunables.exp +++ b/elf/tst-rtld-list-tunables.exp @@ -13,6 +13,6 @@ glibc.malloc.top_pad: 0x20000 (min: 0x0, max: 0x[f]+) glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) glibc.rtld.dynamic_sort: 2 (min: 1, max: 2) glibc.rtld.enable_secure: 0 (min: 0, max: 1) -glibc.rtld.execstack: 1 (min: 0, max: 1) +glibc.rtld.execstack: 1 (min: 0, max: 2) glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) |