public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Make non-executable stack disable by default
@ 2024-06-14 12:50 Adhemerval Zanella
  2024-06-14 12:50 ` [PATCH v2 1/2] elf: Consolidate stackinfo.h Adhemerval Zanella
  2024-06-14 12:50 ` [PATCH v2 2/2] elf: Make non-executable stack disable by default Adhemerval Zanella
  0 siblings, 2 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2024-06-14 12:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu, Florian Weimer, Zack Weinberg

First patch is a stackinfo.h cleanup for better default, while the
second is the patch to disable executable stacks.

Changes from v1:
* Fixed tests invocation without --enable-hardcoded-path-in-tests.
* Added hurd, hppa, mips exceptions.

Adhemerval Zanella (2):
  elf: Consolidate stackinfo.h
  elf: Make non-executable stack disable by default

 Makeconfig                                    |   1 +
 NEWS                                          |   4 +
 elf/Makefile                                  |  50 ++++++++-
 elf/dl-load.c                                 |   8 ++
 elf/dl-support.c                              |   5 +
 elf/dl-tunables.list                          |   6 +
 elf/rtld.c                                    |   4 +
 elf/tst-execstack-prog-static.c               |   1 +
 elf/tst-execstack.c                           | 106 +++++-------------
 elf/tst-ro-dynamic-mod.map                    |   3 +-
 elf/tst-rtld-list-tunables.exp                |   1 +
 manual/tunables.texi                          |  20 ++++
 nptl/Makefile                                 |  11 +-
 sysdeps/aarch64/stackinfo.h                   |  33 ------
 sysdeps/arc/stackinfo.h                       |  33 ------
 sysdeps/csky/stackinfo.h                      |  29 -----
 sysdeps/generic/stackinfo.h                   |  15 ++-
 sysdeps/hppa/dl-tunables.list                 |  11 ++
 sysdeps/loongarch/stackinfo.h                 |  33 ------
 sysdeps/mach/hurd/dl-tunables.list            |  11 ++
 sysdeps/nios2/stackinfo.h                     |  33 ------
 sysdeps/powerpc/{ => powerpc32}/stackinfo.h   |   8 +-
 sysdeps/riscv/stackinfo.h                     |  33 ------
 sysdeps/unix/sysv/linux/mips/Makefile         |  13 +++
 .../sysv/linux/mips/dl-tunables-arch.list     |  12 ++
 25 files changed, 201 insertions(+), 283 deletions(-)
 create mode 100644 elf/tst-execstack-prog-static.c
 delete mode 100644 sysdeps/aarch64/stackinfo.h
 delete mode 100644 sysdeps/arc/stackinfo.h
 delete mode 100644 sysdeps/csky/stackinfo.h
 create mode 100644 sysdeps/hppa/dl-tunables.list
 delete mode 100644 sysdeps/loongarch/stackinfo.h
 create mode 100644 sysdeps/mach/hurd/dl-tunables.list
 delete mode 100644 sysdeps/nios2/stackinfo.h
 rename sysdeps/powerpc/{ => powerpc32}/stackinfo.h (82%)
 delete mode 100644 sysdeps/riscv/stackinfo.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/dl-tunables-arch.list

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] elf: Consolidate stackinfo.h
  2024-06-14 12:50 [PATCH v2 0/2] Make non-executable stack disable by default Adhemerval Zanella
@ 2024-06-14 12:50 ` Adhemerval Zanella
  2024-06-14 12:50 ` [PATCH v2 2/2] elf: Make non-executable stack disable by default Adhemerval Zanella
  1 sibling, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2024-06-14 12:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu, Florian Weimer, Zack Weinberg

And use sane default the generic implementation.
---
 sysdeps/aarch64/stackinfo.h                 | 33 ---------------------
 sysdeps/arc/stackinfo.h                     | 33 ---------------------
 sysdeps/csky/stackinfo.h                    | 29 ------------------
 sysdeps/generic/stackinfo.h                 | 15 ++++++++--
 sysdeps/loongarch/stackinfo.h               | 33 ---------------------
 sysdeps/nios2/stackinfo.h                   | 33 ---------------------
 sysdeps/powerpc/{ => powerpc32}/stackinfo.h |  8 +----
 sysdeps/riscv/stackinfo.h                   | 33 ---------------------
 8 files changed, 13 insertions(+), 204 deletions(-)
 delete mode 100644 sysdeps/aarch64/stackinfo.h
 delete mode 100644 sysdeps/arc/stackinfo.h
 delete mode 100644 sysdeps/csky/stackinfo.h
 delete mode 100644 sysdeps/loongarch/stackinfo.h
 delete mode 100644 sysdeps/nios2/stackinfo.h
 rename sysdeps/powerpc/{ => powerpc32}/stackinfo.h (82%)
 delete mode 100644 sysdeps/riscv/stackinfo.h

