tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
dlopen interception on libasan
Well, the problem in PR/51670 is that with -fsanitizer=address the
dlopen interception is broken. libasan.so provides its own dlopen()
and then tries to find the real dlopen using dlsym(RTLD_NEXT,
"dlopen"). That does not work for NetBSD because dlopen in libc is
just a stub (that perhaps should abort), and the real dlopen is in
ld.elf_so itself. Unfortunately we can't get to it anymore easily
because RTLD_DEFAULT, RTLD_SELF, RTLD_NEXT, NULL all return the
wrong dlopen(). A simple fix is to provide RTLD_DL that returns
symbols defined by the dynamic linker. Here's a patch that does
this. Unless I hear otherwise I am planning to commit this soon.
christos
Index: include/dlfcn.h
===================================================================
RCS file: /cvsroot/src/include/dlfcn.h,v
retrieving revision 1.24
diff -u -u -r1.24 dlfcn.h
--- include/dlfcn.h 16 Feb 2012 23:00:39 -0000 1.24
+++ include/dlfcn.h 30 Nov 2016 01:28:01 -0000
@@ -80,6 +80,7 @@
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search the caller itself. */
+#define RTLD_DL ((void *) -4) /* Search only the dynamic linker */
/*
* dlctl() commands
Index: external/gpl3/gcc/dist/libsanitizer/interception/interception_linux.cc
===================================================================
RCS file: /cvsroot/src/external/gpl3/gcc/dist/libsanitizer/interception/interception_linux.cc,v
retrieving revision 1.4
diff -u -u -r1.4 interception_linux.cc
--- external/gpl3/gcc/dist/libsanitizer/interception/interception_linux.cc 24 Jan 2016 09:43:38 -0000 1.4
+++ external/gpl3/gcc/dist/libsanitizer/interception/interception_linux.cc 30 Nov 2016 01:28:01 -0000
@@ -28,12 +28,16 @@
namespace __interception {
bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
uptr real, uptr wrapper) {
+ void *w = RTLD_NEXT;
#ifdef __NetBSD__
// XXX: Until I come up with something better to deal with renames.
if (mystrcmp(func_name, "sigaction") == 0)
func_name = "__sigaction14";
+ if (mystrcmp(func_name, "dlopen") == 0 || mystrcmp(func_name, "dlclose") == 0)
+ w = RTLD_DL;
+
#endif
- *func_addr = (uptr)dlsym(RTLD_NEXT, func_name);
+ *func_addr = (uptr)dlsym(w, func_name);
return real == wrapper;
}
Index: libexec/ld.elf_so/rtld.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.178
diff -u -u -r1.178 rtld.c
--- libexec/ld.elf_so/rtld.c 24 May 2016 20:32:33 -0000 1.178
+++ libexec/ld.elf_so/rtld.c 30 Nov 2016 01:28:02 -0000
@@ -1106,6 +1106,9 @@
defobj = NULL;
switch ((intptr_t)handle) {
+ case (intptr_t)RTLD_DL:
+ obj = &_rtld_objself;
+ goto gotobj;
case (intptr_t)NULL:
case (intptr_t)RTLD_NEXT:
case (intptr_t)RTLD_DEFAULT:
@@ -1115,8 +1118,9 @@
lookup_mutex_exit();
return NULL;
}
-
+gotobj:
switch ((intptr_t)handle) {
+ case (intptr_t)RTLD_DL:
case (intptr_t)NULL: /* Just the caller's shared object. */
def = _rtld_symlook_obj(name, hash, obj, flags, ventry);
defobj = obj;
Home |
Main Index |
Thread Index |
Old Index