diff options
| author | Ali Bahrami <Ali.Bahrami@Sun.COM> | 2008-12-17 10:52:43 -0700 |
|---|---|---|
| committer | Ali Bahrami <Ali.Bahrami@Sun.COM> | 2008-12-17 10:52:43 -0700 |
| commit | cb511613a15cb3949eadffd67b37d3c665b4ef22 (patch) | |
| tree | d65325047358aac8eee263be91a00c794caa63f1 /usr/src/cmd/sgs | |
| parent | 1493b746b3204fb3c94653caa19c30e2c54508c8 (diff) | |
| download | illumos-joyent-cb511613a15cb3949eadffd67b37d3c665b4ef22.tar.gz | |
6782597 32-bit ld.so.1 needs to accept objects with large inode number
Diffstat (limited to 'usr/src/cmd/sgs')
| -rw-r--r-- | usr/src/cmd/sgs/include/rtld.h | 38 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/ldprof/common/profile.c | 4 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/libcrle/common/audit.c | 11 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 1 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/_rtld.h | 33 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/analyze.c | 26 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/cache_a.out.c | 6 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/config_elf.c | 10 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/debug.c | 18 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/dlfcns.c | 10 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/getcwd.c | 14 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/locale.c | 6 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/object.c | 8 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/remove.c | 3 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/setup.c | 8 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/tls.c | 4 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/tsort.c | 12 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/common/util.c | 90 | ||||
| -rw-r--r-- | usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c | 4 |
19 files changed, 210 insertions, 96 deletions
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h index c8be8e1e17..8652d12a02 100644 --- a/usr/src/cmd/sgs/include/rtld.h +++ b/usr/src/cmd/sgs/include/rtld.h @@ -49,6 +49,17 @@ extern "C" { /* + * We use rtld_ino_t instead of ino_t so that we can get + * access to large inode values from 32-bit code. + */ +#ifdef _LP64 +typedef ino_t rtld_ino_t; +#else +typedef ino64_t rtld_ino_t; +#endif + + +/* * Linked list of directories or filenames (built from colon separated string). */ typedef struct pnode { @@ -594,7 +605,7 @@ struct rt_map { int rt_sortval; /* temporary buffer to traverse graph */ uint_t rt_cycgroup; /* cyclic group */ dev_t rt_stdev; /* device id and inode number for .so */ - ino_t rt_stino; /* multiple inclusion checks */ + rtld_ino_t rt_stino; /* multiple inclusion checks */ char *rt_origname; /* original pathname of loaded object */ size_t rt_dirsz; /* and its size */ Rt_map_copy rt_copy; /* list of copy relocations */ @@ -797,6 +808,31 @@ typedef struct rt_map32 { #define REFNAME(X) ((X)->rt_public.l_refname) /* + * An Rt_map starts with a Link_map, followed by other information. + * ld.so.1 allocates Rt_map structures, and then casts them to Link_map, + * and back, depending on context. + * + * On some platforms, Rt_map can have a higher alignment requirement + * than Link_map. On such platforms, the cast from Link_map to Rt_map will + * draw an E_BAD_PTR_CAST_ALIGN warning from lint. Since we allocate + * the memory as the higher alignment Rt_map, we know that this is a safe + * conversion. The LINKMAP_TO_RTMAP macro is used to handle the conversion + * in a manner that satisfies lint. + */ +#ifdef lint +#define LINKMAP_TO_RTMAP(X) (Rt_map *)(void *)(X) +#else +#define LINKMAP_TO_RTMAP(X) (Rt_map *)(X) +#endif + +/* + * Convenience macros for the common case of using + * NEXT()/PREV() and casting the result to (Rt_map *) + */ +#define NEXT_RT_MAP(X) LINKMAP_TO_RTMAP(NEXT(X)) +#define PREV_RT_MAP(X) LINKMAP_TO_RTMAP(PREV(X)) + +/* * Macros for getting to linker private data. */ #define PATHNAME(X) ((X)->rt_pathname) diff --git a/usr/src/cmd/sgs/ldprof/common/profile.c b/usr/src/cmd/sgs/ldprof/common/profile.c index 90573a9adb..25c1ff5437 100644 --- a/usr/src/cmd/sgs/ldprof/common/profile.c +++ b/usr/src/cmd/sgs/ldprof/common/profile.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Routines to provide profiling of shared libraries required by the called * executable. @@ -407,7 +405,7 @@ la_objopen(Link_map *lmp, Lmid_t lmid, uintptr_t *cookie) * Don't even try to profile an object that does not have * auditing enabled on it's link-map. This catches 'ld.so.1'. */ - if (LIST((Rt_map *)lmp)->lm_flags & LML_FLG_NOAUDIT) + if (LIST(LINKMAP_TO_RTMAP(lmp))->lm_flags & LML_FLG_NOAUDIT) return (LA_FLG_BINDFROM); if (profile_open(pname, lmp) == 0) diff --git a/usr/src/cmd/sgs/libcrle/common/audit.c b/usr/src/cmd/sgs/libcrle/common/audit.c index a83753ca9e..d5e94d7679 100644 --- a/usr/src/cmd/sgs/libcrle/common/audit.c +++ b/usr/src/cmd/sgs/libcrle/common/audit.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* LINTLIBRARY */ @@ -117,7 +115,8 @@ la_objopen(Link_map * lmp, Lmid_t lmid, uintptr_t *cookie) if (auflag == CRLE_AUD_DLDUMP) return (0); - if ((lmid == LM_ID_BASE) && !(FLAGS((Rt_map *)lmp) & FLG_RT_ISMAIN)) { + if ((lmid == LM_ID_BASE) && + !(FLAGS(LINKMAP_TO_RTMAP(lmp)) & FLG_RT_ISMAIN)) { char buffer[PATH_MAX]; (void) snprintf(buffer, PATH_MAX, MSG_ORIG(MSG_AUD_DEPEND), diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index 56322d4a86..3968c34260 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1413,3 +1413,4 @@ Bugid Risk Synopsis 6782977 ld segfaults after support lib version error sends bad args to vprintf() 6773695 ld -z nopartial can break non-pic objects 6778453 RTLD_GROUP prevents use of application defined malloc +6782597 32-bit ld.so.1 needs to accept objects with large inode number diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index 59ed5ab21f..4faacfa1ff 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -233,7 +233,7 @@ typedef struct { const char *fd_nname; /* new file (expanded) name */ const char *fd_pname; /* new path (resolved) name */ dev_t fd_dev; /* file device number */ - ino_t fd_ino; /* file inode number */ + rtld_ino_t fd_ino; /* file inode number */ int fd_fd; /* open file descriptor */ uint_t fd_flags; avl_index_t fd_avlwhere; /* avl tree insertion index */ @@ -425,6 +425,31 @@ typedef struct { /* should be retried */ #define BINFO_MSK_REJECTED 0xff0000 /* a mask of bindings that */ /* have been rejected */ + +/* + * The 32-bit version of rtld uses special stat() wrapper functions + * that preserve the non-largefile semantics of stat()/fstat() while + * allowing for large inode values. The 64-bit rtld uses stat() directly. + */ +#ifdef _LP64 +#define rtld_fstat fstat +#define rtld_stat stat +typedef struct stat rtld_stat_t; +#else +typedef struct { + dev_t st_dev; + rtld_ino_t st_ino; + mode_t st_mode; + uid_t st_uid; + off_t st_size; + timestruc_t st_mtim; +#ifdef sparc + blksize_t st_blksize; +#endif +} rtld_stat_t; +#endif + + /* * Data declarations. */ @@ -525,7 +550,7 @@ extern void addfree(void *, size_t); extern int append_alias(Rt_map *, const char *, int *); extern int analyze_lmc(Lm_list *, Aliste, Rt_map *, int *); extern Am_ret anon_map(Lm_list *, caddr_t *, size_t, int, int); -extern Fct *are_u_this(Rej_desc *, int, struct stat *, +extern Fct *are_u_this(Rej_desc *, int, rtld_stat_t *, const char *); extern void atexit_fini(void); extern int bind_one(Rt_map *, Rt_map *, uint_t); @@ -652,6 +677,10 @@ extern void rtld_db_dlactivity(Lm_list *); extern void rtld_db_preinit(Lm_list *); extern void rtld_db_postinit(Lm_list *); extern void rtldexit(Lm_list *, int); +#ifndef _LP64 +extern int rtld_fstat(int, rtld_stat_t *restrict); +extern int rtld_stat(const char *restrict, rtld_stat_t *restrict); +#endif extern int rtld_getopt(char **, char ***, auxv_t **, Word *, Word *, int); extern void security(uid_t, uid_t, gid_t, gid_t, int); diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c index acae11652e..5849e426ed 100644 --- a/usr/src/cmd/sgs/rtld/common/analyze.c +++ b/usr/src/cmd/sgs/rtld/common/analyze.c @@ -128,7 +128,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl) nlmc->lc_flags |= LMC_FLG_ANALYZING; - for (; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (; lmp; lmp = NEXT_RT_MAP(lmp)) { if (FLAGS(lmp) & (FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE)) continue; @@ -294,7 +294,7 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated, int *in_nfavl) { Rt_map *lmp; - for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) { /* * If this object has already been relocated, we're done. If * this object is being deleted, skip it, there's probably a @@ -639,7 +639,7 @@ rejection_inherit(Rej_desc *rej1, Rej_desc *rej2) * Determine the object type of a file. */ Fct * -are_u_this(Rej_desc *rej, int fd, struct stat *status, const char *name) +are_u_this(Rej_desc *rej, int fd, rtld_stat_t *status, const char *name) { int i; char *maddr = 0; @@ -914,7 +914,7 @@ is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl) * Loop through the callers link-map lists. */ for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { - for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) { if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) continue; @@ -1128,7 +1128,7 @@ append_alias(Rt_map *lmp, const char *str, int *added) * values. */ static Rt_map * -is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name, +is_devinode_loaded(rtld_stat_t *status, Lm_list *lml, const char *name, uint_t flags) { Lm_cntl *lmc; @@ -1164,7 +1164,7 @@ is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name, for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { Rt_map *nlmp; - for (nlmp = lmc->lc_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) { + for (nlmp = lmc->lc_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) { if ((FLAGS(nlmp) & FLG_RT_DELETE) || (FLAGS1(nlmp) & FL1_RT_LDDSTUB)) continue; @@ -1246,7 +1246,7 @@ static int file_open(int err, Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej, int *in_nfavl) { - struct stat status; + rtld_stat_t status; Rt_map *nlmp; int resolved = 0; char *name; @@ -1288,7 +1288,7 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname, } } - if ((err == 0) && ((stat(nname, &status)) != -1)) { + if ((err == 0) && ((rtld_stat(nname, &status)) != -1)) { char path[PATH_MAX]; int fd, size, added; @@ -2679,9 +2679,9 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Sym *osym, sl = *slp; if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY)) - lmp = (Rt_map *)NEXT(lmp); + lmp = NEXT_RT_MAP(lmp); - for (; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (; lmp; lmp = NEXT_RT_MAP(lmp)) { if (FLAGS(lmp) & FLG_RT_DELETE) continue; if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) @@ -2842,11 +2842,11 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, * main link-map control list. */ if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp) - lmp = (Rt_map *)NEXT(ilmp); + lmp = NEXT_RT_MAP(ilmp); else lmp = ilmp; - for (; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (; lmp; lmp = NEXT_RT_MAP(lmp)) { if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) { Sym *sym; @@ -2866,7 +2866,7 @@ _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, { Rt_map *lmp; - for (lmp = ilmp; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = ilmp; lmp; lmp = NEXT_RT_MAP(lmp)) { if (LAZY(lmp) == 0) continue; if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) { diff --git a/usr/src/cmd/sgs/rtld/common/cache_a.out.c b/usr/src/cmd/sgs/rtld/common/cache_a.out.c index f825c3b57d..0afdcdb5e5 100644 --- a/usr/src/cmd/sgs/rtld/common/cache_a.out.c +++ b/usr/src/cmd/sgs/rtld/common/cache_a.out.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * 4.x ld.so directory caching: run-time link-editor specific functions. */ @@ -157,7 +155,7 @@ find_so(const char *ds) int fd; /* descriptor on directory */ int n; /* bytes from getdents */ char *cp; /* working char * */ - struct stat sb; /* buffer for stat'ing directory */ + rtld_stat_t sb; /* buffer for stat'ing directory */ struct db *dbp; /* database */ static caddr_t buf = NULL; /* buffer for doing getdents */ static long bs; /* cached blocksize for getdents */ @@ -183,7 +181,7 @@ find_so(const char *ds) * for the first directory we open successfully. */ if (!buf) { - if (fstat(fd, &sb) == -1) { + if (rtld_fstat(fd, &sb) == -1) { (void) close(fd); return ((struct db *)NULL); } diff --git a/usr/src/cmd/sgs/rtld/common/config_elf.c b/usr/src/cmd/sgs/rtld/common/config_elf.c index d1dddb63ab..47fbb68b61 100644 --- a/usr/src/cmd/sgs/rtld/common/config_elf.c +++ b/usr/src/cmd/sgs/rtld/common/config_elf.c @@ -51,7 +51,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp) Rtc_obj *obj; Rtc_dir *dirtbl; Rtc_file *filetbl; - struct stat status; + rtld_stat_t status; int err; /* @@ -128,7 +128,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp) str = strtbl + obj->co_name; - if (stat(str, &status) != 0) { + if (rtld_stat(str, &status) != 0) { err = errno; eprintf(lml, ERR_WARNING, MSG_INTL(MSG_CONF_DSTAT), config->c_name, str, strerror(err)); @@ -154,7 +154,7 @@ elf_config_validate(Addr addr, Rtc_head *head, Rt_map *lmp) (RTC_OBJ_DUMP | RTC_OBJ_REALPTH)) continue; - if (stat(str, &status) != 0) { + if (rtld_stat(str, &status) != 0) { err = errno; eprintf(lml, ERR_WARNING, MSG_INTL(MSG_CONF_FSTAT), config->c_name, @@ -197,7 +197,7 @@ elf_config(Rt_map *lmp, int aout) Rtc_id *id; Rtc_head *head; int fd, features = 0; - struct stat status; + rtld_stat_t status; Addr addr; Pnode *pnp; const char *str; @@ -267,7 +267,7 @@ elf_config(Rt_map *lmp, int aout) /* * Determine the configuration file size and map the file. */ - (void) fstat(fd, &status); + (void) rtld_fstat(fd, &status); if (status.st_size < sizeof (Rtc_head)) { (void) close(fd); return (DBG_CONF_CORRUPT); diff --git a/usr/src/cmd/sgs/rtld/common/debug.c b/usr/src/cmd/sgs/rtld/common/debug.c index 2168351095..3d8cff944f 100644 --- a/usr/src/cmd/sgs/rtld/common/debug.c +++ b/usr/src/cmd/sgs/rtld/common/debug.c @@ -40,10 +40,10 @@ #include "msg.h" -static int dbg_fd; /* debugging output file descriptor */ -static dev_t dbg_dev; -static ino_t dbg_ino; -static pid_t pid; +static int dbg_fd; /* debugging output file descriptor */ +static dev_t dbg_dev; +static rtld_ino_t dbg_ino; +static pid_t pid; /* * Enable diagnostic output. All debugging functions reside in the linker @@ -53,7 +53,7 @@ uintptr_t dbg_setup(const char *options, Dbg_desc *dbp) { uintptr_t ret; - struct stat status; + rtld_stat_t status; /* * If we're running secure, only allow debugging if ld.so.1 itself is @@ -109,7 +109,7 @@ dbg_setup(const char *options, Dbg_desc *dbp) * the debugging file descriptor is still available once the * application has been entered. */ - (void) fstat(dbg_fd, &status); + (void) rtld_fstat(dbg_fd, &status); dbg_dev = status.st_dev; dbg_ino = status.st_ino; pid = getpid(); @@ -140,7 +140,7 @@ dbg_print(Lm_list *lml, const char *format, ...) va_list args; char buffer[ERRSIZE + 1]; pid_t _pid; - struct stat status; + rtld_stat_t status; Prfbuf prf; /* @@ -168,7 +168,7 @@ dbg_print(Lm_list *lml, const char *format, ...) * same descriptor). */ if (rtld_flags & RT_FL_APPLIC) { - if ((fstat(dbg_fd, &status) == -1) || + if ((rtld_fstat(dbg_fd, &status) == -1) || (status.st_dev != dbg_dev) || (status.st_ino != dbg_ino)) { if (dbg_file) { @@ -185,7 +185,7 @@ dbg_print(Lm_list *lml, const char *format, ...) dbg_desc->d_class = 0; return; } - (void) fstat(dbg_fd, &status); + (void) rtld_fstat(dbg_fd, &status); dbg_dev = status.st_dev; dbg_ino = status.st_ino; } else { diff --git a/usr/src/cmd/sgs/rtld/common/dlfcns.c b/usr/src/cmd/sgs/rtld/common/dlfcns.c index 192c653b25..715fe38657 100644 --- a/usr/src/cmd/sgs/rtld/common/dlfcns.c +++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c @@ -73,7 +73,7 @@ _caller(caddr_t cpc, int flags) Rt_map *lmp; for (lmp = lmc->lc_head; lmp; - lmp = (Rt_map *)NEXT(lmp)) { + lmp = NEXT_RT_MAP(lmp)) { Mmap *mmap; /* @@ -650,7 +650,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp, if ((mode & (RTLD_NOW | RTLD_CONFGEN)) == RTLD_CONFGEN) return (ghp); - for (nlmp = lml->lm_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) { + for (nlmp = lml->lm_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) { if (((MODE(nlmp) & RTLD_GLOBAL) == 0) || (FLAGS(nlmp) & FLG_RT_DELETE)) continue; @@ -1022,7 +1022,7 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo, * traverse the present link-map list looking for promiscuous * entries. */ - for (nlmp = lmp; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) { + for (nlmp = lmp; nlmp; nlmp = NEXT_RT_MAP(nlmp)) { /* * If this handle indicates we're only to look in the @@ -1059,7 +1059,7 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo, sl.sl_flags |= LKUP_NODESCENT; - for (nlmp = lmp; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) { + for (nlmp = lmp; nlmp; nlmp = NEXT_RT_MAP(nlmp)) { if (!(MODE(nlmp) & RTLD_GLOBAL) || !LAZY(nlmp)) continue; @@ -1236,7 +1236,7 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp, * RTLD_NEXT request so that it will use the callers link map to * start any possible lazy dependency loading. */ - sl.sl_imap = nlmp = (Rt_map *)NEXT(clmp); + sl.sl_imap = nlmp = NEXT_RT_MAP(clmp); DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl, (nlmp ? NAME(nlmp) : MSG_INTL(MSG_STR_NULL)), diff --git a/usr/src/cmd/sgs/rtld/common/getcwd.c b/usr/src/cmd/sgs/rtld/common/getcwd.c index 3f8109fb91..1cbf7bb242 100644 --- a/usr/src/cmd/sgs/rtld/common/getcwd.c +++ b/usr/src/cmd/sgs/rtld/common/getcwd.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 <fcntl.h> @@ -40,7 +38,7 @@ #ifndef EXPAND_RELATIVE -static struct stat status; +static rtld_stat_t status; /* * Included here (instead of using libc's) to reduce the number of stat calls. @@ -54,7 +52,7 @@ _opendir(const char *file) if ((fd = open(file, (O_RDONLY | O_NDELAY), 0)) < 0) return (0); - if ((fstat(fd, &status) < 0) || + if ((rtld_fstat(fd, &status) < 0) || ((status.st_mode & S_IFMT) != S_IFDIR) || ((dirp = (DIR *)malloc(sizeof (DIR) + DIRBUF)) == NULL)) { (void) close(fd); @@ -115,7 +113,7 @@ getcwd(char *path, size_t pathsz) { char _path[PATH_MAX], cwd[PATH_MAX]; size_t cwdsz; - ino_t cino; + rtld_ino_t cino; dev_t cdev; _path[--pathsz] = '\0'; @@ -127,7 +125,7 @@ getcwd(char *path, size_t pathsz) (void) strcpy(cwd, MSG_ORIG(MSG_FMT_CWD)); cwdsz = MSG_FMT_CWD_SIZE; - if (stat(cwd, &status) == -1) + if (rtld_stat(cwd, &status) == -1) return (NULL); /* LINTED */ @@ -174,7 +172,7 @@ getcwd(char *path, size_t pathsz) * The parent director is a different filesystem, so * determine filenames of subdirectories and stat. */ - struct stat _status; + rtld_stat_t _status; cwd[cwdsz] = '/'; @@ -196,7 +194,7 @@ getcwd(char *path, size_t pathsz) /* * Silently ignore non-stat'able entries. */ - if (stat(cwd, &_status) == -1) + if (rtld_stat(cwd, &_status) == -1) continue; if ((_status.st_ino == cino) && diff --git a/usr/src/cmd/sgs/rtld/common/locale.c b/usr/src/cmd/sgs/rtld/common/locale.c index 91b4448d44..8c743b01b2 100644 --- a/usr/src/cmd/sgs/rtld/common/locale.c +++ b/usr/src/cmd/sgs/rtld/common/locale.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Messaging support. To minimize ld.so.1's overhead, messaging support isn't * enabled until we need to contruct a message - Note that we don't rely on the @@ -146,7 +144,7 @@ open_mofile(Domain * dom) const char *domain = dom->dom_name; char path[PATH_MAX]; int fd; - struct stat status; + rtld_stat_t status; const Msghdr *msghdr; int count; size_t size_tot, size_old, size_new; @@ -159,7 +157,7 @@ open_mofile(Domain * dom) if ((fd = open(path, O_RDONLY, 0)) == -1) return; - if ((fstat(fd, &status) == -1) || + if ((rtld_fstat(fd, &status) == -1) || (status.st_size < sizeof (Msghdr))) { (void) close(fd); return; diff --git a/usr/src/cmd/sgs/rtld/common/object.c b/usr/src/cmd/sgs/rtld/common/object.c index 163ef2de97..8d1cadd25c 100644 --- a/usr/src/cmd/sgs/rtld/common/object.c +++ b/usr/src/cmd/sgs/rtld/common/object.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Object file dependent suport for ELF objects. */ @@ -230,12 +228,12 @@ elf_obj_fini(Lm_list *lml, Rt_map *lmp, int *in_nfavl) * the contents rather than manipulate the link map pointers as parts * of the dlopen code have remembered the original link map address). */ - NEXT((Rt_map *)PREV(nlmp)) = 0; + NEXT(PREV_RT_MAP(nlmp)) = 0; /* LINTED */ lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(nlmp)); - lmc->lc_tail = (Rt_map *)PREV(nlmp); + lmc->lc_tail = PREV_RT_MAP(nlmp); if (CNTL(nlmp) == ALIST_OFF_DATA) - lml->lm_tail = (Rt_map *)PREV(nlmp); + lml->lm_tail = PREV_RT_MAP(nlmp); lml->lm_obj--; PREV(nlmp) = PREV(olmp); diff --git a/usr/src/cmd/sgs/rtld/common/remove.c b/usr/src/cmd/sgs/rtld/common/remove.c index 32d7d22125..b6789e3465 100644 --- a/usr/src/cmd/sgs/rtld/common/remove.c +++ b/usr/src/cmd/sgs/rtld/common/remove.c @@ -49,7 +49,6 @@ * link-map. If a failures occurs after a handle have been created, * remove_hdl() is called to remove the handle and the link-map. */ -#pragma ident "%Z%%M% %I% %E% SMI" #include <string.h> #include <stdio.h> @@ -530,7 +529,7 @@ remove_incomplete(Lm_list *lml, Aliste lmco) /* * First, remove any lists that may point between objects. */ - for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) + for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) remove_lists(lmp, 1); /* diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c index 6f38807046..20e8a8ed49 100644 --- a/usr/src/cmd/sgs/rtld/common/setup.c +++ b/usr/src/cmd/sgs/rtld/common/setup.c @@ -151,7 +151,7 @@ preload(const char *str, Rt_map *lmp) if (bind_one(clmp, nlmp, BND_REFER) == 0) continue; } - clmp = (Rt_map *)NEXT(lmp); + clmp = NEXT_RT_MAP(lmp); } } while ((ptr = strtok_r(NULL, @@ -170,7 +170,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, { Rt_map *rlmp, *mlmp, **tobj = 0; Ehdr *ehdr; - struct stat status; + rtld_stat_t status; int features = 0, ldsoexec = 0; size_t eaddr, esize; char *str, *argvname; @@ -411,7 +411,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, /* * Find out what type of object we have. */ - (void) fstat(fd, &status); + (void) rtld_fstat(fd, &status); if ((ftp = are_u_this(&rej, fd, &status, argvname)) == 0) { Conv_reject_desc_buf_t rej_buf; @@ -799,7 +799,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, * load_so() checking for those who might dlopen(a.out). */ if ((FLAGS1(mlmp) & FL1_RT_RELATIVE) && - (stat(PATHNAME(mlmp), &status) == 0)) { + (rtld_stat(PATHNAME(mlmp), &status) == 0)) { STDEV(mlmp) = status.st_dev; STINO(mlmp) = status.st_ino; } diff --git a/usr/src/cmd/sgs/rtld/common/tls.c b/usr/src/cmd/sgs/rtld/common/tls.c index 85b1f84fd8..78f049116a 100644 --- a/usr/src/cmd/sgs/rtld/common/tls.c +++ b/usr/src/cmd/sgs/rtld/common/tls.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 <stdio.h> #include <strings.h> @@ -306,7 +304,7 @@ tls_statmod(Lm_list *lml, Rt_map *lmp) * Account for the initial dtv ptr in the TLSSIZE calculation. */ tlsmodndx = 0; - for (lmp = lml->lm_head; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = lml->lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) { if ((FCT(lmp) != &elf_fct) || (PTTLS(lmp) == 0) || (PTTLS(lmp)->p_memsz == 0)) continue; diff --git a/usr/src/cmd/sgs/rtld/common/tsort.c b/usr/src/cmd/sgs/rtld/common/tsort.c index 7afa6c78d9..87f87cb69d 100644 --- a/usr/src/cmd/sgs/rtld/common/tsort.c +++ b/usr/src/cmd/sgs/rtld/common/tsort.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Utilities to handle shared object dependency graph. * @@ -472,7 +470,7 @@ rb_visit(Rt_map * lmp, Sort * sort) { Rt_map * nlmp; - if ((nlmp = (Rt_map *)NEXT(lmp)) != 0) + if ((nlmp = NEXT_RT_MAP(lmp)) != 0) rb_visit(nlmp, sort); /* @@ -510,7 +508,7 @@ fb_visit(Rt_map * lmp, Sort * sort, int flag) FLAGS(lmp) |= FLG_RT_FINICLCT; } } - lmp = (Rt_map *)NEXT(lmp); + lmp = NEXT_RT_MAP(lmp); } } #endif @@ -827,9 +825,9 @@ tsort(Rt_map *lmp, int num, int flag) * the next object. */ if ((FLAGS(ilmp) & MSK_RT_INTPOSE) == 0) - ilmp = (Rt_map *)NEXT(ilmp); + ilmp = NEXT_RT_MAP(ilmp); - for (; ilmp; ilmp = (Rt_map *)NEXT(ilmp)) { + for (; ilmp; ilmp = NEXT_RT_MAP(ilmp)) { if ((FLAGS(ilmp) & MSK_RT_INTPOSE) == 0) break; @@ -857,7 +855,7 @@ tsort(Rt_map *lmp, int num, int flag) /* * Inspect any standard objects. */ - for (; _lmp; _lmp = (Rt_map *)NEXT(_lmp)) { + for (; _lmp; _lmp = NEXT_RT_MAP(_lmp)) { if (FLAGS(_lmp) & MSK_RT_INTPOSE) continue; diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index 727a54fb5d..0927232b37 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -1084,7 +1084,7 @@ load_completion(Rt_map *nlmp) (rtld_flags2 & (RT_FL2_PLMSETUP | RT_FL2_NOPLM)))) { Rt_map *lmp; - for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) { if (PTTLS(lmp) && PTTLS(lmp)->p_memsz) tls_modaddrem(lmp, TM_FLG_MODADD); } @@ -1265,8 +1265,8 @@ lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp) * for now only add interposers after the link-map lists head * object. */ - for (tlmp = (Rt_map *)NEXT(lmc->lc_head); tlmp; - tlmp = (Rt_map *)NEXT(tlmp)) { + for (tlmp = NEXT_RT_MAP(lmc->lc_head); tlmp; + tlmp = NEXT_RT_MAP(tlmp)) { if (FLAGS(tlmp) & FLG_RT_OBJINTPO) continue; @@ -1275,7 +1275,7 @@ lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp) * Insert the new link-map before this non-interposer, * and indicate an interposer is found. */ - NEXT((Rt_map *)PREV(tlmp)) = (Link_map *)lmp; + NEXT(PREV_RT_MAP(tlmp)) = (Link_map *)lmp; PREV(lmp) = PREV(tlmp); NEXT(lmp) = (Link_map *)tlmp; @@ -1350,14 +1350,14 @@ lm_delete(Lm_list *lml, Rt_map *lmp) lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(lmp)); if (lmc->lc_head == lmp) - lmc->lc_head = (Rt_map *)NEXT(lmp); + lmc->lc_head = NEXT_RT_MAP(lmp); else - NEXT((Rt_map *)PREV(lmp)) = (void *)NEXT(lmp); + NEXT(PREV_RT_MAP(lmp)) = (void *)NEXT(lmp); if (lmc->lc_tail == lmp) - lmc->lc_tail = (Rt_map *)PREV(lmp); + lmc->lc_tail = PREV_RT_MAP(lmp); else - PREV((Rt_map *)NEXT(lmp)) = PREV(lmp); + PREV(NEXT_RT_MAP(lmp)) = PREV(lmp); /* * For backward compatibility with debuggers, the link-map list contains @@ -1401,7 +1401,7 @@ lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc) * Indicate each new link-map has been moved to the previous link-map * control list. */ - for (lmp = nlmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) + for (lmp = nlmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) CNTL(lmp) = plmco; /* @@ -3337,7 +3337,7 @@ unused(Lm_list *lml) * is always used. */ nl = 0; - for (lmp = (Rt_map *)NEXT(lmp); lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = NEXT_RT_MAP(lmp); lmp; lmp = NEXT_RT_MAP(lmp)) { /* * Determine if this object contains any runpaths that have * not been used. @@ -3711,10 +3711,10 @@ security(uid_t uid, uid_t euid, gid_t gid, gid_t egid, int auxflags) int is_rtld_setuid() { - struct stat status; + rtld_stat_t status; if ((rtld_flags2 & RT_FL2_SETUID) || - ((stat(NAME(lml_rtld.lm_head), &status) == 0) && + ((rtld_stat(NAME(lml_rtld.lm_head), &status) == 0) && (status.st_uid == 0) && (status.st_mode & S_ISUID))) { rtld_flags2 |= RT_FL2_SETUID; return (1); @@ -3758,3 +3758,69 @@ demangle(const char *name) else return (name); } + + +#ifndef _LP64 +/* + * Wrappers on stat() and fstat() for 32-bit rtld that uses stat64() + * underneath while preserving the object size limits of a non-largefile + * enabled 32-bit process. The purpose of this is to prevent large inode + * values from causing stat() to fail. + */ +inline static int +rtld_stat_process(int r, struct stat64 *lbuf, rtld_stat_t *restrict buf) +{ + extern int errno; + + /* + * Although we used a 64-bit capable stat(), the 32-bit rtld + * can only handle objects < 2GB in size. If this object is + * too big, turn the success into an overflow error. + */ + if ((lbuf->st_size & 0xffffffff80000000) != 0) { + errno = EOVERFLOW; + return (-1); + } + + /* + * Transfer the information needed by rtld into a rtld_stat_t + * structure that preserves the non-largile types for everything + * except inode. + */ + buf->st_dev = lbuf->st_dev; + buf->st_ino = lbuf->st_ino; + buf->st_mode = lbuf->st_mode; + buf->st_uid = lbuf->st_uid; + buf->st_size = (off_t)lbuf->st_size; + buf->st_mtim = lbuf->st_mtim; +#ifdef sparc + buf->st_blksize = lbuf->st_blksize; +#endif + + return (r); +} + +int +rtld_stat(const char *restrict path, rtld_stat_t *restrict buf) +{ + struct stat64 lbuf; + int r; + + r = stat64(path, &lbuf); + if (r != -1) + r = rtld_stat_process(r, &lbuf, buf); + return (r); +} + +int +rtld_fstat(int fildes, rtld_stat_t *restrict buf) +{ + struct stat64 lbuf; + int r; + + r = fstat64(fildes, &lbuf); + if (r != -1) + r = rtld_stat_process(r, &lbuf, buf); + return (r); +} +#endif diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c index 0a6b0ef173..216dcd0035 100644 --- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c +++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c @@ -29,8 +29,6 @@ * All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * SPARC machine dependent and a.out format file class dependent functions. * Contains routines for performing function binding and symbol relocations. @@ -86,7 +84,7 @@ aout_bndr(caddr_t pc) */ entry = enter(0); - for (lmp = lml_main.lm_head; lmp; lmp = (Rt_map *)NEXT(lmp)) { + for (lmp = lml_main.lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) { if (FCT(lmp) == &aout_fct) { if (pc > (caddr_t)(LM2LP(lmp)->lp_plt) && pc < (caddr_t)((int)LM2LP(lmp)->lp_plt + |
