aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-open.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2018-02-21 10:37:22 +0100
committerFlorian Weimer <fweimer@redhat.com>2018-02-21 10:37:22 +0100
commit52a01100ad011293197637e42b5be1a479a2f4ae (patch)
tree8bfbd570b7eda10ee7de5fcb8ce430c1043af0f0 /elf/dl-open.c
parentb5bf62e40c5ff4e3906572f257dcda77b393ffa0 (diff)
downloadglibc-52a01100ad011293197637e42b5be1a479a2f4ae.zip
glibc-52a01100ad011293197637e42b5be1a479a2f4ae.tar.gz
glibc-52a01100ad011293197637e42b5be1a479a2f4ae.tar.bz2
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 'elf/dl-open.c')
-rw-r--r--elf/dl-open.c9
1 files changed, 0 insertions, 9 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 0e37dd7..9dde4ac 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -28,7 +28,6 @@
#include <sys/param.h>
#include <libc-lock.h>
#include <ldsodefs.h>
-#include <caller.h>
#include <sysdep-cancel.h>
#include <tls.h>
#include <stap-probe.h>
@@ -47,8 +46,6 @@ struct dl_open_args
int mode;
/* This is the caller of the dlopen() function. */
const void *caller_dlopen;
- /* This is the caller of _dl_open(). */
- const void *caller_dl_open;
struct link_map *map;
/* Namespace ID. */
Lmid_t nsid;
@@ -187,11 +184,6 @@ dl_open_worker (void *a)
int mode = args->mode;
struct link_map *call_map = NULL;
- /* Check whether _dl_open() has been called from a valid DSO. */
- if (__check_caller (args->caller_dl_open,
- allow_libc|allow_libdl|allow_ldso) != 0)
- _dl_signal_error (0, "dlopen", NULL, N_("invalid caller"));
-
/* Determine the caller's map if necessary. This is needed in case
we have a DST, when we don't know the namespace ID we have to put
the new object in, or when the file name has no path in which
@@ -583,7 +575,6 @@ no more namespaces available for dlmopen()"));
args.file = file;
args.mode = mode;
args.caller_dlopen = caller_dlopen;
- args.caller_dl_open = RETURN_ADDRESS (0);
args.map = NULL;
args.nsid = nsid;
args.argc = argc;