diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-02-10 09:37:03 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-02-10 09:37:03 +0000 |
commit | 4429711ad9b242959dd884f9fc3ff89d5430ae99 (patch) | |
tree | 8e00f07f75739166602840cc3ae24ba730b8127d /lib | |
parent | 6c6c2a86856569b79c1da8a6e16ddcaeaadd281c (diff) |
[msan] Return EINVAL instead of crashing from mmap of an invalid address.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@201074 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/msan/lit_tests/mmap_below_shadow.cc | 16 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 13 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.cc | 1 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.h | 1 |
4 files changed, 20 insertions, 11 deletions
diff --git a/lib/msan/lit_tests/mmap_below_shadow.cc b/lib/msan/lit_tests/mmap_below_shadow.cc index 215311e61..0e94cef74 100644 --- a/lib/msan/lit_tests/mmap_below_shadow.cc +++ b/lib/msan/lit_tests/mmap_below_shadow.cc @@ -1,22 +1,26 @@ // Test mmap behavior when map address is below shadow range. -// With MAP_FIXED, we crash. +// With MAP_FIXED, we return EINVAL. // Without MAP_FIXED, we ignore the address hint and map somewhere in // application range. // RUN: %clangxx_msan -m64 -O0 -DFIXED=0 %s -o %t && %t -// RUN: %clangxx_msan -m64 -O0 -DFIXED=1 %s -o %t && not %t +// RUN: %clangxx_msan -m64 -O0 -DFIXED=1 %s -o %t && %t #include <assert.h> +#include <errno.h> #include <stdint.h> #include <sys/mman.h> int main(void) { // Hint address just below shadow. - uintptr_t hint = 0x1f0000000000ULL; + uintptr_t hint = 0x4f0000000000ULL; const uintptr_t app_start = 0x600000000000ULL; uintptr_t p = (uintptr_t)mmap( - (void *)hint, 4096, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | (FIXED ? MAP_FIXED : 0), 0, 0); - assert(p >= app_start); + (void *)hint, 4096, PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | (FIXED ? MAP_FIXED : 0), -1, 0); + if (FIXED) + assert(p == (uintptr_t)-1 && errno == EINVAL); + else + assert(p >= app_start); return 0; } diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index cb0b1a095..d68e469a4 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -42,6 +42,8 @@ static unsigned g_thread_finalize_key; // True if this is a nested interceptor. static THREADLOCAL int in_interceptor_scope; +extern "C" int *__errno_location(void); + struct InterceptorScope { InterceptorScope() { ++in_interceptor_scope; } ~InterceptorScope() { --in_interceptor_scope; } @@ -796,9 +798,12 @@ INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags, int fd, OFF_T offset) { ENSURE_MSAN_INITED(); if (addr && !MEM_IS_APP(addr)) { - CHECK(!(flags & map_fixed) && - "mmap(..., MAP_FIXED) outside of application memory range."); - addr = 0; + if (flags & map_fixed) { + *__errno_location() = errno_EINVAL; + return (void *)-1; + } else { + addr = 0; + } } void *res = REAL(mmap)(addr, length, prot, flags, fd, offset); if (res != (void*)-1) @@ -1171,8 +1176,6 @@ int OnExit() { } // namespace __msan -extern "C" int *__errno_location(void); - // A version of CHECK_UNPOISONED using a saved scope value. Used in common // interceptors. #define CHECK_UNPOISONED_CTX(ctx, x, n) \ diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 6ba9704a4..83a9d7672 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -769,6 +769,7 @@ namespace __sanitizer { unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL; #endif + const int errno_EINVAL = EINVAL; // EOWNERDEAD is not present in some older platforms. #if defined(EOWNERDEAD) extern const int errno_EOWNERDEAD = EOWNERDEAD; diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index a726a702c..744e180d5 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -1048,6 +1048,7 @@ namespace __sanitizer { extern unsigned IOCTL_TIOCSSERIAL; #endif + extern const int errno_EINVAL; extern const int errno_EOWNERDEAD; } // namespace __sanitizer |