Commit Graph

120 Commits

Author SHA1 Message Date
Peter Collingbourne 1c650debd7 Bring back the pthread_create interceptor, but only on non-aarch64.
We still need the interceptor on non-aarch64 to untag the pthread_t
and pthread_attr_t pointers and disable tagging on allocations done
internally by glibc.

llvm-svn: 350445
2019-01-04 23:24:02 +00:00
Peter Collingbourne 87f477b5e4 hwasan: Implement lazy thread initialization for the interceptor ABI.
The problem is similar to D55986 but for threads: a process with the
interceptor hwasan library loaded might have some threads started by
instrumented libraries and some by uninstrumented libraries, and we
need to be able to run instrumented code on the latter.

The solution is to perform per-thread initialization lazily. If a
function needs to access shadow memory or add itself to the per-thread
ring buffer its prologue checks to see whether the value in the
sanitizer TLS slot is null, and if so it calls __hwasan_thread_enter
and reloads from the TLS slot. The runtime does the same thing if it
needs to access this data structure.

This change means that the code generator needs to know whether we
are targeting the interceptor runtime, since we don't want to pay
the cost of lazy initialization when targeting a platform with native
hwasan support. A flag -fsanitize-hwaddress-abi={interceptor,platform}
has been introduced for selecting the runtime ABI to target. The
default ABI is set to interceptor since it's assumed that it will
be more common that users will be compiling application code than
platform code.

Because we can no longer assume that the TLS slot is initialized,
the pthread_create interceptor is no longer necessary, so it has
been removed.

Ideally, lazy initialization should only cost one instruction in the
hot path, but at present the call may cause us to spill arguments
to the stack, which means more instructions in the hot path (or
theoretically in the cold path if the spills are moved with shrink
wrapping). With an appropriately chosen calling convention for
the per-thread initialization function (TODO) the hot path should
always need just one instruction and the cold path should need two
instructions with no spilling required.

Differential Revision: https://reviews.llvm.org/D56038

llvm-svn: 350429
2019-01-04 19:27:04 +00:00
Peter Collingbourne fcbcc6114f hwasan: Use system allocator to realloc and free untagged pointers in interceptor mode.
The Android dynamic loader has a non-standard feature that allows
libraries such as the hwasan runtime to interpose symbols even after
the symbol already has a value. The new value of the symbol is used to
relocate libraries loaded after the interposing library, but existing
libraries keep the old value. This behaviour is activated by the
DF_1_GLOBAL flag in DT_FLAGS_1, which is set by passing -z global to
the linker, which is what we already do to link the hwasan runtime.

What this means in practice is that if we have .so files that depend
on interceptor-mode hwasan without the main executable depending on
it, some of the libraries in the process will be using the hwasan
allocator and some will be using the system allocator, and these
allocators need to interact somehow. For example, if an instrumented
library calls a function such as strdup that allocates memory on
behalf of the caller, the instrumented library can reasonably expect
to be able to call free to deallocate the memory.

We can handle that relatively easily with hwasan by using tag 0 to
represent allocations from the system allocator. If hwasan's realloc
or free functions are passed a pointer with tag 0, the system allocator
is called.

One limitation is that this scheme doesn't work in reverse: if an
instrumented library allocates memory, it must free the memory itself
and cannot pass ownership to a system library. In a future change,
we may want to expose an API for calling the system allocator so
that instrumented libraries can safely transfer ownership of memory
to system libraries.

Differential Revision: https://reviews.llvm.org/D55986

llvm-svn: 350427
2019-01-04 19:21:51 +00:00
Evgeniy Stepanov d398471a63 [hwasan] Switch to 64 allocator with a dense size class map.
Summary:
Replace the 32-bit allocator with a 64-bit one with a non-constant
base address, and reduce both the number of size classes and the maximum
size of per-thread caches.

As measured on [1], this reduces average weighted memory overhead
(MaxRSS) from 26% to 12% over stock android allocator. These numbers
include overhead from code instrumentation and hwasan shadow (i.e. not a
pure allocator benchmark).

This switch also enables release-to-OS functionality, which is not
implemented in the 32-bit allocator. I have not seen any effect from
that on the benchmark.

