Date: Thu, 16 Jan 2020 10:35:47 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r356785 - stable/11/libexec/rtld-elf Message-ID: <202001161035.00GAZl7K045844@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Jan 16 10:35:47 2020 New Revision: 356785 URL: https://svnweb.freebsd.org/changeset/base/356785 Log: MFC r356549: rtld: Return error if $ORIGIN for a dlopen-ed library cannot be resolved. Modified: stable/11/libexec/rtld-elf/rtld.c Directory Properties: stable/11/ (props changed) Modified: stable/11/libexec/rtld-elf/rtld.c ============================================================================== --- stable/11/libexec/rtld-elf/rtld.c Thu Jan 16 10:25:47 2020 (r356784) +++ stable/11/libexec/rtld-elf/rtld.c Thu Jan 16 10:35:47 2020 (r356785) @@ -77,9 +77,9 @@ typedef void * (*path_enum_proc) (const char *path, si 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 *); @@ -645,7 +645,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr } #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); @@ -1359,13 +1360,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 = (char *)obj->strtab + dyn_runpath->d_un.d_val; @@ -1376,9 +1377,10 @@ digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpa } 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; @@ -1386,7 +1388,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)); } /* @@ -2506,16 +2508,15 @@ do_load_object(int fd, const char *name, char *path, s 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; @@ -2532,7 +2533,12 @@ do_load_object(int fd, const char *name, char *path, s 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 * @@ -3933,12 +3939,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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001161035.00GAZl7K045844>