This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer_common] Don't intercept __tls_get_addr on Solaris
ClosedPublic

Authored by ro on Jan 10 2023, 7:02 AM.

Details

Summary

When building/testing ASan inside the GCC tree on Solaris while using GNU ld instead of Solaris ld, a large number of tests SEGVs on both sparc and x86 like this:

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0xfe014cfc in __sanitizer::atomic_load<__sanitizer::atomic_uintptr_t> (a=0xfc602a58, mo=__sanitizer::memory_order_acquire) at sanitizer_common/sanitizer_atomic_clang_x86.h:46
46	      v = a->val_dont_use;
1: x/i $pc
=> 0xfe014cfc <_ZN11__sanitizer11atomic_loadINS_16atomic_uintptr_tEEENT_4TypeEPVKS2_NS_12memory_orderE+62>:	mov    (%eax),%eax
(gdb) bt
#0  0xfe014cfc in __sanitizer::atomic_load<__sanitizer::atomic_uintptr_t> (a=0xfc602a58, mo=__sanitizer::memory_order_acquire) at sanitizer_common/sanitizer_atomic_clang_x86.h:46
#1  0xfe0bd1d7 in __sanitizer::DTLS_NextBlock (cur=0xfc602a58) at sanitizer_common/sanitizer_tls_get_addr.cpp:53
#2  0xfe0bd319 in __sanitizer::DTLS_Find (id=1) at sanitizer_common/sanitizer_tls_get_addr.cpp:77
#3  0xfe0bd466 in __sanitizer::DTLS_on_tls_get_addr (arg_void=0xfeffd068, res=0xfe602a18, static_tls_begin=0, static_tls_end=0) at sanitizer_common/sanitizer_tls_get_addr.cpp:116
#4  0xfe063f81 in __interceptor___tls_get_addr (arg=0xfeffd068) at sanitizer_common/sanitizer_common_interceptors.inc:5501
#5  0xfe0a3054 in __sanitizer::CollectStaticTlsBlocks (info=0xfeffd108, size=40, data=0xfeffd16c) at sanitizer_common/sanitizer_linux_libcdep.cpp:366
#6  0xfe6ba9fa in dl_iterate_phdr () from /usr/lib/ld.so.1
#7  0xfe0a3132 in __sanitizer::GetStaticTlsBoundary (addr=0xfe608020, size=0xfeffd244, align=0xfeffd1b0) at sanitizer_common/sanitizer_linux_libcdep.cpp:382
#8  0xfe0a33f7 in __sanitizer::GetTls (addr=0xfe608020, size=0xfeffd244) at sanitizer_common/sanitizer_linux_libcdep.cpp:482
#9  0xfe0a34b1 in __sanitizer::GetThreadStackAndTls (main=true, stk_addr=0xfe608010, stk_size=0xfeffd240, tls_addr=0xfe608020, tls_size=0xfeffd244) at sanitizer_common/sanitizer_linux_libcdep.cpp:565

The address being accessed is unmapped. However, even when the tests PASS with Solaris ld, ASAN_OPTIONS=verbosity=2 shows

==6582==__tls_get_addr: Can't guess glibc version

Given that that the code is stricly glibc-specific according to sanitizer_tls_get_addr.h, there seems little point in using the interceptor on non-glibc targets.

That's what this patch does. Tested on i386-pc-solaris2.11 and sparc-sun-solaris2.11 inside the GCC tree.

Given all this, it seems highly dubious to use the interceptor on FreeBSD and NetBSD as is currently done. I'll leave changing this to someone who can actually test such a patch, though.

Diff Detail

Event Timeline

ro created this revision.Jan 10 2023, 7:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 10 2023, 7:02 AM
ro requested review of this revision.Jan 10 2023, 7:02 AM
Herald added a subscriber: Restricted Project. · View Herald TranscriptJan 10 2023, 7:02 AM
ro added a comment.Jan 17 2023, 12:17 AM

Ping? It's been a week. Thanks.

vitalybuka accepted this revision.Jan 17 2023, 12:32 AM
vitalybuka added inline comments.
compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
406

Do you care about msan and COMMON_INTERCEPTOR_INITIALIZE_RANGE?
Maybe solaris just needs a different implementation of the interceptor?

This revision is now accepted and ready to land.Jan 17 2023, 12:32 AM
ro added inline comments.Jan 17 2023, 12:39 AM
compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
406

msan hasn't been ported to Solaris and I probably won't get to that any time soon.

This revision was automatically updated to reflect the committed changes.