diff options
Diffstat (limited to 'compiler-rt/lib/msan')
-rw-r--r-- | compiler-rt/lib/msan/msan.cpp | 43 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan.h | 14 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_allocator.cpp | 14 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_interceptors.cpp | 44 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_interface_internal.h | 6 | ||||
-rw-r--r-- | compiler-rt/lib/msan/msan_origin.h | 2 |
6 files changed, 88 insertions, 35 deletions
diff --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp index 7095ee1bf20f..9afc7b026a8e 100644 --- a/compiler-rt/lib/msan/msan.cpp +++ b/compiler-rt/lib/msan/msan.cpp @@ -380,6 +380,28 @@ void __msan_warning_noreturn() { Die(); } +void __msan_warning_with_origin(u32 origin) { + GET_CALLER_PC_BP_SP; + (void)sp; + PrintWarningWithOrigin(pc, bp, origin); + if (__msan::flags()->halt_on_error) { + if (__msan::flags()->print_stats) + ReportStats(); + Printf("Exiting\n"); + Die(); + } +} + +void __msan_warning_with_origin_noreturn(u32 origin) { + GET_CALLER_PC_BP_SP; + (void)sp; + PrintWarningWithOrigin(pc, bp, origin); + if (__msan::flags()->print_stats) + ReportStats(); + Printf("Exiting\n"); + Die(); +} + static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, @@ -617,34 +639,41 @@ u32 __msan_get_umr_origin() { } u16 __sanitizer_unaligned_load16(const uu16 *p) { - *(uu16 *)&__msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p); + internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p), + sizeof(uu16)); if (__msan_get_track_origins()) __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); return *p; } u32 __sanitizer_unaligned_load32(const uu32 *p) { - *(uu32 *)&__msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p); + internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p), + sizeof(uu32)); if (__msan_get_track_origins()) __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); return *p; } u64 __sanitizer_unaligned_load64(const uu64 *p) { - __msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p); + internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p), + sizeof(uu64)); if (__msan_get_track_origins()) __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); return *p; } void __sanitizer_unaligned_store16(uu16 *p, u16 x) { - u16 s = *(uu16 *)&__msan_param_tls[1]; - *(uu16 *)MEM_TO_SHADOW((uptr)p) = s; + static_assert(sizeof(uu16) == sizeof(u16), "incompatible types"); + u16 s; + internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu16)); + internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu16)); if (s && __msan_get_track_origins()) if (uu32 o = __msan_param_origin_tls[2]) SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); *p = x; } void __sanitizer_unaligned_store32(uu32 *p, u32 x) { - u32 s = *(uu32 *)&__msan_param_tls[1]; - *(uu32 *)MEM_TO_SHADOW((uptr)p) = s; + static_assert(sizeof(uu32) == sizeof(u32), "incompatible types"); + u32 s; + internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu32)); + internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu32)); if (s && __msan_get_track_origins()) if (uu32 o = __msan_param_origin_tls[2]) SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index 12aeaa43519a..e794c7c15f89 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -181,6 +181,20 @@ const MappingDesc kMemoryLayout[] = { #define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL) #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL) +#elif SANITIZER_LINUX && SANITIZER_S390_64 +const MappingDesc kMemoryLayout[] = { + {0x000000000000ULL, 0x040000000000ULL, MappingDesc::APP, "low memory"}, + {0x040000000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"}, + {0x080000000000ULL, 0x180000000000ULL, MappingDesc::SHADOW, "shadow"}, + {0x180000000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"}, + {0x1C0000000000ULL, 0x2C0000000000ULL, MappingDesc::ORIGIN, "origin"}, + {0x2C0000000000ULL, 0x440000000000ULL, MappingDesc::INVALID, "invalid"}, + {0x440000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}}; + +#define MEM_TO_SHADOW(mem) \ + ((((uptr)(mem)) & ~0xC00000000000ULL) + 0x080000000000ULL) +#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL) + #elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64 // Low memory: main binary, MAP_32BIT mappings and modules diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index a08c1a00d2e5..68be794106b1 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -93,6 +93,20 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name. }; typedef SizeClassAllocator64<AP64> PrimaryAllocator; +#elif defined(__s390x__) +static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G + +struct AP64 { // Allocator64 parameters. Deliberately using a short name. + static const uptr kSpaceBeg = 0x440000000000; + static const uptr kSpaceSize = 0x020000000000; // 2T. + static const uptr kMetadataSize = sizeof(Metadata); + typedef DefaultSizeClassMap SizeClassMap; + typedef MsanMapUnmapCallback MapUnmapCallback; + static const uptr kFlags = 0; + using AddressSpaceView = LocalAddressSpaceView; +}; + +typedef SizeClassAllocator64<AP64> PrimaryAllocator; #elif defined(__aarch64__) static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index 1c6956eca0f6..6459c7a593eb 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -824,30 +824,6 @@ INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit, #define MSAN_MAYBE_INTERCEPT_PRLIMIT64 #endif -#if SANITIZER_FREEBSD -// FreeBSD's <sys/utsname.h> define uname() as -// static __inline int uname(struct utsname *name) { -// return __xuname(SYS_NMLN, (void*)name); -// } -INTERCEPTOR(int, __xuname, int size, void *utsname) { - ENSURE_MSAN_INITED(); - int res = REAL(__xuname)(size, utsname); - if (!res) - __msan_unpoison(utsname, __sanitizer::struct_utsname_sz); - return res; -} -#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname) -#else -INTERCEPTOR(int, uname, struct utsname *utsname) { - ENSURE_MSAN_INITED(); - int res = REAL(uname)(utsname); - if (!res) - __msan_unpoison(utsname, __sanitizer::struct_utsname_sz); - return res; -} -#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname) -#endif - INTERCEPTOR(int, gethostname, char *name, SIZE_T len) { ENSURE_MSAN_INITED(); int res = REAL(gethostname)(name, len); @@ -953,7 +929,9 @@ void __sanitizer_dtor_callback(const void *data, uptr size) { 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)) { + SIZE_T rounded_length = RoundUpTo(length, GetPageSize()); + void *end_addr = (char *)addr + (rounded_length - 1); + if (addr && (!MEM_IS_APP(addr) || !MEM_IS_APP(end_addr))) { if (flags & map_fixed) { errno = errno_EINVAL; return (void *)-1; @@ -962,7 +940,18 @@ static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length, } } void *res = real_mmap(addr, length, prot, flags, fd, offset); - if (res != (void *)-1) __msan_unpoison(res, RoundUpTo(length, GetPageSize())); + if (res != (void *)-1) { + void *end_res = (char *)res + (rounded_length - 1); + if (MEM_IS_APP(res) && MEM_IS_APP(end_res)) { + __msan_unpoison(res, rounded_length); + } else { + // Application has attempted to map more memory than is supported by + // MSAN. Act as if we ran out of memory. + internal_munmap(res, length); + errno = errno_ENOMEM; + return (void *)-1; + } + } return res; } @@ -1315,6 +1304,8 @@ int OnExit() { ForEachMappedRegion(map, __msan_unpoison); \ } while (false) +#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!msan_inited) + #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \ if (MsanThread *t = GetCurrentThread()) { \ *begin = t->tls_begin(); \ @@ -1692,7 +1683,6 @@ void InitializeInterceptors() { MSAN_MAYBE_INTERCEPT_GETRLIMIT64; MSAN_MAYBE_INTERCEPT_PRLIMIT; MSAN_MAYBE_INTERCEPT_PRLIMIT64; - MSAN_INTERCEPT_UNAME; INTERCEPT_FUNCTION(gethostname); MSAN_MAYBE_INTERCEPT_EPOLL_WAIT; MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT; diff --git a/compiler-rt/lib/msan/msan_interface_internal.h b/compiler-rt/lib/msan/msan_interface_internal.h index 1abbba018c92..9e3db06bd64d 100644 --- a/compiler-rt/lib/msan/msan_interface_internal.h +++ b/compiler-rt/lib/msan/msan_interface_internal.h @@ -46,6 +46,12 @@ using __sanitizer::u32; using __sanitizer::u16; using __sanitizer::u8; +// Versions of the above which take Origin as a parameter +SANITIZER_INTERFACE_ATTRIBUTE +void __msan_warning_with_origin(u32 origin); +SANITIZER_INTERFACE_ATTRIBUTE __attribute__((noreturn)) void +__msan_warning_with_origin_noreturn(u32 origin); + SANITIZER_INTERFACE_ATTRIBUTE void __msan_maybe_warning_1(u8 s, u32 o); SANITIZER_INTERFACE_ATTRIBUTE diff --git a/compiler-rt/lib/msan/msan_origin.h b/compiler-rt/lib/msan/msan_origin.h index 26a4e7eb90cd..e291f538cbd3 100644 --- a/compiler-rt/lib/msan/msan_origin.h +++ b/compiler-rt/lib/msan/msan_origin.h @@ -57,7 +57,7 @@ class Origin { u32 raw_id() const { return raw_id_; } bool isHeapOrigin() const { - // 1xxx xxxx xxxx xxxx + // 0xxx xxxx xxxx xxxx return raw_id_ >> kHeapShift == 0; } bool isStackOrigin() const { |