diff --git a/compiler-rt/lib/asan/asan_descriptions.h b/compiler-rt/lib/asan/asan_descriptions.h --- a/compiler-rt/lib/asan/asan_descriptions.h +++ b/compiler-rt/lib/asan/asan_descriptions.h @@ -146,6 +146,13 @@ bool GetStackAddressInformation(uptr addr, uptr access_size, StackAddressDescription *descr); +struct WildAddressDescription { + uptr addr; + uptr access_size; + + void Print() const; +}; + struct GlobalAddressDescription { uptr addr; // Assume address is close to at most four globals. @@ -193,7 +200,7 @@ HeapAddressDescription heap; StackAddressDescription stack; GlobalAddressDescription global; - uptr addr; + WildAddressDescription wild; }; }; @@ -211,7 +218,7 @@ uptr Address() const { switch (data.kind) { case kAddressKindWild: - return data.addr; + return data.wild.addr; case kAddressKindShadow: return data.shadow.addr; case kAddressKindHeap: @@ -226,7 +233,7 @@ void Print(const char *bug_descr = nullptr) const { switch (data.kind) { case kAddressKindWild: - Printf("Address %p is a wild pointer.\n", data.addr); + data.wild.Print(); return; case kAddressKindShadow: return data.shadow.Print(); diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp --- a/compiler-rt/lib/asan/asan_descriptions.cpp +++ b/compiler-rt/lib/asan/asan_descriptions.cpp @@ -77,7 +77,6 @@ } else if (AddrIsInLowShadow(addr)) { *shadow_kind = kShadowKindLow; } else { - CHECK(0 && "Address is not in memory and not in shadow?"); return false; } return true; @@ -464,7 +463,13 @@ return; } data.kind = kAddressKindWild; - addr = 0; + data.wild.addr = addr; + data.wild.access_size = access_size; +} + +void WildAddressDescription::Print() const { + Printf("Address %p is a wild pointer - associated offset/access-size = %p.\n", + addr, access_size); } void PrintAddressDescription(uptr addr, uptr access_size, diff --git a/compiler-rt/test/asan/TestCases/wild_pointer.cpp b/compiler-rt/test/asan/TestCases/wild_pointer.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/wild_pointer.cpp @@ -0,0 +1,44 @@ +// Needs -m64 because the tested address is too large for m32 +// RUN: %clangxx_asan %s -o %t -m64 +// RUN: not %run %t 2>&1 | FileCheck %s + +#include + +#include +#include + +// Copied from sanitizer_common/print_address.h +//#include "../../sanitizer_common/print_address.h" +// Not sure why inclusion does not work??? +void print_address(const char *str, int n, ...) { + fprintf(stderr, "%s", str); + va_list ap; + va_start(ap, n); + while (n--) { + void *p = va_arg(ap, void *); +#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ + defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) + // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not + // match to the format used in the diagnotic message. + fprintf(stderr, "0x%012lx ", (unsigned long)p); +#elif defined(__i386__) || defined(__arm__) + fprintf(stderr, "0x%08lx ", (unsigned long)p); +#elif defined(__mips64) + fprintf(stderr, "0x%010lx ", (unsigned long)p); +#endif + } + fprintf(stderr, "\n"); +} + +int main() { + char *p = new char; + char *dest = new char; + const size_t offset = 0x4567890123456789; + print_address("Expected bad addr: ", 1, p + offset); + memmove(dest, p, offset); + return 0; +} + +// CHECK: Expected bad addr: [[ADDR:0x[0-9,a-f]+]] +// CHECK: AddressSanitizer: unknown-crash on address [[ADDR]] +// CHECK: Address [[ADDR]] is a wild pointer - associated offset/access-size = 0x4567890123456789.