mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
Revert "Revert "[hwasan] Add __hwasan_handle_longjmp.""
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
This commit is contained in:
parent
75ca6be1c1
commit
37fb896572
@ -40,6 +40,13 @@ extern "C" {
|
||||
/// Set pointer tag. Previous tag is lost.
|
||||
void *__hwasan_tag_pointer(const volatile void *p, unsigned char tag);
|
||||
|
||||
// Set memory tag from the current SP address to the given address to zero.
|
||||
// This is meant to annotate longjmp and other non-local jumps.
|
||||
// This function needs to know the (almost) exact destination frame address;
|
||||
// clearing shadow for the entire thread stack like __asan_handle_no_return
|
||||
// does would cause false reports.
|
||||
void __hwasan_handle_longjmp(const void *sp_dst);
|
||||
|
||||
// Print shadow and origin for the memory range to stderr in a human-readable
|
||||
// format.
|
||||
void __hwasan_print_shadow(const volatile void *x, size_t size);
|
||||
|
@ -412,6 +412,24 @@ uptr __hwasan_tag_pointer(uptr p, u8 tag) {
|
||||
return AddTagToPointer(p, tag);
|
||||
}
|
||||
|
||||
void __hwasan_handle_longjmp(const void *sp_dst) {
|
||||
uptr dst = (uptr)sp_dst;
|
||||
// HWASan does not support tagged SP.
|
||||
CHECK(GetTagFromPointer(dst) == 0);
|
||||
|
||||
uptr sp = (uptr)__builtin_frame_address(0);
|
||||
static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
|
||||
if (dst < sp || dst - sp > kMaxExpectedCleanupSize) {
|
||||
Report(
|
||||
"WARNING: HWASan is ignoring requested __hwasan_handle_longjmp: "
|
||||
"stack top: %p; target %p; distance: %p (%zd)\n"
|
||||
"False positive error reports may follow\n",
|
||||
(void *)sp, (void *)dst, dst - sp);
|
||||
return;
|
||||
}
|
||||
TagMemory(sp, dst - sp, 0);
|
||||
}
|
||||
|
||||
static const u8 kFallbackTag = 0xBB;
|
||||
|
||||
u8 __hwasan_generate_tag() {
|
||||
|
@ -426,14 +426,27 @@ int OnExit() {
|
||||
*begin = *end = 0; \
|
||||
}
|
||||
|
||||
#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
|
||||
{ \
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \
|
||||
if (common_flags()->intercept_intrin && \
|
||||
MEM_IS_APP(GetAddressFromPointer(dst))) \
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
|
||||
return REAL(memset)(dst, v, size); \
|
||||
// AArch64 has TBI and can (and must!) pass the pointer to system memset as-is.
|
||||
// Other platforms need to remove the tag.
|
||||
#if defined(__aarch64__)
|
||||
#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
|
||||
{ \
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \
|
||||
if (common_flags()->intercept_intrin && \
|
||||
MEM_IS_APP(GetAddressFromPointer(dst))) \
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
|
||||
return REAL(memset)(dst, v, size); \
|
||||
}
|
||||
#else
|
||||
#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
|
||||
{ \
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \
|
||||
if (common_flags()->intercept_intrin && \
|
||||
MEM_IS_APP(GetAddressFromPointer(dst))) \
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
|
||||
return REAL(memset)(GetAddressFromPointer(dst), v, size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \
|
||||
offset) \
|
||||
|
@ -110,6 +110,9 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
void __hwasan_print_shadow(const void *x, uptr size);
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
void __hwasan_handle_longjmp(const void *sp_dst);
|
||||
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
u16 __sanitizer_unaligned_load16(const uu16 *p);
|
||||
|
||||
|
28
compiler-rt/test/hwasan/TestCases/longjmp.c
Normal file
28
compiler-rt/test/hwasan/TestCases/longjmp.c
Normal file
@ -0,0 +1,28 @@
|
||||
// RUN: %clang_hwasan -O0 -DNEGATIVE %s -o %t && %run %t 2>&1
|
||||
// RUN: %clang_hwasan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// REQUIRES: stable-runtime
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sanitizer/hwasan_interface.h>
|
||||
|
||||
__attribute__((noinline))
|
||||
int f(void *caller_frame) {
|
||||
char z[32] = {};
|
||||
char *volatile p = z;
|
||||
// Tag of local is never zero.
|
||||
assert(__hwasan_tag_pointer(p, 0) != p);
|
||||
#ifndef NEGATIVE
|
||||
// This will destroy shadow of "z", and the following load will crash.
|
||||
__hwasan_handle_longjmp(caller_frame);
|
||||
#endif
|
||||
return p[0];
|
||||
}
|
||||
|
||||
int main() {
|
||||
return f(__builtin_frame_address(0));
|
||||
// CHECK: READ of size 8
|
||||
// CHECK: pointer tag
|
||||
// CHECK: memory tag 0x0
|
||||
}
|
Loading…
Reference in New Issue
Block a user