aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile16
-rw-r--r--elf/dl-execstack-tunable.c39
-rw-r--r--elf/dl-support.c4
-rw-r--r--elf/dl-tunables.list2
-rw-r--r--elf/elf.h3
-rw-r--r--elf/rtld.c6
-rw-r--r--elf/tst-execstack-prog-static-tunable.c1
-rw-r--r--elf/tst-execstack-tunable.c1
-rw-r--r--elf/tst-rtld-list-tunables.exp2
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
}
}
diff --git a/elf/elf.h b/elf/elf.h
index c0f6148..1e1a59c 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -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. */
diff --git a/elf/rtld.c b/elf/rtld.c
index 099c447..3af8ee6 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -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]+)