diff options
author | Vitaly Buka <vitalybuka@google.com> | 2018-03-07 00:13:54 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2018-03-07 00:13:54 +0000 |
commit | 78457e68f4363b5dee3007d186618133f227058c (patch) | |
tree | 453cb8aee35d2f4a1532b000f6a06add94916f10 | |
parent | 9f0c36e7a907b1ca893060c0602d3a71f50446ce (diff) | |
download | bcm5719-llvm-78457e68f4363b5dee3007d186618133f227058c.tar.gz bcm5719-llvm-78457e68f4363b5dee3007d186618133f227058c.zip |
[sanitizer] Move mmap interceptors into sanitizer_common
Reviewers: devnexen, krytarowski, eugenis
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D44125
llvm-svn: 326851
8 files changed, 108 insertions, 137 deletions
diff --git a/compiler-rt/lib/esan/esan_interceptors.cpp b/compiler-rt/lib/esan/esan_interceptors.cpp index 4e93a72ae90..da0bf4df5ae 100644 --- a/compiler-rt/lib/esan/esan_interceptors.cpp +++ b/compiler-rt/lib/esan/esan_interceptors.cpp @@ -175,6 +175,15 @@ DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) do { \ } while (false) +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ + off) \ + do { \ + if (!fixMmapAddr(&addr, sz, flags)) \ + return (void *)-1; \ + void *result = REAL(mmap)(addr, sz, prot, flags, fd, off); \ + return (void *)checkMmapResult((uptr)result, sz); \ + } while (false) + #include "sanitizer_common/sanitizer_common_interceptors.inc" //===----------------------------------------------------------------------===// @@ -322,44 +331,6 @@ INTERCEPTOR(int, rmdir, char *path) { } //===----------------------------------------------------------------------===// -// Shadow-related interceptors -//===----------------------------------------------------------------------===// - -// These are candidates for sharing with all sanitizers if shadow memory -// support is also standardized. - -INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, - int fd, OFF_T off) { - if (UNLIKELY(REAL(mmap) == nullptr)) { - // With esan init during interceptor init and a static libc preventing - // our early-calloc from triggering, we can end up here before our - // REAL pointer is set up. - return (void *)internal_mmap(addr, sz, prot, flags, fd, off); - } - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); - if (!fixMmapAddr(&addr, sz, flags)) - return (void *)-1; - void *result = REAL(mmap)(addr, sz, prot, flags, fd, off); - return (void *)checkMmapResult((uptr)result, sz); -} - -#if SANITIZER_LINUX -INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, - int fd, OFF64_T off) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); - if (!fixMmapAddr(&addr, sz, flags)) - return (void *)-1; - void *result = REAL(mmap64)(addr, sz, prot, flags, fd, off); - return (void *)checkMmapResult((uptr)result, sz); -} -#define ESAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64) -#else -#define ESAN_MAYBE_INTERCEPT_MMAP64 -#endif - -//===----------------------------------------------------------------------===// // Signal-related interceptors //===----------------------------------------------------------------------===// @@ -527,9 +498,6 @@ void initializeInterceptors() { INTERCEPT_FUNCTION(puts); INTERCEPT_FUNCTION(rmdir); - INTERCEPT_FUNCTION(mmap); - ESAN_MAYBE_INTERCEPT_MMAP64; - ESAN_MAYBE_INTERCEPT_SIGNAL; ESAN_MAYBE_INTERCEPT_SIGACTION; ESAN_MAYBE_INTERCEPT_SIGPROCMASK; diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cc b/compiler-rt/lib/hwasan/hwasan_interceptors.cc index a026b8011be..db66c1b569c 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cc +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cc @@ -264,28 +264,9 @@ INTERCEPTOR(void *, malloc, SIZE_T size) { return hwasan_malloc(size, &stack); } - -INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags, - int fd, OFF_T offset) { - if (hwasan_init_is_running) - return REAL(mmap)(addr, length, prot, flags, fd, offset); - ENSURE_HWASAN_INITED(); - if (addr && !MEM_IS_APP(addr)) { - if (flags & map_fixed) { - errno = errno_EINVAL; - return (void *)-1; - } else { - addr = nullptr; - } - } - void *res = REAL(mmap)(addr, length, prot, flags, fd, offset); - return res; -} - -#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD -INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, - int fd, OFF64_T offset) { - ENSURE_HWASAN_INITED(); +template <class Mmap> +static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T sz, int prot, + int flags, int fd, OFF64_T off) { if (addr && !MEM_IS_APP(addr)) { if (flags & map_fixed) { errno = errno_EINVAL; @@ -294,13 +275,8 @@ INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, addr = nullptr; } } - void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset); - return res; + return real_mmap(addr, length, prot, flags, fd, offset); } -#define HWASAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64) -#else -#define HWASAN_MAYBE_INTERCEPT_MMAP64 -#endif extern "C" int pthread_attr_init(void *attr); extern "C" int pthread_attr_destroy(void *attr); @@ -436,6 +412,13 @@ int OnExit() { return REAL(memset)(dst, v, size); \ } +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \ + offset) \ + do { \ + return mmap_interceptor(REAL(mmap), addr, length, prot, flags, fd, \ + offset); \ + } while (false) + #include "sanitizer_common/sanitizer_platform_interceptors.h" #include "sanitizer_common/sanitizer_common_interceptors.inc" #include "sanitizer_common/sanitizer_signal_interceptors.inc" @@ -469,8 +452,6 @@ void InitializeInterceptors() { InitializeCommonInterceptors(); InitializeSignalInterceptors(); - INTERCEPT_FUNCTION(mmap); - HWASAN_MAYBE_INTERCEPT_MMAP64; INTERCEPT_FUNCTION(posix_memalign); HWASAN_MAYBE_INTERCEPT_MEMALIGN; INTERCEPT_FUNCTION(__libc_memalign); diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 1d33b5d2721..dce9e8afaa6 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -971,29 +971,9 @@ void __sanitizer_dtor_callback(const void *data, uptr size) { } } -INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags, - int fd, OFF_T offset) { - if (msan_init_is_running) - return REAL(mmap)(addr, length, prot, flags, fd, offset); - ENSURE_MSAN_INITED(); - if (addr && !MEM_IS_APP(addr)) { - 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) - __msan_unpoison(res, RoundUpTo(length, GetPageSize())); - return res; -} - -#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD -INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, - int fd, OFF64_T offset) { - ENSURE_MSAN_INITED(); +template <class Mmap> +static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length, + int prot, int flags, int fd, OFF64_T offset) { if (addr && !MEM_IS_APP(addr)) { if (flags & map_fixed) { errno = errno_EINVAL; @@ -1002,15 +982,10 @@ INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, addr = nullptr; } } - void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset); - if (res != (void*)-1) - __msan_unpoison(res, RoundUpTo(length, GetPageSize())); + void *res = real_mmap(addr, length, prot, flags, fd, offset); + if (res != (void *)-1) __msan_unpoison(res, RoundUpTo(length, GetPageSize())); return res; } -#define MSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64) -#else -#define MSAN_MAYBE_INTERCEPT_MMAP64 -#endif INTERCEPTOR(int, getrusage, int who, void *usage) { ENSURE_MSAN_INITED(); @@ -1329,6 +1304,12 @@ int OnExit() { __msan_unpoison(to + size, 1); \ } while (false) +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \ + offset) \ + do { \ + return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \ + } while (false) + #include "sanitizer_common/sanitizer_platform_interceptors.h" #include "sanitizer_common/sanitizer_common_interceptors.inc" @@ -1577,8 +1558,6 @@ void InitializeInterceptors() { InitializeCommonInterceptors(); InitializeSignalInterceptors(); - INTERCEPT_FUNCTION(mmap); - MSAN_MAYBE_INTERCEPT_MMAP64; INTERCEPT_FUNCTION(posix_memalign); MSAN_MAYBE_INTERCEPT_MEMALIGN; MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index dac3cfb4ad8..eddc54e6f2b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -34,6 +34,7 @@ // COMMON_INTERCEPTOR_MEMSET_IMPL // COMMON_INTERCEPTOR_MEMMOVE_IMPL // COMMON_INTERCEPTOR_MEMCPY_IMPL +// COMMON_INTERCEPTOR_MMAP_IMPL // COMMON_INTERCEPTOR_COPY_STRING // COMMON_INTERCEPTOR_STRNDUP_IMPL //===----------------------------------------------------------------------===// @@ -267,6 +268,12 @@ bool PlatformHasDifferentMemcpyAndMemmove(); } #endif +#ifndef COMMON_INTERCEPTOR_MMAP_IMPL +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ + off) \ + { return REAL(mmap)(addr, sz, prot, flags, fd, off); } +#endif + #ifndef COMMON_INTERCEPTOR_COPY_STRING #define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {} #endif @@ -6792,6 +6799,34 @@ INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) { #define INIT_STRLCPY #endif +#if SANITIZER_INTERCEPT_MMAP +INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd, + OFF_T off) { + void *ctx; + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return (void *)internal_mmap(addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off); +} +#define INIT_MMAP COMMON_INTERCEPT_FUNCTION(mmap); +#else +#define INIT_MMAP +#endif + +#if SANITIZER_INTERCEPT_MMAP64 +INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd, + OFF_T off) { + void *ctx; + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return (void *)internal_mmap(addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off); +} +#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64); +#else +#define INIT_MMAP64 +#endif + #if SANITIZER_INTERCEPT_DEVNAME INTERCEPTOR(char *, devname, u64 dev, u32 type) { void *ctx; @@ -7029,6 +7064,8 @@ static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); + INIT_MMAP; + INIT_MMAP64; INIT_TEXTDOMAIN; INIT_STRLEN; INIT_STRNLEN; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index e44eb568e41..2147766d92d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -420,6 +420,8 @@ #define SANITIZER_INTERCEPT_GETLOADAVG \ (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD) +#define SANITIZER_INTERCEPT_MMAP (SI_POSIX && !SI_FREEBSD && !SI_NETBSD) +#define SANITIZER_INTERCEPT_MMAP64 SI_POSIX #define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) #define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 16a725e6196..e032062346d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -760,35 +760,14 @@ static bool fix_mmap_addr(void **addr, long_t sz, int flags) { return true; } -TSAN_INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, - int fd, OFF_T off) { - SCOPED_TSAN_INTERCEPTOR(mmap, addr, sz, prot, flags, fd, off); - if (!fix_mmap_addr(&addr, sz, flags)) - return MAP_FAILED; - void *res = REAL(mmap)(addr, sz, prot, flags, fd, off); +template <class Mmap> +static void *mmap_interceptor(ThreadState *thr, uptr pc, Mmap real_mmap, + void *addr, SIZE_T sz, int prot, int flags, + int fd, OFF64_T off) { + if (!fix_mmap_addr(&addr, sz, flags)) return MAP_FAILED; + void *res = real_mmap(addr, sz, prot, flags, fd, off); if (res != MAP_FAILED) { - if (fd > 0) - FdAccess(thr, pc, fd); - - if (thr->ignore_reads_and_writes == 0) - MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); - else - MemoryResetRange(thr, pc, (uptr)res, sz); - } - return res; -} - -#if SANITIZER_LINUX -TSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, - int fd, OFF64_T off) { - SCOPED_TSAN_INTERCEPTOR(mmap64, addr, sz, prot, flags, fd, off); - if (!fix_mmap_addr(&addr, sz, flags)) - return MAP_FAILED; - void *res = REAL(mmap64)(addr, sz, prot, flags, fd, off); - if (res != MAP_FAILED) { - if (fd > 0) - FdAccess(thr, pc, fd); - + if (fd > 0) FdAccess(thr, pc, fd); if (thr->ignore_reads_and_writes == 0) MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); else @@ -796,10 +775,6 @@ TSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, } return res; } -#define TSAN_MAYBE_INTERCEPT_MMAP64 TSAN_INTERCEPT(mmap64) -#else -#define TSAN_MAYBE_INTERCEPT_MMAP64 -#endif TSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) { SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz); @@ -2311,6 +2286,13 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, MutexInvalidAccess(((TsanInterceptorContext *)ctx)->thr, \ ((TsanInterceptorContext *)ctx)->pc, (uptr)m) +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ + off) \ + do { \ + return mmap_interceptor(thr, pc, REAL(mmap), addr, sz, prot, flags, fd, \ + off); \ + } while (false) + #if !SANITIZER_MAC #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \ HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \ @@ -2635,8 +2617,6 @@ void InitializeInterceptors() { TSAN_INTERCEPT(realloc); TSAN_INTERCEPT(free); TSAN_INTERCEPT(cfree); - TSAN_INTERCEPT(mmap); - TSAN_MAYBE_INTERCEPT_MMAP64; TSAN_INTERCEPT(munmap); TSAN_MAYBE_INTERCEPT_MEMALIGN; TSAN_INTERCEPT(valloc); diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/mmap64_test.c b/compiler-rt/test/sanitizer_common/TestCases/Linux/mmap64_test.c new file mode 100644 index 00000000000..f4c009d846a --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/mmap64_test.c @@ -0,0 +1,13 @@ +// RUN: %clang %s -o %t && %run %t + +#define _LARGEFILE64_SOURCE 1 + +#include <assert.h> +#include <sys/mman.h> + +int main() { + char *buf = (char *)mmap64(0, 100000, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(buf); + munmap(buf, 100000); +} diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_test.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_test.c new file mode 100644 index 00000000000..3c272f95a01 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/mmap_test.c @@ -0,0 +1,11 @@ +// RUN: %clang %s -o %t && %run %t + +#include <assert.h> +#include <sys/mman.h> + +int main() { + char *buf = (char *)mmap(0, 100000, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(buf); + munmap(buf, 100000); +} |