This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer] Fix LSAN for 32-bit glibc before 2.27
AbandonedPublic

Authored by Lekensteyn on Jun 16 2018, 3:16 AM.

Details

Summary

When dlvsym fails (because the requested symbol does not exist), it
might call malloc and crash with LSAN. Fixes regression in r334363.

Diff Detail

Event Timeline

Lekensteyn created this revision.Jun 16 2018, 3:16 AM
Herald added subscribers: Restricted Project, llvm-commits, kubamracek. · View Herald TranscriptJun 16 2018, 3:16 AM

Oops, wrong (unsplit) diff. This is the correct one and depends on D48254.

jakubjelinek added inline comments.Jun 16 2018, 3:50 AM
lib/sanitizer_common/sanitizer_linux_libcdep.cc
189

Why this hunk? This will unnecessary forever pessimize sanitizers built against glibc 2.27+.

Lekensteyn added inline comments.Jun 16 2018, 9:47 AM
lib/sanitizer_common/sanitizer_linux_libcdep.cc
189

Only 32-bit builds are affected and the overhead is neglible as InitTlsSize is called only *once* per process. The advantage of this dynamic approach is that 32-bit programs can still be copied to a different OS with older glibc and execute without *unconditionally* crashing.

The previous code used dlvsym to perform the version check, but as I now call gnu_get_libc_version directly for GNU libc in D48254, its overhead is pretty small.

Given these circumstances, I think it is reasonable to unconditionally check the version.

If you are interested in some numbers,
line 220 required 2858 instructions (the dlsym call) while
line 226 took 1722 instructions (retrieval of the version and parsing it).
Line 230 took 1806 instructions (as measured with record full and info record in gdb and stepping with next).

Lekensteyn abandoned this revision.Jun 17 2018, 1:54 PM

Superseded by https://reviews.llvm.org/D48265

I still think it would be worth doing the unconditional check on x86 though, but it's a minor issue so I'll defer it.