diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2002-08-11 16:51:05 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2002-08-11 16:51:05 +0000 |
commit | 473832b4224d696359623031c03115a7f9c5a702 (patch) | |
tree | 2da7c2487a20a2b825c3c3e0d41cb15be5d6709b /libexec | |
parent | 8f0370394306356488cffa83b9a1e2de8282b759 (diff) |
Fix for Elfbug, the Xtiherit problem which has been seen on most OpenBSD
ELF dynamic systems. This was due to an oddity in ELF where the address of
fuctions refer to the PLT address in the program, rather than the actual
function address.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/alpha/rtld_machine.c | 13 | ||||
-rw-r--r-- | libexec/ld.so/dlfcn.c | 4 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 10 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/rtld_machine.c | 8 | ||||
-rw-r--r-- | libexec/ld.so/resolve.c | 14 | ||||
-rw-r--r-- | libexec/ld.so/resolve.h | 4 | ||||
-rw-r--r-- | libexec/ld.so/sparc/rtld_machine.c | 9 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/rtld_machine.c | 8 |
8 files changed, 41 insertions, 29 deletions
diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c index 87186b1beeb..cdc29532a92 100644 --- a/libexec/ld.so/alpha/rtld_machine.c +++ b/libexec/ld.so/alpha/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.13 2002/07/07 08:54:50 jufi Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.14 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -111,7 +111,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) this = NULL; switch (ELF64_R_TYPE(relas->r_info)) { case R_TYPE(REFQUAD): - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1, + 0); if (this == NULL) goto resolve_failed; *r_addr += ooff + this->st_value + relas->r_addend; @@ -134,13 +135,15 @@ _dl_printf("unaligned RELATIVE: %p type: %d %s 0x%lx -> 0x%lx\n", r_addr, *r_addr += loff; break; case R_TYPE(JMP_SLOT): - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1, + 1); if (this == NULL) goto resolve_failed; *r_addr = ooff + this->st_value + relas->r_addend; break; case R_TYPE(GLOB_DAT): - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1, + 0); if (this == NULL) goto resolve_failed; *r_addr = ooff + this->st_value + relas->r_addend; @@ -191,7 +194,7 @@ _dl_bind(elf_object_t *object, Elf_Word reloff) symn = object->dyn.strtab + sym->st_name; addr = (Elf_Addr *)(object->load_offs + rela->r_offset); - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1, 1); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c index 3ec5fd02e83..8fc1ee588fe 100644 --- a/libexec/ld.so/dlfcn.c +++ b/libexec/ld.so/dlfcn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dlfcn.c,v 1.17 2002/05/28 00:23:57 deraadt Exp $ */ +/* $OpenBSD: dlfcn.c,v 1.18 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -126,7 +126,7 @@ dlsym(void *handle, const char *name) return(0); } - retval = (void *)_dl_find_symbol(name, object, &sym, 1, 1); + retval = (void *)_dl_find_symbol(name, object, &sym, 1, 1, 0); if (sym != NULL) retval += sym->st_value; else diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index f70edab0e97..333a720625c 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.44 2002/08/09 14:35:43 art Exp $ */ +/* $OpenBSD: loader.c,v 1.45 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -255,7 +255,7 @@ _dl_boot(const char **argv, char **envp, const long loff, Elf_Addr ooff; sym = NULL; - ooff = _dl_find_symbol("atexit", _dl_objects, &sym, 0, 0); + ooff = _dl_find_symbol("atexit", _dl_objects, &sym, 0, 0, 1); if (sym == NULL) { _dl_printf("cannot find atexit, destructors will not be run!\n"); } else { @@ -531,14 +531,14 @@ _dl_call_init(elf_object_t *object) * XXX that should be fixed. */ sym = NULL; - ooff = _dl_find_symbol("__CTOR_LIST__", object, &sym, 1, 1); + ooff = _dl_find_symbol("__CTOR_LIST__", object, &sym, 1, 1, 1); if (sym != NULL) { int i = *(int *)(sym->st_value + ooff); while (i--) *(int *)(sym->st_value + ooff + 4 + 4 * i) += ooff; } sym = NULL; - ooff = _dl_find_symbol("__DTOR_LIST__", object, &sym, 1, 1); + ooff = _dl_find_symbol("__DTOR_LIST__", object, &sym, 1, 1, 1); if (sym != NULL) { int i = *(int *)(sym->st_value + ooff); while (i--) @@ -551,7 +551,7 @@ _dl_call_init(elf_object_t *object) * XXX Instead we rely on a symbol named '.init' and call it if it exists. */ sym = NULL; - ooff = _dl_find_symbol(".init", object, &sym, 1, 1); + ooff = _dl_find_symbol(".init", object, &sym, 1, 1, 1); if (sym != NULL) { DL_DEB(("calling .init in '%s'\n",object->load_name)); (*(void(*)(void))(sym->st_value + ooff))(); diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c index fb88fcd70fc..9ea6e483bf9 100644 --- a/libexec/ld.so/powerpc/rtld_machine.c +++ b/libexec/ld.so/powerpc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.12 2002/07/12 20:18:30 drahn Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.13 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -139,6 +139,7 @@ _dl_printf("object relocation size %x, numrela %x\n", Elf32_Addr ooff; const Elf32_Sym *sym, *this; const char *symn; + int inplt; if (ELF32_R_SYM(relas->r_info) == 0xffffff) continue; @@ -153,7 +154,8 @@ _dl_printf("object relocation size %x, numrela %x\n", if (ELF32_R_SYM(relas->r_info) && !(ELF32_ST_BIND(sym->st_info) == STB_LOCAL && ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE)) { - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 0); + inplt = (ELF32_R_TYPE(relas->r_info) == RELOC_JMP_SLOT); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 0, inplt); if (!this && ELF32_ST_BIND(sym->st_info) == STB_GLOBAL) { _dl_printf("%s: %s :can't resolve reference '%s'\n", _dl_progname, object->load_name, symn); @@ -356,7 +358,7 @@ _dl_dcbf(r_addr); if (object != cobj) { /* only look in this object */ src_loff = _dl_find_symbol(symn, cobj, - &cpysrc, 1, 1); + &cpysrc, 1, 1, 0); } } if (cpysrc == NULL) { diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index 0a76b18e9b5..312401ffbd8 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.11 2002/07/07 08:54:50 jufi Exp $ */ +/* $OpenBSD: resolve.c,v 1.12 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -175,7 +175,7 @@ _dl_lookup_object(const char *name) Elf_Addr _dl_find_symbol(const char *name, elf_object_t *startlook, - const Elf_Sym **ref, int myself, int warnnotfound) + const Elf_Sym **ref, int myself, int warnnotfound, int inplt) { const Elf_Sym *weak_sym = 0; Elf_Addr weak_offs = 0; @@ -200,8 +200,7 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, si != STN_UNDEF; si = object->chains[si]) { const Elf_Sym *sym = symt + si; - if (sym->st_value == 0 || - sym->st_shndx == SHN_UNDEF) + if (sym->st_value == 0) continue; if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE && @@ -213,6 +212,13 @@ _dl_find_symbol(const char *name, elf_object_t *startlook, _dl_strcmp(strt + sym->st_name, name)) continue; + if (sym->st_shndx == SHN_UNDEF) { + if ((inplt || sym->st_value == 0 || + ELF_ST_TYPE(sym->st_info) != STT_FUNC)) { + continue; + } + } + if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) { *ref = sym; return(object->load_offs); diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h index 6c70ed52799..b0eabad8784 100644 --- a/libexec/ld.so/resolve.h +++ b/libexec/ld.so/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.15 2002/07/24 04:11:10 deraadt Exp $ */ +/* $OpenBSD: resolve.h,v 1.16 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -134,7 +134,7 @@ extern int _dl_md_reloc(elf_object_t *object, int rel, int relsz); extern void _dl_md_reloc_got(elf_object_t *object, int lazy); Elf_Addr _dl_find_symbol(const char *name, elf_object_t *startlook, - const Elf_Sym **ref, int myself, int warnnotfound); + const Elf_Sym **ref, int myself, int warnnotfound, int inplt); void _dl_rtld(elf_object_t *object); void _dl_call_init(elf_object_t *object); diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c index f6cce421f58..b67826de258 100644 --- a/libexec/ld.so/sparc/rtld_machine.c +++ b/libexec/ld.so/sparc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.5 2002/08/09 14:38:23 art Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.6 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -254,7 +254,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } else { this = NULL; ooff = _dl_find_symbol(symn, - _dl_objects, &this, 0, 1); + _dl_objects, &this, 0, 1, + type == R_TYPE(JMP_SLOT)); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -291,7 +292,7 @@ resolve_failed: Elf_Addr soff; soff = _dl_find_symbol(symn, object->next, &srcsym, - 0, 2); + 0, 2, 0); if (srcsym == NULL) goto resolve_failed; @@ -348,7 +349,7 @@ _dl_bind(elf_object_t *object, Elf_Word reloff) symn = object->dyn.strtab + sym->st_name; addr = (Elf_Addr *)(object->load_offs + rela->r_offset); - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1, 1); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ diff --git a/libexec/ld.so/sparc64/rtld_machine.c b/libexec/ld.so/sparc64/rtld_machine.c index bfc20126dc4..602d1f33b2a 100644 --- a/libexec/ld.so/sparc64/rtld_machine.c +++ b/libexec/ld.so/sparc64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.17 2002/07/12 20:18:30 drahn Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.18 2002/08/11 16:51:04 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -277,7 +277,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } else { this = NULL; ooff = _dl_find_symbol(symn, _dl_objects, - &this, 0, 1); + &this, 0, 1, type == R_TYPE(JMP_SLOT)); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " @@ -318,7 +318,7 @@ resolve_failed: Elf_Addr soff; soff = _dl_find_symbol(symn, object->next, &srcsym, - 0, 2); + 0, 2, 0); if (srcsym == NULL) goto resolve_failed; @@ -643,7 +643,7 @@ _dl_bind(elf_object_t *object, int index) symn = object->dyn.strtab + sym->st_name; addr = (Elf_Word *)(object->load_offs + rela->r_offset); - ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); + ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1, 1); if (this == NULL) { _dl_printf("lazy binding failed!\n"); *((int *)0) = 0; /* XXX */ |