Index: lib/esan/esan_interceptors.cpp =================================================================== --- lib/esan/esan_interceptors.cpp +++ lib/esan/esan_interceptors.cpp @@ -175,6 +175,15 @@ 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 @@ } //===----------------------------------------------------------------------===// -// 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 @@ 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; Index: lib/hwasan/hwasan_interceptors.cc =================================================================== --- lib/hwasan/hwasan_interceptors.cc +++ lib/hwasan/hwasan_interceptors.cc @@ -264,28 +264,9 @@ 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 +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 @@ 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 @@ 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 @@ InitializeCommonInterceptors(); InitializeSignalInterceptors(); - INTERCEPT_FUNCTION(mmap); - HWASAN_MAYBE_INTERCEPT_MMAP64; INTERCEPT_FUNCTION(posix_memalign); HWASAN_MAYBE_INTERCEPT_MEMALIGN; INTERCEPT_FUNCTION(__libc_memalign); Index: lib/msan/msan_interceptors.cc =================================================================== --- lib/msan/msan_interceptors.cc +++ lib/msan/msan_interceptors.cc @@ -971,29 +971,9 @@ } } -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 +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 @@ 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 @@ __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 @@ InitializeCommonInterceptors(); InitializeSignalInterceptors(); - INTERCEPT_FUNCTION(mmap); - MSAN_MAYBE_INTERCEPT_MMAP64; INTERCEPT_FUNCTION(posix_memalign); MSAN_MAYBE_INTERCEPT_MEMALIGN; MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN; Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ 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 @@ } #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 @@ #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 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; Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ 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) Index: lib/tsan/rtl/tsan_interceptors.cc =================================================================== --- lib/tsan/rtl/tsan_interceptors.cc +++ lib/tsan/rtl/tsan_interceptors.cc @@ -760,35 +760,14 @@ 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 +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 @@ } 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 @@ 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 @@ 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); Index: test/sanitizer_common/TestCases/Linux/mmap64_test.c =================================================================== --- test/sanitizer_common/TestCases/Linux/mmap64_test.c +++ test/sanitizer_common/TestCases/Linux/mmap64_test.c @@ -0,0 +1,13 @@ +// RUN: %clang %s -o %t && %run %t + +#define _LARGEFILE64_SOURCE 1 + +#include +#include + +int main() { + char *buf = (char *)mmap64(0, 100000, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(buf); + munmap(buf, 100000); +} Index: test/sanitizer_common/TestCases/Posix/mmap_test.c =================================================================== --- test/sanitizer_common/TestCases/Posix/mmap_test.c +++ test/sanitizer_common/TestCases/Posix/mmap_test.c @@ -0,0 +1,11 @@ +// RUN: %clang %s -o %t && %run %t + +#include +#include + +int main() { + char *buf = (char *)mmap(0, 100000, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(buf); + munmap(buf, 100000); +}