summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibELF
diff options
context:
space:
mode:
authorGunnar Beutner <gunnar@beutner.name>2021-04-19 11:00:06 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-19 12:14:43 +0200
commitc32b58873a05fe9abf5677f164e52e1ca0af1a46 (patch)
tree13f1e6625a50e24b9f0f3e5fef1a10b68546c3b8 /Userland/Libraries/LibELF
parent0cca23def5e4770e3b59798355172bb52fb981cf (diff)
downloadserenity-c32b58873a05fe9abf5677f164e52e1ca0af1a46.zip
LibELF: Fix calculation for TLS relocations
The calculation for TLS relocations was incorrect which would result in overlapping TLS variables when more than one shared object used TLS variables. This bug can be reproduced with a shared library and a program like this: $ cat tlstest.c #include <string.h> __thread char tls_val[1024]; void set_val() { memset(tls_val, 0, sizeof(tls_val)); } $ gcc -g -shared -o usr/lib/libtlstest.so tlstest.c $ cat test.c void set_val(); int main() { set_val(); } $ gcc -g -o tls test.c -ltlstest Due to the way the TLS relocations are done this program would clobber libc's TLS variables (e.g. errno).
Diffstat (limited to 'Userland/Libraries/LibELF')
-rw-r--r--Userland/Libraries/LibELF/DynamicLoader.cpp3
1 files changed, 1 insertions, 2 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp
index a483dc7801..08681c08ad 100644
--- a/Userland/Libraries/LibELF/DynamicLoader.cpp
+++ b/Userland/Libraries/LibELF/DynamicLoader.cpp
@@ -498,8 +498,7 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si
u32 symbol_value = res.value().value;
auto* dynamic_object_of_symbol = res.value().dynamic_object;
VERIFY(dynamic_object_of_symbol);
- size_t offset_of_tls_end = dynamic_object_of_symbol->tls_offset().value() + dynamic_object_of_symbol->tls_size().value();
- *patch_ptr = (offset_of_tls_end - total_tls_size - symbol_value - sizeof(Elf32_Addr));
+ *patch_ptr = dynamic_object_of_symbol->tls_offset().value() + symbol_value - total_tls_size;
break;
}
case R_386_JMP_SLOT: {