diff --git a/sysdeps/aarch64/stackinfo.h b/sysdeps/aarch64/stackinfo.h
deleted file mode 100644
index 5a4dce7309..0000000000
--- a/sysdeps/aarch64/stackinfo.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2001-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 file contains a bit of information about the stack allocation
-   of the processor.  */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H	1
-
-#include <elf.h>
-
-/* On AArch64 the stack grows down.  */
-#define _STACK_GROWS_DOWN	1
-
-/* Default to a non-executable stack. */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W)
-
-#endif	/* stackinfo.h */
diff --git a/sysdeps/arc/stackinfo.h b/sysdeps/arc/stackinfo.h
deleted file mode 100644
index 99a7f56ea0..0000000000
--- a/sysdeps/arc/stackinfo.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Stack environment definitions for ARC.
-   Copyright (C) 2020-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 file contains a bit of information about the stack allocation
-   of the processor.  */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H	1
-
-#include <elf.h>
-
-/* On ARC the stack grows down.  */
-#define _STACK_GROWS_DOWN	1
-
-/* Default to a non-executable stack.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W)
-
-#endif	/* stackinfo.h */
diff --git a/sysdeps/csky/stackinfo.h b/sysdeps/csky/stackinfo.h
deleted file mode 100644
index ef22fa3249..0000000000
--- a/sysdeps/csky/stackinfo.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Stack environment definitions.  C-SKY version.
-   Copyright (C) 2018-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/>.  */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H	1
-
-#include <elf.h>
-
-/* On C-SKY the stack grows down.  */
-#define _STACK_GROWS_DOWN	1
-
-#define DEFAULT_STACK_PERMS (PF_R|PF_W)
-
-#endif	/* stackinfo.h */
diff --git a/sysdeps/generic/stackinfo.h b/sysdeps/generic/stackinfo.h
index bf752ce94d..51e5f92055 100644
--- a/sysdeps/generic/stackinfo.h
+++ b/sysdeps/generic/stackinfo.h
@@ -15,6 +15,15 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-/* This file contains a bit of information about the stack allocation
-   of the processor.  Since there is no general truth we can't say
-   anything here.  */
+/* This file contains a bit of information about the stack allocation of the
+   processor.  Default to a non executable stack that grows downwards.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H	1
+
+#include <elf.h>
+
+#define _STACK_GROWS_DOWN	1
+#define DEFAULT_STACK_PERMS	(PF_R|PF_W)
+
+#endif
diff --git a/sysdeps/loongarch/stackinfo.h b/sysdeps/loongarch/stackinfo.h
deleted file mode 100644
index 6ee50552b7..0000000000
--- a/sysdeps/loongarch/stackinfo.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Stack environment definitions for LoongArch.
-   Copyright (C) 2022-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 file contains a bit of information about the stack allocation
-   of the processor.  */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H 1
-
-#include <elf.h>
-
-/* On LoongArch the stack grows down.  */
-#define _STACK_GROWS_DOWN 1
-
-/* Default to a non-executable stack.  */
-#define DEFAULT_STACK_PERMS (PF_R | PF_W)
-
-#endif /* stackinfo.h */
diff --git a/sysdeps/nios2/stackinfo.h b/sysdeps/nios2/stackinfo.h
deleted file mode 100644
index e67d53ee87..0000000000
--- a/sysdeps/nios2/stackinfo.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Stack environment definitions for Nios II.
-   Copyright (C) 2012-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 file contains a bit of information about the stack allocation
-   of the processor.  */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H	1
-
-#include <elf.h>
-
-/* On Nios II the stack grows down.  */
-#define _STACK_GROWS_DOWN	1
-
-/* Default to a non-executable stack.  */
-#define DEFAULT_STACK_PERMS (PF_R|PF_W)
-
-#endif	/* stackinfo.h */
diff --git a/sysdeps/powerpc/stackinfo.h b/sysdeps/powerpc/powerpc32/stackinfo.h
similarity index 82%
rename from sysdeps/powerpc/stackinfo.h
rename to sysdeps/powerpc/powerpc32/stackinfo.h
index 410689bc27..2ca360068a 100644
--- a/sysdeps/powerpc/stackinfo.h
+++ b/sysdeps/powerpc/powerpc32/stackinfo.h
@@ -26,13 +26,7 @@
 /* On PPC the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
-#if __WORDSIZE == 64
-/* PPC64 doesn't need an executable stack and doesn't need PT_GNU_STACK
- * to make the stack nonexecutable.  */
-# define DEFAULT_STACK_PERMS (PF_R|PF_W)
-#else
 /* PF_X can be overridden if PT_GNU_STACK is present but is presumed absent.  */
-# define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
-#endif
+#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
 
 #endif	/* stackinfo.h */
