diff options
author | Florian Weimer <fweimer@redhat.com> | 2018-02-21 10:37:22 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2018-02-21 10:37:22 +0100 |
commit | 52a01100ad011293197637e42b5be1a479a2f4ae (patch) | |
tree | 8bfbd570b7eda10ee7de5fcb8ce430c1043af0f0 /sysdeps | |
parent | b5bf62e40c5ff4e3906572f257dcda77b393ffa0 (diff) | |
download | glibc-52a01100ad011293197637e42b5be1a479a2f4ae.tar.gz glibc-52a01100ad011293197637e42b5be1a479a2f4ae.tar.xz glibc-52a01100ad011293197637e42b5be1a479a2f4ae.zip |
elf: Remove ad-hoc restrictions on dlopen callers [BZ #22787]
This looks like a post-exploitation hardening measure: If an attacker is able to redirect execution flow, they could use that to load a DSO which contains additional code (or perhaps make the stack executable). However, the checks are not in the correct place to be effective: If they are performed before the critical operation, an attacker with sufficient control over execution flow could simply jump directly to the code which performs the operation, bypassing the check. The check would have to be executed unconditionally after the operation and terminate the process in case a caller violation was detected. Furthermore, in _dl_check_caller, there was a fallback reading global writable data (GL(dl_rtld_map).l_map_start and GL(dl_rtld_map).l_text_end), which could conceivably be targeted by an attacker to disable the check, too. Other critical functions (such as system) remain completely unprotected, so the value of these additional checks does not appear that large. Therefore this commit removes this functionality.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 5 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/dl-execstack.c | 7 |
2 files changed, 0 insertions, 12 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 0ea27865c0..5e1b24ecb5 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -596,7 +596,6 @@ struct rtld_global_ro const ElfW(Sym) **, struct r_scope_elem *[], const struct r_found_version *, int, int, struct link_map *); - int (*_dl_check_caller) (const void *, enum allowmask); void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, int argc, char *argv[], char *env[]); void (*_dl_close) (void *map); @@ -1102,10 +1101,6 @@ extern size_t _dl_dst_count (const char *name) attribute_hidden; extern char *_dl_dst_substitute (struct link_map *l, const char *name, char *result) attribute_hidden; -/* Check validity of the caller. */ -extern int _dl_check_caller (const void *caller, enum allowmask mask) - attribute_hidden; - /* Open the shared object NAME, relocate it, and run its initializer if it hasn't already been run. MODE is as for `dlopen' (see <dlfcn.h>). If the object is already opened, returns its existing map. */ diff --git a/sysdeps/unix/sysv/linux/dl-execstack.c b/sysdeps/unix/sysv/linux/dl-execstack.c index c36d809d02..8ea69bdde3 100644 --- a/sysdeps/unix/sysv/linux/dl-execstack.c +++ b/sysdeps/unix/sysv/linux/dl-execstack.c @@ -22,7 +22,6 @@ #include <libintl.h> #include <stdbool.h> #include <stackinfo.h> -#include <caller.h> #include <sysdep.h> @@ -37,12 +36,6 @@ _dl_make_stack_executable (void **stack_endp) & -(intptr_t) GLRO(dl_pagesize)); int result = 0; - /* Challenge the caller. */ - if (__builtin_expect (__check_caller (RETURN_ADDRESS (0), - allow_ldso|allow_libpthread) != 0, 0) - || __builtin_expect (*stack_endp != __libc_stack_end, 0)) - return EPERM; - if (__builtin_expect (__mprotect ((void *) page, GLRO(dl_pagesize), __stack_prot) == 0, 1)) goto return_success; |