12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- From add514edf4299d1bf540d85d0aa0bd5fe0d46b78 Mon Sep 17 00:00:00 2001
- From: Khem Raj <raj.khem@gmail.com>
- Date: Wed, 18 Mar 2015 00:20:09 +0000
- Subject: [PATCH] Quote from bug 1443 which explains what the patch does :
- We build some random program and link it with -lust. When we run it,
- it dies with a SIGSEGV before reaching main().
- Libust.so depends on liburcu-bp.so from the usermode-rcu package.
- Although libust.so is not prelinked, liburcu-bp.so IS prelinked; this
- is critical.
- Libust.so uses a TLS / __thread variable that is defined in liburcu-
- bp.so. There are special ARM-specific relocation types that allow two
- shared libraries to share thread-specific data. This is critical too.
- One more critical issue: although liburcu-bp.so is prelinked, we can't
- load it at its prelinked address, because we also link against
- librt.so, and librt.so uses that address.
- The dynamic linker is forced to relink liburcu-bp.so at a different
- address. In the course of relinking, it processes the special ARM
- relocation record mentioned above. The prelinker has already filled
- in the information, which is a short offset into a table of thread-
- specific data that is allocated per-thread for each library that uses
- TLS. Because the normal behavior of a relocation is to add the symbol
- value to an addend stored at the address being relocated, we end up
- adding the short offset to itself, doubling it.
- Now we have an awkward situation. The libust.so library doesn't know
- about the addend, so its TLS data for this element is correct. The
- liburcu-bp.so library has a different offset for the element. When we
- go to initialize the element for the first time in liburcu-bp.so, we
- write the address of the result at the doubled (broken) offset.
- Later, when we refer to the address from libust.so, we check the value
- at the correct offset, but it's NULL, so we eat hot SIGSEGV.
- Upstream-Status: Pending
- Signed-off-by: Andrei Dinu <andrei.adrianx.dinu@intel.com>
- Signed-off-by: Khem Raj <raj.khem@gmail.com>
- ---
- sysdeps/arm/dl-machine.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
- index ff5e09e207..d68bfe5cbe 100644
- --- a/sysdeps/arm/dl-machine.h
- +++ b/sysdeps/arm/dl-machine.h
- @@ -510,7 +510,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
-
- case R_ARM_TLS_DTPOFF32:
- if (sym != NULL)
- - *reloc_addr += sym->st_value;
- + *reloc_addr = sym->st_value;
- break;
-
- case R_ARM_TLS_TPOFF32:
|