Mercurial > illumos > illumos-gate
changeset 9963:d23f520cfd07
6853809 ld.so.1: rescan fallback optimization is invalid
6854158 ld.so.1: interposition can be skipped because of incorrect caller/destination validation
author | Rod Evans <Rod.Evans@Sun.COM> |
---|---|
date | Wed, 24 Jun 2009 14:42:58 -0700 |
parents | 2b6bca766b65 |
children | a4f88c4f7496 |
files | usr/src/cmd/sgs/include/conv.h usr/src/cmd/sgs/include/rtld.h usr/src/cmd/sgs/libconv/common/group.c usr/src/cmd/sgs/libconv/common/group.msg usr/src/cmd/sgs/packages/common/SUNWonld-README usr/src/cmd/sgs/rtld/common/analyze.c usr/src/cmd/sgs/rtld/common/dlfcns.c usr/src/cmd/sgs/rtld/common/elf.c usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg |
diffstat | 10 files changed, 87 insertions(+), 128 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/sgs/include/conv.h Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/include/conv.h Wed Jun 24 14:42:58 2009 -0700 @@ -186,7 +186,7 @@ } Conv_dl_flag_buf_t; /* conv_grphdl_flags() */ -#define CONV_GRPHDL_FLAGS_BUFSIZE 92 +#define CONV_GRPHDL_FLAGS_BUFSIZE 78 typedef union { Conv_inv_buf_t inv_buf; char buf[CONV_GRPHDL_FLAGS_BUFSIZE];
--- a/usr/src/cmd/sgs/include/rtld.h Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/include/rtld.h Wed Jun 24 14:42:58 2009 -0700 @@ -293,7 +293,8 @@ Word lm_tflags; /* transferable flags */ uint_t lm_obj; /* total number of objs on link-map */ uint_t lm_init; /* new obj since last init processing */ - uint_t lm_lazy; /* obj with pending lazy dependencies */ + uint_t lm_lazy; /* number of objects with pending */ + /* lazy dependencies */ uint_t lm_tls; /* new obj that require TLS */ uint_t lm_lmid; /* unique link-map list identifier, */ char *lm_lmidstr; /* and associated diagnostic string */ @@ -359,8 +360,6 @@ #define LML_FLG_OBJDELETED 0x00004000 /* object(s) deleted */ #define LML_FLG_OBJREEVAL 0x00008000 /* existing object(s) needs */ /* tsort reevaluation */ -#define LML_FLG_NOPENDGLBLAZY 0x00010000 /* no pending, global, lazy */ - /* dependencies remain */ #define LML_FLG_INTRPOSETSORT 0x00020000 /* interpose tsorting done */ #define LML_FLG_AUDITNOTIFY 0x00040000 /* audit consistent required */ #define LML_FLG_GROUPSEXIST 0x00080000 /* local groups exist */ @@ -549,8 +548,7 @@ * Define any state that is associated with the handle. */ #define GPH_INITIAL 0x0100 /* handle is initialized */ -#define GPH_NOPENDLAZY 0x0200 /* no pending lazy dependencies */ - /* remain for this handle */ + /* * Define a Group Descriptor. * @@ -572,8 +570,6 @@ #define GPD_FILTER 0x0010 /* dependency is our filter */ #define GPD_REMOVE 0x0100 /* descriptor is a candidate for */ /* removal from the group */ -#define GPD_MODECHANGE 0x0200 /* dependency mode has changed, e.g. */ - /* promoted to RTLD_GOBAL */ /* * Define threading structures. For compatibility with libthread (T1_VERSION 1 @@ -705,7 +701,8 @@ uint_t rt_dyninfocnt; /* count of dyninfo entries */ uint_t rt_relacount; /* no. of RELATIVE relocations */ uint_t rt_idx; /* hold index within linkmap list */ - uint_t rt_lazy; /* lazy dependencies pending */ + uint_t rt_lazy; /* number of lazy dependencies */ + /* pending */ Xword rt_hwcap; /* hardware capabilities */ Xword rt_sfcap; /* software capabilities */ uint_t rt_cntl; /* link-map control list we belong to */
--- a/usr/src/cmd/sgs/libconv/common/group.c Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/libconv/common/group.c Wed Jun 24 14:42:58 2009 -0700 @@ -67,7 +67,6 @@ { GPH_FIRST, MSG_GPH_FIRST }, { GPH_FILTEE, MSG_GPH_FILTEE }, { GPH_INITIAL, MSG_GPH_INITIAL }, - { GPH_NOPENDLAZY, MSG_GPH_NOPENDLAZY }, { 0, 0 } }; static CONV_EXPN_FIELD_ARG conv_arg = { @@ -121,7 +120,6 @@ { GPD_PARENT, MSG_GPD_PARENT }, { GPD_FILTER, MSG_GPD_FILTER }, { GPD_REMOVE, MSG_GPD_REMOVE }, - { GPD_MODECHANGE, MSG_GPD_MODECHANGE }, { 0, 0 } }; static CONV_EXPN_FIELD_ARG conv_arg = {
--- a/usr/src/cmd/sgs/libconv/common/group.msg Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/libconv/common/group.msg Wed Jun 24 14:42:58 2009 -0700 @@ -31,7 +31,6 @@ @ MSG_GPH_FIRST "GPH_FIRST" @ MSG_GPH_FILTEE "GPH_FILTEE" @ MSG_GPH_INITIAL "GPH_INITIAL" -@ MSG_GPH_NOPENDLAZY "GPH_NOPENDLAZY" @ MSG_GPD_DLSYM "GPD_DLSYM" @ MSG_GPD_RELOC "GPD_RELOC" @@ -39,6 +38,5 @@ @ MSG_GPD_PARENT "GPD_PARENT" @ MSG_GPD_FILTER "GPD_FILTER" @ MSG_GPD_REMOVE "GPD_REMOVE" -@ MSG_GPD_MODECHANGE "GPD_MODECHANGE" @ MSG_GBL_NULL ""
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README Wed Jun 24 14:42:58 2009 -0700 @@ -1488,3 +1488,6 @@ 6851224 elf_getshnum() and elf_getshstrndx() incompatible with 2002 ELF gABI agreement PSARC/2009/363 replace elf_getphnum, elf_getshnum, and elf_getshstrndx +6853809 ld.so.1: rescan fallback optimization is invalid +6854158 ld.so.1: interposition can be skipped because of incorrect + caller/destination validation
--- a/usr/src/cmd/sgs/rtld/common/analyze.c Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/rtld/common/analyze.c Wed Jun 24 14:42:58 2009 -0700 @@ -2213,13 +2213,6 @@ rdflags = (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS); /* - * If this is a global object, ensure the associated link-map list can - * be rescanned for global, lazy dependencies. - */ - if (MODE(nlmp) & RTLD_GLOBAL) - LIST(nlmp)->lm_flags &= ~LML_FLG_NOPENDGLBLAZY; - - /* * If we've been asked to establish a handle create one for this object. * Or, if this object has already been analyzed, but this reference * requires that the mode of the object be promoted, create a private @@ -2283,22 +2276,6 @@ return (0); /* - * If the new link-map has been promoted, record this mode - * change for possible rescan use. - */ - if (promote) { - Aliste idx2; - Grp_desc *gdp; - - for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { - if (gdp->gd_depend == nlmp) { - gdp->gd_flags |= GPD_MODECHANGE; - break; - } - } - } - - /* * Add any dependencies that are already loaded, to the handle. */ if (hdl_initialize(ghp, nlmp, nmode, promote) == 0) @@ -2358,13 +2335,6 @@ return (0); /* - * If the new link-map has been promoted, record this mode - * change for possible rescan use. - */ - if (promote) - gdp->gd_flags |= GPD_MODECHANGE; - - /* * If this member already exists then its dependencies will * have already been processed. */ @@ -2419,9 +2389,8 @@ return (0); } - if ((ale == ALE_CREATE) && - (update_mode(dlmp1, MODE(dlmp1), nmode))) - gdp->gd_flags |= GPD_MODECHANGE; + if (ale == ALE_CREATE) + (void) update_mode(dlmp1, MODE(dlmp1), nmode); } free(lmalp); } @@ -2440,6 +2409,14 @@ Rt_map *nlmp; if ((nmode & RTLD_NOLOAD) == 0) { + int oin_nfavl; + + /* + * Keep track of the number of not-found loads. + */ + if (in_nfavl) + oin_nfavl = *in_nfavl; + /* * If this isn't a noload request attempt to load the file. */ @@ -2448,6 +2425,16 @@ return (NULL); /* + * If this file has been found, reset the not-found load count. + * Although a search for this file might have inspected a number + * of non-existent path names, the file has been found so there + * is no need to to accumulate a non-found count, as this may + * trigger unnecessary fall back (retry) processing. + */ + if (in_nfavl) + *in_nfavl = oin_nfavl; + + /* * If we've loaded a library which identifies itself as not * being dlopen()'able catch it here. Let non-dlopen()'able * objects through under RTLD_CONFGEN as they're only being @@ -2731,7 +2718,18 @@ if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) break; - if (callable(lmp, clmp, 0, sl.sl_flags)) { + /* + * If we had already bound to this object, there's no point in + * searching it again, we're done. + */ + if (lmp == *dlmp) + break; + + /* + * If this interposer can be inspected by the caller, look for + * the symbol within the interposer. + */ + if (callable(clmp, lmp, 0, sl.sl_flags)) { Rt_map *ilmp; Sym *isym;
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c Wed Jun 24 14:42:58 2009 -0700 @@ -413,19 +413,16 @@ continue; for (APLIST_TRAVERSE(DEPENDS(lmp), idx1, bdp)) { - Grp_desc *gdp; - Rt_map *dlmp = bdp->b_depend; + Rt_map *dlmp = bdp->b_depend; if ((bdp->b_flags & BND_NEEDED) == 0) continue; - if ((gdp = hdl_add(ghp, dlmp, - (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS), - NULL)) == NULL) + if (hdl_add(ghp, dlmp, + (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS), NULL) == NULL) return (0); - if (update_mode(dlmp, MODE(dlmp), mode)) - gdp->gd_flags |= GPD_MODECHANGE; + (void) update_mode(dlmp, MODE(dlmp), mode); } } ghp->gh_flags |= GPH_INITIAL; @@ -1059,7 +1056,7 @@ * the address space. If the symbol isn't located, and lazy * dependencies still exist, then a second pass is made to load these * dependencies if applicable. This model means that in the case where - * a symbols exists in more than one object, the one located may not be + * a symbol exists in more than one object, the one located may not be * constant - this is the standard issue with lazy loading. In addition, * attempting to locate a symbol that doesn't exist will result in the * loading of all lazy dependencies on the given handle, which can @@ -1067,6 +1064,7 @@ */ if (ghp->gh_flags & GPH_ZERO) { Lm_list *lml; + uint_t lazy = 0; /* * If this symbol lookup is triggered from a dlopen(0) handle, @@ -1074,7 +1072,6 @@ * entries. */ for (nlmp = lmp; nlmp; nlmp = NEXT_RT_MAP(nlmp)) { - /* * If this handle indicates we're only to look in the * first object check whether we're done. @@ -1092,20 +1089,22 @@ if (sym = LM_LOOKUP_SYM(clmp)(&sl, _lmp, binfo, in_nfavl)) return (sym); + + /* + * Keep track of any global pending lazy loads. + */ + lazy += LAZY(nlmp); } /* - * If we're unable to locate the symbol and this link-map still - * has pending lazy dependencies, start loading them in an + * If we're unable to locate the symbol and this link-map list + * still has pending lazy dependencies, start loading them in an * attempt to exhaust the search. Note that as we're already * traversing a dynamic linked list of link-maps there's no * need for elf_lazy_find_sym() to descend the link-maps itself. */ lml = LIST(lmp); - if ((lml->lm_lazy) && - ((lml->lm_flags & LML_FLG_NOPENDGLBLAZY) == 0)) { - int lazy = 0; - + if (lazy) { DBG_CALL(Dbg_syms_lazy_rescan(lml, name)); sl.sl_flags |= LKUP_NODESCENT; @@ -1118,55 +1117,48 @@ ((FLAGS(clmp) & FLG_RT_DELETE) == 0)) continue; - lazy = 1; sl.sl_imap = nlmp; if (sym = elf_lazy_find_sym(&sl, _lmp, binfo, in_nfavl)) return (sym); } - - /* - * If no global, lazy loadable dependencies are found, - * then none exist for this link-map list. Pending lazy - * loadable objects may still exist for non-local - * objects that are associated with this link-map list, - * which is why we entered this fallback. Tag this - * link-map list to prevent further searching for lazy - * dependencies. - */ - if (lazy == 0) - lml->lm_flags |= LML_FLG_NOPENDGLBLAZY; } } else { /* - * Traverse the dlopen() handle for the presently loaded + * Traverse the dlopen() handle searching all presently loaded * link-maps. */ Grp_desc *gdp; Aliste idx; + uint_t lazy = 0; for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) { + nlmp = gdp->gd_depend; + if ((gdp->gd_flags & GPD_DLSYM) == 0) continue; - sl.sl_imap = gdp->gd_depend; + sl.sl_imap = nlmp; if (sym = LM_LOOKUP_SYM(clmp)(&sl, _lmp, binfo, in_nfavl)) return (sym); if (ghp->gh_flags & GPH_FIRST) return (NULL); + + /* + * Keep track of any pending lazy loads associated + * with this handle. + */ + lazy += LAZY(nlmp); } /* - * If we're unable to locate the symbol and this link-map still - * has pending lazy dependencies, start loading them in an - * attempt to exhaust the search. + * If we're unable to locate the symbol and this handle still + * has pending lazy dependencies, start loading the lazy + * dependencies, in an attempt to exhaust the search. */ - if ((LIST(lmp)->lm_lazy) && - ((ghp->gh_flags & GPH_NOPENDLAZY) == 0)) { - int lazy = 0; - + if (lazy) { DBG_CALL(Dbg_syms_lazy_rescan(LIST(lmp), name)); for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) { @@ -1176,23 +1168,11 @@ (LAZY(nlmp) == 0)) continue; - lazy = 1; sl.sl_imap = nlmp; if (sym = elf_lazy_find_sym(&sl, _lmp, binfo, in_nfavl)) return (sym); } - - /* - * If no lazy loadable dependencies are found, then - * none exist for this handle. Pending lazy loadable - * objects may still exist for the associated link-map - * list, which is why we entered this fallback. Tag - * this handle to prevent further searching for lazy - * dependencies. - */ - if (lazy == 0) - ghp->gh_flags |= GPH_NOPENDLAZY; } } return (NULL);
--- a/usr/src/cmd/sgs/rtld/common/elf.c Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/rtld/common/elf.c Wed Jun 24 14:42:58 2009 -0700 @@ -2622,13 +2622,13 @@ * * If the symbol hasn't been found, use the referenced * objects handle, as it might have dependencies on - * objects that are already loaded. We only need to - * look in any existing objects if the mode of those - * objects has changed. Existing objects would have - * already been searched, however, a lazy load might - * still cause the promotion of modes, and in this case - * the handle associated with the object is used to - * carry out the symbol search. + * objects that are already loaded. Note that existing + * objects might have already been searched and skipped + * as non-available to this caller. However, a lazy + * load might have caused the promotion of modes, or + * added this object to the family of the caller. In + * either case, the handle associated with the object + * is then used to carry out the symbol search. */ if ((nlmp = elf_lazy_load(lmp, &sl1, cnt, name, FLG_RT_PRIHDL, &ghp, in_nfavl)) == NULL) @@ -2641,41 +2641,33 @@ sl1.sl_imap = NEXT_RT_MAP(llmp); sl1.sl_flags &= ~LKUP_STDRELOC; - sym = lookup_sym(&sl1, _lmp, binfo, in_nfavl); + if ((sym = lookup_sym(&sl1, _lmp, binfo, + in_nfavl)) != NULL) + return (sym); } /* - * Use the objects handle to determine any promoted - * objects. Clear any modes regardless. Note, there's + * Use the objects handle to inspect the family of + * objects associated with the handle. Note, there's * a possibility of overlap with the above search, * should a lazy load bring in new objects and * reference existing objects. */ sl2 = sl1; for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { - if ((gdp->gd_flags & GPD_MODECHANGE) == 0) - continue; - - if ((sym == NULL) && - (gdp->gd_depend != NEXT_RT_MAP(llmp)) && + if ((gdp->gd_depend != NEXT_RT_MAP(llmp)) && (gdp->gd_flags & GPD_DLSYM)) { sl2.sl_imap = gdp->gd_depend; sl2.sl_flags |= LKUP_FIRST; - sym = lookup_sym(&sl2, _lmp, binfo, - in_nfavl); + if ((sym = lookup_sym(&sl2, _lmp, binfo, + in_nfavl)) != NULL) + return (sym); } - gdp->gd_flags &= ~GPD_MODECHANGE; } /* - * If the symbol has been found, cleanup and return. - */ - if (sym) - return (sym); - - /* * Some dlsym() operations are already traversing a * link-map (dlopen(0)), and thus there's no need to * save them on the dynamic dependency list.
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c Wed Jun 24 14:42:58 2009 -0700 @@ -152,7 +152,6 @@ { MSG_ORIG(MSG_GPH_FIRST), GPH_FIRST, GPH_FIRST }, { MSG_ORIG(MSG_GPH_FILTEE), GPH_FILTEE, GPH_FILTEE }, { MSG_ORIG(MSG_GPH_INITIAL), GPH_INITIAL, GPH_INITIAL }, - { MSG_ORIG(MSG_GPH_NOPENDLAZY), GPH_NOPENDLAZY, GPH_NOPENDLAZY }, { NULL, 0, 0} }; @@ -163,7 +162,6 @@ { MSG_ORIG(MSG_GPD_PARENT), GPD_PARENT, GPD_PARENT }, { MSG_ORIG(MSG_GPD_FILTER), GPD_FILTER, GPD_FILTER }, { MSG_ORIG(MSG_GPD_REMOVE), GPD_REMOVE, GPD_REMOVE }, - { MSG_ORIG(MSG_GPD_MODECHANGE), GPD_MODECHANGE, GPD_MODECHANGE }, { NULL, 0, 0} }; @@ -723,8 +721,6 @@ { MSG_ORIG(MSG_LFL_OBJDELETED), LML_FLG_OBJDELETED, LML_FLG_OBJDELETED }, { MSG_ORIG(MSG_LFL_OBJREEVAL), LML_FLG_OBJREEVAL, LML_FLG_OBJREEVAL }, - { MSG_ORIG(MSG_LFL_NOPENDGLBLAZY), LML_FLG_NOPENDGLBLAZY, - LML_FLG_NOPENDGLBLAZY }, { MSG_ORIG(MSG_LFL_INTRPOSETSORT), LML_FLG_INTRPOSETSORT, LML_FLG_INTRPOSETSORT }, { MSG_ORIG(MSG_LFL_AUDITNOTIFY), LML_FLG_AUDITNOTIFY,
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg Wed Jun 24 13:36:16 2009 -0600 +++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg Wed Jun 24 14:42:58 2009 -0700 @@ -133,7 +133,6 @@ @ MSG_GPH_FIRST "FIRST-ONLY" @ MSG_GPH_FILTEE "FILTEE" @ MSG_GPH_INITIAL "INITIALIZED" -@ MSG_GPH_NOPENDLAZY "NO-PENDING-LAZY-DEPENDENCIES" @ MSG_GPD_DLSYM "AVAIL-TO-DLSYM" @ MSG_GPD_RELOC "AVAIL-FOR-RELOCATION" @@ -141,7 +140,6 @@ @ MSG_GPD_PARENT "PARENT" @ MSG_GPD_FILTER "FILTER" @ MSG_GPD_REMOVE "REMOVAL-CANDIDATE" -@ MSG_GPD_MODECHANGE "MODES-HAVE-CHANGED" @ MSG_LFL_BASELM "BASELM" @ MSG_LFL_RTLDLM "RTLDLM" @@ -159,9 +157,8 @@ @ MSG_LFL_OBJADDED "OBJECT-ADDED" @ MSG_LFL_OBJDELETED "OBJECT-DELETED" @ MSG_LFL_OBJREEVAL "OBJECT-REEVALUATE" -@ MSG_LFL_NOPENDGLBLAZY "NO-PENDING-GLOBAL-LAZY-DEPENDENCY" @ MSG_LFL_INTRPOSETSORT "INTERPOSE-TSORTING-DONE" -@ MSG_LFL_AUDITNOTIFY "AUDIT-CONSISTANT-REQUIRED" +@ MSG_LFL_AUDITNOTIFY "AUDIT-CONSISTENT-REQUIRED" @ MSG_LFL_GROUPSEXIST "LOCAL-GROUPS-EXIST" @ MSG_LFL_TRC_LDDSTUB "LDDSTUB"