diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/sgs/include/debug.h | 6 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libelf/Makefile.targ | 4 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libelf/common/error.c | 45 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/liblddbg.msg | 3 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/libs.c | 9 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/llib-llddbg | 4 | ||||
-rw-r--r-- | usr/src/cmd/sgs/liblddbg/common/mapfile-vers | 6 | ||||
-rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/_rtld.h | 6 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/analyze.c | 19 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/debug.c | 14 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/paths.c | 58 | ||||
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/util.c | 158 |
13 files changed, 207 insertions, 127 deletions
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h index 0e588be0f1..f8f9e641b6 100644 --- a/usr/src/cmd/sgs/include/debug.h +++ b/usr/src/cmd/sgs/include/debug.h @@ -273,7 +273,7 @@ extern uintptr_t Dbg_setup(const char *, Dbg_desc *); #define Dbg_libs_audit Dbg64_libs_audit #define Dbg_libs_find Dbg64_libs_find #define Dbg_libs_found Dbg64_libs_found -#define Dbg_libs_ignore Dbg64_libs_ignore +#define Dbg_libs_insecure Dbg64_libs_insecure #define Dbg_libs_init Dbg64_libs_init #define Dbg_libs_l Dbg64_libs_l #define Dbg_libs_path Dbg64_libs_path @@ -478,7 +478,7 @@ extern uintptr_t Dbg_setup(const char *, Dbg_desc *); #define Dbg_libs_audit Dbg32_libs_audit #define Dbg_libs_find Dbg32_libs_find #define Dbg_libs_found Dbg32_libs_found -#define Dbg_libs_ignore Dbg32_libs_ignore +#define Dbg_libs_insecure Dbg32_libs_insecure #define Dbg_libs_init Dbg32_libs_init #define Dbg_libs_l Dbg32_libs_l #define Dbg_libs_path Dbg32_libs_path @@ -713,7 +713,7 @@ extern void Dbg_got_display(Ofl_desc *, Off, int, Word, size_t); extern void Dbg_libs_audit(Lm_list *, const char *, const char *); extern void Dbg_libs_find(Lm_list *, const char *); extern void Dbg_libs_found(Lm_list *, const char *, int); -extern void Dbg_libs_ignore(Lm_list *, const char *); +extern void Dbg_libs_insecure(Lm_list *, const char *, int); extern void Dbg_libs_init(Lm_list *, List *, List *); extern void Dbg_libs_l(Lm_list *, const char *, const char *); extern void Dbg_libs_path(Lm_list *, const char *, uint_t, const char *); diff --git a/usr/src/cmd/sgs/libelf/Makefile.targ b/usr/src/cmd/sgs/libelf/Makefile.targ index e5d688a517..6ede755fb4 100644 --- a/usr/src/cmd/sgs/libelf/Makefile.targ +++ b/usr/src/cmd/sgs/libelf/Makefile.targ @@ -22,8 +22,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# $(VAR_POUND_2)LIBS += $(LIBRARY) @@ -138,8 +136,6 @@ pics/xlate.o: xlate.c native: $(SGSPROTO)/$(DYNLIB) -native := CPPFLAGS += -DNATIVE_BUILD - $(SGSPROTO)/$(DYNLIB): \ pics .WAIT $$(PICS) $(BUILD.SO) diff --git a/usr/src/cmd/sgs/libelf/common/error.c b/usr/src/cmd/sgs/libelf/common/error.c index 21433d05eb..0a55a9efe6 100644 --- a/usr/src/cmd/sgs/libelf/common/error.c +++ b/usr/src/cmd/sgs/libelf/common/error.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <thread.h> #include <pthread.h> #include <stdlib.h> @@ -39,7 +37,6 @@ #define ELFERRSHIFT 16 #define SYSERRMASK 0xffff - /* * _elf_err has two values encoded in it, both the _elf_err # and * the system errno value (if relevant). These values are encoded @@ -47,57 +44,15 @@ */ static int _elf_err = 0; -#if !defined(NATIVE_BUILD) - static thread_key_t errkey = THR_ONCE_KEY; static thread_key_t bufkey = THR_ONCE_KEY; -#else /* NATIVE_BUILD */ - -/* - * This code is here to enable the building of a native version - * of libelf.so when the build machine has not yet been upgraded - * to a version of libc that provides thr_keycreate_once(). - * It should be deleted when solaris_nevada ships. - * The code is not MT-safe in a relaxed memory model. - */ - -static thread_key_t errkey = 0; -static thread_key_t bufkey = 0; - -int -thr_keycreate_once(thread_key_t *keyp, void (*destructor)(void *)) -{ - static mutex_t key_lock = DEFAULTMUTEX; - thread_key_t key; - int error; - - if (*keyp == 0) { - mutex_lock(&key_lock); - if (*keyp == 0) { - error = thr_keycreate(&key, destructor); - if (error) { - mutex_unlock(&key_lock); - return (error); - } - *keyp = key; - } - mutex_unlock(&key_lock); - } - - return (0); -} - -#endif /* NATIVE_BUILD */ - - const char * _libelf_msg(Msg mid) { return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid))); } - void _elf_seterr(Msg lib_err, int sys_err) { diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg index ef0190871c..aec5e954ae 100644 --- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg +++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg @@ -492,7 +492,8 @@ @ MSG_LIB_ALTER " trying path=%s (auditing supplied alternative)" @ MSG_LIB_SKIP " skip path=%s (auditing directed)" @ MSG_LIB_IGNORE " ignore path=%s (insecure directory name)" - +@ MSG_LIB_INUSE " use path=%s (implicitly secure, as directory \ + has already provided dependencies)" # Mapfile messages diff --git a/usr/src/cmd/sgs/liblddbg/common/libs.c b/usr/src/cmd/sgs/liblddbg/common/libs.c index 227a0cce0c..5ccfce723e 100644 --- a/usr/src/cmd/sgs/liblddbg/common/libs.c +++ b/usr/src/cmd/sgs/liblddbg/common/libs.c @@ -23,8 +23,6 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "msg.h" #include "_debug.h" #include "libld.h" @@ -64,12 +62,15 @@ Dbg_libs_found(Lm_list *lml, const char *path, int alter) } void -Dbg_libs_ignore(Lm_list *lml, const char *path) +Dbg_libs_insecure(Lm_list *lml, const char *path, int usable) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; - dbg_print(lml, MSG_INTL(MSG_LIB_IGNORE), path); + if (usable) + dbg_print(lml, MSG_INTL(MSG_LIB_INUSE), path); + else + dbg_print(lml, MSG_INTL(MSG_LIB_IGNORE), path); } static void diff --git a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg index f2981d8fce..6ab7e7be27 100644 --- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg +++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg @@ -166,8 +166,8 @@ void Dbg32_libs_find(Lm_list *, const char *); void Dbg64_libs_find(Lm_list *, const char *); void Dbg32_libs_found(Lm_list *, const char *, int); void Dbg64_libs_found(Lm_list *, const char *, int); -void Dbg32_libs_ignore(Lm_list *, const char *); -void Dbg64_libs_ignore(Lm_list *, const char *); +void Dbg32_libs_insecure(Lm_list *, const char *, int); +void Dbg64_libs_insecure(Lm_list *, const char *, int); void Dbg32_libs_init(Lm_list *, List *, List *); void Dbg64_libs_init(Lm_list *, List *, List *); void Dbg32_libs_l(Lm_list *, const char *, const char *); diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers index 605e179bfb..102ba73c67 100644 --- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers +++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers @@ -38,7 +38,7 @@ # Policy for Shared Library Version Names and Interface Definitions -SUNWprivate_4.65 { +SUNWprivate_4.66 { global: dbg_desc = NODIRECT; # interposed - ld.so.1(1) dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1) @@ -166,8 +166,8 @@ SUNWprivate_4.65 { Dbg64_libs_find; Dbg32_libs_found; Dbg64_libs_found; - Dbg32_libs_ignore; - Dbg64_libs_ignore; + Dbg32_libs_insecure; + Dbg64_libs_insecure; Dbg32_libs_init; Dbg64_libs_init; Dbg32_libs_l; diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index f964e166fa..d5ad09bd9d 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1376,3 +1376,5 @@ Bugid Risk Synopsis linking gnu object code 6744003 ld(1) could provide better argument processing diagnostics PSARC 2008/583 add gld options to ld(1) +6746674 setuid applications do not find libraries any more because trusted + directories behavior changed diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index ef5c19f602..57764f9526 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -30,8 +30,6 @@ #ifndef __RTLD_H #define __RTLD_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Common header for run-time linker. */ @@ -318,6 +316,7 @@ typedef struct { #define RT_FL2_PLMSETUP 0x00000400 /* primary link-map set up complete */ #define RT_FL2_BRANDED 0x00000800 /* process is branded */ #define RT_FL2_NOPLM 0x00001000 /* process has no primary link map */ +#define RT_FL2_SETUID 0x00002000 /* ld.so.1 is setuid root */ /* * Information flags for env_info. @@ -585,6 +584,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_rtld_setuid(); extern int is_sym_interposer(Rt_map *, Sym *); extern void ldso_plt_init(Rt_map *); extern Listnode *list_append(List *, const void *); @@ -650,6 +650,8 @@ extern Rt_map *setup(char **, auxv_t *, Word, char *, int, char *, Dyn *, ulong_t, ulong_t, int fd, Phdr *, char *, char **, int, uid_t, uid_t, gid_t, gid_t, void *, int, uint_t); +extern void spavl_insert(const char *); +extern int spavl_recorded(const char *, avl_index_t *); extern int tls_assign(Lm_list *, Rt_map *, Phdr *); extern void tls_modaddrem(Rt_map *, uint_t); extern int tls_statmod(Lm_list *, Rt_map *); diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c index f5111d803d..7dcf5b00d0 100644 --- a/usr/src/cmd/sgs/rtld/common/analyze.c +++ b/usr/src/cmd/sgs/rtld/common/analyze.c @@ -29,8 +29,6 @@ * All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <string.h> #include <stdio.h> #include <unistd.h> @@ -1741,6 +1739,23 @@ load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc, int *in_nfavl) remove_so(lml, nlmp); return (0); } + + /* + * If this is a secure application, record any full path name + * directory in which this dependency has been found. This + * directory can be deemed safe (as we've already found a + * dependency here). This recording provides a fall-back + * should another objects $ORIGIN definition expands to this + * directory, an expansion that would ordinarily be deemed + * insecure. + */ + if (rtld_flags & RT_FL_SECURE) { + if (NAME(nlmp)[0] == '/') + spavl_insert(NAME(nlmp)); + if ((NAME(nlmp) != PATHNAME(nlmp)) && + (PATHNAME(nlmp)[0] == '/')) + spavl_insert(PATHNAME(nlmp)); + } } /* diff --git a/usr/src/cmd/sgs/rtld/common/debug.c b/usr/src/cmd/sgs/rtld/common/debug.c index a58e294246..2168351095 100644 --- a/usr/src/cmd/sgs/rtld/common/debug.c +++ b/usr/src/cmd/sgs/rtld/common/debug.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> @@ -61,16 +59,8 @@ dbg_setup(const char *options, Dbg_desc *dbp) * If we're running secure, only allow debugging if ld.so.1 itself is * owned by root and has its mode setuid. Fail silently. */ - if (rtld_flags & RT_FL_SECURE) { - struct stat status; - - if (stat(NAME(lml_rtld.lm_head), &status) == 0) { - if ((status.st_uid != 0) || - (!(status.st_mode & S_ISUID))) - return (0); - } else - return (0); - } + if ((rtld_flags & RT_FL_SECURE) && (is_rtld_setuid() == 0)) + return (0); /* * As Dbg_setup() will effectively lazy load the necessary support diff --git a/usr/src/cmd/sgs/rtld/common/paths.c b/usr/src/cmd/sgs/rtld/common/paths.c index da750728d4..23391d59ab 100644 --- a/usr/src/cmd/sgs/rtld/common/paths.c +++ b/usr/src/cmd/sgs/rtld/common/paths.c @@ -29,8 +29,6 @@ * All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * PATH setup and search directory functions. */ @@ -715,7 +713,7 @@ 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; - Lm_list *lml; + Lm_list *lml = LIST(clmp); /* * If a pathname originates from a configuration file, use it. The use @@ -736,20 +734,24 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) str = strrchr(opath, '/'); /* - * A simple filename (one containing no "/") is fine, as this - * will be combined with search paths to determine the complete - * path. Other paths are checked: + * Carry out some initial security checks. * + * . a simple file name (one containing no "/") is fine, as + * this file name will be combined with search paths to + * determine the complete path. * . a full path (one starting with "/") is fine, provided - * it isn't a preload/audit path. - * . any $ORIGIN expansion - * . any relative path + * 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) && ((info & PN_FLG_EXTLOAD) == 0))) && ((flags & PN_TKN_ORIGIN) == 0)) return (1); + /* + * Determine the directory name of the present path. + */ if (str == opath) npath = (char *)MSG_ORIG(MSG_STR_SLASH); else { @@ -762,19 +764,47 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) 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); + } + } else { /* * A search path, i.e., RPATH, configuration file path, etc. is * used as is. Exceptions to this are: * - * . LD_LIBRARY_PATH - * . any $ORIGIN expansion - * . any relative path + * . LD_LIBRARY_PATH. + * . any $ORIGIN expansion, unless used by a setuid ld.so.1 + * to find its own dependencies, or the path name has + * already been used to find other dependencies. + * . any relative path. */ if (((info & LA_SER_LIBPATH) == 0) && (*opath == '/') && ((flags & PN_TKN_ORIGIN) == 0)) return (1); + /* + * If $ORIGIN processing is requested, allow a setuid ld.so.1 + * to use this path for its own dependencies. Allow the + * application to use this path name only if the path name has + * already been used to locate other dependencies. + */ + if (flags & PN_TKN_ORIGIN) { + if ((lml->lm_flags & LML_FLG_RTLDLM) && + is_rtld_setuid()) + return (1); + else if (spavl_recorded(opath, 0)) { + DBG_CALL(Dbg_libs_insecure(lml, opath, 1)); + return (1); + } + } npath = (char *)opath; } @@ -784,8 +814,6 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) sdir = sdir->p_next; } - lml = LIST(clmp); - /* * The path is insecure, so depending on the caller, provide a * diagnostic. Preloaded, or audit libraries generate a warning, as @@ -830,7 +858,7 @@ is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags) /* * Search paths. */ - DBG_CALL(Dbg_libs_ignore(lml, opath)); + DBG_CALL(Dbg_libs_insecure(lml, opath, 0)); if ((lml->lm_flags & LML_FLG_TRC_SEARCH) && ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) (void) printf(MSG_INTL(MSG_LDD_PTH_IGNORE), opath); diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index c7671087d7..5f2047bb64 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -29,8 +29,6 @@ * All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Utility routines for run-time linker. some are duplicated here from libc * (with different names) to avoid name space collisions. @@ -47,6 +45,7 @@ #include <dlfcn.h> #include <unistd.h> #include <stdlib.h> +#include <limits.h> #include <sys/auxv.h> #include <debug.h> #include <conv.h> @@ -380,6 +379,20 @@ pnavl_compare(const void *n1, const void *n2) } /* + * Create an AVL tree. + */ +static avl_tree_t * +pnavl_create(size_t size) +{ + avl_tree_t *avlt; + + if ((avlt = malloc(sizeof (avl_tree_t))) == NULL) + return (NULL); + avl_create(avlt, pnavl_compare, size, SGSOFFSETOF(PathNode, pn_avl)); + return (avlt); +} + +/* * Determine if a pathname has already been recorded on the full path name * AVL tree. This tree maintains a node for each path name that ld.so.1 has * successfully loaded. If the path name does not exist in this AVL tree, then @@ -390,18 +403,13 @@ Rt_map * fpavl_recorded(Lm_list *lml, const char *name, avl_index_t *where) { FullPathNode fpn, *fpnp; - avl_tree_t *avlt; /* * Create the avl tree if required. */ - if ((avlt = lml->lm_fpavl) == NULL) { - if ((avlt = calloc(sizeof (avl_tree_t), 1)) == 0) - return (0); - avl_create(avlt, pnavl_compare, sizeof (FullPathNode), - SGSOFFSETOF(FullPathNode, fpn_node.pn_avl)); - lml->lm_fpavl = avlt; - } + if ((lml->lm_fpavl == NULL) && + ((lml->lm_fpavl = pnavl_create(sizeof (FullPathNode))) == NULL)) + return (NULL); fpn.fpn_node.pn_name = name; fpn.fpn_node.pn_hash = sgs_str_hash(name); @@ -439,7 +447,7 @@ fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where) /* * Insert new node in tree. */ - if ((fpnp = calloc(sizeof (FullPathNode), 1)) == 0) + if ((fpnp = calloc(sizeof (FullPathNode), 1)) == NULL) return (0); fpnp->fpn_node.pn_name = name; @@ -487,23 +495,18 @@ int nfavl_recorded(const char *name, avl_index_t *where) { PathNode pn; - avl_tree_t *avlt; /* * Create the avl tree if required. */ - if ((avlt = nfavl) == NULL) { - if ((avlt = calloc(sizeof (avl_tree_t), 1)) == 0) - return (0); - avl_create(avlt, pnavl_compare, sizeof (PathNode), - SGSOFFSETOF(PathNode, pn_avl)); - nfavl = avlt; - } + if ((nfavl == NULL) && + ((nfavl = pnavl_create(sizeof (PathNode))) == NULL)) + return (0); pn.pn_name = name; pn.pn_hash = sgs_str_hash(name); - if (avl_find(avlt, &pn, where) == NULL) + if (avl_find(nfavl, &pn, where) == NULL) return (0); return (1); @@ -538,6 +541,76 @@ nfavl_insert(const char *name, avl_index_t where) } } +static avl_tree_t *spavl = NULL; + +/* + * Search for a path name within the secure path AVL tree. This tree is used + * to maintain a list of directories in which the dependencies of a secure + * process have been found. This list provides a fall-back in the case that a + * $ORIGIN expansion is deemed insecure, when the expansion results in a path + * name that has already provided dependencies. + */ +int +spavl_recorded(const char *name, avl_index_t *where) +{ + PathNode pn; + + /* + * Create the avl tree if required. + */ + if ((spavl == NULL) && + ((spavl = pnavl_create(sizeof (PathNode))) == NULL)) + return (0); + + pn.pn_name = name; + pn.pn_hash = sgs_str_hash(name); + + if (avl_find(spavl, &pn, where) == NULL) + return (0); + + return (1); +} + +/* + * Insert the directory name, of a full path name, into the secure path AVL + * tree. + */ +void +spavl_insert(const char *name) +{ + char buffer[PATH_MAX], *str; + size_t size; + avl_index_t where; + PathNode *pnp; + + /* + * Separate the directory name from the path name. + */ + if ((str = strrchr(name, '/')) == name) + size = 1; + else + size = str - name; + + (void) strncpy(buffer, name, size); + buffer[size] = '\0'; + + /* + * Determine whether this directory name is already recorded, or if + * not, 'where" will provide the insertion point for the new string. + */ + if (spavl_recorded(buffer, &where)) + return; + + /* + * Insert new node in tree. + */ + if ((pnp = calloc(sizeof (PathNode), 1)) != 0) { + pnp->pn_name = strdup(buffer); + pnp->pn_hash = sgs_str_hash(buffer); + avl_insert(spavl, pnp, where); + } +} + /* * Prior to calling an object, either via a .plt or through dlsym(), make sure * its .init has fired. Through topological sorting, ld.so.1 attempts to fire @@ -1034,8 +1107,8 @@ list_append(List *lst, const void *item) { Listnode *_lnp; - if ((_lnp = malloc(sizeof (Listnode))) == 0) - return (0); + if ((_lnp = malloc(sizeof (Listnode))) == NULL) + return (NULL); _lnp->data = (void *)item; _lnp->next = NULL; @@ -1109,7 +1182,7 @@ list_delete(List *lst, void *item) plnp = clnp; } - if (clnp == 0) + if (clnp == NULL) return; if (lst->head == clnp) @@ -1335,16 +1408,16 @@ lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc) * Move the new link-map control list, to the callers link-map control * list. */ - if (plmc->lc_head == 0) { + if (plmc->lc_head == NULL) { plmc->lc_head = nlmc->lc_head; - PREV(nlmc->lc_head) = 0; + PREV(nlmc->lc_head) = NULL; } else { NEXT(plmc->lc_tail) = (Link_map *)nlmc->lc_head; PREV(nlmc->lc_head) = (Link_map *)plmc->lc_tail; } plmc->lc_tail = nlmc->lc_tail; - nlmc->lc_head = nlmc->lc_tail = 0; + nlmc->lc_head = nlmc->lc_tail = NULL; /* * For backward compatibility with debuggers, the link-map list contains @@ -2133,10 +2206,10 @@ static int ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, uint_t env_flags, int aout) { - char *nstr, *sstr, *estr = 0; + char *nstr, *sstr, *estr = NULL; size_t nlen, len; - if (str == 0) + if (str == NULL) return (0); /* @@ -2144,7 +2217,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, * uppercase and separate tokens with nulls. */ len = strlen(str); - if ((nstr = malloc(len + 1)) == 0) + if ((nstr = malloc(len + 1)) == NULL) return (1); (void) strcpy(nstr, str); @@ -2152,7 +2225,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, int flags; if ((*sstr != '\0') && (*sstr != ',')) { - if (estr == 0) { + if (estr == NULL) { if (*sstr == '=') estr = sstr; else { @@ -2183,7 +2256,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, * the term "(null)" is specifically chosen in case someone * mistakenly supplies something like LD_FLAGS=library_path. */ - if (estr == 0) + if (estr == NULL) estr = (char *)MSG_INTL(MSG_STR_NULL); /* @@ -2282,7 +2355,7 @@ ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags, * within a configuration file, these null user settings can be * used to disable any configuration replaceable definitions. */ - if ((s2 = strchr(s1, '=')) == 0) { + if ((s2 = strchr(s1, '=')) == NULL) { len = strlen(s1); s2 = 0; } else if (*++s2 == '\0') { @@ -3179,7 +3252,7 @@ is_path_used(Lm_list *lml, Word unref, int *nl, Pnode *pnp, const char *obj) * If this pathname originated from an expanded token, use the * original for any diagnostic output. */ - if ((name = pnp->p_oname) == 0) + if ((name = pnp->p_oname) == NULL) name = pnp->p_name; if (unref == 0) { @@ -3399,7 +3472,7 @@ leave(Lm_list *lml, int flags) * case of tearing down a whole link-map list, lml will be null. In * this case use the main link-map list to test for a notification. */ - if (elml == 0) + if (elml == NULL) elml = &lml_main; if (elml->lm_flags & LML_FLG_DBNOTIF) rd_event(elml, RD_DLACTIVITY, RT_CONSISTENT); @@ -3632,6 +3705,23 @@ security(uid_t uid, uid_t euid, gid_t gid, gid_t egid, int auxflags) } /* + * Determine whether ld.so.1 itself is owned by root and has its mode setuid. + */ +int +is_rtld_setuid() +{ + struct stat status; + + if ((rtld_flags2 & RT_FL2_SETUID) || + ((stat(NAME(lml_rtld.lm_head), &status) == 0) && + (status.st_uid == 0) && (status.st_mode & S_ISUID))) { + rtld_flags2 |= RT_FL2_SETUID; + return (1); + } + return (0); +} + +/* * _REENTRANT code gets errno redefined to a function so provide for return * of the thread errno if applicable. This has no meaning in ld.so.1 which * is basically singled threaded. Provide the interface for our dependencies. |