libc dlfcn.c: make dl_iterate_phdr() from libc more useful
Apparently there are applications that resolve dl_iterate_phdr from libc and try to call the symbol. Our libc only provides stubs for dl* to satisfy static linker or statically linked binaries, and is not prepared to this situation. Add a code to dso libc to find real dl_iterate_phdr and redirect the call to it. Reported by: yuri PR: 272992 Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
+12
-3
@@ -169,7 +169,9 @@ _rtld_thread_init(void *li __unused)
|
|||||||
#ifndef IN_LIBDL
|
#ifndef IN_LIBDL
|
||||||
static pthread_once_t dl_phdr_info_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t dl_phdr_info_once = PTHREAD_ONCE_INIT;
|
||||||
static struct dl_phdr_info phdr_info;
|
static struct dl_phdr_info phdr_info;
|
||||||
|
#ifndef PIC
|
||||||
static mutex_t dl_phdr_info_lock = MUTEX_INITIALIZER;
|
static mutex_t dl_phdr_info_lock = MUTEX_INITIALIZER;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dl_init_phdr_info(void)
|
dl_init_phdr_info(void)
|
||||||
@@ -208,7 +210,16 @@ int
|
|||||||
dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *) __unused,
|
dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *) __unused,
|
||||||
void *data __unused)
|
void *data __unused)
|
||||||
{
|
{
|
||||||
#ifndef IN_LIBDL
|
#if defined IN_LIBDL
|
||||||
|
return (0);
|
||||||
|
#elif defined PIC
|
||||||
|
int (*r)(int (*)(struct dl_phdr_info *, size_t, void *), void *);
|
||||||
|
|
||||||
|
r = dlsym(RTLD_DEFAULT, "dl_iterate_phdr");
|
||||||
|
if (r == NULL)
|
||||||
|
return (0);
|
||||||
|
return (r(callback, data));
|
||||||
|
#else
|
||||||
tls_index ti;
|
tls_index ti;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -223,8 +234,6 @@ dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *) __unused,
|
|||||||
ret = callback(&phdr_info, sizeof(phdr_info), data);
|
ret = callback(&phdr_info, sizeof(phdr_info), data);
|
||||||
mutex_unlock(&dl_phdr_info_lock);
|
mutex_unlock(&dl_phdr_info_lock);
|
||||||
return (ret);
|
return (ret);
|
||||||
#else
|
|
||||||
return (0);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user