[1] https://android.googlesource.com/platform/system/extras/+/master/memory_replay/

Reviewers: vitalybuka, kcc

Subscribers: kubamracek, cryptoad, llvm-commits

Differential Revision: https://reviews.llvm.org/D56239

llvm-svn: 350370
2019-01-03 23:19:02 +00:00
Evgeniy Stepanov 3408b497f9 Revert "[asan] Support running without /proc.", +1
Revert r350104 "[asan] Fix build on windows."
Revert r350101 "[asan] Support running without /proc."

These changes break Mac build, too.

llvm-svn: 350112
2018-12-28 01:27:18 +00:00
Evgeniy Stepanov d9df65fd0d [asan] Support running without /proc.
Summary:
This patch lets ASan run when /proc is not accessible (ex. not mounted
yet). It includes a special test-only flag that emulates this condition
in an unpriviledged process.

This only matters on Linux, where /proc is necessary to enumerate
virtual memory mappings.

Reviewers: pcc, vitalybuka

Subscribers: kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D55874

llvm-svn: 350101
2018-12-27 21:31:52 +00:00
Eugene Leviant d3bd614856 [HWASAN] Add support for memory intrinsics
This is patch complements D55117 implementing __hwasan_mem*
functions in runtime

Differential revision: https://reviews.llvm.org/D55554

llvm-svn: 349730
2018-12-20 09:10:03 +00:00
Peter Collingbourne 44ea4f5744 hwasan: Allow range of frame descriptors to be empty.
As of r349413 it's now possible for a binary to contain an empty
hwasan frame section. Handle that case simply by doing nothing.

Differential Revision: https://reviews.llvm.org/D55796

llvm-svn: 349428
2018-12-18 00:48:07 +00:00
Peter Collingbourne 1ad24332d1 hwasan: Fix typo: Previosly -> Previously.
llvm-svn: 349254
2018-12-15 07:06:24 +00:00
Dan Liew 41fec1bfc5 Introduce `AddressSpaceView` template parameter to `SizeClassAllocator32`, `FlatByteMap`, and `TwoLevelByteMap`.
Summary:
This is a follow up patch to r346956 for the `SizeClassAllocator32`
allocator.

This patch makes `AddressSpaceView` a template parameter both to the
`ByteMap` implementations (but makes `LocalAddressSpaceView` the
default), some `AP32` implementations and is used in `SizeClassAllocator32`.
The actual changes to `ByteMap` implementations and
`SizeClassAllocator32` are very simple. However the patch is large
because it requires changing all the `AP32` definitions, and users of
those definitions.

For ASan and LSan we make `AP32` and `ByteMap` templateds type that take
a single `AddressSpaceView` argument. This has been done because we will
instantiate the allocator with a type that isn't `LocalAddressSpaceView`
in the future patches. For the allocators used in the other sanitizers
(i.e. HWAsan, MSan, Scudo, and TSan) use of `LocalAddressSpaceView` is
hard coded because we do not intend to instantiate the allocators with
any other type.

In the cases where untemplated types have become templated on a single
`AddressSpaceView` parameter (e.g. `PrimaryAllocator`) their name has
been changed to have a `ASVT` suffix (Address Space View Type) to
indicate they are templated.  The only exception to this are the `AP32`
types due to the desire to keep the type name as short as possible.

In order to check that template is instantiated in the correct a way a
`static_assert(...)` has been added that checks that the
`AddressSpaceView` type used by `Params::ByteMap::AddressSpaceView` matches
the `Params::AddressSpaceView`. This uses the new `sanitizer_type_traits.h`
header.

rdar://problem/45284065

Reviewers: kcc, dvyukov, vitalybuka, cryptoad, eugenis, kubamracek, george.karpenkov

Subscribers: mgorny, llvm-commits, #sanitizers

Differential Revision: https://reviews.llvm.org/D54904

llvm-svn: 349138
2018-12-14 09:03:18 +00:00
Evgeniy Stepanov 1020085898 [hwasan] Link ubsan_cxx to shared runtime library.
Summary: This is needed for C++-specific ubsan and cfi error reporting to work.

Reviewers: kcc, vitalybuka

Subscribers: srhines, kubamracek, mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D55589

