Skip to content

Instantly share code, notes, and snippets.

@MaskRay
Last active September 28, 2021 23:07
Show Gist options
  • Save MaskRay/e035b85dce008f0c6d4997b98354d355 to your computer and use it in GitHub Desktop.
Save MaskRay/e035b85dce008f0c6d4997b98354d355 to your computer and use it in GitHub Desktop.
diff --git i/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp w/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index 7ce9e25da342..37ff9af84679 100644
--- i/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ w/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -458,2 +458,3 @@ static void GetTls(uptr *addr, uptr *size) {
*addr += ThreadDescriptorSize();
+ Printf("+++GetTls: %p %zd\n", *addr, *size);
#elif SANITIZER_GLIBC && defined(__aarch64__)
@@ -462,2 +463,3 @@ static void GetTls(uptr *addr, uptr *size) {
*size = g_tls_size + ThreadDescriptorSize();
+ Printf("+++GetTls: %p %zd\n", *addr, *size);
#elif SANITIZER_GLIBC && defined(__powerpc64__)
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
__thread int var;
int main() {
void *get_tls = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
size_t size = 0, align = 0;
((void (*)(size_t *, size_t *))get_tls)(&size, &align);
printf("_dl_get_tls_static_info: %zd %zd\n", size, align);
void *get_static = dlsym(RTLD_NEXT, "__libc_get_static_tls_bounds");
if (get_static) {
void *start = 0, *stop = 0;
((void (*)(void **, void **))get_static)(&start, &stop);
printf("__libc_get_static_tls_bounds: %p %zd\n", start, (size_t)((char*)stop-(char*)start));
}
}
@MaskRay
Copy link
Author

MaskRay commented Sep 28, 2021

The __libc_get_static_tls_bounds patch intends to provide a more robust way getting static TLS boundaries in sanitizer runtime.
Currently compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp hard codes the thread descriptor size for some glibc versions, which are brittle and cannot keep up with distribution cherrypicks which may affect struct pthread size.

% cd ~/llvm
% patch -p1 -i /tmp/compiler-rt.patch
% ninja -C ~/llvm/out/release asan msan clang
% ~/llvm/out/release/bin/clang -g test-tls-boundary.c -o test-tls-boundary -fsanitize=memory
% ./test-tls-boundary  # system glibc, apparently there is no __libc_get_static_tls_bounds line
+++GetTls: 0xffff85746020 7744
_dl_get_tls_static_info: 5968 16

How to use freshly built libc.so/ld.so?

% cd ~/Dev/glibc/out/bfd
% ./testrun.sh ~/tmp/test-tls-boundary              
==15634==ERROR: MemorySanitizer failed to allocate 0x0 (0) bytes of ReadFileToBuffer (error code: 22)
ERROR: Failed to mmap

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment