Index: compiler-rt/lib/hwasan/hwasan.cc =================================================================== --- compiler-rt/lib/hwasan/hwasan.cc +++ compiler-rt/lib/hwasan/hwasan.cc @@ -88,6 +88,8 @@ cf.check_printf = false; cf.intercept_tls_get_addr = true; cf.exitcode = 99; + // 8 shadow pages ~~ 512kB, small enough to cover common stack sizes. + cf.clear_shadow_mmap_threshold = 4096 * (SANITIZER_ANDROID ? 2 : 8); // Sigtrap is used in error reporting. cf.handle_sigtrap = kHandleSignalExclusive; Index: compiler-rt/lib/hwasan/hwasan_poisoning.cc =================================================================== --- compiler-rt/lib/hwasan/hwasan_poisoning.cc +++ compiler-rt/lib/hwasan/hwasan_poisoning.cc @@ -24,7 +24,24 @@ CHECK(IsAligned(size, kShadowAlignment)); uptr shadow_start = MemToShadow(p); uptr shadow_size = MemToShadowSize(size); - internal_memset((void *)shadow_start, tag, shadow_size); + + uptr page_size = GetPageSizeCached(); + uptr page_start = RoundUpTo(shadow_start, page_size); + uptr page_end = RoundDownTo(shadow_start + shadow_size, page_size); + uptr threshold = common_flags()->clear_shadow_mmap_threshold; + if (SANITIZER_LINUX && + UNLIKELY(page_end >= page_start + threshold && tag == 0)) { + if (page_start > shadow_start) + internal_memset((void *)shadow_start, tag, page_start - shadow_start); + if (shadow_start + shadow_size > page_end) + internal_memset((void *)page_end, tag, + shadow_start + shadow_size - page_end); + // For an anonymous private mapping MADV_DONTNEED will return a zero page on + // Linux. + ReleaseMemoryPagesToOS(page_start, page_end); + } else { + internal_memset((void *)shadow_start, tag, shadow_size); + } return AddTagToPointer(p, tag); }