Index: lib/hwasan/hwasan_checks.h =================================================================== --- lib/hwasan/hwasan_checks.h +++ lib/hwasan/hwasan_checks.h @@ -15,6 +15,7 @@ #define HWASAN_CHECKS_H #include "hwasan_mapping.h" +#include "sanitizer_common/sanitizer_common.h" namespace __hwasan { template @@ -23,8 +24,7 @@ (void)p; // 0x900 is added to do not interfere with the kernel use of lower values of // brk immediate. - // FIXME: Add a constraint to put the pointer into x0, the same as x86 branch. - asm("brk %0\n\t" ::"n"(0x900 + X)); + asm("ldr X0, %0\nbrk %1\n\t" ::"g"(p), "n"(0x900 + X)); #elif defined(__x86_64__) // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes // total. The pointer is passed via rdi. @@ -42,6 +42,26 @@ // __builtin_unreachable(); } +// Version with access size which is not power of 2 +template +__attribute__((always_inline)) static void SigTrap(uptr p, uptr size) { +#if defined(__aarch64__) + asm("ldr X0, %0\n" + "ldr X1, %1\n" + "brk %2\n\t" ::"g"(p), + "g"(size), "n"(0x900 + X)); +#elif defined(__x86_64__) + // Size is stored in rsi. + asm volatile( + "int3\n" + "nopl %c0(%%rax)\n" ::"n"(0x40 + X), + "D"(p), "S"(size)); +#else + __builtin_trap(); +#endif + // __builtin_unreachable(); +} + enum class ErrorAction { Abort, Recover }; enum class AccessType { Load, Store }; @@ -67,13 +87,17 @@ uptr ptr_raw = p & ~kAddressTagMask; tag_t *shadow_first = (tag_t *)MemToShadow(ptr_raw); tag_t *shadow_last = (tag_t *)MemToShadow(ptr_raw + sz - 1); - for (tag_t *t = shadow_first; t <= shadow_last; ++t) + for (tag_t *t = shadow_first; t <= shadow_last; ++t) { if (UNLIKELY(ptr_tag != *t)) { SigTrap<0x20 * (EA == ErrorAction::Recover) + - 0x10 * (AT == AccessType::Store) + 0xf>(p); + 0x10 * (AT == AccessType::Store) + 0xf>(p, sz); if (EA == ErrorAction::Abort) __builtin_unreachable(); } + uptr next_p = RoundUpTo(p + 1, 1 << kShadowScale); + sz -= (next_p - p); + p = next_p; + } } } // end namespace __hwasan Index: test/hwasan/TestCases/mem-intrinsics.c =================================================================== --- test/hwasan/TestCases/mem-intrinsics.c +++ test/hwasan/TestCases/mem-intrinsics.c @@ -21,15 +21,15 @@ #endif write(STDOUT_FILENO, "recovered\n", 10); // WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address - // WRITE: WRITE {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) + // WRITE: WRITE of size 16 at {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) // WRITE: Memory tags around the buggy address (one tag corresponds to 16 bytes): - // WRITE: =>{{.*}}[[MEM_TAG]] + // WRITE: =>{{.*}}[[PTR_TAG]]{{[[:space:]]\[}}[[MEM_TAG]] // WRITE-NOT: recovered // READ: ERROR: HWAddressSanitizer: tag-mismatch on address - // READ: READ {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) + // READ: READ of size 16 at {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) // READ: Memory tags around the buggy address (one tag corresponds to 16 bytes): - // READ: =>{{.*}}[[MEM_TAG]] + // READ: =>{{.*}}[[PTR_TAG]]{{[[:space:]]\[}}[[MEM_TAG]] // READ-NOT: recovered // RECOVER: recovered