llvm-svn: 348986
2018-12-12 22:56:00 +00:00
Evgeniy Stepanov 0af6e5facd [hwasan] Verify Android TLS slot at startup.
Summary:
Add a check that TLS_SLOT_TSAN / TLS_SLOT_SANITIZER, whichever
android_get_tls_slot is using, is not conflicting with
TLS_SLOT_DLERROR.

Reviewers: rprichard, vitalybuka

Subscribers: srhines, kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D55587

llvm-svn: 348979
2018-12-12 22:10:52 +00:00
Kostya Serebryany 0e799d92fd [hwasan] don't check tail magic when in right_align mode (should fix the bot)
llvm-svn: 347121
2018-11-17 01:02:09 +00:00
Kostya Serebryany c265e7673d [hwasan] implement free_checks_tail_magic=1
Summary:
With free_checks_tail_magic=1 (default) HWASAN
writes magic bytes to the tail of every heap allocation
(last bytes of the last granule, if the last granule is not fully used)
and checks these bytes on free().

This feature will detect buffer overwires within the last granule
at the time of free().

This is an alternative to malloc_align_right=[1289] that should have
fewer compatibility issues. It is also weaker since it doesn't
detect read overflows and reports bugs at free() instead of at access.

Reviewers: eugenis

Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits

Differential Revision: https://reviews.llvm.org/D54656

llvm-svn: 347116
2018-11-17 00:25:17 +00:00
Kostya Serebryany ba5c7169c5 [hwasan] optionally right-align heap allocations
Summary:
... so that we can find intra-granule buffer overflows.
The default is still to always align left.
It remains to be seen wether we can enable this mode at scale.

Reviewers: eugenis

Reviewed By: eugenis

Subscribers: jfb, dvyukov, kubamracek, delcypher, #sanitizers, llvm-commits

Differential Revision: https://reviews.llvm.org/D53789

llvm-svn: 347082
2018-11-16 19:38:48 +00:00
Evgeniy Stepanov 771d6d37ca [hwasan] Add entire report to abort message on Android.
Summary:
When reporting a fatal error, collect and add the entire report text to
android_set_abort_message so that it can be found in the tombstone.

Reviewers: kcc, vitalybuka

Subscribers: srhines, kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D54284

llvm-svn: 346557
2018-11-09 21:54:03 +00:00
Evgeniy Stepanov 4680386c34 [hwasan] Remove dead code.
llvm-svn: 346452
2018-11-09 00:03:39 +00:00
Petr Hosek 5dc0fba2e3 [CMake][ASan][HWASan] Set an explicit dependency on libc++ headers
We have seen failing builds due to a race condition between
RTAsan_dynamic and libc++ headers builds, specifically libc++
headers depend on __config and if this header hasn't been copied
into the final location, including other headers will typically
result in failure. To avoid this race, we add an explicit dependency
on libc++ headers which ensures that they've been copied into place
before the sanitizer object library build starts.

Differential Revision: https://reviews.llvm.org/D54198

llvm-svn: 346339
2018-11-07 18:35:44 +00:00
Evgeniy Stepanov ea857e8225 [sanitizer] Fix mallopt interceptor.
On error, mallopt is supposed to return 0, not -1.

llvm-svn: 345323
2018-10-25 22:15:44 +00:00
Kostya Serebryany ad11526c30 [hwasan] when printing a stack-related bugs, also print stack frame descriptions provided by the compiler
llvm-svn: 345110
2018-10-24 01:35:50 +00:00
Kostya Serebryany af95597c3c [hwasan] add stack frame descriptions.
Summary:
At compile-time, create an array of {PC,HumanReadableStackFrameDescription}
for every function that has an instrumented frame, and pass this array
to the run-time at the module-init time.
Similar to how we handle pc-table in SanitizerCoverage.
The run-time is dummy, will add the actual logic in later commits.

Reviewers: morehouse, eugenis

Reviewed By: eugenis

Subscribers: srhines, llvm-commits, kubamracek

Differential Revision: https://reviews.llvm.org/D53227

