[PATCH v7 2/4] elf: Do not change stack permission on dlopen/dlmopen
Stafford Horne
shorne@gmail.com
Mon Jan 6 11:19:04 GMT 2025
On Mon, Jan 06, 2025 at 09:47:29AM +0000, Stafford Horne wrote:
> 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.
I was able to fix this in GCC by marking a .note.GNU-stack in one of the
libgcc helper files that was missing it.
After this the or1k libgcc_s.so.1 file no longer needs an executable stack. I
will run a few more tests on this before pushing upstream to gcc.
-Stafford
> > [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