summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf
diff options
context:
space:
mode:
authorjdp <jdp@FreeBSD.org>1999-07-18 00:02:19 +0000
committerjdp <jdp@FreeBSD.org>1999-07-18 00:02:19 +0000
commitd0a94902b29c71b75c5fcfc5b196fb7f162e7f31 (patch)
treedf2a69050355d66f9b3d0ec560bc9c0170f6293a /libexec/rtld-elf
parent9eace4ac40f13ffdcd8b06aca5e9a24b8e3ed044 (diff)
downloadFreeBSD-src-d0a94902b29c71b75c5fcfc5b196fb7f162e7f31.zip
FreeBSD-src-d0a94902b29c71b75c5fcfc5b196fb7f162e7f31.tar.gz
Change many asserts into normal errors. They were all for conditions
caused by invalid shared objects rather than by internal errors. Enable format string mismatch checking for _rtld_error().
Diffstat (limited to 'libexec/rtld-elf')
-rw-r--r--libexec/rtld-elf/map_object.c62
-rw-r--r--libexec/rtld-elf/rtld.c36
-rw-r--r--libexec/rtld-elf/rtld.h6
3 files changed, 65 insertions, 39 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c
index a393bb8..523a80b 100644
--- a/libexec/rtld-elf/map_object.c
+++ b/libexec/rtld-elf/map_object.c
@@ -22,13 +22,12 @@
* (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: map_object.c,v 1.1.1.1 1998/03/07 19:24:35 jdp Exp $
+ * $Id: map_object.c,v 1.2 1998/09/04 19:03:57 dfr Exp $
*/
#include <sys/param.h>
#include <sys/mman.h>
-#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
@@ -39,14 +38,15 @@
static int protflags(int); /* Elf flags -> mmap protection */
/*
- * Map a shared object into memory. The argument is a file descriptor,
+ * Map a shared object into memory. The "fd" argument is a file descriptor,
* which must be open on the object and positioned at its beginning.
+ * The "path" argument is a pathname that is used only for error messages.
*
* The return value is a pointer to a newly-allocated Obj_Entry structure
* for the shared object. Returns NULL on failure.
*/
Obj_Entry *
-map_object(int fd)
+map_object(int fd, const char *path)
{
Obj_Entry *obj;
union {
@@ -78,7 +78,7 @@ map_object(int fd)
caddr_t bss_addr;
if ((nbytes = read(fd, u.buf, PAGE_SIZE)) == -1) {
- _rtld_error("Read error: %s", strerror(errno));
+ _rtld_error("%s: read error: %s", path, strerror(errno));
return NULL;
}
@@ -88,25 +88,25 @@ map_object(int fd)
|| u.hdr.e_ident[EI_MAG1] != ELFMAG1
|| u.hdr.e_ident[EI_MAG2] != ELFMAG2
|| u.hdr.e_ident[EI_MAG3] != ELFMAG3) {
- _rtld_error("Invalid file format");
+ _rtld_error("%s: invalid file format", path);
return NULL;
}
if (u.hdr.e_ident[EI_CLASS] != ELF_TARG_CLASS
|| u.hdr.e_ident[EI_DATA] != ELF_TARG_DATA) {
- _rtld_error("Unsupported file layout");
+ _rtld_error("%s: unsupported file layout", path);
return NULL;
}
if (u.hdr.e_ident[EI_VERSION] != EV_CURRENT
|| u.hdr.e_version != EV_CURRENT) {
- _rtld_error("Unsupported file version");
+ _rtld_error("%s: unsupported file version", path);
return NULL;
}
if (u.hdr.e_type != ET_EXEC && u.hdr.e_type != ET_DYN) {
- _rtld_error("Unsupported file type");
+ _rtld_error("%s: unsupported file type", path);
return NULL;
}
if (u.hdr.e_machine != ELF_TARG_MACH) {
- _rtld_error("Unsupported machine");
+ _rtld_error("%s: unsupported machine", path);
return NULL;
}
@@ -115,9 +115,15 @@ map_object(int fd)
* not strictly required by the ABI specification, but it seems to
* always true in practice. And, it simplifies things considerably.
*/
- assert(u.hdr.e_phentsize == sizeof(Elf_Phdr));
- assert(u.hdr.e_phoff + u.hdr.e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE);
- assert(u.hdr.e_phoff + u.hdr.e_phnum*sizeof(Elf_Phdr) <= nbytes);
+ if (u.hdr.e_phentsize != sizeof(Elf_Phdr)) {
+ _rtld_error(
+ "%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
+ return NULL;
+ }
+ if (u.hdr.e_phoff + u.hdr.e_phnum*sizeof(Elf_Phdr) > nbytes) {
+ _rtld_error("%s: program header too large", path);
+ return NULL;
+ }
/*
* Scan the program header entries, and save key information.
@@ -134,7 +140,10 @@ map_object(int fd)
switch (phdr->p_type) {
case PT_LOAD:
- assert(nsegs < 2);
+ if (nsegs >= 2) {
+ _rtld_error("%s: too many PT_LOAD segments", path);
+ return NULL;
+ }
segs[nsegs] = phdr;
++nsegs;
break;
@@ -151,13 +160,18 @@ map_object(int fd)
++phdr;
}
if (phdyn == NULL) {
- _rtld_error("Object is not dynamically-linked");
+ _rtld_error("%s: object is not dynamically-linked", path);
return NULL;
}
- assert(nsegs == 2);
- assert(segs[0]->p_align >= PAGE_SIZE);
- assert(segs[1]->p_align >= PAGE_SIZE);
+ if (nsegs < 2) {
+ _rtld_error("%s: too few PT_LOAD segments", path);
+ return NULL;
+ }
+ if (segs[0]->p_align < PAGE_SIZE || segs[1]->p_align < PAGE_SIZE) {
+ _rtld_error("%s: PT_LOAD segments not page-aligned", path);
+ return NULL;
+ }
/*
* Map the entire address space of the object, to stake out our
@@ -172,13 +186,13 @@ map_object(int fd)
mapbase = mmap(base_addr, mapsize, protflags(segs[0]->p_flags),
MAP_PRIVATE, fd, base_offset);
if (mapbase == (caddr_t) -1) {
- _rtld_error("mmap of entire address space failed: %s",
- strerror(errno));
+ _rtld_error("%s: mmap of entire address space failed: %s",
+ path, strerror(errno));
return NULL;
}
if (base_addr != NULL && mapbase != base_addr) {
- _rtld_error("mmap returned wrong address: wanted %p, got %p",
- base_addr, mapbase);
+ _rtld_error("%s: mmap returned wrong address: wanted %p, got %p",
+ path, base_addr, mapbase);
munmap(mapbase, mapsize);
return NULL;
}
@@ -190,7 +204,7 @@ map_object(int fd)
data_addr = mapbase + (data_vaddr - base_vaddr);
if (mmap(data_addr, data_vlimit - data_vaddr, protflags(segs[1]->p_flags),
MAP_PRIVATE|MAP_FIXED, fd, data_offset) == (caddr_t) -1) {
- _rtld_error("mmap of data failed: %s", strerror(errno));
+ _rtld_error("%s: mmap of data failed: %s", path, strerror(errno));
return NULL;
}
@@ -207,7 +221,7 @@ map_object(int fd)
if (bss_vlimit > bss_vaddr) { /* There is something to do */
if (mmap(bss_addr, bss_vlimit - bss_vaddr, protflags(segs[1]->p_flags),
MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) == (caddr_t) -1) {
- _rtld_error("mmap of bss failed: %s", strerror(errno));
+ _rtld_error("%s: mmap of bss failed: %s", path, strerror(errno));
return NULL;
}
}
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)
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 1380e74..95a057a 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -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.h,v 1.5 1998/09/04 19:03:57 dfr Exp $
+ * $Id: rtld.h,v 1.6 1999/04/09 00:28:31 jdp Exp $
*/
#ifndef RTLD_H /* { */
@@ -123,8 +123,8 @@ typedef struct Struct_Obj_Entry {
#define RTLD_MAGIC 0xd550b87a
#define RTLD_VERSION 1
-extern void _rtld_error(const char *, ...);
-extern Obj_Entry *map_object(int);
+extern void _rtld_error(const char *, ...) __printflike(1, 2);
+extern Obj_Entry *map_object(int, const char *);
extern void *xcalloc(size_t);
extern void *xmalloc(size_t);
extern char *xstrdup(const char *);
OpenPOWER on IntegriCloud