Skip site navigation (1)Skip section navigation (2)
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>