forked from OSchip/llvm-project
[asan] fix unwinding inside libc intercepors (asan issue #46)
llvm-svn: 152768
This commit is contained in:
parent
fd2037162e
commit
54a3cac5c5
|
@ -63,12 +63,12 @@ namespace __asan {
|
|||
|
||||
// Instruments read/write access to a single byte in memory.
|
||||
// On error calls __asan_report_error, which aborts the program.
|
||||
static NOINLINE void AccessAddress(uintptr_t address, bool isWrite) {
|
||||
if (AddressIsPoisoned(address)) {
|
||||
GET_BP_PC_SP;
|
||||
__asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1);
|
||||
}
|
||||
}
|
||||
#define ACCESS_ADDRESS(address, isWrite) do { \
|
||||
if (AddressIsPoisoned(address)) { \
|
||||
GET_CURRENT_PC_BP_SP; \
|
||||
__asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
|
||||
// and ASAN_WRITE_RANGE as macro instead of function so
|
||||
|
@ -81,8 +81,8 @@ static NOINLINE void AccessAddress(uintptr_t address, bool isWrite) {
|
|||
#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
|
||||
if (size > 0) { \
|
||||
uintptr_t ptr = (uintptr_t)(offset); \
|
||||
AccessAddress(ptr, isWrite); \
|
||||
AccessAddress(ptr + (size) - 1, isWrite); \
|
||||
ACCESS_ADDRESS(ptr, isWrite); \
|
||||
ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -296,12 +296,6 @@ bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size);
|
|||
|
||||
typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg);
|
||||
|
||||
#define GET_BP_PC_SP \
|
||||
uintptr_t bp = GET_CURRENT_FRAME(); \
|
||||
uintptr_t pc = GET_CALLER_PC(); \
|
||||
uintptr_t local_stack; \
|
||||
uintptr_t sp = (uintptr_t)&local_stack;
|
||||
|
||||
// These magic values are written to shadow for better error reporting.
|
||||
const int kAsanHeapLeftRedzoneMagic = 0xfa;
|
||||
const int kAsanHeapRightRedzoneMagic = 0xfb;
|
||||
|
|
|
@ -221,7 +221,7 @@ static NOINLINE void DescribeAddress(uintptr_t addr, uintptr_t access_size) {
|
|||
NOINLINE ASAN_INTERFACE_ATTRIBUTE \
|
||||
extern "C" void __asan_report_ ## type ## size(uintptr_t addr); \
|
||||
extern "C" void __asan_report_ ## type ## size(uintptr_t addr) { \
|
||||
GET_BP_PC_SP; \
|
||||
GET_CALLER_PC_BP_SP; \
|
||||
__asan_report_error(pc, bp, sp, addr, is_write, size); \
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,22 @@ struct AsanStackTrace {
|
|||
|
||||
} // namespace __asan
|
||||
|
||||
// Use this macro if you want to print stack trace with the caller
|
||||
// of the current function in the top frame.
|
||||
#define GET_CALLER_PC_BP_SP \
|
||||
uintptr_t bp = GET_CURRENT_FRAME(); \
|
||||
uintptr_t pc = GET_CALLER_PC(); \
|
||||
uintptr_t local_stack; \
|
||||
uintptr_t sp = (uintptr_t)&local_stack;
|
||||
|
||||
// Use this macro if you want to print stack trace with the current
|
||||
// function in the top frame.
|
||||
#define GET_CURRENT_PC_BP_SP \
|
||||
uintptr_t bp = GET_CURRENT_FRAME(); \
|
||||
uintptr_t pc = AsanStackTrace::GetCurrentPc(); \
|
||||
uintptr_t local_stack; \
|
||||
uintptr_t sp = (uintptr_t)&local_stack;
|
||||
|
||||
// Get the stack trace with the given pc and bp.
|
||||
// The pc will be in the position 0 of the resulting stack trace.
|
||||
// The bp may refer to the current frame or to the caller's frame.
|
||||
|
|
|
@ -3,6 +3,8 @@ int main(int argc, char **argv) {
|
|||
char a1[] = {argc, 2, 3, 4};
|
||||
char a2[] = {1, 2*argc, 3, 4};
|
||||
// Check-Common: AddressSanitizer stack-buffer-overflow
|
||||
// Check-Common: {{#0.*memcmp}}
|
||||
// Check-Common: {{#1.*main}}
|
||||
int res = memcmp(a1, a2, 4 + argc); // BOOM
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue