From owner-svn-src-head@FreeBSD.ORG Mon Apr 27 18:41:31 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D5291F0D; Mon, 27 Apr 2015 18:41:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C30991B24; Mon, 27 Apr 2015 18:41:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t3RIfVQM022729; Mon, 27 Apr 2015 18:41:31 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t3RIfVhf022728; Mon, 27 Apr 2015 18:41:31 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201504271841.t3RIfVhf022728@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Mon, 27 Apr 2015 18:41:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282109 - head/libexec/rtld-elf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Apr 2015 18:41:32 -0000 Author: kib Date: Mon Apr 27 18:41:31 2015 New Revision: 282109 URL: https://svnweb.freebsd.org/changeset/base/282109 Log: Change interpretation of the DF_ORIGIN and DF_1_ORIGIN flags. According to standard, the presence of the flags only means that the object path must be resolved at the time object loading, instead of my reading that the flag is required to enable token substitution at all. The consequence is that -z origin linker flag is no longer required for the token substitution in the run/rpath or the needed library soname. It is only recommended if token substition is needed at dlopen(3) time, since namecache might drop the required entries at the time of resolution. Found, reviewed and tested by: emaste Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/libexec/rtld-elf/rtld.c Modified: head/libexec/rtld-elf/rtld.c ============================================================================== --- head/libexec/rtld-elf/rtld.c Mon Apr 27 18:21:42 2015 (r282108) +++ head/libexec/rtld-elf/rtld.c Mon Apr 27 18:41:31 2015 (r282109) @@ -148,8 +148,10 @@ static void unlink_object(Obj_Entry *); static void unload_object(Obj_Entry *); static void unref_dag(Obj_Entry *); static void ref_dag(Obj_Entry *); -static char *origin_subst_one(char *, const char *, const char *, bool); -static char *origin_subst(char *, const char *); +static char *origin_subst_one(Obj_Entry *, char *, const char *, + const char *, bool); +static char *origin_subst(Obj_Entry *, char *); +static bool obj_resolve_origin(Obj_Entry *obj); static void preinit_main(void); static int rtld_verify_versions(const Objlist *); static int rtld_verify_object_versions(Obj_Entry *); @@ -788,8 +790,8 @@ basename(const char *name) static struct utsname uts; static char * -origin_subst_one(char *real, const char *kw, const char *subst, - bool may_free) +origin_subst_one(Obj_Entry *obj, char *real, const char *kw, + const char *subst, bool may_free) { char *p, *p1, *res, *resp; int subst_len, kw_len, subst_count, old_len, new_len; @@ -808,9 +810,15 @@ origin_subst_one(char *real, const char /* * If the keyword is not found, just return. + * + * Return non-substituted string if resolution failed. We + * cannot do anything more reasonable, the failure mode of the + * caller is unresolved library anyway. */ - if (subst_count == 0) + if (subst_count == 0 || (obj != NULL && !obj_resolve_origin(obj))) return (may_free ? real : xstrdup(real)); + if (obj != NULL) + subst = obj->origin_path; /* * There is indeed something to substitute. Calculate the @@ -847,20 +855,22 @@ origin_subst_one(char *real, const char } static char * -origin_subst(char *real, const char *origin_path) +origin_subst(Obj_Entry *obj, char *real) { char *res1, *res2, *res3, *res4; + if (obj == NULL || !trust) + return (xstrdup(real)); if (uts.sysname[0] == '\0') { if (uname(&uts) != 0) { _rtld_error("utsname failed: %d", errno); return (NULL); } } - res1 = origin_subst_one(real, "$ORIGIN", origin_path, false); - res2 = origin_subst_one(res1, "$OSNAME", uts.sysname, true); - res3 = origin_subst_one(res2, "$OSREL", uts.release, true); - res4 = origin_subst_one(res3, "$PLATFORM", uts.machine, true); + res1 = origin_subst_one(obj, real, "$ORIGIN", NULL, false); + res2 = origin_subst_one(NULL, res1, "$OSNAME", uts.sysname, true); + res3 = origin_subst_one(NULL, res2, "$OSREL", uts.release, true); + res4 = origin_subst_one(NULL, res3, "$PLATFORM", uts.machine, true); return (res4); } @@ -1124,7 +1134,7 @@ digest_dynamic1(Obj_Entry *obj, int earl #endif case DT_FLAGS: - if ((dynp->d_un.d_val & DF_ORIGIN) && trust) + if (dynp->d_un.d_val & DF_ORIGIN) obj->z_origin = true; if (dynp->d_un.d_val & DF_SYMBOLIC) obj->symbolic = true; @@ -1156,7 +1166,7 @@ digest_dynamic1(Obj_Entry *obj, int earl case DT_FLAGS_1: if (dynp->d_un.d_val & DF_1_NOOPEN) obj->z_noopen = true; - if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust) + if (dynp->d_un.d_val & DF_1_ORIGIN) obj->z_origin = true; if (dynp->d_un.d_val & DF_1_GLOBAL) obj->z_global = true; @@ -1207,30 +1217,33 @@ digest_dynamic1(Obj_Entry *obj, int earl } } +static bool +obj_resolve_origin(Obj_Entry *obj) +{ + + if (obj->origin_path != NULL) + return (true); + obj->origin_path = xmalloc(PATH_MAX); + return (rtld_dirname_abs(obj->path, obj->origin_path) != -1); +} + static void 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->origin_path == NULL) { - obj->origin_path = xmalloc(PATH_MAX); - if (rtld_dirname_abs(obj->path, obj->origin_path) == -1) - rtld_die(); - } - - if (dyn_runpath != NULL) { - obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val; - if (obj->z_origin) - obj->runpath = origin_subst(obj->runpath, obj->origin_path); - } - else if (dyn_rpath != NULL) { - obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val; - if (obj->z_origin) - obj->rpath = origin_subst(obj->rpath, obj->origin_path); - } + if (obj->z_origin && !obj_resolve_origin(obj)) + rtld_die(); - if (dyn_soname != NULL) - object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val); + if (dyn_runpath != NULL) { + obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val; + obj->runpath = origin_subst(obj, obj->runpath); + } else if (dyn_rpath != NULL) { + obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val; + obj->rpath = origin_subst(obj, obj->rpath); + } + if (dyn_soname != NULL) + object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val); } static void @@ -1480,12 +1493,8 @@ find_library(const char *xname, const Ob xname); return NULL; } - if (objgiven && refobj->z_origin) { - return (origin_subst(__DECONST(char *, xname), - refobj->origin_path)); - } else { - return (xstrdup(xname)); - } + return (origin_subst(__DECONST(Obj_Entry *, refobj), + __DECONST(char *, xname))); } if (libmap_disable || !objgiven ||