From 18d39a4f89a4c485af1b89815f4e63988532be5e Mon Sep 17 00:00:00 2001 From: Alex Hornung Date: Sun, 24 Jul 2011 14:45:50 +0100 Subject: [PATCH] rtld-elf - restore old tls/tcb code * This was ported incorrectly from FreBSD; the dtv in the TCB needs to be updated properly. * This fixes a fairly tricky issue that appears in threaded programs using dlopen() and family, such as php and Java. It presented itself as a strcmp segfault in object_match_name() due to a messed up STAILQ ->next pointer. The pointer was being messed up by the TLS code. Reported-by: Peter Avalos, Antonio Huete, Francois Tigeot --- libexec/rtld-elf/i386/reloc.c | 14 +++----------- libexec/rtld-elf/rtld.c | 1 - libexec/rtld-elf/x86_64/reloc.c | 9 ++------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index 84e22b8b99..adf777468e 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -363,12 +363,9 @@ void * ___tls_get_addr(tls_index *ti) { struct tls_tcb *tcb; - Elf_Addr* dtv; tcb = tls_get_tcb(); - dtv = (Elf_Addr*)tcb->tcb_dtv; - - return tls_get_addr_common(&dtv, ti->ti_module, ti->ti_offset); + return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset); } /* Sun ABI */ @@ -376,20 +373,15 @@ void * __tls_get_addr(tls_index *ti) { struct tls_tcb *tcb; - Elf_Addr* dtv; tcb = tls_get_tcb(); - dtv = (Elf_Addr*)tcb->tcb_dtv; - - return tls_get_addr_common(&dtv, ti->ti_module, ti->ti_offset); + return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset); } /* Sun ABI */ void * __tls_get_addr_tcb(struct tls_tcb *tcb, tls_index *ti) { - Elf_Addr* dtv = (Elf_Addr*)tcb->tcb_dtv; - - return tls_get_addr_common(&dtv, ti->ti_module, ti->ti_offset); + return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset); } diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 65aeee020e..c982a7cf42 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -3362,7 +3362,6 @@ free_tls(struct tls_tcb *tcb) } free((void*) tls_start); - free((void*) dtv); } #else diff --git a/libexec/rtld-elf/x86_64/reloc.c b/libexec/rtld-elf/x86_64/reloc.c index 8a0a31b699..ca11a80e21 100644 --- a/libexec/rtld-elf/x86_64/reloc.c +++ b/libexec/rtld-elf/x86_64/reloc.c @@ -381,18 +381,13 @@ reloc_jmpslots(Obj_Entry *obj) void *__tls_get_addr(tls_index *ti) { struct tls_tcb *tcb; - Elf_Addr* dtv; tcb = tls_get_tcb(); - dtv = (Elf_Addr*)tcb->tcb_dtv; - - return tls_get_addr_common(&dtv, ti->ti_module, ti->ti_offset); + return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset); } void * __tls_get_addr_tcb(struct tls_tcb *tcb, tls_index *ti) { - Elf_Addr* dtv = (Elf_Addr*)tcb->tcb_dtv; - - return tls_get_addr_common(&dtv, ti->ti_module, ti->ti_offset); + return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset); } -- 2.41.0