diff --git a/sysdeps/riscv/stackinfo.h b/sysdeps/riscv/stackinfo.h
deleted file mode 100644
index a786d4f9b0..0000000000
--- a/sysdeps/riscv/stackinfo.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Stack environment definitions for RISC-V.
-   Copyright (C) 2011-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 file contains a bit of information about the stack allocation
-   of the processor.  */
-
-#ifndef _STACKINFO_H
-#define _STACKINFO_H	1
-
-#include <elf.h>
-
-/* On RISC-V the stack grows down.  */
-#define _STACK_GROWS_DOWN	1
-
-/* Default to a non-executable stack.  */
-#define DEFAULT_STACK_PERMS (PF_R | PF_W)
-
-#endif	/* stackinfo.h */
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] elf: Make non-executable stack disable by default
  2024-06-14 12:50 [PATCH v2 0/2] Make non-executable stack disable by default Adhemerval Zanella
  2024-06-14 12:50 ` [PATCH v2 1/2] elf: Consolidate stackinfo.h Adhemerval Zanella
@ 2024-06-14 12:50 ` Adhemerval Zanella
  2024-06-14 17:56   ` Zack Weinberg
  1 sibling, 1 reply; 6+ messages in thread
From: Adhemerval Zanella @ 2024-06-14 12:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu, Florian Weimer, Zack Weinberg

It is past time to not allow executable stacks as default, even if
kernel protection like SELinux already exists (although not widely
deployed).  Binutils 2.39 now warns of the need of executable stacks
by default [1] and gcc nested function trampolines can now be heap
based [2] (besides being a gcc-only extension).

For compatibility, a new tunable, glibc.rtld.noexecstack, can be use
to allow programs to run with an executable stack.  It has the side
effect of complete disable executable stacks for setuid binaries,
but allowing in first place is *really* a bad idea.

Some ABIs still require executable stacks: hurd, Linux/hppa (where
gcc/binutils still does not generate .note.GNU-stack as default [3]),
and mips for some ABI on kernels older than 4.8.  For such ABIs,
the non-executable is not enforced.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

[1] https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments
[2] https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=28d8c680aaea46137170fef2bd1c6a98301518dc
[3] https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
---
 Makeconfig                                    |   1 +
 NEWS                                          |   4 +
 elf/Makefile                                  |  50 ++++++++-
 elf/dl-load.c                                 |   8 ++
 elf/dl-support.c                              |   5 +
 elf/dl-tunables.list                          |   6 +
 elf/rtld.c                                    |   4 +
 elf/tst-execstack-prog-static.c               |   1 +
 elf/tst-execstack.c                           | 106 +++++-------------
 elf/tst-ro-dynamic-mod.map                    |   3 +-
 elf/tst-rtld-list-tunables.exp                |   1 +
 manual/tunables.texi                          |  20 ++++
 nptl/Makefile                                 |  11 +-
 sysdeps/hppa/dl-tunables.list                 |  11 ++
 sysdeps/mach/hurd/dl-tunables.list            |  11 ++
 sysdeps/unix/sysv/linux/mips/Makefile         |  13 +++
 .../sysv/linux/mips/dl-tunables-arch.list     |  12 ++
 17 files changed, 188 insertions(+), 79 deletions(-)
 create mode 100644 elf/tst-execstack-prog-static.c
 create mode 100644 sysdeps/hppa/dl-tunables.list
 create mode 100644 sysdeps/mach/hurd/dl-tunables.list
 create mode 100644 sysdeps/unix/sysv/linux/mips/dl-tunables-arch.list

diff --git a/Makeconfig b/Makeconfig
index 29819363da..76f5772272 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -356,6 +356,7 @@ endif
 # Must be supported by the linker.
 no-whole-archive = -Wl,--no-whole-archive
 whole-archive = -Wl,--whole-archive
+noexecstack = -Wl,-z,noexecstack
 
 # Installed name of the startup code.
 # The ELF convention is that the startfile is called crt1.o
diff --git a/NEWS b/NEWS
index 20e263f581..3419a0a2e8 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,10 @@ Major new features:
 * On Linux, update epoll header to include epoll ioctl definitions and
   related structure added in Linux kernel 6.9.
 
+* A new tunable, glibc.rtld.noexecstack, can be used to enable executable
+  stacks from either main program, dependencies, or dynamically loaded
+  libraries.  The default is to disable executable stacks.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * Architectures which use a 32-bit seconds-since-epoch field in struct
diff --git a/elf/Makefile b/elf/Makefile
index 57b3a19d36..17768d81f7 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -543,6 +543,15 @@ tests-execstack-yes = \
   tst-execstack-needed \
   tst-execstack-prog \
   # tests-execstack-yes
+tests-execstack-static-yes = \
+  tst-execstack-prog-static \
+  # tests-execstack-static-yes
+tests-execstack-special-yes = \
+  $(objpfx)tst-execstack-default.out \
+  $(objpfx)tst-execstack-needed-default.out \
+  $(objpfx)tst-execstack-prog-default.out \
+  $(objpfx)tst-execstack-prog-static-default.out \
+  # tests-execstack-special-yes
 endif
 ifeq ($(have-depaudit),yes)
 tests += \
@@ -630,6 +639,8 @@ $(objpfx)tst-rtld-does-not-exist.out: tst-rtld-does-not-exist.sh $(objpfx)ld.so
 	$(evaluate-test)
 
 tests += $(tests-execstack-$(have-z-execstack))
+tests-static += $(tests-execstack-static-$(have-z-execstack))
+tests-special += $(tests-execstack-special-$(have-z-execstack))
 ifeq ($(run-built-tests),yes)
 tests-special += \
   $(objpfx)noload-mem.out \
@@ -1845,16 +1856,53 @@ $(objpfx)unload8.out: $(objpfx)unload8mod1.so $(objpfx)unload8mod1x.so
 $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
 
 ifeq ($(have-z-execstack),yes)
-$(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so
+$(objpfx)tst-execstack: $(objpfx)tst-execstack-mod.so
 CPPFLAGS-tst-execstack.c += -DUSE_PTHREADS=0
 LDFLAGS-tst-execstack = -Wl,-z,noexecstack
 LDFLAGS-tst-execstack-mod.so = -Wl,-z,execstack
 
+$(objpfx)tst-execstack-default.out: $(objpfx)tst-execstack
+	$(test-program-cmd) $< > $@ 2>&1; echo "status: $$?" >> $@; \
+	grep -q 'error while loading shared libraries:.*executable stack is not allowed$$' $@ \
+	  && grep -q '^status: 127$$' $@; \
+	  $(evaluate-test)
+
+tst-execstack-ENV = GLIBC_TUNABLES=glibc.rtld.noexecstack=0 \
+		    ALLOW_EXECSTACK=1
+
 $(objpfx)tst-execstack-needed: $(objpfx)tst-execstack-mod.so
 LDFLAGS-tst-execstack-needed = -Wl,-z,noexecstack
 
+tst-execstack-needed-ENV = GLIBC_TUNABLES=glibc.rtld.noexecstack=0 \
+			   ALLOW_EXECSTACK=1
+
+$(objpfx)tst-execstack-needed-default.out: $(objpfx)tst-execstack-needed
+	$(test-program-cmd) $< > $@ 2>&1; echo "status: $$?" >> $@; \
+	grep -q 'error while loading shared libraries:.*executable stack is not allowed$$' $@ \
+	  && grep -q '^status: 127$$' $@; \
+	  $(evaluate-test)
+
 LDFLAGS-tst-execstack-prog = -Wl,-z,execstack
 CFLAGS-tst-execstack-prog.c += -Wno-trampolines
+tst-execstack-prog-ENV = GLIBC_TUNABLES=glibc.rtld.noexecstack=0
+
+LDFLAGS-tst-execstack-prog-static = -Wl,-z,execstack
+CFLAGS-tst-execstack-prog-static.c += -Wno-trampolines
+tst-execstack-prog-static-ENV = GLIBC_TUNABLES=glibc.rtld.noexecstack=0
+
+$(objpfx)tst-execstack-prog-default.out: $(objpfx)tst-execstack-prog
+	$(test-program-cmd) $< > $@ 2>&1; echo "status: $$?" >> $@; \
+	grep -q 'executable stack is not allowed$$' $@ \
+	grep -q 'error while loading shared libraries:.*executable stack is not allowed$$' $@ \
+	  && grep -q '^status: 127$$' $@; \
+	  $(evaluate-test)
+
+$(objpfx)tst-execstack-prog-static-default.out: $(objpfx)tst-execstack-prog-static
+	$(host-test-program-cmd) $< > $@ 2>&1; echo "status: $$?" >> $@; \
+	grep -q 'executable stack is not allowed$$' $@ \
+	  && grep -q '^status: 127$$' $@; \
+	  $(evaluate-test)
+
 CFLAGS-tst-execstack-mod.c += -Wno-trampolines
 endif
 
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 8a89b71016..414955694f 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -32,6 +32,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <gnu/lib-names.h>
+#include <dl-tunables.h>
 
 /* Type for the buffer we put the ELF header and hopefully the program
    header.  This buffer does not really have to be too large.  In most
@@ -1297,6 +1298,13 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 
   if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
     {
+      if (TUNABLE_GET (glibc, rtld, noexecstack, int32_t, NULL) == 1)
+	{
+	  errstring = N_("\
+executable stack is not allowed");
+	  goto lose;
+	}
+
       /* The stack is presently not executable, but this module
 	 requires that it be executable.  */
 #if PTHREAD_IN_LIBC
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 451932dd03..084e2579b1 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -45,6 +45,7 @@
 #include <dl-find_object.h>
 #include <array_length.h>
 #include <dl-symbol-redir-ifunc.h>
+#include <dl-tunables.h>
 
 extern char *__progname;
 char **_dl_argv = &__progname;	/* This is checked for some error messages.  */
@@ -335,6 +336,10 @@ _dl_non_dynamic_init (void)
 	break;
       }
 
+  if ((__glibc_unlikely (GL(dl_stack_flags)) & PF_X)
+      && TUNABLE_GET (glibc, rtld, noexecstack, int32_t, NULL) == 1)
+    _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n");
+
   call_function_static_weak (_dl_find_object_init);
 
   /* Setup relro on the binary itself.  */
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
index 1186272c81..745c9ce2c1 100644
--- a/elf/dl-tunables.list
+++ b/elf/dl-tunables.list
@@ -142,6 +142,12 @@ glibc {
       maxval: 1
       default: 0
     }
+    noexecstack {
+      type: INT_32
+      minval: 0
+      maxval: 1
+      default: 1
+    }
   }
 
   mem {
diff --git a/elf/rtld.c b/elf/rtld.c
index e9525ea987..0762d68d68 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1668,6 +1668,10 @@ 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, noexecstack, int32_t, NULL) == 1)
+    _dl_fatal_printf ("Fatal glibc error: executable stack is not allowed\n");
+
   /* If the current libname is different from the SONAME, add the
      latter as well.  */
   if (GL(dl_rtld_map).l_info[DT_SONAME] != NULL
diff --git a/elf/tst-execstack-prog-static.c b/elf/tst-execstack-prog-static.c
new file mode 100644
index 0000000000..180657e5ef
--- /dev/null
+++ b/elf/tst-execstack-prog-static.c
@@ -0,0 +1 @@
+#include "tst-execstack-prog.c"
diff --git a/elf/tst-execstack.c b/elf/tst-execstack.c
index 560b353918..56fb8bd874 100644
--- a/elf/tst-execstack.c
+++ b/elf/tst-execstack.c
@@ -8,17 +8,10 @@
 #include <unistd.h>
 #include <error.h>
 #include <stackinfo.h>
-
-static void
-print_maps (void)
-{
-#if 0
-  char *cmd = NULL;
-  asprintf (&cmd, "cat /proc/%d/maps", getpid ());
-  system (cmd);
-  free (cmd);
-#endif
-}
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/xthread.h>
+#include <support/xdlfcn.h>
 
 static void deeper (void (*f) (void));
 
@@ -47,7 +40,7 @@ waiter_thread (void *arg)
 }
 #endif
 
-static bool allow_execstack = true;
+static bool kernel_allow_execstack = true;
 
 
 static int
@@ -74,61 +67,46 @@ do_test (void)
 	    {
 	      n = getline (&line, &linelen, fp);
 	      if (n > 0 && line[0] == '0')
-		allow_execstack = false;
+		kernel_allow_execstack = false;
 	    }
 
 	  fclose (fp);
 	}
     }
 
-  printf ("executable stacks %sallowed\n", allow_execstack ? "" : "not ");
+  printf ("kernel allows executable stacks: %s\n",
+	  kernel_allow_execstack ? "yes" : "not ");
+
+  bool glibc_allow_execstack = getenv ("ALLOW_EXECSTACK") != 0;
+  printf ("expected allow executable stacks: %s\n",
+	  glibc_allow_execstack ? "yes" : "not ");
 
   static void *f;		/* Address of this is used in other threads. */
 
 #if USE_PTHREADS
   /* Create some threads while stacks are nonexecutable.  */
   #define N 5
-  pthread_t thr[N];
 
-  pthread_barrier_init (&startup_barrier, NULL, N + 1);
-  pthread_barrier_init (&go_barrier, NULL, N + 1);
+  xpthread_barrier_init (&startup_barrier, NULL, N + 1);
+  xpthread_barrier_init (&go_barrier, NULL, N + 1);
 
   for (int i = 0; i < N; ++i)
-    {
-      int rc = pthread_create (&thr[i], NULL, &waiter_thread, &f);
-      if (rc)
-	error (1, rc, "pthread_create");
-    }
+    xpthread_create (NULL, &waiter_thread, &f);
 
   /* Make sure they are all there using their stacks.  */
-  pthread_barrier_wait (&startup_barrier);
+  xpthread_barrier_wait (&startup_barrier);
   puts ("threads waiting");
 #endif
 
-  print_maps ();
-
 #if USE_PTHREADS
   void *old_stack_addr, *new_stack_addr;
   size_t stack_size;
   pthread_t me = pthread_self ();
   pthread_attr_t attr;
-  int ret = 0;
 
-  ret = pthread_getattr_np (me, &attr);
-  if (ret)
-    {
-      printf ("before execstack: pthread_getattr_np returned error: %s\n",
-	      strerror (ret));
-      return 1;
-    }
-
-  ret = pthread_attr_getstack (&attr, &old_stack_addr, &stack_size);
-  if (ret)
-    {
-      printf ("before execstack: pthread_attr_getstack returned error: %s\n",
-	      strerror (ret));
-      return 1;
-    }
+  TEST_VERIFY_EXIT (pthread_getattr_np (me, &attr) == 0);
+  TEST_VERIFY_EXIT (pthread_attr_getstack (&attr, &old_stack_addr,
+					   &stack_size) == 0);
 # if _STACK_GROWS_DOWN
     old_stack_addr += stack_size;
 # else
@@ -146,39 +124,22 @@ do_test (void)
   if (h == NULL)
     {
       printf ("cannot load: %s\n", dlerror ());
-      return allow_execstack;
+      return kernel_allow_execstack
+	     ? (glibc_allow_execstack ? 1 : 0)
+	     : 0;
     }
 
-  f = dlsym (h, "tryme");
-  if (f == NULL)
-    {
-      printf ("symbol not found: %s\n", dlerror ());
-      return 1;
-    }
+  f = xdlsym (h, "tryme");
 
   /* Test if that really made our stack executable.
      The `tryme' function should crash if not.  */
 
   (*((void (*) (void)) f)) ();
 
