mbox series

[v4,0/4] Improve executable stack handling

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

Message

Adhemerval Zanella Netto July 25, 2024, 8:05 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 second patch 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 fourth patch also adds a tunable, glibc.rtld.execstack, which can be
used to control whether executable stacks are allowed from either the
main program or dependencies.  The default is to allow 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

--

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                                        |  10 +-
 elf/Makefile                                |  49 +++++++
 elf/dl-load.c                               |  13 +-
 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                         | 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/stackinfo.h                 |  15 ++-
 sysdeps/loongarch/stackinfo.h               |  33 -----
 sysdeps/nios2/stackinfo.h                   |  33 -----
 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 +
 23 files changed, 180 insertions(+), 389 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
 delete mode 100644 sysdeps/nios2/stackinfo.h
 rename sysdeps/powerpc/{ => powerpc32}/stackinfo.h (82%)
 delete mode 100644 sysdeps/riscv/stackinfo.h

Comments

Adhemerval Zanella Netto Aug. 14, 2024, 6:44 p.m. UTC | #1
Ping.

On 25/07/24 17:05, Adhemerval Zanella wrote:
> 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 second patch 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 fourth patch also adds a tunable, glibc.rtld.execstack, which can be
> used to control whether executable stacks are allowed from either the
> main program or dependencies.  The default is to allow 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
> 
> --
> 
> 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                                        |  10 +-
>  elf/Makefile                                |  49 +++++++
>  elf/dl-load.c                               |  13 +-
>  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                         | 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/stackinfo.h                 |  15 ++-
>  sysdeps/loongarch/stackinfo.h               |  33 -----
>  sysdeps/nios2/stackinfo.h                   |  33 -----
>  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 +
>  23 files changed, 180 insertions(+), 389 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
>  delete mode 100644 sysdeps/nios2/stackinfo.h
>  rename sysdeps/powerpc/{ => powerpc32}/stackinfo.h (82%)
>  delete mode 100644 sysdeps/riscv/stackinfo.h
>
Adhemerval Zanella Netto Oct. 10, 2024, 1:33 p.m. UTC | #2
Ping (x2).

On 14/08/24 15:44, Adhemerval Zanella Netto wrote:
> Ping.
> 
> On 25/07/24 17:05, Adhemerval Zanella wrote:
>> 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 second patch 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 fourth patch also adds a tunable, glibc.rtld.execstack, which can be
>> used to control whether executable stacks are allowed from either the
>> main program or dependencies.  The default is to allow 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
>>
>> --
>>
>> 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                                        |  10 +-
>>  elf/Makefile                                |  49 +++++++
>>  elf/dl-load.c                               |  13 +-
>>  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                         | 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/stackinfo.h                 |  15 ++-
>>  sysdeps/loongarch/stackinfo.h               |  33 -----
>>  sysdeps/nios2/stackinfo.h                   |  33 -----
>>  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 +
>>  23 files changed, 180 insertions(+), 389 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
>>  delete mode 100644 sysdeps/nios2/stackinfo.h
>>  rename sysdeps/powerpc/{ => powerpc32}/stackinfo.h (82%)
>>  delete mode 100644 sysdeps/riscv/stackinfo.h
>>