summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRod Evans <Rod.Evans@Sun.COM>2008-10-14 14:26:05 -0700
committerRod Evans <Rod.Evans@Sun.COM>2008-10-14 14:26:05 -0700
commit247b82a1f1cb5ebd2d163bd9afdb1a3065611962 (patch)
treea903644b3c902ea8d9074397f4f4d6a75ac7b5c9 /usr/src
parent43e66171b65c11eb7211db1eaf6747980a88d39c (diff)
downloadillumos-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-README12
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h2
-rw-r--r--usr/src/cmd/sgs/rtld/common/config_elf.c114
-rw-r--r--usr/src/cmd/sgs/rtld/common/paths.c109
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.
*/