|
Message-Id: <20230508181413.194379-3-pedro.falcato@gmail.com> Date: Mon, 8 May 2023 19:14:13 +0100 From: Pedro Falcato <pedro.falcato@...il.com> To: musl@...ts.openwall.com Cc: Pedro Falcato <pedro.falcato@...il.com> Subject: [RFC PATCH 2/2] ldso: Add fdlopen Add fdlopen as specified and implemented in FreeBSD (see fdlopen(3) in the FreeBSD manpages). Signed-off-by: Pedro Falcato <pedro.falcato@...il.com> --- include/dlfcn.h | 1 + ldso/dynlink.c | 43 +++++++++++++++++++++++++++++++++++++++---- src/ldso/fdlopen.c | 10 ++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/ldso/fdlopen.c diff --git a/include/dlfcn.h b/include/dlfcn.h index 13ab71dd..6a01106d 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -33,6 +33,7 @@ typedef struct { } Dl_info; int dladdr(const void *, Dl_info *); int dlinfo(void *, int, void *); +void *fdlopen(int, int); #endif #if _REDIR_TIME64 diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 2272b768..161dde52 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -2040,7 +2040,7 @@ static void prepare_lazy(struct dso *p) lazy_head = p; } -void *dlopen(const char *file, int mode) +static void *dlopen_internal(int fd, const char *file, int mode) { struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next; struct tls_module *orig_tls_tail; @@ -2050,8 +2050,6 @@ void *dlopen(const char *file, int mode) jmp_buf jb; struct dso **volatile ctor_queue = 0; - if (!file) return head; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); pthread_rwlock_wrlock(&lock); __inhibit_ptc(); @@ -2104,7 +2102,32 @@ void *dlopen(const char *file, int mode) tail->next = 0; p = 0; goto end; - } else p = load_library(file, head); + } else { + if (fd != -1) { + /* We were called from fdlopen. First, we must dup the fd (as FreeBSD does). */ + fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); + if (fd < 0) { + error("Failed to duplicate file descriptor: %m"); + goto end; + } + + /* Now try to figure out the path using procfs. If we fail, use a fallback. */ + char path[PATH_MAX + 1]; + const char *pathname = path; + + __procfdname(path, fd); + ssize_t st = readlink(path, path, PATH_MAX); + if (st < 0) { + pathname = "<anon_fdlopen>"; + } else { + path[st] = '\0'; + } + + p = load_library_core(fd, head, pathname, pathname); + } else { + p = load_library(file, head); + } + } if (!p) { error(noload ? @@ -2167,6 +2190,18 @@ end: return p; } +void *fdlopen(int fd, int mode) +{ + if (fd == -1) return head; + return dlopen_internal(fd, 0, mode); +} + +void *dlopen(const char *file, int mode) +{ + if (!file) return head; + return dlopen_internal(-1, file, mode); +} + hidden int __dl_invalid_handle(void *h) { struct dso *p; diff --git a/src/ldso/fdlopen.c b/src/ldso/fdlopen.c new file mode 100644 index 00000000..a9380b57 --- /dev/null +++ b/src/ldso/fdlopen.c @@ -0,0 +1,10 @@ +#include <dlfcn.h> +#include "dynlink.h" + +static void *stub_fdlopen(int fd, int mode) +{ + __dl_seterr("Dynamic loading not supported"); + return 0; +} + +weak_alias(stub_fdlopen, fdlopen); -- 2.40.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.