diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -15,18 +15,46 @@ //===----------------------------------------------------------------------===// #include "hwasan.h" +#include "hwasan_allocator.h" #include "hwasan_checks.h" #include "hwasan_platform_interceptors.h" #include "hwasan_thread.h" #include "hwasan_thread_list.h" #include "interception/interception.h" +#include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_stackdepot.h" + #if !SANITIZER_FUCHSIA using namespace __hwasan; +# if !SANITIZER_APPLE +# define HWASAN_INTERCEPT_FUNC(name) \ + do { \ + if (!INTERCEPT_FUNCTION(name)) \ + VReport(1, "HWAddressSanitizer: failed to intercept '%s'\n", #name); \ + } while (0) +# define HWASAN_INTERCEPT_FUNC_VER(name, ver) \ + do { \ + if (!INTERCEPT_FUNCTION_VER(name, ver)) \ + VReport(1, "HWAddressSanitizer: failed to intercept '%s@@%s'\n", \ + #name, ver); \ + } while (0) +# define HWASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \ + do { \ + if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \ + VReport( \ + 1, "HWAddressSanitizer: failed to intercept '%s@@%s' or '%s'\n", \ + #name, ver, #name); \ + } while (0) + +# else +// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. +# define HWASAN_INTERCEPT_FUNC(name) +# endif // SANITIZER_APPLE + # if HWASAN_WITH_INTERCEPTORS # define COMMON_SYSCALL_PRE_READ_RANGE(p, s) __hwasan_loadN((uptr)p, (uptr)s) @@ -133,9 +161,61 @@ do { \ } while (false) -#define COMMON_INTERCEPT_FUNCTION(name) \ - do { \ - (void)(name); \ +#define COMMON_INTERCEPT_FUNCTION(name) HWASAN_INTERCEPT_FUNC(name) + +#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!hwasan_inited) + +// The main purpose of the mmap interceptor is to prevent the user from +// allocating on top of shadow pages. +// +// For compatibility, it does not tag pointers, nor does it allow +// MAP_FIXED in combination with a tagged pointer. (Since mmap itself +// will not return a tagged pointer, the tagged pointer must have come +// from elsewhere, such as the secondary allocator, which makes it a +// very odd usecase.) +template +static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length, + int prot, int flags, int fd, OFF64_T offset) { + if(addr) { + if (flags & map_fixed) { + tag_t tag = GetTagFromPointer(reinterpret_cast(addr)); + CHECK(tag == 0); + } + + addr = UntagPtr(addr); + } + SIZE_T rounded_length = RoundUpTo(length, GetPageSize()); + void *end_addr = (char *)addr + (rounded_length - 1); + if (addr && (!MemIsApp(reinterpret_cast(addr)) || !MemIsApp(reinterpret_cast(end_addr)))) { + // User requested an address that is incompatible with HWASan's + // memory layout. Use a different address if allowed, else fail. + if (flags & map_fixed) { + errno = errno_EINVAL; + return (void *)-1; + } else { + addr = nullptr; + } + } + void *res = real_mmap(addr, length, prot, flags, fd, offset); + if (res != (void *)-1) { + void *end_res = (char *)res + (rounded_length - 1); + if (!MemIsApp(reinterpret_cast(res)) || !MemIsApp(reinterpret_cast(end_res))) { + // Application has attempted to map more memory than is supported by + // HWASan. Act as if we ran out of memory. + internal_munmap(res, length); + errno = errno_ENOMEM; + return (void *)-1; + } + } + + return res; +} + +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \ + offset) \ + do { \ + (void)(ctx); \ + return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \ } while (false) #include "sanitizer_common/sanitizer_common_interceptors.inc" @@ -414,7 +494,8 @@ static int inited = 0; CHECK_EQ(inited, 0); - (void)(InitializeCommonInterceptors); + InitializeCommonInterceptors(); + (void)(read_iovec); (void)(write_iovec); diff --git a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h --- a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h +++ b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h @@ -728,8 +728,8 @@ #undef SANITIZER_INTERCEPT_GETLOADAVG #define SANITIZER_INTERCEPT_GETLOADAVG 0 -#undef SANITIZER_INTERCEPT_MMAP -#define SANITIZER_INTERCEPT_MMAP 0 +// #undef SANITIZER_INTERCEPT_MMAP +// #define SANITIZER_INTERCEPT_MMAP 0 #undef SANITIZER_INTERCEPT_MMAP64 #define SANITIZER_INTERCEPT_MMAP64 0 diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_write_exec.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_write_exec.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_write_exec.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_write_exec.cpp @@ -7,9 +7,6 @@ // TODO: Fix option on Android, it hangs there for unknown reasons. // XFAIL: android -// FIXME: Implement. -// XFAIL: hwasan - #if defined(__APPLE__) #include #endif