-  print_maps ();
-
 #if USE_PTHREADS
-  ret = pthread_getattr_np (me, &attr);
-  if (ret)
-    {
-      printf ("after execstack: pthread_getattr_np returned error: %s\n",
-	      strerror (ret));
-      return 1;
-    }
-
-  ret = pthread_attr_getstack (&attr, &new_stack_addr, &stack_size);
-  if (ret)
-    {
-      printf ("after execstack: pthread_attr_getstack returned error: %s\n",
-	      strerror (ret));
-      return 1;
-    }
+  TEST_VERIFY_EXIT (pthread_getattr_np (me, &attr) == 0);
+  TEST_VERIFY_EXIT (pthread_attr_getstack (&attr, &new_stack_addr,
+					   &stack_size) == 0);
 
 # if _STACK_GROWS_DOWN
     new_stack_addr += stack_size;
@@ -206,26 +167,19 @@ do_test (void)
   /* Test that growing the stack region gets new executable pages too.  */
   deeper ((void (*) (void)) f);
 
-  print_maps ();
-
 #if USE_PTHREADS
   /* Test that a fresh thread now gets an executable stack.  */
-  {
-    pthread_t th;
-    int rc = pthread_create (&th, NULL, &tryme_thread, f);
-    if (rc)
-      error (1, rc, "pthread_create");
-  }
+  xpthread_create (NULL, &tryme_thread, f);
 
   puts ("threads go");
   /* The existing threads' stacks should have been changed.
      Let them run to test it.  */
