summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2002-08-11 16:51:05 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2002-08-11 16:51:05 +0000
commit473832b4224d696359623031c03115a7f9c5a702 (patch)
tree2da7c2487a20a2b825c3c3e0d41cb15be5d6709b /libexec
parent8f0370394306356488cffa83b9a1e2de8282b759 (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.c13
-rw-r--r--libexec/ld.so/dlfcn.c4
-rw-r--r--libexec/ld.so/loader.c10
-rw-r--r--libexec/ld.so/powerpc/rtld_machine.c8
-rw-r--r--libexec/ld.so/resolve.c14
-rw-r--r--libexec/ld.so/resolve.h4
-rw-r--r--libexec/ld.so/sparc/rtld_machine.c9
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c8
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 */