llvm-svn: 344985
2018-10-23 00:50:40 +00:00
Kostya Serebryany dac7b2abaf [hwasan] more compact printing for 'Previosly allocated frames'
llvm-svn: 344210
2018-10-11 00:34:20 +00:00
Kostya Serebryany d7c60e42e3 [hwasan] when reporting a bug, print some very basic information about the heap chunk (in addition to the more detailed info that we may fail to show)
llvm-svn: 344193
2018-10-10 22:24:44 +00:00
Kostya Serebryany a393399741 [hwasan] print all threads in a bug report
llvm-svn: 344174
2018-10-10 18:56:31 +00:00
Kostya Serebryany 3fc15200e2 [hwasan] print more tags around the buggy address, and do it with a single Printf
llvm-svn: 344169
2018-10-10 18:32:31 +00:00
Evgeniy Stepanov edede5daff [hwasan] Fix top PC in error stack trace being off by 1 instruction.
Summary:
GetStackTrace treats top PC as a return address from an error reporting
function, and adjusts it down by 1 instruction. This is not necessary in
a signal handler, so adjust PC up to compensate.

Reviewers: kcc, vitalybuka, jfb

Subscribers: kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D52802

llvm-svn: 343638
2018-10-02 21:52:02 +00:00
Stephen Hines 80e7d65a42 [sanitizer] Use -Wl,-z,global on Android for sanitizers except UBsan
Summary:
This essentially reverts r337010 since it breaks UBSan, which is used
for a few platform libraries. The "-z global" flag is now added for
Scudo as well. The only other sanitizer shared libraries are for asan
and hwasan, which have also been reinstated to use the global flag.

Reviewers: cryptoad, eugenis

Reviewed By: cryptoad

Subscribers: kubamracek, mgorny, delcypher, #sanitizers, nickdesaulniers, chh, kongyi, pirama, llvm-commits

Differential Revision: https://reviews.llvm.org/D52770

llvm-svn: 343599
2018-10-02 16:19:42 +00:00
Evgeniy Stepanov 090f0f9504 [hwasan] Record and display stack history in stack-based reports.
Summary:
Display a list of recent stack frames (not a stack trace!) when
tag-mismatch is detected on a stack address.

The implementation uses alignment tricks to get both the address of
the history buffer, and the base address of the shadow with a single
8-byte load. See the comment in hwasan_thread_list.h for more
details.

Developed in collaboration with Kostya Serebryany.

Reviewers: kcc

Subscribers: srhines, kubamracek, mgorny, hiraditya, jfb, llvm-commits

Differential Revision: https://reviews.llvm.org/D52249

llvm-svn: 342923
2018-09-24 23:03:34 +00:00
Evgeniy Stepanov 20c4999e8b Revert "[hwasan] Record and display stack history in stack-based reports."
This reverts commit r342921: test failures on clang-cmake-arm* bots.

llvm-svn: 342922
2018-09-24 22:50:32 +00:00
Evgeniy Stepanov 9043e17edd [hwasan] Record and display stack history in stack-based reports.
Summary:
Display a list of recent stack frames (not a stack trace!) when
tag-mismatch is detected on a stack address.

The implementation uses alignment tricks to get both the address of
the history buffer, and the base address of the shadow with a single
8-byte load. See the comment in hwasan_thread_list.h for more
details.

Developed in collaboration with Kostya Serebryany.

Reviewers: kcc

Subscribers: srhines, kubamracek, mgorny, hiraditya, jfb, llvm-commits

Differential Revision: https://reviews.llvm.org/D52249

llvm-svn: 342921
2018-09-24 21:38:42 +00:00
David Carlier 362e6095a6 [Hwasan] interceptor macro / extra comma removal
gcc being pedantic, removing the unnecessary comma.

Reviewers: eugenis, kcc

Reviewed By: eugenis

Differential Revision: https://reviews.llvm.org/D52305

llvm-svn: 342680
2018-09-20 19:30:51 +00:00
Kostya Serebryany c173a703b5 [hwasan] use a single Printf per line when printing a report (more friendly to android logging)
llvm-svn: 342164
2018-09-13 19:14:22 +00:00
Kostya Serebryany ee9bb8761c [hwasan] On every use-after-free print a developer note: the index of this heap object in the thread's deallocation ring buffer. Mostly useful to hwasan developers, will hopefully let us know the good size of the deallocation ring buffer
llvm-svn: 342014
2018-09-12 00:58:15 +00:00
Evgeniy Stepanov d263cb8ea1 [hwasan] Export memory stats through /proc/$PID/maps.
Adds a line to /proc/$PID/maps with more or less up-to-date memory
stats of the process.

