forked from OSchip/llvm-project
[asan] add __asan_load1/__asan_store1/... callbacks to asan-rt; together with -mllvm -asan-instrumentation-with-call-threshold=N this will be a workaround for PR17409
llvm-svn: 206387
This commit is contained in:
parent
ed1547040c
commit
ae401ca5e7
|
@ -121,6 +121,20 @@ extern "C" {
|
|||
// Global flag, copy of ASAN_OPTIONS=detect_stack_use_after_return
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
extern int __asan_option_detect_stack_use_after_return;
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
extern uptr *__asan_test_only_reported_buggy_pointer;
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8(uptr p);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16(uptr p);
|
||||
} // extern "C"
|
||||
|
||||
#endif // ASAN_INTERFACE_INTERNAL_H
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "lsan/lsan_common.h"
|
||||
|
||||
int __asan_option_detect_stack_use_after_return; // Global interface symbol.
|
||||
uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
|
||||
|
||||
namespace __asan {
|
||||
|
||||
|
@ -374,6 +375,36 @@ void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
|
|||
ASAN_REPORT_ERROR_N(load, false)
|
||||
ASAN_REPORT_ERROR_N(store, true)
|
||||
|
||||
#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_##type##size(uptr addr); \
|
||||
void __asan_##type##size(uptr addr) { \
|
||||
uptr sp = MEM_TO_SHADOW(addr); \
|
||||
uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
|
||||
: *reinterpret_cast<u16 *>(sp); \
|
||||
if (s) { \
|
||||
if (size >= SHADOW_GRANULARITY || \
|
||||
(((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= s) { \
|
||||
if (__asan_test_only_reported_buggy_pointer) { \
|
||||
*__asan_test_only_reported_buggy_pointer = addr; \
|
||||
} else { \
|
||||
GET_CALLER_PC_BP_SP; \
|
||||
__asan_report_error(pc, bp, sp, addr, is_write, size); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
|
||||
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
|
||||
|
||||
// Force the linker to keep the symbols for various ASan interface functions.
|
||||
// We want to keep those in the executable in order to let the instrumented
|
||||
// dynamic libraries access the symbol even if it is not used by the executable
|
||||
|
|
|
@ -217,3 +217,40 @@ TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {
|
|||
ptr = kHighShadowBeg + 200;
|
||||
EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
|
||||
}
|
||||
|
||||
// Test __asan_load1 & friends.
|
||||
TEST(AddressSanitizer, LoadStoreCallbacks) {
|
||||
typedef void (*CB)(uptr p);
|
||||
CB cb[2][5] = {
|
||||
{
|
||||
__asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,
|
||||
}, {
|
||||
__asan_store1, __asan_store2, __asan_store4, __asan_store8,
|
||||
__asan_store16,
|
||||
}
|
||||
};
|
||||
|
||||
uptr buggy_ptr;
|
||||
__asan_test_only_reported_buggy_pointer = &buggy_ptr;
|
||||
for (uptr len = 16; len <= 32; len++) {
|
||||
char *ptr = new char[len];
|
||||
uptr p = reinterpret_cast<uptr>(ptr);
|
||||
for (uptr is_write = 0; is_write <= 1; is_write++) {
|
||||
for (uptr size_log = 0; size_log <= 4; size_log++) {
|
||||
uptr size = 1 << size_log;
|
||||
CB call = cb[is_write][size_log];
|
||||
// Iterate only size-aligned offsets.
|
||||
for (uptr offset = 0; offset < len; offset += size) {
|
||||
buggy_ptr = 0;
|
||||
call(p + offset);
|
||||
if (offset + size <= len)
|
||||
EXPECT_EQ(buggy_ptr, 0U);
|
||||
else
|
||||
EXPECT_EQ(buggy_ptr, p + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] ptr;
|
||||
}
|
||||
__asan_test_only_reported_buggy_pointer = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue