diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2024-11-28 14:36:43 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2024-12-31 09:04:20 -0300 |
commit | 0ca8785a28515291d4ef074b5b6cfb27434c1d2b (patch) | |
tree | ba0b23b8b1bcef4d2717f1d605d32ef11518430c /sysdeps/generic | |
parent | ca96ea06b37c8601dcc9579dd4c8619322ab1ea1 (diff) | |
download | glibc-0ca8785a28515291d4ef074b5b6cfb27434c1d2b.zip glibc-0ca8785a28515291d4ef074b5b6cfb27434c1d2b.tar.gz glibc-0ca8785a28515291d4ef074b5b6cfb27434c1d2b.tar.bz2 |
elf: Do not change stack permission on dlopen/dlmopen
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 a 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.
[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.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 22 |
1 files changed, 4 insertions, 18 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index cec56e2..172bcd2 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -399,13 +399,6 @@ struct rtld_global #endif #include <dl-procruntime.c> -#if !PTHREAD_IN_LIBC - /* If loading a shared object requires that we make the stack executable - when it was not, we do it by calling this function. - It returns an errno code or zero on success. */ - EXTERN int (*_dl_make_stack_executable_hook) (void **); -#endif - /* Prevailing state of the stack, PF_X indicating it's executable. */ EXTERN ElfW(Word) _dl_stack_flags; @@ -702,17 +695,10 @@ extern const ElfW(Phdr) *_dl_phdr; extern size_t _dl_phnum; #endif -#if PTHREAD_IN_LIBC -/* This function changes the permissions of all stacks (not just those - of the main stack). */ -int _dl_make_stacks_executable (void **stack_endp) attribute_hidden; -#else -/* This is the initial value of GL(dl_make_stack_executable_hook). - A threads library can change it. The ld.so implementation changes - the permissions of the main stack only. */ -extern int _dl_make_stack_executable (void **stack_endp); -rtld_hidden_proto (_dl_make_stack_executable) -#endif +/* This function changes the permission of the memory region pointed + by STACK_ENDP to executable and update the internal memory protection + flags for future thread stack creation. */ +int _dl_make_stack_executable (void **stack_endp) attribute_hidden; /* Variable pointing to the end of the stack (or close to it). This value must be constant over the runtime of the application. Some programs |