diff options
author | Rod Evans <Rod.Evans@Sun.COM> | 2008-10-14 14:26:05 -0700 |
---|---|---|
committer | Rod Evans <Rod.Evans@Sun.COM> | 2008-10-14 14:26:05 -0700 |
commit | 247b82a1f1cb5ebd2d163bd9afdb1a3065611962 (patch) | |
tree | a903644b3c902ea8d9074397f4f4d6a75ac7b5c9 /usr/src | |
parent | 43e66171b65c11eb7211db1eaf6747980a88d39c (diff) | |
download | illumos-joyent-247b82a1f1cb5ebd2d163bd9afdb1a3065611962.tar.gz |
6754965 introduce the SF1_SUNW_ADDR32 bit in software capabilities
PSARC/2008/622 32-bit Address Restriction Software Capabilities Flag
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 12 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/_rtld.h | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/config_elf.c | 114 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/paths.c | 109 |
4 files changed, 142 insertions, 95 deletions
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 8400ac1665..322328f062 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1211,6 +1211,9 @@ Bugid Risk Synopsis 6672544 elf_rtbndr must support non-ABI aligned stacks on amd64 6668050 First trip through PLT does not preserve args in xmm registers -------------------------------------------------------------------------------- +All the above changes are incorporated in the following patch: + Solaris/SunOS 5.10_x86 patch T137138-01 +-------------------------------------------------------------------------------- ------------------------------------- Solaris 10 409 (7th Q-update - s10u7) @@ -1219,6 +1222,12 @@ Bugid Risk Synopsis ================================================================================ 6629404 ld with -z ignore doesn't scale 6606203 link editor ought to allow creation of >2gb sized objects (P) +6746674 setuid applications do not find libraries any more because trusted + directories behavior changed (D) +-------------------------------------------------------------------------------- +All the above changes are incorporated in the following patches: + Solaris/SunOS 5.10_sparc patch TXXXXXX-YY + Solaris/SunOS 5.10_x86 patch TXXXXXX-YY -------------------------------------------------------------------------------- -------------- @@ -1383,8 +1392,6 @@ Bugid Risk Synopsis linking gnu object code 6744003 ld(1) could provide better argument processing diagnostics (D) PSARC 2008/583 add gld options to ld(1) -6746674 setuid applications do not find libraries any more because trusted - directories behavior changed (D) 6749055 ld should generate GNU style VERSYM indexes for VERNEED records (D) PSARC/2008/603 ELF objects to adopt GNU-style Versym indexes 6752728 link-editor can enter UNDEF symbols in symbol sort sections @@ -1392,3 +1399,4 @@ Bugid Risk Synopsis 6754965 introduce the SF1_SUNW_ADDR32 bit in software capabilities (D) (link-editor components only) PSARC/2008/622 32-bit Address Restriction Software Capabilities Flag +6756953 customer requests that DT_CONFIG strings be honored for secure apps (D) diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index 5b427fe3ad..59a2aafca0 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -376,6 +376,7 @@ typedef struct { #define PN_FLG_UNIQUE 0x00002000 /* ensure path is unique */ #define PN_FLG_USED 0x00004000 /* indicate that path is used */ #define PN_FLG_DUPLICAT 0x00008000 /* path is a duplicate */ +#define PN_FLG_FULLPATH 0x00010000 /* ensure path is a full path */ #define PN_FLG_MASK 0x000ff000 /* mask for p_orig incorporation */ @@ -585,6 +586,7 @@ extern Pnode *hwcap_filtees(Pnode **, Aliste, Lm_cntl *, Dyninfo *, extern void is_dep_ready(Rt_map *, Rt_map *, int); extern void is_dep_init(Rt_map *, Rt_map *); extern int is_move_data(caddr_t); +extern int is_path_secure(char *, Rt_map *, uint_t, uint_t); extern int is_rtld_setuid(); extern int is_sym_interposer(Rt_map *, Sym *); extern void ldso_plt_init(Rt_map *); diff --git a/usr/src/cmd/sgs/rtld/common/config_elf.c b/usr/src/cmd/sgs/rtld/common/config_elf.c index dbb585155f..d1dddb63ab 100644 --- a/usr/src/cmd/sgs/rtld/common/config_elf.c +++ b/usr/src/cmd/sgs/rtld/common/config_elf.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> @@ -40,8 +38,7 @@ #include "msg.h" static Config _config = { 0 }; -Config * config = &_config; - +Config *config = &_config; /* * Validate a configuration file. @@ -118,7 +115,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp) * RTC_OBJ_NOEXIST directories. */ filetbl = (Rtc_file *)(dirtbl->cd_file + addr); - if (filetbl->cf_obj == 0) + if (filetbl->cf_obj == NULL) continue; /* @@ -178,6 +175,22 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp) } } +/* + * Process a configuration file. + * + * A configuration file can be specified using the LD_CONFIG environment + * variable, from a DT_CONFIG string recorded in the executable (see ld(1) -c), + * or in the case of a crle() dumped image, the file is "fabricated" to a + * configuration file that may have been associated with the dumped image. In + * the absence of any of these techniques, a default configuration file is used. + * + * The LD_CONFIG variable take precedence, unless the application is secure, in + * which case the environment variable is ignored (see ld_generic_env()). + * + * A DT_CONFIG string is honored, even if the application is secure. However, + * the path name follows the same rules as RUNPATH's, which must be a full path + * name with no use of $ORIGIN. + */ int elf_config(Rt_map *lmp, int aout) { @@ -187,48 +200,61 @@ elf_config(Rt_map *lmp, int aout) struct stat status; Addr addr; Pnode *pnp; - const char *str = config->c_name; + const char *str; + char path[PATH_MAX]; /* - * If an alternative configuration file has been specified use it - * (expanding any tokens), otherwise try opening up the default. + * If we're dealing with an alternative application, fabricate the need + * for a $ORIGIN/ld.config.app-name configuration file. */ - if ((str == 0) && ((rtld_flags & RT_FL_CONFAPP) == 0)) -#if defined(_ELF64) - str = MSG_ORIG(MSG_PTH_CONFIG_64); -#else - str = MSG_ORIG(MSG_PTH_CONFIG); -#endif - else if (rtld_flags & RT_FL_SECURE) - return (0); - else { - size_t size; - char *name; + if (rtld_flags & RT_FL_CONFAPP) { + if ((str = strrchr(PATHNAME(lmp), '/')) != NULL) + str++; + else + str = PATHNAME(lmp); - /* - * If we're dealing with an alternative application, fabricate - * the need for a $ORIGIN/ld.config.app-name configuration file. - */ - if (rtld_flags & RT_FL_CONFAPP) { - char _name[PATH_MAX]; + (void) snprintf(path, PATH_MAX, MSG_ORIG(MSG_ORG_CONFIG), str); + str = path; + } else + str = config->c_name; - if ((str = strrchr(PATHNAME(lmp), '/')) != NULL) - str++; - else - str = PATHNAME(lmp); + /* + * If a configuration file name is known, expand and verify the name. + */ + if (str) { + size_t size = strlen(str); + char *estr = (char *)str; + uint_t tkns; - (void) snprintf(_name, PATH_MAX, - MSG_ORIG(MSG_ORG_CONFIG), str); - str = _name; - } + /* + * Expand any configuration string. + */ + if ((tkns = expand(&estr, &size, 0, 0, + (PN_TKN_ISALIST | PN_TKN_HWCAP), lmp)) == 0) + return (0); - size = strlen(str); - name = (char *)str; + /* + * If this is a secure application, validate the configuration + * file path name. Ignore any untrustworthy path name, and + * fall through to pick up the defaults. + */ + if ((rtld_flags & RT_FL_SECURE) && + (is_path_secure(estr, lmp, PN_FLG_FULLPATH, tkns) == 0)) + str = NULL; + else + str = (const char *)estr; + } - if (expand(&name, &size, 0, 0, - (PN_TKN_ISALIST | PN_TKN_HWCAP), lmp) == 0) - return (0); - str = (const char *)name; + /* + * If a configuration file has not been specified try opening up the + * default. + */ + if (str == NULL) { +#if defined(_ELF64) + str = MSG_ORIG(MSG_PTH_CONFIG_64); +#else + str = MSG_ORIG(MSG_PTH_CONFIG); +#endif } config->c_name = str; @@ -453,8 +479,8 @@ elf_config_ent(const char *name, Word hash, int id, const char **alternate) Pnode * elf_config_flt(Lm_list *lml, const char *filter, const char *string) { - Rtc_fltr * fltrtbl; - Pnode * pnp = 0, *npnp, *opnp = 0; + Rtc_fltr *fltrtbl; + Pnode *pnp = NULL, *npnp, *opnp = NULL; for (fltrtbl = (Rtc_fltr *)config->c_fltr; fltrtbl->fr_filter; fltrtbl++) { @@ -480,13 +506,13 @@ elf_config_flt(Lm_list *lml, const char *filter, const char *string) flte = config->c_strtbl + fltetbl->fe_filtee; - if (((npnp = calloc(1, sizeof (Pnode))) == 0) || - ((npnp->p_name = strdup(flte)) == 0)) + if (((npnp = calloc(1, sizeof (Pnode))) == NULL) || + ((npnp->p_name = strdup(flte)) == NULL)) return (0); DBG_CALL(Dbg_file_filter(lml, fltr, flte, 1)); - if (opnp == 0) + if (opnp == NULL) pnp = npnp; else opnp->p_next = npnp; diff --git a/usr/src/cmd/sgs/rtld/common/paths.c b/usr/src/cmd/sgs/rtld/common/paths.c index 23391d59ab..54b2dba709 100644 --- a/usr/src/cmd/sgs/rtld/common/paths.c +++ b/usr/src/cmd/sgs/rtld/common/paths.c @@ -88,7 +88,7 @@ get_dir_list(uchar_t rules, Rt_map *lmp, uint_t flags) /* * For ldd(1) -s, indicate the search paths that'll - * be used. If this is a secure program then some + * be used. If this is a secure application then some * search paths may be ignored, therefore reset the * rpl_libdirs pointer each time so that the * diagnostics related to these unsecure directories @@ -136,7 +136,7 @@ get_dir_list(uchar_t rules, Rt_map *lmp, uint_t flags) /* * For ldd(1) -s, indicate the search paths that'll - * be used. If this is a secure program then some + * be used. If this is a secure application then some * search paths may be ignored, therefore reset the * prm_libdirs pointer each time so that the * diagnostics related to these unsecure directories @@ -173,7 +173,7 @@ get_dir_list(uchar_t rules, Rt_map *lmp, uint_t flags) /* * For ldd(1) -s, indicate the search paths that'll - * be used. If this is a secure program then some + * be used. If this is a secure application then some * search paths may be ignored, therefore reset the * runlist pointer each time so that the diagnostics * related to these unsecure directories will be @@ -549,7 +549,7 @@ expand(char **name, size_t *len, char **list, uint_t orig, uint_t omit, * $HWCAP expansion required. For compatibility with * older environments, only expand this token when hard- * ware capability information is available. This - * expansion is only allowed for non-simple pathnames + * expansion is only allowed for non-simple path names * (must contain a '/'), with the token itself being the * last element of the path. Therefore, all we need do * is test the existence of the string "/$HWCAP\0". @@ -630,9 +630,9 @@ expand(char **name, size_t *len, char **list, uint_t orig, uint_t omit, * handle one ISALIST per node. For more than one ISALIST to be * processed we'd need a better algorithm than above to replace the * newly generated list. Whether we want to encourage the number of - * pathname permutations this would provide is another question. So, for - * now if more than one ISALIST is encountered we return the original - * node untouched. + * path name permutations this would provide is another question. So, + * for now if more than one ISALIST is encountered we return the + * original node untouched. */ if (isa && isaflag) { if (isaflag == 1) { @@ -667,13 +667,13 @@ expand(char **name, size_t *len, char **list, uint_t orig, uint_t omit, *nptr = '\0'; /* - * A path that has been expanded, is typically used to create full - * pathnames for objects that will be opened. The final pathname is + * A path that has been expanded is typically used to create full + * path names for objects that will be opened. The final path name is * resolved to simplify it, and set the stage for possible $ORIGIN * processing. Therefore, it's usually unnecessary to resolve the path * at this point. However, if a configuration file, containing * directory information is in use, then we might need to lookup this - * path in the configuration file. To keep the number of pathname + * path in the configuration file. To keep the number of path name * resolutions to a minimum, only resolve paths that contain "./". The * use of "$ORIGIN/../lib" will probably only match a configuration file * entry after resolution. @@ -699,24 +699,25 @@ expand(char **name, size_t *len, char **list, uint_t orig, uint_t omit, /* * Return an indication of any token expansion that may have occurred. - * Under security, any pathname expanded with the $ORIGIN token must be - * validated against any registered secure directories. + * If this is a secure application, any path name expanded with the + * $ORIGIN token must be validated against any registered trusted + * directories. */ return (flags ? flags : TKN_NONE); } /* - * Determine whether a pathname is secure. + * Determine whether a path name is secure. */ -static int +int is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) { Pnode *sdir = LM_SECURE_DIRS(LIST(clmp)->lm_head); - char buffer[PATH_MAX], *npath; + char buffer[PATH_MAX], *npath = NULL; Lm_list *lml = LIST(clmp); /* - * If a pathname originates from a configuration file, use it. The use + * If a path name originates from a configuration file, use it. The use * of a configuration file is already validated for secure applications, * so if we're using a configuration file, we must be able to use all * that it defines. @@ -728,7 +729,7 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) char *str; /* - * If the pathname specifies a file (rather than a directory), + * If the path name specifies a file (rather than a directory), * peel off the file before making the comparison. */ str = strrchr(opath, '/'); @@ -738,13 +739,16 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) * * . a simple file name (one containing no "/") is fine, as * this file name will be combined with search paths to - * determine the complete path. + * determine the complete path. Note, a secure application + * may provide a configuration file, and this can only be + * a full path name (PN_FLG_FULLPATH). * . a full path (one starting with "/") is fine, provided * this path name isn't a preload/audit path. * . provided $ORIGIN expansion has not been employed, the * above categories of path are deemed secure. */ - if (((str == 0) || ((*opath == '/') && (str != opath) && + if ((((str == 0) && ((info & PN_FLG_FULLPATH) == 0)) || + ((*opath == '/') && (str != opath) && ((info & PN_FLG_EXTLOAD) == 0))) && ((flags & PN_TKN_ORIGIN) == 0)) return (1); @@ -752,29 +756,31 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) /* * Determine the directory name of the present path. */ - if (str == opath) - npath = (char *)MSG_ORIG(MSG_STR_SLASH); - else { - size_t size; + if (str) { + if (str == opath) + npath = (char *)MSG_ORIG(MSG_STR_SLASH); + else { + size_t size; - if ((size = str - opath) >= PATH_MAX) - return (0); + if ((size = str - opath) >= PATH_MAX) + return (0); - (void) strncpy(buffer, opath, size); - buffer[size] = '\0'; - npath = buffer; - } + (void) strncpy(buffer, opath, size); + buffer[size] = '\0'; + npath = buffer; + } - /* - * If $ORIGIN processing has been employed, then allow any - * directory that has already been used to satisfy other - * dependencies, to be used. - */ - if ((flags & PN_TKN_ORIGIN) && spavl_recorded(npath, 0)) { - DBG_CALL(Dbg_libs_insecure(lml, npath, 1)); - return (1); + /* + * If $ORIGIN processing has been employed, then allow + * any directory that has already been used to satisfy + * other dependencies, to be used. + */ + if ((flags & PN_TKN_ORIGIN) && + spavl_recorded(npath, 0)) { + DBG_CALL(Dbg_libs_insecure(lml, npath, 1)); + return (1); + } } - } else { /* * A search path, i.e., RPATH, configuration file path, etc. is @@ -808,10 +814,15 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) npath = (char *)opath; } - while (sdir) { - if (strcmp(npath, sdir->p_name) == 0) - return (1); - sdir = sdir->p_next; + /* + * Determine whether the present directory is trusted. + */ + if (npath) { + while (sdir) { + if (strcmp(npath, sdir->p_name) == 0) + return (1); + sdir = sdir->p_next; + } } /* @@ -880,17 +891,17 @@ is_path_unique(Pnode *pnp, const char *path) } /* - * Expand one or more pathnames. This routine is called for all path strings, + * Expand one or more path names. This routine is called for all path strings, * i.e., NEEDED, rpaths, default search paths, configuration file search paths, - * filtees, etc. The path may be a single pathname, or a colon separated list - * of pathnames. Each individual pathname is processed for possible reserved + * filtees, etc. The path may be a single path name, or a colon separated list + * of path names. Each individual path name is processed for possible reserved * token expansion. All string nodes are maintained in allocated memory * (regardless of whether they are constant (":"), or token expanded) to * simplify pnode removal. * * The info argument passes in auxiliary information regarding the callers - * intended use of the pathnames. This information may be maintained in the - * pnode element produced to describe the pathname (i.e., LA_SER_LIBPATH etc.), + * intended use of the path names. This information may be maintained in the + * pnode element produced to describe the path name (i.e., LA_SER_LIBPATH etc.), * or may be used to determine additional security or diagnostic processing. */ Pnode * @@ -965,7 +976,7 @@ expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit) /* * If this a secure application, validation of the expanded - * pathname may be necessary. + * path name may be necessary. */ if (rtld_flags & RT_FL_SECURE) { if (is_path_secure(str, clmp, orig, tkns) == 0) { @@ -1019,7 +1030,7 @@ expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit) char *oname; /* - * If this is a pathname, and any token expansion + * If this is a path name, and any token expansion * occurred, maintain the original string for possible * diagnostic use. */ |