From: tobias Date: Wed, 14 Oct 2015 17:29:44 +0000 (+0000) Subject: Check mmap and read return values. While at it, remove unused duplicated file. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=87f51a35404731700bba6f9a1c8a8e6c2e1294d5;p=openbsd Check mmap and read return values. While at it, remove unused duplicated file. ok millert@ --- diff --git a/libexec/ld.so/dl_prebind.c b/libexec/ld.so/dl_prebind.c index 6d38b52a549..5f3ccf1b9d5 100644 --- a/libexec/ld.so/dl_prebind.c +++ b/libexec/ld.so/dl_prebind.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dl_prebind.c,v 1.17 2015/01/16 16:18:07 deraadt Exp $ */ +/* $OpenBSD: dl_prebind.c,v 1.18 2015/10/14 17:29:44 tobias Exp $ */ /* * Copyright (c) 2006 Dale Rahn * @@ -131,6 +131,12 @@ prebind_load_fd(int fd, const char *name) prebind_data = _dl_mmap(0, footer.prebind_size, PROT_READ, MAP_FILE, fd, footer.prebind_base); + if (_dl_mmap_error(prebind_data)) { + _dl_prebind_match_failed = 1; + DL_DEB(("prebind match failed %s\n", name)); + return (NULL); + } + DL_DEB(("prebind_load_fd for lib %s\n", name)); nameidx = (void *)(_dl_prog_prebind_map + prog_footer->nameidx_idx); diff --git a/libexec/ld.so/ldconfig/dl_prebind.c b/libexec/ld.so/ldconfig/dl_prebind.c deleted file mode 100644 index 151b44062dd..00000000000 --- a/libexec/ld.so/ldconfig/dl_prebind.c +++ /dev/null @@ -1,618 +0,0 @@ -/* $OpenBSD: dl_prebind.c,v 1.3 2015/01/16 16:18:07 deraadt Exp $ */ - -/* - * Copyright (c) 2006 Dale Rahn - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "syscall.h" -#include "archdep.h" -#include "resolve.h" -#include "sod.h" -#include "stdlib.h" -#include "dl_prebind.h" - -void elf_dump_footer(struct prebind_footer *footer); -void dump_prelink(Elf_Addr base, u_long size); -void prebind_dump_footer(struct prebind_footer *footer, char *file); -void prebind_dump_symcache(struct symcachetab *symcachetab, u_int32_t cnt); -void prebind_dump_nameidx(struct nameidx *nameidx, u_int32_t numblibs, - char *nametab); -void prebind_dump_fixup(struct fixup *fixup, u_int32_t numfixups); -void prebind_dump_libmap(u_int32_t *libmap, u_int32_t numlibs); -struct prebind_footer *_dl_prebind_data_to_footer(void *data); - -void *_dl_prog_prebind_map; -struct prebind_footer *prog_footer; -extern char *_dl_noprebind; -extern char *_dl_prebind_validate; - -int _dl_prebind_match_failed; /* = 0 */ - -char *prebind_bind_now = "prebind"; - -struct prebind_footer * -_dl_prebind_data_to_footer(void *prebind_data) -{ - u_int32_t *poffset, offset; - struct prebind_footer *footer; - char *c; - - poffset = prebind_data; - c = prebind_data; - offset = *poffset; - c += offset; - footer = (void *)c; - return footer; -} - -void -prebind_load_exe(Elf_Phdr *phdp, elf_object_t *exe_obj) -{ - struct prebind_footer *footer; - - exe_obj->prebind_data = (void *)phdp->p_vaddr; - _dl_prog_prebind_map = exe_obj->prebind_data; - - footer = _dl_prebind_data_to_footer(_dl_objects->prebind_data); - - if (footer->bind_id[0] == BIND_ID0 && - footer->bind_id[1] == BIND_ID1 && - footer->bind_id[2] == BIND_ID2 && - footer->bind_id[3] == BIND_ID3 && - footer->prebind_version == PREBIND_VERSION) { - prog_footer = footer; - if (_dl_bindnow == NULL) - _dl_bindnow = prebind_bind_now; - } else { - DL_DEB(("prebind data missing\n")); - _dl_prog_prebind_map = NULL; - } - if (_dl_noprebind != NULL) { - /*prog_footer is valid, we should free it */ - _dl_prog_prebind_map = NULL; - prog_footer = NULL; - exe_obj->prebind_data = NULL; - if (_dl_bindnow == prebind_bind_now) - _dl_bindnow = NULL; - } -#if 0 - else if (_dl_debug) - dump_prelink((long)_dl_prog_prebind_map, - prog_footer->prebind_size); -#endif -} - -void * -prebind_load_fd(int fd, const char *name) -{ - struct prebind_footer footer; - struct nameidx *nameidx; - void *prebind_data; - char *nametab; - ssize_t len; - int idx; - - if (_dl_prog_prebind_map == NULL || _dl_prebind_match_failed) - return 0; - - _dl_lseek(fd, -(off_t)sizeof(struct prebind_footer), SEEK_END); - len = _dl_read(fd, (void *)&footer, sizeof(struct prebind_footer)); - - if (len != sizeof(struct prebind_footer) || - footer.bind_id[0] != BIND_ID0 || - footer.bind_id[1] != BIND_ID1 || - footer.bind_id[2] != BIND_ID2 || - footer.bind_id[3] != BIND_ID3 || - footer.prebind_version != PREBIND_VERSION) { - _dl_prebind_match_failed = 1; - DL_DEB(("prebind match failed %s\n", name)); - return (NULL); - } - - prebind_data = _dl_mmap(0, footer.prebind_size, PROT_READ, - MAP_FILE, fd, footer.prebind_base); - DL_DEB(("prebind_load_fd for lib %s\n", name)); - - nameidx = _dl_prog_prebind_map + prog_footer->nameidx_idx; - nametab = _dl_prog_prebind_map + prog_footer->nametab_idx; - - /* libraries are loaded in random order, so we just have - * to look thru the list to find ourselves - */ - for (idx = 0; idx < prog_footer->numlibs; idx++) { - if (_dl_strcmp(nametab + nameidx[idx].name, name) == 0) - break; - } - - if (idx == prog_footer->numlibs) { - _dl_prebind_match_failed = 1; /* not found */ - } else if (footer.id0 != nameidx[idx].id0 || - footer.id1 != nameidx[idx].id1) { - _dl_prebind_match_failed = 1; - DL_DEB(("prebind match id0 %d pid0 %d id1 %d pid1 %d\n", - footer.id0, nameidx[idx].id0, - footer.id1, nameidx[idx].id1)); - } - - if (_dl_prebind_match_failed == 1) { - DL_DEB(("prebind match failed for %s\n", name)); - } - - return prebind_data; -} -#define NUM_STATIC_OBJS 10 -elf_object_t *objarray_static[NUM_STATIC_OBJS]; -elf_object_t **objarray; - -void -prebind_symcache(elf_object_t *object, int plt) -{ - u_int32_t *fixupidx, *fixupcnt, *libmap, *idxtolib; - u_int32_t *poffset, offset, symcache_cnt; - struct symcachetab *symcachetab; - struct prebind_footer *footer; - int i = 0, cur_obj = -1, idx; - void *prebind_map; - struct nameidx *nameidx; - char *nametab, *c; - struct fixup *fixup; - elf_object_t *obj; - - struct symcachetab *s; - - if (object->prebind_data == NULL) - return; -// DL_DEB(("prebind symcache %s\n", object->load_name)); - - obj = _dl_objects; - while (obj != NULL) { - if (obj == object) - cur_obj = i; - i++; - obj = obj->next; - } - - if (cur_obj == -1) - return; /* unable to find object ? */ - - if (objarray == NULL) { - if (i <= NUM_STATIC_OBJS) { - objarray = &objarray_static[0]; - } else { - objarray = _dl_malloc(sizeof(elf_object_t *) * i); - } - - obj = _dl_objects; - i = 0; - while (obj != NULL) { - objarray[i] = obj; - i++; - obj = obj->next; - } - } - - poffset = (u_int32_t *)object->prebind_data; - c = object->prebind_data; - offset = *poffset; - c += offset; - - footer = (void *)c; - prebind_map = (void *)object->prebind_data; - nameidx = prebind_map + footer->nameidx_idx;; - if (plt) { - symcachetab = prebind_map + footer->pltsymcache_idx; - symcache_cnt = footer->pltsymcache_cnt; -// DL_DEB(("loading plt %d\n", symcache_cnt)); - } else { - symcachetab = prebind_map + footer->symcache_idx; - symcache_cnt = footer->symcache_cnt; -// DL_DEB(("loading got %d\n", symcache_cnt)); - } - nametab = prebind_map + footer->nametab_idx; - - libmap = _dl_prog_prebind_map + prog_footer->libmap_idx; - idxtolib = _dl_prog_prebind_map + libmap[cur_obj]; - - for (i = 0; i < symcache_cnt; i++) { - struct elf_object *tobj; - const Elf_Sym *sym; - const char *str; - - s = &(symcachetab[i]); - if (cur_obj == 0) - idx = s->obj_idx; - else - idx = idxtolib[s->obj_idx]; - - if (idx == -1) /* somehow an invalid object ref happend */ - continue; -#if 0 - DL_DEB(("%s:", object->load_name)); - DL_DEB(("symidx %d: obj %d %d sym %d flags %x\n", - s->idx, s->obj_idx, idx, s->sym_idx, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt)); -#endif - tobj = objarray[idx]; - sym = tobj->dyn.symtab + s->sym_idx; - str = tobj->dyn.strtab + sym->st_name; -#ifdef DEBUG2 - DL_DEB(("symidx %d: obj %d %s sym %d %s flags %d %x\n", - s->idx, s->obj_idx, tobj->load_name, - s->sym_idx, str, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt, - object->obj_base + sym->st_value)); -#endif - _dl_symcache[s->idx].obj = tobj; - _dl_symcache[s->idx].sym = sym; - _dl_symcache[s->idx].flags = - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt; - } - - if (!plt) { - fixupidx = _dl_prog_prebind_map + prog_footer->fixup_idx; - fixup = _dl_prog_prebind_map + fixupidx[2*cur_obj]; - fixupcnt = _dl_prog_prebind_map + prog_footer->fixupcnt_idx; - - for (i = 0; i < fixupcnt[2*cur_obj]; i++) { - struct fixup *f; - struct elf_object *tobj; - const Elf_Sym *sym; - const char *str; - - f = &(fixup[i]); -#if 0 - DL_DEB(("symidx %d: obj %d sym %d flags %x\n", - f->sym, f->obj_idx, f->sym_idx, f->flags)); -#endif - tobj = objarray[f->obj_idx]; - sym = tobj->dyn.symtab + f->sym_idx; - str = tobj->dyn.strtab + sym->st_name; -#ifdef DEBUG2 - DL_DEB(("symidx %d: obj %d %s sym %d %s flags %d %x\n", - f->sym, f->obj_idx, tobj->load_name, - f->sym_idx, str, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt, - object->obj_base + sym->st_value)); -#endif - _dl_symcache[f->sym].obj = tobj; - _dl_symcache[f->sym].sym = sym; - _dl_symcache[f->sym].flags = - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt; - } - } else { - - fixupidx = _dl_prog_prebind_map + prog_footer->fixup_idx; - fixup = _dl_prog_prebind_map + fixupidx[2*cur_obj+1]; - fixupcnt = _dl_prog_prebind_map + prog_footer->fixupcnt_idx; - -#if 0 - DL_DEB(("prebind loading symbols fixup plt %s\n", - object->load_name)); -#endif - for (i = 0; i < fixupcnt[2*cur_obj+1]; i++) { - struct fixup *f; - struct elf_object *tobj; - const Elf_Sym *sym; - const char *str; - - f = &(fixup[i]); -#if 0 - DL_DEB(("symidx %d: obj %d sym %d flags %x\n", - f->sym, f->obj_idx, f->sym_idx, - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt)); -#endif - tobj = objarray[f->obj_idx]; - sym = tobj->dyn.symtab + f->sym_idx; - str = tobj->dyn.strtab + sym->st_name; -#ifdef DEBUG2 - DL_DEB(("symidx %d: obj %d %s sym %d %s flags %d %x\n", - f->sym, f->obj_idx, tobj->load_name, - f->sym_idx, str, SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt, - object->obj_base + sym->st_value)); -#endif - _dl_symcache[f->sym].obj = tobj; - _dl_symcache[f->sym].sym = sym; - _dl_symcache[f->sym].flags = - SYM_SEARCH_ALL|SYM_WARNNOTFOUND|plt; - } - } -// DL_DEB(("prebind_data loaded\n")); -} - -void -prebind_free(elf_object_t *object) -{ - struct prebind_footer *footer; - - if (object->prebind_data == NULL) - return; -#ifdef DEBUG1 - DL_DEB(("prebind_free for %s %p\n", object->load_name, - object->prebind_data)); -#endif - if (object->prebind_data != 0) { - footer = _dl_prebind_data_to_footer(object->prebind_data); - -#ifdef DEBUG1 - DL_DEB(("freeing prebind data sz %x\n", footer->prebind_size)); -#endif - - _dl_munmap((void *)ELF_TRUNC((long)object->prebind_data, _dl_pagesz), - ELF_ROUND((long)object->prebind_data+footer->prebind_size, - _dl_pagesz) - ELF_TRUNC((long)object->prebind_data, _dl_pagesz)); - - object->prebind_data = NULL; - _dl_prog_prebind_map = NULL; - - if (_dl_bindnow == prebind_bind_now) - _dl_bindnow = NULL; - } -} - -int validate_errs; - -struct timeval beforetp; - -void -_dl_prebind_pre_resolve() -{ - struct prebind_footer *footer; - elf_object_t *object; - struct nameidx *nameidx; - char *nametab, *name; - int idx; - - if (_dl_prog_prebind_map != NULL) { - nameidx = _dl_prog_prebind_map + prog_footer->nameidx_idx; - nametab = _dl_prog_prebind_map + prog_footer->nametab_idx; - for (idx = 1, object = _dl_objects->next; object != NULL; - object = object->next, idx++) { - if (object->prebind_data == NULL) { - /* ld.so doesn't have prebind data */ - if (object->next == NULL) - continue; - DL_DEB(("missing prebind data %s\n", - object->load_name)); - _dl_prebind_match_failed = 1; - break; - } - footer = _dl_prebind_data_to_footer( - object->prebind_data); - if (footer == NULL || - nameidx[idx].id0 != footer->id0 || - nameidx[idx].id1 != footer->id1) { - DL_DEB(("invalid prebind data %s\n", - object->load_name)); - _dl_prebind_match_failed = 1; - break; - } - name = object->load_name; - if (_dl_strcmp(nametab + nameidx[idx].name, name) - != 0) { - DL_DEB(("invalid prebind name %s\n", - object->load_name)); - _dl_prebind_match_failed = 1; - break; - } - } - } - - if (_dl_prebind_match_failed) { - for (object = _dl_objects; object != NULL; - object = object->next) - prebind_free(object); - if (_dl_bindnow == prebind_bind_now) - _dl_bindnow = NULL; - } - - if (_dl_debug) - _dl_gettimeofday(&beforetp, NULL); -} - -void -_dl_prebind_post_resolve() -{ - char buf[7]; - int i; - struct timeval after_tp; - struct timeval diff_tp; - elf_object_t *object; - - if (_dl_debug) { - _dl_gettimeofday(&after_tp, NULL); - - timersub(&after_tp, &beforetp, &diff_tp); - - for (i = 0; i < 6; i++) { - buf[5-i] = (diff_tp.tv_usec % 10) + '0'; - diff_tp.tv_usec /= 10; - } - buf[6] = '\0'; - - _dl_printf("relocation took %d.%s\n", diff_tp.tv_sec, buf); - } - - for (object = _dl_objects; object != NULL; object = object->next) - prebind_free(object); - - if (_dl_prebind_validate) { - if (validate_errs) { - _dl_printf("validate_errs %d\n", validate_errs); - _dl_exit(20); - } else { - _dl_exit(0); - } - } -} - -void -prebind_validate(elf_object_t *req_obj, unsigned int symidx, int flags, - const Elf_Sym *ref_sym) -{ - const Elf_Sym *sym, **this; - const elf_object_t *sobj; - const char *symn; - Elf_Addr ret; - - /* Don't verify non-matching flags*/ - - sym = req_obj->dyn.symtab; - sym += symidx; - symn = req_obj->dyn.strtab + sym->st_name; - this = &sym; - - //_dl_printf("checking %s\n", symn); - ret = _dl_find_symbol(symn, this, flags, ref_sym, req_obj, &sobj); - - if (_dl_symcache[symidx].sym != *this || - _dl_symcache[symidx].obj != sobj) { - _dl_printf("symbol %d mismatch on sym %s req_obj %s,\n" - "should be obj %s is obj %s\n", - symidx, symn, req_obj->load_name, sobj->load_name, - _dl_symcache[symidx].obj->load_name); - if (req_obj == sobj) - _dl_printf("obj %p %p\n", _dl_symcache[symidx].obj, sobj); - sym = _dl_symcache[symidx].obj->dyn.symtab; - sym += symidx; - symn = _dl_symcache[symidx].obj->dyn.strtab + sym->st_name; - _dl_printf("obj %s name %s\n", - _dl_symcache[symidx].obj->load_name, - symn); - } -} - -#ifdef DEBUG1 -void -prebind_dump_symcache(struct symcachetab *symcachetab, u_int32_t cnt) -{ - struct symcachetab *s; - int i; - - _dl_printf("cache: cnt %d\n", cnt); - for (i = 0; i < cnt; i++) { - s = &(symcachetab[i]); - _dl_printf("symidx %d: obj %d sym %d\n", - s->idx, s->obj_idx, s->sym_idx); - } -} - -void -prebind_dump_nameidx(struct nameidx *nameidx, u_int32_t numlibs, char *nametab) -{ - struct nameidx *n; - int i; - - _dl_printf("libs:\n"); - for (i = 0; i < numlibs; i++) { - _dl_printf("lib %d offset %d id0 %d, id1 %d\n", i, - nameidx[i].name, nameidx[i].id0, nameidx[i].id1); - } - for (i = 0; i < numlibs; i++) { - n = &(nameidx[i]); - _dl_printf("nametab %p n %d\n", nametab, n->name); - _dl_printf("lib %s %x %x\n", nametab + n->name, n->id0, n->id1); - } -} - -void -prebind_dump_fixup(struct fixup *fixup, u_int32_t numfixups) -{ - struct fixup *f; - int i; - - _dl_printf("fixup: %d\n", numfixups); - for (i = 0; i < numfixups; i++) { - f = &(fixup[i]); - - _dl_printf("idx %d obj %d sym idx %d\n", - f->sym, f->obj_idx, f->sym_idx); - - } -} - -void -prebind_dump_libmap(u_int32_t *libmap, u_int32_t numlibs) -{ - int i; - - for (i = 0; i < numlibs; i++) { - //_dl_printf("lib%d off %d %s\n", i, libmap[i], strtab+libmap[i]); - _dl_printf("lib%d off %d\n", i, libmap[i]); - } -} - -void -dl_dump_footer(struct prebind_footer *footer) -{ -// _dl_printf("base %qd\n", (long long)footer->prebind_base); - _dl_printf("nameidx_idx %d\n", footer->nameidx_idx); - _dl_printf("symcache_idx %d\n", footer->symcache_idx); - _dl_printf("fixupcnt_idx %d\n", footer->fixupcnt_idx); - _dl_printf("fixup_cnt %d\n", footer->fixup_cnt); - _dl_printf("nametab_idx %d\n", footer->nametab_idx); - _dl_printf("symcache_cnt %d\n", footer->symcache_cnt); - _dl_printf("fixup_cnt %d\n", footer->fixup_cnt); - _dl_printf("numlibs %d\n", footer->numlibs); - _dl_printf("id0 %d\n", footer->id0); - _dl_printf("id1 %d\n", footer->id1); -// _dl_printf("orig_size %lld\n", (long long)footer->orig_size); - _dl_printf("version %d\n", footer->prebind_version); - _dl_printf("bind_id %c%c%c%c\n", footer->bind_id[0], - footer->bind_id[1], footer->bind_id[2], footer->bind_id[3]); -} -void -dump_prelink(Elf_Addr base, u_long size) -{ - u_int32_t *fixupidx, *fixupcnt, *libmap; - struct symcachetab *symcachetab; - struct prebind_footer *footer; - struct nameidx *nameidx; - struct fixup *fixup; - char *nametab, *id; - void *prebind_map; - int i; - - id = (char *) (base+size); - id -= 4; - DL_DEB(("id %c %c %c %c\n", id[0], id[1], id[2], id[3])); - footer = (void *) (base+size - sizeof (struct prebind_footer)); - dl_dump_footer(footer); - - prebind_map = (void *)base; - nameidx = prebind_map + footer->nameidx_idx;; - symcachetab = prebind_map + footer->symcache_idx; - fixupidx = prebind_map + footer->fixup_idx; - nametab = prebind_map + footer->nametab_idx; - fixupcnt = prebind_map + footer->fixupcnt_idx; - libmap = prebind_map + footer->libmap_idx; - - prebind_dump_symcache(symcachetab, footer->symcache_cnt); - prebind_dump_nameidx(nameidx, footer->numlibs, nametab); - for (i = 0; i < footer->fixup_cnt; i++) { - _dl_printf("fixup %d cnt %d idx %d\n", i, fixupcnt[i], fixupidx[i]); - fixup = prebind_map + fixupidx[i]; - prebind_dump_fixup(fixup, fixupcnt[i]); - } - prebind_dump_libmap(libmap, footer->numlibs); -} -#endif /* DEBUG1 */ diff --git a/libexec/ld.so/ldconfig/prebind.c b/libexec/ld.so/ldconfig/prebind.c index f3cdc06d665..d38398ab0b1 100644 --- a/libexec/ld.so/ldconfig/prebind.c +++ b/libexec/ld.so/ldconfig/prebind.c @@ -1,4 +1,4 @@ -/* $OpenBSD: prebind.c,v 1.30 2015/09/06 08:44:07 tobias Exp $ */ +/* $OpenBSD: prebind.c,v 1.31 2015/10/14 17:29:44 tobias Exp $ */ /* * Copyright (c) 2006 Dale Rahn * @@ -2220,9 +2220,12 @@ elf_load_existing_prebind(struct elf_object *object, int fd) { struct prebind_footer footer; void *prebind_data; + ssize_t len; lseek(fd, -((off_t)sizeof(struct prebind_footer)), SEEK_END); - read(fd, &footer, sizeof(struct prebind_footer)); + len = read(fd, &footer, sizeof(struct prebind_footer)); + if (len != sizeof(struct prebind_footer)) + return; if (footer.bind_id[0] != BIND_ID0 || footer.bind_id[1] != BIND_ID1 || @@ -2232,6 +2235,8 @@ elf_load_existing_prebind(struct elf_object *object, int fd) prebind_data = mmap(0, footer.prebind_size, PROT_READ, MAP_FILE, fd, footer.prebind_base); + if (prebind_data == MAP_FAILED) + return; objarray[object->dyn.null].oprebind_data = prebind_data; objarray[object->dyn.null].id0 = footer.id0; objarray[object->dyn.null].id1 = footer.id1;