-  pthread_barrier_wait (&go_barrier);
+  xpthread_barrier_wait (&go_barrier);
 
-  pthread_exit ((void *) (long int) (! allow_execstack));
+  pthread_exit ((void *) (long int) (! kernel_allow_execstack));
 #endif
 
-  return ! allow_execstack;
+  return ! kernel_allow_execstack;
 }
 
 static void
diff --git a/elf/tst-ro-dynamic-mod.map b/elf/tst-ro-dynamic-mod.map
index 2fe4a2998c..b68b036d3a 100644
--- a/elf/tst-ro-dynamic-mod.map
+++ b/elf/tst-ro-dynamic-mod.map
@@ -4,7 +4,7 @@ SECTIONS
  .dynamic : { *(.dynamic) } :text :dynamic
  .rodata : { *(.data*) *(.bss*) } :text
  /DISCARD/ : {
-  *(.note.gnu.property)
+  *(.note.gnu.property) *(.note.GNU-stack)
  }
  .note : { *(.note.*) } :text :note
 }
@@ -13,4 +13,5 @@ PHDRS
  text PT_LOAD FLAGS(5) FILEHDR PHDRS;
  dynamic PT_DYNAMIC FLAGS(4);
  note PT_NOTE FLAGS(4);
+ gnu_stack PT_GNU_STACK FLAGS(6);
 }
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
index db0e1c86e9..2ac06e083a 100644
--- a/elf/tst-rtld-list-tunables.exp
+++ b/elf/tst-rtld-list-tunables.exp
@@ -14,4 +14,5 @@ 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.nns: 0x4 (min: 0x1, max: 0x10)
+glibc.rtld.noexecstack: 1 (min: 0, max: 1)
 glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+)
