summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2019-01-16 12:12:40 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2019-01-16 12:12:40 +0000
commit9b35e90238589365e9b86f45fd4f74c759cebc4b (patch)
treeb2dec7b8a48a0ca8ef1ed8df100564a7d7c5b2f9 /libexec
parent8733962697c0ace5e8fee3fc122d8b85192b6d3f (diff)
downloadsrc-test2-9b35e90238589365e9b86f45fd4f74c759cebc4b.tar.gz
src-test2-9b35e90238589365e9b86f45fd4f74c759cebc4b.zip
Implement dlopenat(3).
MFC after: 3 weeks
Notes
Notes: svn path=/head/; revision=343093
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 1a2a0089bb7a..2014bf0d3fea 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -93,8 +93,8 @@ static void digest_dynamic(Obj_Entry *, int);
static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
static Obj_Entry *dlcheck(void *);
static int dlclose_locked(void *, RtldLockState *);
-static Obj_Entry *dlopen_object(const char *name, int fd, Obj_Entry *refobj,
- int lo_flags, int mode, RtldLockState *lockstate);
+static Obj_Entry *dlopen_object(int, const char *name, int fd,
+ Obj_Entry *refobj, int lo_flags, int mode, RtldLockState *lockstate);
static Obj_Entry *do_load_object(int, const char *, char *, struct stat *, int);
static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *);
static bool donelist_check(DoneList *, const Obj_Entry *);
@@ -118,7 +118,7 @@ static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
static void unload_filtees(Obj_Entry *, RtldLockState *);
static int load_needed_objects(Obj_Entry *, int);
static int load_preload_objects(void);
-static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
+static Obj_Entry *load_object(int, const char *, int, const Obj_Entry *, int);
static void map_stacks_exec(RtldLockState *);
static int obj_disable_relro(Obj_Entry *);
static int obj_enforce_relro(Obj_Entry *);
@@ -147,7 +147,7 @@ static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, int,
static int resolve_object_ifunc(Obj_Entry *, bool, int, RtldLockState *);
static int rtld_dirname(const char *, char *);
static int rtld_dirname_abs(const char *, char *);
-static void *rtld_dlopen(const char *name, int fd, int mode);
+static void *rtld_dlopen(int, const char *name, int fd, int mode);
static void rtld_exit(void);
static char *search_library_path(const char *, const char *, const char *,
int *);
@@ -231,6 +231,7 @@ extern Elf_Dyn _DYNAMIC;
int dlclose(void *) __exported;
char *dlerror(void) __exported;
void *dlopen(const char *, int) __exported;
+void *dlopenat(int, const char *, int) __exported;
void *fdlopen(int, int) __exported;
void *dlsym(void *, const char *) __exported;
dlfunc_t dlfunc(void *, const char *) __exported;
@@ -2292,8 +2293,8 @@ load_filtee1(Obj_Entry *obj, Needed_Entry *needed, int flags,
{
for (; needed != NULL; needed = needed->next) {
- needed->obj = dlopen_object(obj->strtab + needed->name, -1, obj,
- flags, ((ld_loadfltr || obj->z_loadfltr) ? RTLD_NOW : RTLD_LAZY) |
+ needed->obj = dlopen_object(AT_FDCWD, obj->strtab + needed->name, -1,
+ obj, flags, ((ld_loadfltr || obj->z_loadfltr) ? RTLD_NOW : RTLD_LAZY) |
RTLD_LOCAL, lockstate);
}
}
@@ -2316,8 +2317,8 @@ process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
Obj_Entry *obj1;
for (; needed != NULL; needed = needed->next) {
- obj1 = needed->obj = load_object(obj->strtab + needed->name, -1, obj,
- flags & ~RTLD_LO_NOLOAD);
+ obj1 = needed->obj = load_object(AT_FDCWD, obj->strtab + needed->name,
+ -1, obj, flags & ~RTLD_LO_NOLOAD);
if (obj1 == NULL && !ld_tracing && (flags & RTLD_LO_FILTEES) == 0)
return (-1);
}
@@ -2360,7 +2361,7 @@ load_preload_objects(void)
savech = p[len];
p[len] = '\0';
- obj = load_object(p, -1, NULL, 0);
+ obj = load_object(AT_FDCWD, p, -1, NULL, 0);
if (obj == NULL)
return -1; /* XXX - cleanup */
obj->z_interpose = true;
@@ -2389,7 +2390,8 @@ printable_path(const char *path)
* on failure.
*/
static Obj_Entry *
-load_object(const char *name, int fd_u, const Obj_Entry *refobj, int flags)
+load_object(int atfd, const char *name, int fd_u, const Obj_Entry *refobj,
+ int flags)
{
Obj_Entry *obj;
int fd;
@@ -2426,7 +2428,7 @@ load_object(const char *name, int fd_u, const Obj_Entry *refobj, int flags)
* To avoid a race, we open the file and use fstat() rather than
* using stat().
*/
- if ((fd = open(path, O_RDONLY | O_CLOEXEC | O_VERIFY)) == -1) {
+ if ((fd = openat(atfd, path, O_RDONLY | O_CLOEXEC | O_VERIFY)) == -1) {
_rtld_error("Cannot open \"%s\"", path);
free(path);
return (NULL);
@@ -3255,21 +3257,28 @@ dllockinit(void *context,
}
void *
+dlopenat(int fd, const char *name, int mode)
+{
+
+ return (rtld_dlopen(fd, name, -1, mode));
+}
+
+void *
dlopen(const char *name, int mode)
{
- return (rtld_dlopen(name, -1, mode));
+ return (rtld_dlopen(AT_FDCWD, name, -1, mode));
}
void *
fdlopen(int fd, int mode)
{
- return (rtld_dlopen(NULL, fd, mode));
+ return (rtld_dlopen(AT_FDCWD, NULL, fd, mode));
}
static void *
-rtld_dlopen(const char *name, int fd, int mode)
+rtld_dlopen(int atfd, const char *name, int fd, int mode)
{
RtldLockState lockstate;
int lo_flags;
@@ -3291,7 +3300,7 @@ rtld_dlopen(const char *name, int fd, int mode)
if (ld_tracing != NULL)
lo_flags |= RTLD_LO_TRACE;
- return (dlopen_object(name, fd, obj_main, lo_flags,
+ return (dlopen_object(atfd, name, fd, obj_main, lo_flags,
mode & (RTLD_MODEMASK | RTLD_GLOBAL), NULL));
}
@@ -3306,8 +3315,8 @@ dlopen_cleanup(Obj_Entry *obj, RtldLockState *lockstate)
}
static Obj_Entry *
-dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
- int mode, RtldLockState *lockstate)
+dlopen_object(int atfd, const char *name, int fd, Obj_Entry *refobj,
+ int lo_flags, int mode, RtldLockState *lockstate)
{
Obj_Entry *old_obj_tail;
Obj_Entry *obj;
@@ -3329,7 +3338,7 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
obj = obj_main;
obj->refcount++;
} else {
- obj = load_object(name, fd, refobj, lo_flags);
+ obj = load_object(atfd, name, fd, refobj, lo_flags);
}
if (obj) {