diff options
| author | Rod Evans <Rod.Evans@Sun.COM> | 2009-02-23 12:46:16 -0800 |
|---|---|---|
| committer | Rod Evans <Rod.Evans@Sun.COM> | 2009-02-23 12:46:16 -0800 |
| commit | 43d7826ada3fc66e7100086426530c695d695911 (patch) | |
| tree | 6e5d7eca470bdeb19e0f3d05b50452fade30790c | |
| parent | fc4da20a853fc51a23289ca955c3a07a3abfaf8a (diff) | |
| download | illumos-joyent-43d7826ada3fc66e7100086426530c695d695911.tar.gz | |
6807864 ld.so.1 is susceptible to a fatal dlsym()/setlocale() race
| -rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 1 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/_rtld.h | 4 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/audit.c | 14 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/external.c | 156 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/globals.c | 2 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/util.c | 80 |
6 files changed, 135 insertions, 122 deletions
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 8c3e0b60ec..1fe0253dcd 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1443,3 +1443,4 @@ Bugid Risk Synopsis pfinstall does it again. 6807050 GNU linkonce sections can create duplicate and incompatible eh_frame FDE entries +6807864 ld.so.1 is susceptible to a fatal dlsym()/setlocale() race diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index b86c5d5005..92101c6a99 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -579,7 +579,8 @@ extern const char *profile_lib; /* audit library to perform profile */ extern Dl_argsinfo argsinfo; /* process argument, environment and */ /* auxv information */ -extern const char *err_strs[]; /* diagnostic error string headers */ +extern const char *err_strs[ERR_NUM]; + /* diagnostic error string headers */ extern const char *nosym_str; /* MSG_GEN_NOSYM message cache */ extern ulong_t hwcap; /* hardware capabilities */ @@ -634,7 +635,6 @@ extern Rt_map *fpavl_recorded(Lm_list *, const char *, uint_t, avl_index_t *); extern void fpavl_remove(Rt_map *); extern size_t fullpath(Rt_map *, Fdesc *); -extern void get_lcinterface(Rt_map *, Lc_interface *); extern Lmid_t get_linkmap_id(Lm_list *); extern Pdesc *get_next_dir(Spath_desc *, Rt_map *, uint_t); extern int hdl_add(Grp_hdl *, Rt_map *, uint_t); diff --git a/usr/src/cmd/sgs/rtld/common/audit.c b/usr/src/cmd/sgs/rtld/common/audit.c index c7e6467d8b..d4f8d699a2 100644 --- a/usr/src/cmd/sgs/rtld/common/audit.c +++ b/usr/src/cmd/sgs/rtld/common/audit.c @@ -963,14 +963,12 @@ audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig, int *in_nfavl) } /* - * If we are not running in the environment where - * libc/libthread are merged, we hold on to rtld lock - * upon leave() function. - * - * There is a possibility that libc is not mapped in yet. - * We may later find out that we will be running in - * libc/libthread merged enviornment. Refer to: - * get_lcinterface() in mutex.c. + * Prior to the Unified Process Model (UPM) environment, an + * rtld lock had to be held upon leave(). However, even within + * a UPM environment, an old auditor, that has a lazy dependency + * on libc, is still a possibility. As libc isn't loaded, we + * don't know the process model, and will determine this later. + * Refer to external.c:get_lcinterface(). */ if ((rtld_flags2 & RT_FL2_UNIFPROC) == 0) LIST(lmp)->lm_flags |= LML_FLG_HOLDLOCK; diff --git a/usr/src/cmd/sgs/rtld/common/external.c b/usr/src/cmd/sgs/rtld/common/external.c index 217ab10440..72e537813b 100644 --- a/usr/src/cmd/sgs/rtld/common/external.c +++ b/usr/src/cmd/sgs/rtld/common/external.c @@ -28,9 +28,10 @@ * Implementation of all external interfaces between ld.so.1 and libc. * * This file started as a set of routines that provided synchronization and - * locking operations using calls to libthread. libthread has merged with libc, - * and things have gotten a little simpler. This file continues to establish - * and redirect various events within ld.so.1 to interfaces within libc. + * locking operations using calls to libthread. libthread has merged with libc + * under the Unified Process Model (UPM), and things have gotten a lot simpler. + * This file continues to establish and redirect various events within ld.so.1 + * to interfaces within libc. * * Until libc is loaded and relocated, any external interfaces are captured * locally. Each link-map list maintains its own set of external vectors, as @@ -177,20 +178,37 @@ /* * This interface provides the unified process model communication between - * ld.so.1 and libc. This interface is supplied through RTLDINFO. + * ld.so.1 and libc. This interface can be called a number of times: + * + * - Initially, this interface is called to process RTLDINFO. This data + * structure is typically provided by libc, and contains the address of + * libc interfaces that must be called to initialize threads information. + * + * - _ld_libc(), this interface can also be called by libc at process + * initialization, after libc has been loaded and relocated, but before + * control has been passed to any user code (.init's or main()). This + * call provides additional libc interface information that ld.so.1 must + * call during process execution. + * + * - _ld_libc() can also be called by libc during process execution to + * re-establish interfaces such as the locale. */ -void +static void get_lcinterface(Rt_map *lmp, Lc_interface *funcs) { - int threaded = 0; - int version; - int tag; + int threaded = 0, entry = 0, tag; Lm_list *lml; Lc_desc *lcp; - if ((lmp == 0) || (funcs == 0)) + if ((lmp == NULL) || (funcs == NULL)) return; + /* + * Once the process is active, ensure we grab a lock. + */ + if (rtld_flags & RT_FL_APPLIC) + entry = enter(0); + lml = LIST(lmp); lcp = &lml->lm_lcs[0]; @@ -243,7 +261,7 @@ get_lcinterface(Rt_map *lmp, Lc_interface *funcs) * on the primrary link-map may change this locale. */ if ((lml->lm_flags & LML_FLG_BASELM) && - ((gptr == 0) || (strcmp(gptr, lptr) != 0))) { + ((gptr == NULL) || (strcmp(gptr, lptr) != 0))) { /* * If we've obtained a message locale (typically * supplied via libc's setlocale()), then @@ -260,12 +278,8 @@ get_lcinterface(Rt_map *lmp, Lc_interface *funcs) /* * Clear any cached messages. */ - err_strs[ERR_NONE] = 0; - err_strs[ERR_WARNING] = 0; - err_strs[ERR_FATAL] = 0; - err_strs[ERR_ELF] = 0; - - nosym_str = 0; + bzero(err_strs, sizeof (err_strs)); + nosym_str = NULL; } break; @@ -276,7 +290,7 @@ get_lcinterface(Rt_map *lmp, Lc_interface *funcs) * If the global vector is unset, or this is the primary * link-map, set the global vector. */ - if ((gptr == 0) || (lml->lm_flags & LML_FLG_BASELM)) + if ((gptr == NULL) || (lml->lm_flags & LML_FLG_BASELM)) glcs[tag].lc_un.lc_ptr = lptr; /* FALLTHROUGH */ @@ -290,6 +304,10 @@ get_lcinterface(Rt_map *lmp, Lc_interface *funcs) case CI_VERSION: if ((rtld_flags2 & RT_FL2_RTLDSEEN) == 0) { + Listnode *lnp; + Lm_list *lml2; + int version; + rtld_flags2 |= RT_FL2_RTLDSEEN; version = funcs->ci_un.ci_val; @@ -299,36 +317,30 @@ get_lcinterface(Rt_map *lmp, Lc_interface *funcs) thr_flg_reenter = THR_FLG_REENTER; } #endif - if (version >= CI_V_FOUR) { - Listnode *lnp; - Lm_list *lml2; - - rtld_flags2 |= RT_FL2_UNIFPROC; - - /* - * We might have seen auditor which is - * not dependent on libc. Such an - * auditor's link map list has - * LML_FLG_HOLDLOCK set. This lock - * needs to be dropped. Refer to - * audit_setup() in audit.c. - */ - if ((rtld_flags2 & RT_FL2_HASAUDIT) == - 0) + if (version < CI_V_FOUR) break; - /* - * Yes, we did. Take care of them. - */ - for (LIST_TRAVERSE(&dynlm_list, lnp, - lml2)) { - Rt_map *map = - (Rt_map *)lml2->lm_head; - - if (FLAGS(map) & FLG_RT_AUDIT) { - lml2->lm_flags &= - ~LML_FLG_HOLDLOCK; - } + rtld_flags2 |= RT_FL2_UNIFPROC; + + /* + * We might have seen an auditor which is not + * dependent on libc. Such an auditor's link + * map list has LML_FLG_HOLDLOCK set. This + * lock needs to be dropped. Refer to + * audit_setup() in audit.c. + */ + if ((rtld_flags2 & RT_FL2_HASAUDIT) == 0) + break; + + /* + * Yes, we did. Take care of them. + */ + for (LIST_TRAVERSE(&dynlm_list, lnp, lml2)) { + Rt_map *map = (Rt_map *)lml2->lm_head; + + if (FLAGS(map) & FLG_RT_AUDIT) { + lml2->lm_flags &= + ~LML_FLG_HOLDLOCK; } } } @@ -339,26 +351,28 @@ get_lcinterface(Rt_map *lmp, Lc_interface *funcs) } } - if (threaded == 0) - return; + if (threaded) { + /* + * If a version of libc gives us only a subset of the TLS + * interfaces, it's confused and we discard the whole lot. + */ + if ((lcp[CI_TLS_MODADD].lc_un.lc_func && + lcp[CI_TLS_MODREM].lc_un.lc_func && + lcp[CI_TLS_STATMOD].lc_un.lc_func) == NULL) { + lcp[CI_TLS_MODADD].lc_un.lc_func = NULL; + lcp[CI_TLS_MODREM].lc_un.lc_func = NULL; + lcp[CI_TLS_STATMOD].lc_un.lc_func = NULL; + } - /* - * If a version of libc gives us only a subset of the TLS interfaces - - * it's confused and we discard the whole lot. - */ - if ((lcp[CI_TLS_MODADD].lc_un.lc_func && - lcp[CI_TLS_MODREM].lc_un.lc_func && - lcp[CI_TLS_STATMOD].lc_un.lc_func) == 0) { - lcp[CI_TLS_MODADD].lc_un.lc_func = 0; - lcp[CI_TLS_MODREM].lc_un.lc_func = 0; - lcp[CI_TLS_STATMOD].lc_un.lc_func = 0; + /* + * Indicate that we're now thread capable. + */ + if ((lml->lm_flags & LML_FLG_RTLDLM) == 0) + rtld_flags |= RT_FL_THREADS; } - /* - * Indicate that we're now thread capable. - */ - if ((lml->lm_flags & LML_FLG_RTLDLM) == 0) - rtld_flags |= RT_FL_THREADS; + if (entry) + leave(lml, 0); } /* @@ -384,7 +398,8 @@ rt_get_extern(Lm_list *lml, Rt_map *lmp) * Perform some sanity checks. If we have TLS requirements we better * have the associated external interfaces. */ - if (lml->lm_tls && (lml->lm_lcs[CI_TLS_STATMOD].lc_un.lc_func == 0)) { + if (lml->lm_tls && + (lml->lm_lcs[CI_TLS_STATMOD].lc_un.lc_func == NULL)) { eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TLS_NOSUPPORT), NAME(lmp)); return (0); @@ -392,6 +407,16 @@ rt_get_extern(Lm_list *lml, Rt_map *lmp) return (1); } +/* + * Provide an interface for libc to communicate additional interface + * information. + */ +void +_ld_libc(void *ptr) +{ + get_lcinterface(_caller(caller(), CL_EXECDEF), (Lc_interface *)ptr); +} + static int bindmask = 0; int @@ -440,8 +465,9 @@ rt_thr_init(Lm_list *lml) { void (*fptr)(void); - if ((fptr = (void (*)())lml->lm_lcs[CI_THRINIT].lc_un.lc_func) != 0) { - lml->lm_lcs[CI_THRINIT].lc_un.lc_func = 0; + if ((fptr = + (void (*)())lml->lm_lcs[CI_THRINIT].lc_un.lc_func) != NULL) { + lml->lm_lcs[CI_THRINIT].lc_un.lc_func = NULL; leave(NULL, thr_flg_reenter); (*fptr)(); (void) enter(thr_flg_reenter); diff --git a/usr/src/cmd/sgs/rtld/common/globals.c b/usr/src/cmd/sgs/rtld/common/globals.c index 6fb2c19c9f..8e14e4da6c 100644 --- a/usr/src/cmd/sgs/rtld/common/globals.c +++ b/usr/src/cmd/sgs/rtld/common/globals.c @@ -179,7 +179,7 @@ Dl_argsinfo argsinfo = { 0 }; /* process argument, environment and */ * Frequently used messages are cached here to reduce _dgettext() overhead and * also provide for resetting should the locale change (see _ld_libc()). */ -const char *err_strs[ERR_NUM] = { 0 }; +const char *err_strs[ERR_NUM] = { NULL }; const char *nosym_str = NULL; diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index c05f7866d5..b527affc4e 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -328,7 +328,7 @@ rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags, /* * Make sure an object file has been specified. */ - if (argv[ndx] == 0) + if (argv[ndx] == NULL) return (1); /* @@ -432,7 +432,7 @@ fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where) * We better not get a hit now, we do not want duplicates in * the tree. */ - ASSERT(_lmp == 0); + ASSERT(_lmp == NULL); } /* @@ -595,7 +595,7 @@ spavl_insert(const char *name) /* * Insert new node in tree. */ - if ((pnp = calloc(sizeof (PathNode), 1)) != 0) { + if ((pnp = calloc(sizeof (PathNode), 1)) != NULL) { pnp->pn_name = strdup(buffer); pnp->pn_hash = sgs_str_hash(buffer); avl_insert(spavl, pnp, where); @@ -963,7 +963,7 @@ atexit_fini() /* * Reverse topologically sort the main link-map for .fini execution. */ - if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) && + if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != NULL) && (tobj != (Rt_map **)S_ERROR)) call_fini(lml, tobj); @@ -997,7 +997,7 @@ atexit_fini() if (lml->lm_flags & (LML_FLG_BASELM | LML_FLG_RTLDLM)) continue; - if ((lmp = (Rt_map *)lml->lm_head) == 0) + if ((lmp = (Rt_map *)lml->lm_head) == NULL) continue; lml->lm_flags |= LML_FLG_ATEXIT; @@ -1006,7 +1006,7 @@ atexit_fini() /* * Reverse topologically sort the link-map for .fini execution. */ - if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) && + if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != NULL) && (tobj != (Rt_map **)S_ERROR)) call_fini(lml, tobj); @@ -1022,7 +1022,7 @@ atexit_fini() lml->lm_flags &= ~LML_FLG_INTRPOSETSORT; lmp = (Rt_map *)lml->lm_head; - if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) && + if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != NULL) && (tobj != (Rt_map **)S_ERROR)) call_fini(lml, tobj); @@ -1038,7 +1038,7 @@ atexit_fini() void load_completion(Rt_map *nlmp) { - Rt_map **tobj = 0; + Rt_map **tobj = NULL; Lm_list *nlml; /* @@ -1066,7 +1066,7 @@ load_completion(Rt_map *nlmp) (rtld_flags2 & (RT_FL2_PLMSETUP | RT_FL2_NOPLM)))) { if ((tobj = tsort(nlmp, nlml->lm_init, RT_SORT_REV)) == (Rt_map **)S_ERROR) - tobj = 0; + tobj = NULL; } /* @@ -1455,10 +1455,10 @@ lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc) * from a configuration file. The latter provides a fallback if no user * environment setting is found, and can take two forms: * - * . a replaceable definition - this will be used if no user environment + * - a replaceable definition - this will be used if no user environment * setting has been seen, or * - * . an permanent definition - this will be used no matter what user + * - an permanent definition - this will be used no matter what user * environment setting is seen. In the case of list variables it will be * appended to any process environment setting seen. * @@ -2060,7 +2060,7 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, if (s2) rpl_debug = MSG_ORIG(MSG_TKN_BINDINGS); else - rpl_debug = 0; + rpl_debug = NULL; } else if (variable == ENV_FLG_CONFGEN) { if (s2) { rtld_flags |= RT_FL_CONFGEN; @@ -2203,7 +2203,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, if (estr) { nlen = estr - nstr; if ((*++estr == '\0') || (*estr == ',')) - estr = 0; + estr = NULL; } else nlen = sstr - nstr; @@ -2230,7 +2230,7 @@ ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, return (0); nstr = sstr + 1; - estr = 0; + estr = NULL; } return (0); } @@ -2315,10 +2315,10 @@ ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags, */ if ((s2 = strchr(s1, '=')) == NULL) { len = strlen(s1); - s2 = 0; + s2 = NULL; } else if (*++s2 == '\0') { len = strlen(s1) - 1; - s2 = 0; + s2 = NULL; } else { len = s2 - s1 - 1; while (isspace(*s2)) @@ -2395,11 +2395,11 @@ readenv_user(const char **envp, Word *lmflags, Word *lmtflags, int aout) * generic handling of message files does). Duplicate the string so * that new locale setting can generically cleanup any previous locales. */ - if ((locale = glcs[CI_LCMESSAGES].lc_un.lc_ptr) != 0) { + if ((locale = glcs[CI_LCMESSAGES].lc_un.lc_ptr) != NULL) { if (((*locale == 'C') && (*(locale + 1) == '\0')) || (strcmp(locale, MSG_ORIG(MSG_TKN_POSIX)) == 0) || (strstr(locale, MSG_ORIG(MSG_TKN_DOTDOT)) != NULL)) - glcs[CI_LCMESSAGES].lc_un.lc_ptr = 0; + glcs[CI_LCMESSAGES].lc_un.lc_ptr = NULL; else glcs[CI_LCMESSAGES].lc_un.lc_ptr = strdup(locale); } @@ -2812,7 +2812,7 @@ printf(const char *format, ...) return (dowrite(&prf)); } -static char errbuf[ERRSIZE], *nextptr = errbuf, *prevptr = 0; +static char errbuf[ERRSIZE], *nextptr = errbuf, *prevptr = NULL; /* * All error messages go through eprintf(). During process initialization, @@ -2863,14 +2863,14 @@ eprintf(Lm_list *lml, Error error, const char *format, ...) if ((error == ERR_FATAL) && (rtld_flags2 & RT_FL2_FTL2WARN)) error = ERR_WARNING; if (error == ERR_WARNING) { - if (err_strs[ERR_WARNING] == 0) + if (err_strs[ERR_WARNING] == NULL) err_strs[ERR_WARNING] = MSG_INTL(MSG_ERR_WARNING); } else if (error == ERR_FATAL) { - if (err_strs[ERR_FATAL] == 0) + if (err_strs[ERR_FATAL] == NULL) err_strs[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL); } else if (error == ERR_ELF) { - if (err_strs[ERR_ELF] == 0) + if (err_strs[ERR_ELF] == NULL) err_strs[ERR_ELF] = MSG_INTL(MSG_ERR_ELF); } if (procname) { @@ -2907,16 +2907,17 @@ eprintf(Lm_list *lml, Error error, const char *format, ...) if (NEXT(lmp) && (elfeno == 0)) { if (((elfemg = (const char *(*)())dlsym_intn(RTLD_NEXT, - MSG_ORIG(MSG_SYM_ELFERRMSG), lmp, &dlmp)) == 0) || + MSG_ORIG(MSG_SYM_ELFERRMSG), + lmp, &dlmp)) == NULL) || ((elfeno = (int (*)())dlsym_intn(RTLD_NEXT, - MSG_ORIG(MSG_SYM_ELFERRNO), lmp, &dlmp)) == 0)) + MSG_ORIG(MSG_SYM_ELFERRNO), lmp, &dlmp)) == NULL)) elfeno = 0; } /* * Lookup the message; equivalent to elf_errmsg(elf_errno()). */ - if (elfeno && ((emsg = (* elfemg)((* elfeno)())) != 0)) { + if (elfeno && ((emsg = (* elfemg)((* elfeno)())) != NULL)) { prf.pr_cur--; if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR2), emsg) == 0) @@ -2985,7 +2986,7 @@ eprintf(Lm_list *lml, Error error, const char *format, ...) * created to prevent any duplication clutter. */ if ((rtld_flags & RT_FL_APPLIC) && - ((prevptr == 0) || (strcmp(prevptr, nextptr) != 0))) { + ((prevptr == NULL) || (strcmp(prevptr, nextptr) != 0))) { prevptr = nextptr; nextptr = prf.pr_cur; *nextptr = '\0'; @@ -3336,7 +3337,7 @@ leave(Lm_list *lml, int flags) * Reinitialize error message pointer, and any overflow indication. */ nextptr = errbuf; - prevptr = 0; + prevptr = NULL; /* * Defragment any freed memory. @@ -3349,9 +3350,8 @@ leave(Lm_list *lml, int flags) * there's little point in doing so since we are single-threaded. * * LML_FLG_HOLDLOCK is set for: - * *) The ld.so.1's link-map list. - * *) The auditor's link-map if the environment is - * libc/libthread un-unified. + * - The ld.so.1's link-map list. + * - The auditor's link-map if the environment is pre-UPM. */ if (lml && (lml->lm_flags & LML_FLG_HOLDLOCK)) return; @@ -3457,13 +3457,13 @@ callable(Rt_map *clmp, Rt_map *dlmp, Grp_hdl *ghp, uint_t slflags) * * This routine is called after a relocation() pass, and thus provides for: * - * o setting environ on the main link-map after the initial application and + * - setting environ on the main link-map after the initial application and * its dependencies have been established. Typically environ lives in the * application (provided by its crt), but in older applications it might * be in libc. Who knows what's expected of applications not built on * Solaris. * - * o after loading a new shared object. We can add shared objects to various + * - after loading a new shared object. We can add shared objects to various * link-maps, and any link-map dependencies requiring getopt() require * their own environ. In addition, lazy loading might bring in the * supplier of environ (libc used to be a lazy loading candidate) after @@ -3503,9 +3503,9 @@ set_environ(Lm_list *lml) * can be passed to us via the aux vector, however if these values are -1 * then use the appropriate system call to obtain them. * - * o If the user is the root they can do anything + * - If the user is the root they can do anything * - * o If the real and effective uid's don't match, or the real and + * - If the real and effective uid's don't match, or the real and * effective gid's don't match then this is determined to be a `secure' * application. * @@ -3571,17 +3571,6 @@ ___errno() } /* - * The interface with the c library which is supplied through libdl.so.1. - * A non-null argument allows a function pointer array to be passed to us which - * is used to re-initialize the linker libc table. - */ -void -_ld_libc(void * ptr) -{ - get_lcinterface(_caller(caller(), CL_EXECDEF), (Lc_interface *)ptr); -} - -/* * Determine whether a symbol name should be demangled. */ const char * @@ -3593,7 +3582,6 @@ demangle(const char *name) return (name); } - #ifndef _LP64 /* * Wrappers on stat() and fstat() for 32-bit rtld that uses stat64() |