llvm-svn: 341735
2018-09-08 00:11:12 +00:00
Evgeniy Stepanov 5b332abd66 [hwasan] Fix malloc overflow detection.
Check size limit before rounding up, otherwise malloc((size_t)-1)
would happily allocate 0 bytes.

Steal a nice test case from scudo.

llvm-svn: 341612
2018-09-07 00:27:11 +00:00
Kostya Serebryany f9ec62cb3a [hwasan] change the thread list so that main_thread can also be removed
llvm-svn: 341610
2018-09-07 00:16:55 +00:00
Evgeniy Stepanov fe4808eba7 [hwasan] Remove allocator interceptors.
Summary:
When building without COMPILER_RT_HWASAN_WITH_INTERCEPTORS, skip
interceptors for malloc/free/etc and only export their versions with
__sanitizer_ prefix.

Also remove a hack in mallinfo() interceptor that does not apply to
hwasan.

Reviewers: kcc

Subscribers: kubamracek, krytarowski, llvm-commits

Differential Revision: https://reviews.llvm.org/D51711

llvm-svn: 341598
2018-09-06 22:53:08 +00:00
Kostya Serebryany f1f556c179 [hwasan] fix pthread_exit
llvm-svn: 341594
2018-09-06 22:13:43 +00:00
Kostya Serebryany 950a1a3936 [hwasan] introduce __hwasan_print_memory_usage
llvm-svn: 341592
2018-09-06 22:08:41 +00:00
Kostya Serebryany 68902c7050 [hwasan] when verbose_threads==1, print the memory usage per thread
llvm-svn: 341507
2018-09-05 23:52:31 +00:00
Kostya Serebryany b29d42ee31 [hwasan] simplify the code, NFC
llvm-svn: 341501
2018-09-05 23:22:38 +00:00
Evgeniy Stepanov 6afce6a438 [hwasan] Don't handle signals on Android.
Sigtrap is used for error reporting, but all other signals are better
left for the platform.

In particular, sanitizer signal handlers do not dump registers or
memory which makes debugging harder for no good reason.

llvm-svn: 341500
2018-09-05 22:46:19 +00:00
Kostya Serebryany ee0e2f8323 [hwasan] revert r341435 as it breaks the bot on aarch64
llvm-svn: 341441
2018-09-05 01:29:08 +00:00
Kostya Serebryany c12cc9b85c [hwasan] fix colored output
llvm-svn: 341440
2018-09-05 01:27:48 +00:00
Kostya Serebryany 5d05be84b7 [hwasan] print thread IDs when reporting a bug (also had to fix pthread_create on Linux)
llvm-svn: 341438
2018-09-05 01:16:50 +00:00
Kostya Serebryany 9fbedcad71 [hwasan] use real TLS on linux to store the current thread -- this way we can call t->Destroy in __hwasan_thread_exit, same as on Android
llvm-svn: 341435
2018-09-05 00:17:23 +00:00
Kostya Serebryany 2768b52117 [hwasan] simplify the code, NFC
llvm-svn: 341432
2018-09-05 00:01:45 +00:00
Kostya Serebryany c551220de8 [hwasan] remove stale Thread:: data members. While doing so noticed that GetThreadStackAndTls was always called with 'at_initialization=true', fixed that.
llvm-svn: 341431
2018-09-04 23:57:09 +00:00
Kostya Serebryany 3d8f49a6bf [hwasan] add a unique id to a thread and add debug prints for thread creation/destruction
llvm-svn: 341428
2018-09-04 23:26:08 +00:00
Evgeniy Stepanov 5abf7d90ac [hwasan] Fix new[] with zero size.
Fixes "allocator is out of memory trying to allocate 0x0 bytes" by
always allocating at least one byte.

llvm-svn: 341229
2018-08-31 17:49:49 +00:00