Similar to __asan_set_error_report_callback, pass the entire report to a
user provided callback function.
Differential Revision: https://reviews.llvm.org/D91825
Summary:
GCC would like to emit a function call to report a tag mismatch
rather than hard-code the `brk` instruction directly.
__hwasan_tag_mismatch_stub contains most of the functionality to do
this already, but requires exposure in the dynamic library.
This patch moves __hwasan_tag_mismatch_stub outside of the anonymous
namespace that it was defined in and declares it in
hwasan_interface_internal.h.
We also add the ability to pass sizes larger than 16 bytes to this
reporting function by providing a fourth parameter that is only looked
at when the size provided is not in the original accepted range.
This does not change the behaviour where it is already being called,
since the previous definition only accepted sizes up to 16 bytes and
hence the change in behaviour is not seen by existing users.
The change in declaration does not matter, since the only existing use
is in the __hwasan_tag_mismatch function written in assembly.
Reviewers: eugenis, kcc, pcc, #sanitizers
Reviewed By: eugenis, #sanitizers
Subscribers: kristof.beyls, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D69113
Patch by Matthew Malcomson <matthew.malcomson@arm.com>
Summary:
GCC would like to emit a function call to report a tag mismatch
rather than hard-code the `brk` instruction directly.
__hwasan_tag_mismatch_stub contains most of the functionality to do
this already, but requires exposure in the dynamic library.
This patch moves __hwasan_tag_mismatch_stub outside of the anonymous
namespace that it was defined in and declares it in
hwasan_interface_internal.h.
We also add the ability to pass sizes larger than 16 bytes to this
reporting function by providing a fourth parameter that is only looked
at when the size provided is not in the original accepted range.
This does not change the behaviour where it is already being called,
since the previous definition only accepted sizes up to 16 bytes and
hence the change in behaviour is not seen by existing users.
The change in declaration does not matter, since the only existing use
is in the __hwasan_tag_mismatch function written in assembly.
Tested with gcc and clang on an AArch64 vm.
Reviewers: eugenis, kcc, pcc, #sanitizers
Reviewed By: eugenis, #sanitizers
Subscribers: kristof.beyls, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D69113
Globals are instrumented by adding a pointer tag to their symbol values
and emitting metadata into a special section that allows the runtime to tag
their memory when the library is loaded.
Due to order of initialization issues explained in more detail in the comments,
shadow initialization cannot happen during regular global initialization.
Instead, the location of the global section is marked using an ELF note,
and we require libc support for calling a function provided by the HWASAN
runtime when libraries are loaded and unloaded.
Based on ideas discussed with @evgeny777 in D56672.
Differential Revision: https://reviews.llvm.org/D65770
llvm-svn: 368102
Summary:
This change change the instrumentation to allow users to view the registers at the point at which tag mismatch occured. Most of the heavy lifting is done in the runtime library, where we save the registers to the stack and emit unwind information. This allows us to reduce the overhead, as very little additional work needs to be done in each __hwasan_check instance.
In this implementation, the fast path of __hwasan_check is unmodified. There are an additional 4 instructions (16B) emitted in the slow path in every __hwasan_check instance. This may increase binary size somewhat, but as most of the work is done in the runtime library, it's manageable.
The failure trace now contains a list of registers at the point of which the failure occured, in a format similar to that of Android's tombstones. It currently has the following format:
Registers where the failure occurred (pc 0x0055555561b4):
x0 0000000000000014 x1 0000007ffffff6c0 x2 1100007ffffff6d0 x3 12000056ffffe025
x4 0000007fff800000 x5 0000000000000014 x6 0000007fff800000 x7 0000000000000001
x8 12000056ffffe020 x9 0200007700000000 x10 0200007700000000 x11 0000000000000000
x12 0000007fffffdde0 x13 0000000000000000 x14 02b65b01f7a97490 x15 0000000000000000
x16 0000007fb77376b8 x17 0000000000000012 x18 0000007fb7ed6000 x19 0000005555556078
x20 0000007ffffff768 x21 0000007ffffff778 x22 0000000000000001 x23 0000000000000000
x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000
x28 0000000000000000 x29 0000007ffffff6f0 x30 00000055555561b4
... and prints after the dump of memory tags around the buggy address.
Every register is saved exactly as it was at the point where the tag mismatch occurs, with the exception of x16/x17. These registers are used in the tag mismatch calculation as scratch registers during __hwasan_check, and cannot be saved without affecting the fast path. As these registers are designated as scratch registers for linking, there should be no important information in them that could aid in debugging.
Reviewers: pcc, eugenis
Reviewed By: pcc, eugenis
Subscribers: srhines, kubamracek, mgorny, javed.absar, krytarowski, kristof.beyls, hiraditya, jdoerfert, llvm-commits, #sanitizers
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D58857
llvm-svn: 355738
This function initializes enough of the runtime to be able to run
instrumented code in a statically linked executable. It replaces
__hwasan_shadow_init() which wasn't doing enough initialization for
instrumented code that uses either TLS or IFUNC to work.
Differential Revision: https://reviews.llvm.org/D57490
llvm-svn: 352816
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
This is patch complements D55117 implementing __hwasan_mem*
functions in runtime
Differential revision: https://reviews.llvm.org/D55554
llvm-svn: 349730
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
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
Summary:
The idea behind this change is to allow sanitization of libc. We are prototyping on Bionic,
but the tool interface will be general enough (or at least generalizable) to support any other libc.
When libc depends on libclang_rt.hwasan, the latter can not interpose libc functions.
In fact, majority of interceptors become unnecessary when libc code is instrumented.
This change gets rid of most hwasan interceptors and provides interface for libc to notify
hwasan about thread creation and destruction events. Some interceptors (pthread_create)
are kept under #ifdef to enable testing with uninstrumented libc. They are expressed in
terms of the new libc interface.
The new cmake switch, COMPILER_RT_HWASAN_WITH_INTERCEPTORS, ON by default, builds testing
version of the library with the aforementioned pthread_create interceptor.
With the OFF setting, the library becomes more of a libc plugin.
Reviewers: vitalybuka, kcc, jfb
Subscribers: srhines, kubamracek, mgorny, jfb, llvm-commits
Differential Revision: https://reviews.llvm.org/D50922
llvm-svn: 340216
This reapplies commit r339935 with the following changes:
* make longjmp test C, not C++, to avoid dependency on libc++/libstdc++
* untag pointer in memset interceptor
x86_64 does not have TBI, so hwasan barely works there. Tests must be carefully
written in a way that does not leak tagged pointer to system libraries.
llvm-svn: 339963
Summary:
A callback to annotate longjmp-like code.
Unlike __asan_handle_no_return, in hwasan we can not conservatively
"unpoison" the entire thread stack, because there is no such thing as
unpoisoned memory. Pointer and memory tags must always match.
Reviewers: vitalybuka, kcc
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D50752
llvm-svn: 339935
Summary:
Provide __hwasan_shadow_init that can be used to initialize shadow w/o touching libc.
It can be used to bootstrap an unusual case of fully-static executable with
hwasan-instrumented libc, which needs to run hwasan code before it is ready to serve
user calls like madvise().
Reviewers: vitalybuka, kcc
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D50581
llvm-svn: 339606
Retire the fixed shadow memory mapping to avoid conflicts with default
process memory mapping (currently manifests on Android).
Tests on AArch64 show <1% performance loss and code size increase,
making it possible to use dynamic shadow memory by default.
Keep the fixed shadow memory mapping around to be able to run
performance comparison tests later.
Re-commiting D45847 with fixed shadow for x86-64.
llvm-svn: 330624
This commit causes internal errors with ld.bfd 2.24. My guess is that
the ifunc usage in this commit is causing problems. This is the default
system linker on Trusty Tahr, which is from 2014. I claim it's still in
our support window. Maybe we will decide to drop support for it, but
let's get the bots green while we do the investigation and have that
discussion.
Discovered here: https://crbug.com/835864
llvm-svn: 330619
Summary:
Retire the fixed shadow memory mapping to avoid conflicts with default
process memory mapping (currently manifests on Android).
Tests on AArch64 show <1% performance loss and code size increase,
making it possible to use dynamic shadow memory by default.
For the simplicity and unifirmity sake, use dynamic shadow memory mapping
with base address accessed via ifunc resolver on all supported platforms.
Keep the fixed shadow memory mapping around to be able to run
performance comparison tests later.
Complementing D45840.
Reviewers: eugenis
Subscribers: srhines, kubamracek, dberris, mgorny, kristof.beyls, delcypher, #sanitizers, llvm-commits
Differential Revision: https://reviews.llvm.org/D45847
llvm-svn: 330474
Summary:
"N" suffix is added by the instrumentation and interface functions
are expected to be exported from the library as __hwasan_loadN* and
__hwasan_storeN*.
Reviewers: eugenis
Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits
Differential Revision: https://reviews.llvm.org/D45739
llvm-svn: 330297
Summary:
Very basic stack instrumentation using tagged pointers.
Tag for N'th alloca in a function is built as XOR of:
* base tag for the function, which is just some bits of SP (poor
man's random)
* small constant which is a function of N.
Allocas are aligned to 16 bytes. On every ReturnInst allocas are
re-tagged to catch use-after-return.
This implementation has a bunch of issues that will be taken care of
later:
1. lifetime intrinsics referring to tagged pointers are not
recognized in SDAG. This effectively disables stack coloring.
2. Generated code is quite inefficient. There is one extra
instruction at each memory access that adds the base tag to the
untagged alloca address. It would be better to keep tagged SP in a
callee-saved register and address allocas as an offset of that XOR
retag, but that needs better coordination between hwasan
instrumentation pass and prologue/epilogue insertion.
3. Lifetime instrinsics are ignored and use-after-scope is not
implemented. This would be harder to do than in ASan, because we
need to use a differently tagged pointer depending on which
lifetime.start / lifetime.end the current instruction is dominated
/ post-dominated.
Reviewers: kcc, alekseyshl
Subscribers: srhines, kubamracek, javed.absar, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D41602
llvm-svn: 322324
Summary: Very similar to AddressSanitizer, with the exception of the error type encoding.
Reviewers: kcc, alekseyshl
Subscribers: cfe-commits, kubamracek, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D41417
llvm-svn: 321203
Summary: This brings CPU overhead on bzip2 down from 5.5x to 2x.
Reviewers: kcc, alekseyshl
Subscribers: kubamracek, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D41137
llvm-svn: 320538