diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2020-01-16 10:25:47 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2020-01-16 10:25:47 +0000 |
| commit | caca492fe2dcd7426ed63ac124da54384569024b (patch) | |
| tree | 3a1806cbd74cbbe95e44e0cf456198843eb98d8c /libexec/rtld-elf/rtld.c | |
| parent | 457bb816c369249fb1fd3a8468d679696f8be6d6 (diff) | |
Notes
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
| -rw-r--r-- | libexec/rtld-elf/rtld.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index cddb0f7c2e46..c5303e861a99 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -88,9 +88,9 @@ extern void (*__cleanup)(void); static const char *basename(const char *); static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **, const Elf_Dyn **, const Elf_Dyn **); -static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *, +static bool digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *, const Elf_Dyn *); -static void digest_dynamic(Obj_Entry *, int); +static bool digest_dynamic(Obj_Entry *, int); static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *); static void distribute_static_tls(Objlist *, RtldLockState *); static Obj_Entry *dlcheck(void *); @@ -640,7 +640,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) } #endif - digest_dynamic(obj_main, 0); + if (!digest_dynamic(obj_main, 0)) + rtld_die(); dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", obj_main->path, obj_main->valid_hash_sysv, obj_main->valid_hash_gnu, obj_main->dynsymcount); @@ -1364,13 +1365,13 @@ obj_resolve_origin(Obj_Entry *obj) return (rtld_dirname_abs(obj->path, obj->origin_path) != -1); } -static void +static bool digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath, const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath) { if (obj->z_origin && !obj_resolve_origin(obj)) - rtld_die(); + return (false); if (dyn_runpath != NULL) { obj->runpath = (const char *)obj->strtab + dyn_runpath->d_un.d_val; @@ -1381,9 +1382,10 @@ digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath, } if (dyn_soname != NULL) object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val); + return (true); } -static void +static bool digest_dynamic(Obj_Entry *obj, int early) { const Elf_Dyn *dyn_rpath; @@ -1391,7 +1393,7 @@ digest_dynamic(Obj_Entry *obj, int early) const Elf_Dyn *dyn_runpath; digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath); - digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath); + return (digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath)); } /* @@ -2521,16 +2523,15 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp, if (name != NULL) object_add_name(obj, name); obj->path = path; - digest_dynamic(obj, 0); + if (!digest_dynamic(obj, 0)) + goto errp; dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", obj->path, obj->valid_hash_sysv, obj->valid_hash_gnu, obj->dynsymcount); if (obj->z_noopen && (flags & (RTLD_LO_DLOPEN | RTLD_LO_TRACE)) == RTLD_LO_DLOPEN) { dbg("refusing to load non-loadable \"%s\"", obj->path); _rtld_error("Cannot dlopen non-loadable %s", obj->path); - munmap(obj->mapbase, obj->mapsize); - obj_free(obj); - return (NULL); + goto errp; } obj->dlopened = (flags & RTLD_LO_DLOPEN) != 0; @@ -2547,7 +2548,12 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp, LD_UTRACE(UTRACE_LOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0, obj->path); - return obj; + return (obj); + +errp: + munmap(obj->mapbase, obj->mapsize); + obj_free(obj); + return (NULL); } static Obj_Entry * @@ -3948,12 +3954,17 @@ rtld_dirname_abs(const char *path, char *base) { char *last; - if (realpath(path, base) == NULL) + if (realpath(path, base) == NULL) { + _rtld_error("realpath \"%s\" failed (%s)", path, + rtld_strerror(errno)); return (-1); + } dbg("%s -> %s", path, base); last = strrchr(base, '/'); - if (last == NULL) + if (last == NULL) { + _rtld_error("non-abs result from realpath \"%s\"", path); return (-1); + } if (last != base) *last = '\0'; return (0); |
