mbox series

[v5,0/4] Improve executable stack handling

Message ID 20241128173851.1920696-1-adhemerval.zanella@linaro.org
Headers show
Series Improve executable stack handling | expand

Message

Adhemerval Zanella Nov. 28, 2024, 5:36 p.m. UTC
If some shared library loaded with dlopen/dlmopen requires an executable
stack, either implicitly because of a missing GNU_STACK ELF header
(where the ABI default flags implies in the executable bit) or
explicitly because of the executable bit from GNU_STACK; the loader will
try to set the both the main thread and all thread stacks (from the
pthread cache) as executable.

Besides the issue where any executable stack transition failure does not
undo the previous transitions (meaning that if the library fails to load,
there can be thread stacks with executable stacks), this behavior was
used on recent CVE [1] as a vector for RCE.

The patchset changes the behavior where if a shared library requires an
executable stack, and the current stack is not executable, dlopen fails.
The change is done only for dynamically loaded modules, if the program or
any dependency requires an executable stack, the loader will still change
the main thread before program execution and any thread created with
default stack configuration.

The patchset also adds a tunable, glibc.rtld.execstack, which can control
whether executable stacks are allowed from either the main program or
dependencies.  The default is to enable executable stacks.

The executable stacks default permission is checked against the one
provided by the PT_GNU_STACK from program headers (if present).  The
tunable also disables the stack permission change if any dependency
requires an executable stack at loading time.

[1] https://www.qualys.com/2023/07/19/cve-2023-38408/rce-openssh-forwarded-ssh-agent.txt

--
Changes from v4:
- Rebased against master.
- Also adapt the new semantic for Hurd.
- Fixed the new tests to only run is make check is instructed to run the tests.

Changed from v3:
- Rebased against master.
- Improve the NEWS entry wording.

Changes from v2:
- Removed the dlopen executable stack support.
- Allow program and dependencies with executable stack as default.
- Rename tunable from glibc.rtld.noexecstack to glibc.rtld.execstack.

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

Adhemerval Zanella (4):
  elf: Consolidate stackinfo.h
  elf: Do not change stack permission on dlopen/dlmopen
  elf: Add tst-execstack-prog-static
  elf: Add glibc.rtld.execstack

 NEWS                                        |  11 ++
 elf/Makefile                                |  51 +++++++
 elf/dl-load.c                               |  15 ++-
 elf/dl-support.c                            |   9 +-
 elf/dl-tunables.list                        |   6 +
 elf/rtld.c                                  |  10 +-
 elf/tst-execstack-prog-static.c             |   1 +
 elf/tst-execstack.c                         | 142 ++++++++------------
 elf/tst-rtld-list-tunables.exp              |   1 +
 manual/tunables.texi                        |  19 +++
 nptl/allocatestack.c                        |  19 ---
 sysdeps/aarch64/stackinfo.h                 |  33 -----
 sysdeps/arc/stackinfo.h                     |  33 -----
 sysdeps/csky/stackinfo.h                    |  29 ----
 sysdeps/generic/ldsodefs.h                  |  22 +--
 sysdeps/generic/stackinfo.h                 |  15 ++-
 sysdeps/loongarch/stackinfo.h               |  33 -----
 sysdeps/mach/hurd/dl-execstack.c            |   1 -
 sysdeps/nptl/pthreadP.h                     |   6 -
 sysdeps/powerpc/{ => powerpc32}/stackinfo.h |   8 +-
 sysdeps/riscv/stackinfo.h                   |  33 -----
 sysdeps/unix/sysv/linux/Versions            |   3 -
 sysdeps/unix/sysv/linux/dl-execstack.c      |  67 +--------
 sysdeps/unix/sysv/linux/mips/Makefile       |   7 +
 24 files changed, 187 insertions(+), 387 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
 delete mode 100644 sysdeps/loongarch/stackinfo.h
 rename sysdeps/powerpc/{ => powerpc32}/stackinfo.h (82%)
 delete mode 100644 sysdeps/riscv/stackinfo.h