summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 313e8ef..796742a 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: rtld.c,v 1.27 1999/07/09 16:22:55 jdp Exp $
+ * $Id: rtld.c,v 1.28 1999/07/14 04:09:11 jdp Exp $
*/
/*
@@ -73,7 +73,7 @@ static void call_fini_functions(Obj_Entry *);
static void call_init_functions(Obj_Entry *);
static void die(void);
static void digest_dynamic(Obj_Entry *);
-static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t);
+static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
static Obj_Entry *dlcheck(void *);
static char *find_library(const char *, const Obj_Entry *);
static const char *gethints(void);
@@ -170,6 +170,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
char **env;
Elf_Auxinfo *aux;
Elf_Auxinfo *auxp;
+ const char *argv0;
/*
* On entry, the dynamic linker itself has not been relocated yet.
@@ -200,6 +201,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
__progname = obj_rtld.path;
+ argv0 = argv[0] != NULL ? argv[0] : "(null)";
environ = env;
trust = geteuid() == getuid() && getegid() == getgid();
@@ -226,7 +228,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */
int fd = aux_info[AT_EXECFD]->a_un.a_val;
dbg("loading main program");
- obj_main = map_object(fd);
+ obj_main = map_object(fd, argv0);
close(fd);
if (obj_main == NULL)
die();
@@ -244,10 +246,11 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr));
assert(aux_info[AT_ENTRY] != NULL);
entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr;
- obj_main = digest_phdr(phdr, phnum, entry);
+ if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL)
+ die();
}
- obj_main->path = xstrdup(argv[0] ? argv[0] : "(null)");
+ obj_main->path = xstrdup(argv0);
obj_main->mainprog = true;
digest_dynamic(obj_main);
@@ -543,7 +546,7 @@ digest_dynamic(Obj_Entry *obj)
* returns an Obj_Entry structure.
*/
static Obj_Entry *
-digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
+digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
{
Obj_Entry *obj = CNEW(Obj_Entry);
const Elf_Phdr *phlimit = phdr + phnum;
@@ -554,13 +557,19 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
switch (ph->p_type) {
case PT_PHDR:
- assert((const Elf_Phdr *) ph->p_vaddr == phdr);
+ if ((const Elf_Phdr *)ph->p_vaddr != phdr) {
+ _rtld_error("%s: invalid PT_PHDR", path);
+ return NULL;
+ }
obj->phdr = (const Elf_Phdr *) ph->p_vaddr;
obj->phsize = ph->p_memsz;
break;
case PT_LOAD:
- assert(nsegs < 2);
+ if (nsegs >= 2) {
+ _rtld_error("%s: too many PT_LOAD segments", path);
+ return NULL;
+ }
if (nsegs == 0) { /* First load segment */
obj->vaddrbase = trunc_page(ph->p_vaddr);
obj->mapbase = (caddr_t) obj->vaddrbase;
@@ -579,7 +588,10 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
break;
}
}
- assert(nsegs == 2);
+ if (nsegs < 2) {
+ _rtld_error("%s: too few PT_LOAD segments", path);
+ return NULL;
+ }
obj->entry = entry;
return obj;
@@ -944,7 +956,7 @@ load_object(char *path)
return NULL;
}
dbg("loading \"%s\"", path);
- obj = map_object(fd);
+ obj = map_object(fd, path);
close(fd);
if (obj == NULL) {
free(path);
@@ -1366,9 +1378,9 @@ symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
const Elf_Sym *symp;
const char *strp;
- assert(symnum < obj->nchains);
+ if (symnum >= obj->nchains)
+ return NULL; /* Bad object */
symp = obj->symtab + symnum;
- assert(symp->st_name != 0);
strp = obj->strtab + symp->st_name;
if (strcmp(name, strp) == 0)
OpenPOWER on IntegriCloud