diff --git a/manual/tunables.texi b/manual/tunables.texi
index 8dd02d8149..bc8ef6effa 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -356,6 +356,26 @@ tests for @code{AT_SECURE} programs and not meant to be a security feature.
 The default value of this tunable is @samp{0}.
 @end deftp
 
+@deftp Tunable glibc.rtld.noexecstack
+Initially, @theglibc{} will use either the default architecture flags (that might
+contain the executable bit) or the value of @code{PT_GNU_STACK} (if present).
+If any shared library dependency or dynamic object loaded with @code{dlopen}
+or @code{dlmopen} requires an executable stack (either by the default flags
+or @code{PT_GNU_STACK} from the library) @theglibc{} will try to change the
+permission of the stack to enable execution for all running threads.
+
+The @code{glibc.rtld.noexecstack} tunable allows the user to control whether
+to control executable stacks from the main program, dependencies, or from
+dynamically loaded libraries.  Setting its value to @code{0} allows executable
+stacks, where @code{1} disables it.  The default value is @code{1} (except
+for Hurd, and hppa/mips on Linux which requires executables stacks).
+
+When executable stacks are not allowed, and if the main program or dependencies
+require an executable stack, the loader will fail with an error message.  Trying
+to load a dynamic shared library with @code{dlopen} or @code{dlmopen} will fail,
+with a proper message that can be obtained with @code{dlerror}.
+@end deftp
+
 @node Elision Tunables
 @section Elision Tunables
 @cindex elision tunables
diff --git a/nptl/Makefile b/nptl/Makefile
index b3f8af2e1c..e16be8ff13 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -468,6 +468,7 @@ tests-internal += \
   # tests-internal
 ifeq ($(have-z-execstack),yes)
 tests += tst-execstack-threads
+tests-special += $(objpfx)tst-execstack-threads-default.out
 endif
 endif
 
@@ -671,10 +672,18 @@ endif
 
 tst-exec4-ARGS = $(host-test-program-cmd)
 
-$(objpfx)tst-execstack-threads.out: $(objpfx)tst-execstack-threads-mod.so
+$(objpfx)tst-execstack-threads: $(objpfx)tst-execstack-threads-mod.so
 LDFLAGS-tst-execstack-threads = -Wl,-z,noexecstack
 LDFLAGS-tst-execstack-threads-mod.so = -Wl,-z,execstack
 CFLAGS-tst-execstack-threads-mod.c += -Wno-trampolines
