Date: Tue, 15 Aug 2017 21:12:47 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [Bug 221337] -fsanitize=address (asan) fails on i386 Message-ID: <bug-221337-8-9hGPEyVhNf@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-221337-8@https.bugs.freebsd.org/bugzilla/> References: <bug-221337-8@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D221337 Dimitry Andric <dim@FreeBSD.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kib@FreeBSD.org --- Comment #1 from Dimitry Andric <dim@FreeBSD.org> --- I did a bit of further research, adding some instrumentation to ASan. In particular, to its initialization in ClearShadowForThreadStackAndTLS() here: https://github.com/llvm-mirror/compiler-rt/blob/master/lib/asan/asan_thread= .cc#L301 and the TLS support here: https://github.com/llvm-mirror/compiler-rt/blob/master/lib/sanitizer_common= /sanitizer_linux_libcdep.cc#L358 It turns out that the beginning of its TLS area (tls_begin) is not aligned = to 8 bytes anymore, after r319971: $ asprintf.cc.tmp =3D=3D65176=3D=3DDEBUG lib/asan/asan_thread.cc(228): stack_top=3D0x00000000, stack_bottom=3D0x00000000 =3D=3D65176=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(358): segbase=3D0x28423a0c =3D=3D65176=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(368): dtv[0]=3D0x00000002, dtv[1]=3D0x00000002, dtv[2]=3D0x284239f4 =3D=3D65176=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(402): tls_addr=3D0x284239f4, tls_size=3D0x00000018 =3D=3D65176=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(407): stack_top=3D0xbfbdf000, stack_bottom=3D0xbfbff000 =3D=3D65176=3D=3DDEBUG lib/asan/asan_thread.cc(235): stack_top=3D0xbfbdf000, stack_bottom=3D0xbfbff000 =3D=3D65176=3D=3DDEBUG lib/asan/asan_thread.cc(292): stack_top=3D0xbfbdf000, stack_bottom=3D0xbfbff000 =3D=3D65176=3D=3DDEBUG lib/asan/asan_thread.cc(296): tls_begin=3D0x284239f4, tls_end=3D0x28423a0c =3D=3D65176=3D=3DAddressSanitizer CHECK failed: lib/asan/asan_poisoning.cc:= 36 "((AddrIsAlignedByGranularity(addr))) !=3D (0)" (0x0, 0x0) #0 0x80b5850 in __asan::AsanCheckFailed(char const*, int, char const, unsigned long long, unsigned long long) lib/asan/asan_rtl.cc:69:3 #1 0x80c76ca in __sanitizer::CheckFailed(char const*, int, char const, unsigned long long, unsigned long long) lib/sanitizer_common/sanitizer_termination.cc:79:5 #2 0x80af170 in __asan::PoisonShadow(unsigned long, unsigned long, unsi= gned char) lib/asan/asan_poisoning.cc:36:3 #3 0x80b7581 in ClearShadowForThreadStackAndTLS lib/asan/asan_thread.cc:298:5 #4 0x80b7581 in __asan::AsanThread::Init(void) lib/asan/asan_thread.cc:= 240 #5 0x80b774d in __asan::AsanThread::ThreadStart(unsigned long, __sanitizer::atomic_uintptr_t*) lib/asan/asan_thread.cc:249:3 #6 0x80b54c5 in __asan::AsanInitInternal(void) lib/asan/asan_rtl.cc:591= :16 #7 0x807c7aa in clock_gettime lib/sanitizer_common/sanitizer_common_interceptors.inc:1995:3 E.g in its GetTls() routine it retrieves segbase (probably from %gs), then derives the DTV array from that, and uses the third element as the TLS base address. In this particular case it ends up at 0x284239f4, which is not 8-= byte aligned, causing the internal CHECK failure. In contrast, with older libc, from r319970 or before, the TLS base is align= ed to 8 bytes, whether that is by accident or on purpose, I don't know: $ LD_LIBRARY_PATH=3D/usr/obj/usr/src/lib/libc.r319970 asprintf.cc.tmp =3D=3D65175=3D=3DDEBUG lib/asan/asan_thread.cc(228): stack_top=3D0x00000000, stack_bottom=3D0x00000000 =3D=3D65175=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(358): segbase=3D0x281212f8 =3D=3D65175=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(368): dtv[0]=3D0x00000002, dtv[1]=3D0x00000002, dtv[2]=3D0x281212e0 =3D=3D65175=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(402): tls_addr=3D0x281212e0, tls_size=3D0x00000018 =3D=3D65175=3D=3DDEBUG lib/sanitizer_common/sanitizer_linux_libcdep.cc(407): stack_top=3D0xbfbdf000, stack_bottom=3D0xbfbff000 =3D=3D65175=3D=3DDEBUG lib/asan/asan_thread.cc(235): stack_top=3D0xbfbdf000, stack_bottom=3D0xbfbff000 =3D=3D65175=3D=3DDEBUG lib/asan/asan_thread.cc(292): stack_top=3D0xbfbdf000, stack_bottom=3D0xbfbff000 =3D=3D65175=3D=3DDEBUG lib/asan/asan_thread.cc(296): tls_begin=3D0x281212e0, tls_end=3D0x281212f8 x1 1x DONE And then all the ASan machinery works fine. I have tried to follow how the DTV array is filled, but I end up in rtld instead of libc, so I don't fully understand how replacing libc can make a difference in this case. Konstantin, maybe you can shed some light? Of course I know that there is no guarantee at all for any other alignment = than 4 bytes on i386, but it seems that we have somehow always managed (until no= w) to align the TLS base addresses (at least for ASan's threads) to 8 bytes.... Could we do some sort of compat hack to make this work? Because after r319= 971, all executables with ASan fail in the above manner, even those compiled long ago with earlier versions of clang (and maybe even gcc). --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-221337-8-9hGPEyVhNf>