From owner-svn-src-stable-11@freebsd.org Thu Jan 16 10:35:48 2020 Return-Path: Delivered-To: svn-src-stable-11@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 25031231E1B; Thu, 16 Jan 2020 10:35:48 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47z0w40Bdnz3Jp2; Thu, 16 Jan 2020 10:35:48 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 01DC31E0EB; Thu, 16 Jan 2020 10:35:48 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 00GAZlUQ045845; Thu, 16 Jan 2020 10:35:47 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 00GAZl7K045844; Thu, 16 Jan 2020 10:35:47 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202001161035.00GAZl7K045844@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 16 Jan 2020 10:35:47 +0000 (UTC) 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 X-SVN-Group: stable-11 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: stable/11/libexec/rtld-elf X-SVN-Commit-Revision: 356785 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jan 2020 10:35:48 -0000 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);