[PATCH v7 2/4] elf: Do not change stack permission on dlopen/dlmopen
Stafford Horne
shorne@gmail.com
Mon Jan 6 09:47:29 GMT 2025
On Thu, Dec 26, 2024 at 02:57:43PM -0300, 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 __nptl_change_stack_perm failure does not
> undo the previous executable transition (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.
>
> This patch changes that 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.
Note,
This causes an issue on OpenRISC which I found when running machine testing
for 2.41. I bisected the issue to this commit.
Many tests are failing with (example nptl/tst-robust1):
libgcc_s.so.1 must be installed for pthread_cancel to work
make[2]: Leaving directory '/home/shorne/work/gnu-toolchain/glibc/nptl'
FAIL: nptl/tst-robust1
original exit status 1
Didn't expect signal from child: got `Aborted'
make[1]: Leaving directory '/home/shorne/work/gnu-toolchain/glibc'
I do have libgcc_s.so.1, but dlopen seems to be failing due to having an
executable stack header.
$ readelf -l /home/shorne/work/gnu-toolchain/build-glibc/nptl/tst-robust1
Elf file type is DYN (Position-Independent Executable file)
Entry point 0x185c
There are 9 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x00120 0x00120 R 0x4
INTERP 0x0042ac 0x000042ac 0x000042ac 0x00018 0x00018 R 0x1
[Requesting program interpreter: /lib/ld-linux-or1k.so.1]
LOAD 0x000000 0x00000000 0x00000000 0x0464c 0x0464c R E 0x2000
LOAD 0x005ecc 0x00007ecc 0x00007ecc 0x0028c 0x002f0 RW 0x2000
DYNAMIC 0x005f18 0x00007f18 0x00007f18 0x000e8 0x000e8 RW 0x4
NOTE 0x00462c 0x0000462c 0x0000462c 0x00020 0x00020 R 0x4
GNU_EH_FRAME 0x0042c4 0x000042c4 0x000042c4 0x00094 0x00094 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10 <-- test RW
GNU_RELRO 0x005ecc 0x00007ecc 0x00007ecc 0x00134 0x00134 R 0x1
$ readelf -l ~/work/openrisc/buildroot/output/target/lib/libgcc_s.so.1
Elf file type is DYN (Shared object file)
Entry point 0x0
There are 6 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x00000000 0x00000000 0x1c348 0x1c348 R E 0x2000
LOAD 0x01df04 0x0001ff04 0x0001ff04 0x00208 0x002e4 RW 0x2000
DYNAMIC 0x01df10 0x0001ff10 0x0001ff10 0x000f0 0x000f0 RW 0x4
GNU_EH_FRAME 0x01b234 0x0001b234 0x0001b234 0x00294 0x00294 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10 <-- module RWE
GNU_RELRO 0x01df04 0x0001ff04 0x0001ff04 0x000fc 0x000fc R 0x1
I will look to fixing this by seeing if I can get GCC to not need to have an
executable stack for libgcc_s.so.1. But it will mean running new glibc with old
gcc installs may have some issues.
If you have any suggestions let me know.
> [1] https://www.qualys.com/2023/07/19/cve-2023-38408/rce-openssh-forwarded-ssh-agent.txt
>
> Checked on x86_64-linux-gnu and i686-linux-gnu.
> ---
> NEWS | 6 +++
> elf/dl-load.c | 13 ++---
> elf/dl-support.c | 4 --
> elf/rtld.c | 6 ---
> elf/tst-execstack.c | 62 +++++++++++++++---------
> nptl/allocatestack.c | 19 --------
> sysdeps/generic/ldsodefs.h | 22 ++-------
> sysdeps/mach/hurd/Makefile | 2 +
> sysdeps/mach/hurd/dl-execstack.c | 1 -
> sysdeps/nptl/pthreadP.h | 6 ---
> sysdeps/unix/sysv/linux/Versions | 3 --
> sysdeps/unix/sysv/linux/dl-execstack.c | 67 +-------------------------
> sysdeps/unix/sysv/linux/mips/Makefile | 7 +++
> 13 files changed, 66 insertions(+), 152 deletions(-)
[snip]
-Stafford
More information about the Libc-alpha
mailing list