+tst-execstack-threads-ENV = GLIBC_TUNABLES=glibc.rtld.noexecstack=0 \
+			    ALLOW_EXECSTACK=1
+
+$(objpfx)tst-execstack-threads-default.out: $(objpfx)tst-execstack-threads
+	$(test-program-cmd) $< > $@ 2>&1; echo "status: $$?" >> $@; \
+	grep -q 'error while loading shared libraries:.*executable stack is not allowed$$' $@ \
+	  && grep -q '^status: 127$$' $@; \
+	  $(evaluate-test)
 
 tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child"
 tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
diff --git a/sysdeps/hppa/dl-tunables.list b/sysdeps/hppa/dl-tunables.list
new file mode 100644
index 0000000000..2e53a235db
--- /dev/null
+++ b/sysdeps/hppa/dl-tunables.list
@@ -0,0 +1,11 @@
+# HPPA defaults to executable stacks.
+glibc {
+  rtld {
+    noexecstack {
+      type: INT_32
+      minval: 0
+      maxval: 1
+      default: 0
+    }
+  }
+}
diff --git a/sysdeps/mach/hurd/dl-tunables.list b/sysdeps/mach/hurd/dl-tunables.list
new file mode 100644
index 0000000000..dc6a7aa21b
--- /dev/null
+++ b/sysdeps/mach/hurd/dl-tunables.list
@@ -0,0 +1,11 @@
+# Hurd default to an executable stack.
+glibc {
+  rtld {
+    noexecstack {
+      type: INT_32
+      minval: 0
+      maxval: 1
+      default: 0
+    }
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile
index d5725c69d8..2cb0f6268f 100644
--- a/sysdeps/unix/sysv/linux/mips/Makefile
+++ b/sysdeps/unix/sysv/linux/mips/Makefile
@@ -78,4 +78,17 @@ ASFLAGS-.o += -Wa,-execstack
 ASFLAGS-.os += -Wa,-execstack
 ASFLAGS-.op += -Wa,-execstack
 ASFLAGS-.oS += -Wa,-execstack
+mips_noexecstack := 0
+else
+mips_noexecstack := 1
 endif
+
+# Change the default value of glibc.rtld.noexecstack based on mips-force-execstack
+$(common-objpfx)dl-tunable-list.stmp: $(common-objpfx)dl-tunable-arch.list
+$(common-objpfx)dl-tunable-arch.list: $(common-objpfx)dl-tunable-arch.stmp; @:
+$(common-objpfx)dl-tunable-arch.stmp: \
+		$(wildcard $(sysdirs:%=%/dl-tunables-arch.list))
+	cp $^ ${@:stmp=T}
+	sed -i 's/mips_noexecstack/$(mips_noexecstack)/' ${@:stmp=T}
+	$(move-if-change) ${@:stmp=T} ${@:stmp=list}
+	touch $@
diff --git a/sysdeps/unix/sysv/linux/mips/dl-tunables-arch.list b/sysdeps/unix/sysv/linux/mips/dl-tunables-arch.list
new file mode 100644
index 0000000000..c9656c4a15
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/dl-tunables-arch.list
@@ -0,0 +1,12 @@
+# MIPS migth require an executable stack on kernels older than 4.8.  The
+# 'mips_noexecstack' is set by configure depending on how glibc is configured.
+glibc {
+  rtld {
+    noexecstack {
+      type: INT_32
+      minval: 0
+      maxval: 1
+      default: mips_noexecstack
+    }
+  }
+}
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] elf: Make non-executable stack disable by default
  2024-06-14 12:50 ` [PATCH v2 2/2] elf: Make non-executable stack disable by default Adhemerval Zanella
@ 2024-06-14 17:56   ` Zack Weinberg
  2024-06-14 18:02     ` Sam James
  2024-06-17 12:27     ` Adhemerval Zanella Netto
  0 siblings, 2 replies; 6+ messages in thread
From: Zack Weinberg @ 2024-06-14 17:56 UTC (permalink / raw)
  To: Adhemerval Zanella, GNU libc development; +Cc: H . J . Lu, Florian Weimer

On Fri, Jun 14, 2024, at 8:50 AM, Adhemerval Zanella wrote:
> It is past time to not allow executable stacks as default, even if
> kernel protection like SELinux already exists (although not widely
> deployed).  Binutils 2.39 now warns of the need of executable stacks
> by default [1] and gcc nested function trampolines can now be heap
> based [2] (besides being a gcc-only extension).

I want to be clear that I fully support disallowing executable stacks
by default, and, in fact, removing the code to support them.  If Florian
thinks we need a transition period, then I believe him, but I think
we should be loud and specific about the timeline toward complete
removal, and that timeline should be as short as possible.
Something like:

2.40:
  - executable stacks disabled for setuid binaries and dlopened
    modules, with no override
  - for non-setuid binaries, an executable stack will continue
    to be provided based on PT_GNU_EXECSTACK, but we only
    look at the main executable and its static dependencies
    for that annotation
  - tunable allows executable stacks to be turned off system-wide

2.41:
  - flip the default for the tunable: executable stacks are off
    system-wide but can be re-enabled (for binaries that request them)

2.43 (one year after the release of 2.41), assuming hurd and hppa-linux
have caught up:
  - all support code for executable stacks permanently removed

> For compatibility, a new tunable, glibc.rtld.noexecstack

Can we please call this tunable glibc.rtld.execstack instead of
glibc.rtld.noexecstack, with a value of 0 meaning executable
stacks are forbidden and 1 meaning they are allowed?  The double
negative is going to confuse people.

zw

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] elf: Make non-executable stack disable by default
  2024-06-14 17:56   ` Zack Weinberg
@ 2024-06-14 18:02     ` Sam James
  2024-06-17 12:27     ` Adhemerval Zanella Netto
  1 sibling, 0 replies; 6+ messages in thread
From: Sam James @ 2024-06-14 18:02 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: Adhemerval Zanella, GNU libc development, H . J . Lu, Florian Weimer

[-- Attachment #1: Type: text/plain, Size: 758 bytes --]

"Zack Weinberg" <zack@owlfolio.org> writes:

> On Fri, Jun 14, 2024, at 8:50 AM, Adhemerval Zanella wrote:
>> It is past time to not allow executable stacks as default, even if
>> kernel protection like SELinux already exists (although not widely
>> deployed).  Binutils 2.39 now warns of the need of executable stacks
>> by default [1] and gcc nested function trampolines can now be heap
>> based [2] (besides being a gcc-only extension).
>
> [...]
> 2.43 (one year after the release of 2.41), assuming hurd and hppa-linux
> have caught up:
>   - all support code for executable stacks permanently removed

HPPA is nearly there, we just need to flip the default in Binutils. I'll
look at it again shortly. I've been running with it locally for a while now.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 377 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] elf: Make non-executable stack disable by default
  2024-06-14 17:56   ` Zack Weinberg
  2024-06-14 18:02     ` Sam James
@ 2024-06-17 12:27     ` Adhemerval Zanella Netto
  1 sibling, 0 replies; 6+ messages in thread
