diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2019-01-16 12:12:40 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2019-01-16 12:12:40 +0000 |
commit | 9b35e90238589365e9b86f45fd4f74c759cebc4b (patch) | |
tree | b2dec7b8a48a0ca8ef1ed8df100564a7d7c5b2f9 /libexec | |
parent | 8733962697c0ace5e8fee3fc122d8b85192b6d3f (diff) | |
download | src-9b35e90238589365e9b86f45fd4f74c759cebc4b.tar.gz src-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.c | 45 |
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) { |