浏览代码

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).
Gunnar Beutner 4 年之前
父节点
当前提交
c32b58873a
共有 1 个文件被更改,包括 1 次插入2 次删除
  1. 1 2
      Userland/Libraries/LibELF/DynamicLoader.cpp

+ 1 - 2
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: {