From: Adhemerval Zanella Netto @ 2024-06-17 12:27 UTC (permalink / raw)
  To: Zack Weinberg, GNU libc development; +Cc: H . J . Lu, Florian Weimer



On 14/06/24 14:56, Zack Weinberg wrote:
> On Fri, Jun 14, 2024, at 8:50 AM, Adhemerval Zanella wrote:
>> It is past time to not allow executable stacks as default, even if
>> kernel protection like SELinux already exists (although not widely
>> deployed).  Binutils 2.39 now warns of the need of executable stacks
>> by default [1] and gcc nested function trampolines can now be heap
>> based [2] (besides being a gcc-only extension).
> 
> I want to be clear that I fully support disallowing executable stacks
> by default, and, in fact, removing the code to support them.  If Florian
> thinks we need a transition period, then I believe him, but I think
> we should be loud and specific about the timeline toward complete
> removal, and that timeline should be as short as possible.
> Something like:
> 
> 2.40:
>   - executable stacks disabled for setuid binaries and dlopened
>     modules, with no override
>   - for non-setuid binaries, an executable stack will continue
>     to be provided based on PT_GNU_EXECSTACK, but we only
>     look at the main executable and its static dependencies
>     for that annotation
>   - tunable allows executable stacks to be turned off system-wide
> 
> 2.41:
>   - flip the default for the tunable: executable stacks are off
>     system-wide but can be re-enabled (for binaries that request them)
> 
> 2.43 (one year after the release of 2.41), assuming hurd and hppa-linux
> have caught up:
>   - all support code for executable stacks permanently removed
> 
>> For compatibility, a new tunable, glibc.rtld.noexecstack

Thanks for the feedback and this seems reasonable.  I will update my
patch to:

  1. Remove the executable stack switch that change the stack permission
     all running thread on dlopen case.  This would remove the support of
     loading a module with executable stack from a process with nx-stack
     set for setuid and non-setuid binaries.

     If the main process requires an executable stack, the loader and libc
     will continue to both change the top of stack permission and create
     executable stack with executable bit.

  2. Add a tunable to disable executable stacks altogether, and defaults
     it to not enforce it.

  3. Remove executable stack support altogether from setuid binaries.

And later on 2.41 we can switch the tunable default to disable executable
stacks.

> 
> Can we please call this tunable glibc.rtld.execstack instead of
> glibc.rtld.noexecstack, with a value of 0 meaning executable
> stacks are forbidden and 1 meaning they are allowed?  The double
> negative is going to confuse people.

Yeah, I am unsure about the naming (I used the usual binutils naming
to disable stack on x86).  I will change to execstack.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-06-17 12:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-14 12:50 [PATCH v2 0/2] Make non-executable stack disable by default Adhemerval Zanella
2024-06-14 12:50 ` [PATCH v2 1/2] elf: Consolidate stackinfo.h Adhemerval Zanella
2024-06-14 12:50 ` [PATCH v2 2/2] elf: Make non-executable stack disable by default Adhemerval Zanella
2024-06-14 17:56   ` Zack Weinberg
2024-06-14 18:02     ` Sam James
2024-06-17 12:27     ` Adhemerval Zanella Netto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).