diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 18:41:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 18:41:23 +0000 |
commit | f31bcc68c72371a2bf63aead9f3373a1ff2053b6 (patch) | |
tree | b259e5d585da0f8cde9579939a74d5ef44c72abd /lib/msan | |
parent | cd2dd3df15523e2be8d2bbace27641d6ac9fa40d (diff) | |
download | src-f31bcc68c72371a2bf63aead9f3373a1ff2053b6.tar.gz src-f31bcc68c72371a2bf63aead9f3373a1ff2053b6.zip |
Import compiler-rt 3.7.0 release (r246257).vendor/compiler-rt/compiler-rt-release_370-r246257
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=287516
svn path=/vendor/compiler-rt/compiler-rt-release_370-r246257/; revision=287517; tag=vendor/compiler-rt/compiler-rt-release_370-r246257
Diffstat (limited to 'lib/msan')
-rw-r--r-- | lib/msan/CMakeLists.txt | 20 | ||||
-rw-r--r-- | lib/msan/msan.cc | 44 | ||||
-rw-r--r-- | lib/msan/msan.h | 27 | ||||
-rw-r--r-- | lib/msan/msan.syms.extra | 1 | ||||
-rw-r--r-- | lib/msan/msan_allocator.cc | 9 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 30 | ||||
-rw-r--r-- | lib/msan/msan_interface_internal.h | 7 | ||||
-rw-r--r-- | lib/msan/msan_linux.cc | 43 | ||||
-rw-r--r-- | lib/msan/msan_new_delete.cc | 7 | ||||
-rw-r--r-- | lib/msan/msan_origin.h | 2 | ||||
-rw-r--r-- | lib/msan/msan_poisoning.cc | 2 | ||||
-rw-r--r-- | lib/msan/msan_report.cc | 4 | ||||
-rw-r--r-- | lib/msan/msan_thread.cc | 2 | ||||
-rw-r--r-- | lib/msan/tests/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/msan/tests/msan_test.cc | 46 |
15 files changed, 183 insertions, 64 deletions
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt index ccf47fc45cf3..de5980e5644b 100644 --- a/lib/msan/CMakeLists.txt +++ b/lib/msan/CMakeLists.txt @@ -7,12 +7,15 @@ set(MSAN_RTL_SOURCES msan_chained_origin_depot.cc msan_interceptors.cc msan_linux.cc - msan_new_delete.cc msan_report.cc msan_thread.cc msan_poisoning.cc ) +set(MSAN_RTL_CXX_SOURCES + msan_new_delete.cc) + + set(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS}) append_no_rtti_flag(MSAN_RTL_CFLAGS) append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS) @@ -29,12 +32,21 @@ foreach(arch ${MSAN_SUPPORTED_ARCH}) $<TARGET_OBJECTS:RTInterception.${arch}> $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> + $<TARGET_OBJECTS:RTUbsan.${arch}> + CFLAGS ${MSAN_RTL_CFLAGS}) + add_compiler_rt_runtime(clang_rt.msan_cxx-${arch} ${arch} STATIC + SOURCES ${MSAN_RTL_CXX_SOURCES} + $<TARGET_OBJECTS:RTUbsan_cxx.${arch}> CFLAGS ${MSAN_RTL_CFLAGS}) - add_dependencies(msan clang_rt.msan-${arch}) - list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch}) + add_dependencies(msan clang_rt.msan-${arch} + clang_rt.msan_cxx-${arch}) + list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch} + clang_rt.msan_cxx-${arch}) if(UNIX) add_sanitizer_rt_symbols(clang_rt.msan-${arch} msan.syms.extra) - add_dependencies(msan clang_rt.msan-${arch}-symbols) + add_sanitizer_rt_symbols(clang_rt.msan_cxx-${arch} msan.syms.extra) + add_dependencies(msan clang_rt.msan-${arch}-symbols + clang_rt.msan_cxx-${arch}-symbols) endif() endforeach() diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index ed6efbdd682f..163d59dabfa8 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -26,6 +26,8 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "sanitizer_common/sanitizer_stackdepot.h" +#include "ubsan/ubsan_flags.h" +#include "ubsan/ubsan_init.h" // ACHTUNG! No system header includes in this file. @@ -133,11 +135,6 @@ static void RegisterMsanFlags(FlagParser *parser, Flags *f) { } static void InitializeFlags() { - Flags *f = flags(); - FlagParser parser; - RegisterMsanFlags(&parser, f); - RegisterCommonFlags(&parser); - SetCommonFlagsDefaults(); { CommonFlags cf; @@ -151,14 +148,35 @@ static void InitializeFlags() { OverrideCommonFlags(cf); } + Flags *f = flags(); f->SetDefaults(); + FlagParser parser; + RegisterMsanFlags(&parser, f); + RegisterCommonFlags(&parser); + +#if MSAN_CONTAINS_UBSAN + __ubsan::Flags *uf = __ubsan::flags(); + uf->SetDefaults(); + + FlagParser ubsan_parser; + __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); + RegisterCommonFlags(&ubsan_parser); +#endif + // Override from user-specified string. if (__msan_default_options) parser.ParseString(__msan_default_options()); +#if MSAN_CONTAINS_UBSAN + const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); + ubsan_parser.ParseString(ubsan_default_options); +#endif const char *msan_options = GetEnv("MSAN_OPTIONS"); parser.ParseString(msan_options); +#if MSAN_CONTAINS_UBSAN + ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); +#endif VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>"); SetVerbosity(common_flags()->verbosity); @@ -355,13 +373,12 @@ void __msan_init() { InitTlsSize(); InitializeFlags(); + CacheBinaryName(); __sanitizer_set_report_path(common_flags()->log_path); InitializeInterceptors(); InstallAtExitHandler(); // Needs __cxa_atexit interceptor. - if (MSAN_REPLACE_OPERATORS_NEW_AND_DELETE) - ReplaceOperatorsNewAndDelete(); DisableCoreDumperIfNecessary(); if (StackSizeIsUnlimited()) { VPrintf(1, "Unlimited stack, doing reexec\n"); @@ -374,7 +391,7 @@ void __msan_init() { __msan_clear_on_return(); if (__msan_get_track_origins()) VPrintf(1, "msan_track_origins\n"); - if (!InitShadow(/* map_shadow */ true, __msan_get_track_origins())) { + if (!InitShadow(__msan_get_track_origins())) { Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n"); Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); Printf("FATAL: Disabling ASLR is known to cause this error.\n"); @@ -394,6 +411,10 @@ void __msan_init() { SetCurrentThread(main_thread); main_thread->ThreadStart(); +#if MSAN_CONTAINS_UBSAN + __ubsan::InitAsPlugin(); +#endif + VPrintf(1, "MemorySanitizer init done\n"); msan_init_is_running = 0; @@ -543,6 +564,13 @@ u32 __msan_get_origin(const void *a) { return *(u32*)origin_ptr; } +int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id) { + Origin o = Origin::FromRawId(this_id); + while (o.raw_id() != prev_id && o.isChainedOrigin()) + o = o.getNextChainedOrigin(nullptr); + return o.raw_id() == prev_id; +} + u32 __msan_get_umr_origin() { return __msan_origin_tls; } diff --git a/lib/msan/msan.h b/lib/msan/msan.h index ed18f21d0282..cd8bc19f51ef 100644 --- a/lib/msan/msan.h +++ b/lib/msan/msan.h @@ -20,11 +20,16 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "msan_interface_internal.h" #include "msan_flags.h" +#include "ubsan/ubsan_platform.h" #ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1 #endif +#ifndef MSAN_CONTAINS_UBSAN +# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB +#endif + struct MappingDesc { uptr start; uptr end; @@ -47,6 +52,25 @@ const MappingDesc kMemoryLayout[] = { #define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL) #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x002000000000) +#elif SANITIZER_LINUX && defined(__powerpc64__) + +const MappingDesc kMemoryLayout[] = { + {0x000000000000ULL, 0x000100000000ULL, MappingDesc::APP, "low memory"}, + {0x000100000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"}, + {0x080000000000ULL, 0x180100000000ULL, MappingDesc::SHADOW, "shadow"}, + {0x180100000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"}, + {0x1C0000000000ULL, 0x2C0100000000ULL, MappingDesc::ORIGIN, "origin"}, + {0x2C0100000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"}, + {0x300000000000ULL, 0x400000000000ULL, MappingDesc::APP, "high memory"}}; + +// Maps low and high app ranges to contiguous space with zero base: +// Low: 0000 0000 0000 - 0000 ffff ffff -> 1000 0000 0000 - 1000 ffff ffff +// High: 3000 0000 0000 - 3fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff +#define LINEARIZE_MEM(mem) \ + (((uptr)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL) +#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL) +#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL) + #elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64 // Low memory: main binary, MAP_32BIT mappings and modules @@ -120,7 +144,7 @@ extern bool msan_init_is_running; extern int msan_report_count; bool ProtectRange(uptr beg, uptr end); -bool InitShadow(bool map_shadow, bool init_origins); +bool InitShadow(bool init_origins); char *GetProcSelfMaps(); void InitializeInterceptors(); @@ -131,7 +155,6 @@ void *MsanReallocate(StackTrace *stack, void *oldp, uptr size, void MsanDeallocate(StackTrace *stack, void *ptr); void InstallTrapHandler(); void InstallAtExitHandler(); -void ReplaceOperatorsNewAndDelete(); const char *GetStackOriginDescr(u32 id, uptr *pc); diff --git a/lib/msan/msan.syms.extra b/lib/msan/msan.syms.extra index aad41cf1124e..950e6f4ad5ad 100644 --- a/lib/msan/msan.syms.extra +++ b/lib/msan/msan.syms.extra @@ -1 +1,2 @@ __msan_* +__ubsan_* diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc index 698b6cddd30b..6df35664279f 100644 --- a/lib/msan/msan_allocator.cc +++ b/lib/msan/msan_allocator.cc @@ -58,6 +58,15 @@ struct MsanMapUnmapCallback { typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize, DefaultSizeClassMap, MsanMapUnmapCallback> PrimaryAllocator; +#elif defined(__powerpc64__) + static const uptr kAllocatorSpace = 0x300000000000; + static const uptr kAllocatorSize = 0x020000000000; // 2T + static const uptr kMetadataSize = sizeof(Metadata); + static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G + + typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize, + DefaultSizeClassMap, + MsanMapUnmapCallback> PrimaryAllocator; #endif typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache; typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator; diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 4a243941b8a3..6d5a056a3bb3 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -94,6 +94,13 @@ bool IsInInterceptorScope() { if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \ } while (0); +#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n) \ + CHECK_UNPOISONED((x), \ + common_flags()->strict_string_checks ? (len) + 1 : (n) ) + +#define CHECK_UNPOISONED_STRING(x, n) \ + CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n)) + INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) { ENSURE_MSAN_INITED(); SIZE_T res = REAL(fread)(ptr, size, nmemb, file); @@ -118,6 +125,7 @@ INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb, INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { ENSURE_MSAN_INITED(); + CHECK_UNPOISONED_STRING(path, 0) SSIZE_T res = REAL(readlink)(path, buf, bufsiz); if (res > 0) __msan_unpoison(buf, res); @@ -283,13 +291,11 @@ INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) { return res; } -// FIXME: Add stricter shadow checks in str* interceptors (ex.: strcpy should -// check the shadow of the terminating \0 byte). - INTERCEPTOR(char *, strcpy, char *dest, const char *src) { // NOLINT ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T n = REAL(strlen)(src); + CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(strcpy)(dest, src); // NOLINT CopyShadowAndOrigin(dest, src, n + 1, &stack); return res; @@ -311,6 +317,7 @@ INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { // NOLINT ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T n = REAL(strlen)(src); + CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(stpcpy)(dest, src); // NOLINT CopyShadowAndOrigin(dest, src, n + 1, &stack); return res; @@ -322,6 +329,7 @@ INTERCEPTOR(char *, strdup, char *src) { // On FreeBSD strdup() leverages strlen(). InterceptorScope interceptor_scope; SIZE_T n = REAL(strlen)(src); + CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(strdup)(src); CopyShadowAndOrigin(res, src, n + 1, &stack); return res; @@ -332,6 +340,7 @@ INTERCEPTOR(char *, __strdup, char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T n = REAL(strlen)(src); + CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(__strdup)(src); CopyShadowAndOrigin(res, src, n + 1, &stack); return res; @@ -381,6 +390,8 @@ INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT GET_STORE_STACK_TRACE; SIZE_T src_size = REAL(strlen)(src); SIZE_T dest_size = REAL(strlen)(dest); + CHECK_UNPOISONED_STRING(src + src_size, 0); + CHECK_UNPOISONED_STRING(dest + dest_size, 0); char *res = REAL(strcat)(dest, src); // NOLINT CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack); return res; @@ -391,6 +402,7 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT GET_STORE_STACK_TRACE; SIZE_T dest_size = REAL(strlen)(dest); SIZE_T copy_size = REAL(strnlen)(src, n); + CHECK_UNPOISONED_STRING(dest + dest_size, 0); char *res = REAL(strncat)(dest, src, n); // NOLINT CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack); __msan_unpoison(dest + dest_size + copy_size, 1); // \0 @@ -667,6 +679,7 @@ static void UnpoisonEnviron() { INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) { ENSURE_MSAN_INITED(); + CHECK_UNPOISONED_STRING(name, 0) int res = REAL(setenv)(name, value, overwrite); if (!res) UnpoisonEnviron(); return res; @@ -1384,6 +1397,14 @@ int OnExit() { if (map) ForEachMappedRegion(map, __msan_unpoison); \ } while (false) +#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \ + if (MsanThread *t = GetCurrentThread()) { \ + *begin = t->tls_begin(); \ + *end = t->tls_end(); \ + } else { \ + *begin = *end = 0; \ + } + #include "sanitizer_common/sanitizer_common_interceptors.inc" #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s) @@ -1420,7 +1441,8 @@ void __msan_clear_and_unpoison(void *a, uptr size) { void *__msan_memcpy(void *dest, const void *src, SIZE_T n) { if (!msan_inited) return internal_memcpy(dest, src, n); - if (msan_init_is_running) return REAL(memcpy)(dest, src, n); + if (msan_init_is_running || __msan::IsInSymbolizer()) + return REAL(memcpy)(dest, src, n); ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; void *res = REAL(memcpy)(dest, src, n); diff --git a/lib/msan/msan_interface_internal.h b/lib/msan/msan_interface_internal.h index 8641f814bc5f..f4d37d96c5b5 100644 --- a/lib/msan/msan_interface_internal.h +++ b/lib/msan/msan_interface_internal.h @@ -96,6 +96,13 @@ u32 __msan_chain_origin(u32 id); SANITIZER_INTERFACE_ATTRIBUTE u32 __msan_get_origin(const void *a); +// Test that this_id is a descendant of prev_id (or they are simply equal). +// "descendant" here means that are part of the same chain, created with +// __msan_chain_origin. +SANITIZER_INTERFACE_ATTRIBUTE +int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id); + + SANITIZER_INTERFACE_ATTRIBUTE void __msan_clear_on_return(); diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc index 6c185165fc50..7025ef6c812d 100644 --- a/lib/msan/msan_linux.cc +++ b/lib/msan/msan_linux.cc @@ -53,10 +53,19 @@ static bool CheckMemoryRangeAvailability(uptr beg, uptr size) { return true; } -static bool ProtectMemoryRange(uptr beg, uptr size) { +static bool ProtectMemoryRange(uptr beg, uptr size, const char *name) { if (size > 0) { - uptr end = beg + size - 1; - if (!Mprotect(beg, size)) { + void *addr = MmapNoAccess(beg, size, name); + if (beg == 0 && addr != 0) { + // Depending on the kernel configuration, we may not be able to protect + // the page at address zero. + uptr gap = 16 * GetPageSizeCached(); + beg += gap; + size -= gap; + addr = MmapNoAccess(beg, size, name); + } + if ((uptr)addr != beg) { + uptr end = beg + size - 1; Printf("FATAL: Cannot protect memory range %p - %p.\n", beg, end); return false; } @@ -95,7 +104,7 @@ static void CheckMemoryLayoutSanity() { } } -bool InitShadow(bool map_shadow, bool init_origins) { +bool InitShadow(bool init_origins) { // Let user know mapping parameters first. VPrintf(1, "__msan_init %p\n", &__msan_init); for (unsigned i = 0; i < kMemoryLayoutSize; ++i) @@ -115,15 +124,27 @@ bool InitShadow(bool map_shadow, bool init_origins) { uptr end = kMemoryLayout[i].end; uptr size= end - start; MappingDesc::Type type = kMemoryLayout[i].type; - if ((map_shadow && type == MappingDesc::SHADOW) || - (init_origins && type == MappingDesc::ORIGIN)) { - if (!CheckMemoryRangeAvailability(start, size)) return false; - if ((uptr)MmapFixedNoReserve(start, size) != start) return false; + + bool map = type == MappingDesc::SHADOW || + (init_origins && type == MappingDesc::ORIGIN); + bool protect = type == MappingDesc::INVALID || + (!init_origins && type == MappingDesc::ORIGIN); + CHECK(!(map && protect)); + if (!map && !protect) + CHECK(type == MappingDesc::APP); + if (map) { + if (!CheckMemoryRangeAvailability(start, size)) + return false; + if ((uptr)MmapFixedNoReserve(start, size, kMemoryLayout[i].name) != start) + return false; if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(start, size); - } else if (type == MappingDesc::INVALID) { - if (!CheckMemoryRangeAvailability(start, size)) return false; - if (!ProtectMemoryRange(start, size)) return false; + } + if (protect) { + if (!CheckMemoryRangeAvailability(start, size)) + return false; + if (!ProtectMemoryRange(start, size, kMemoryLayout[i].name)) + return false; } } diff --git a/lib/msan/msan_new_delete.cc b/lib/msan/msan_new_delete.cc index 9a8e56e4a28a..c8bc0651b507 100644 --- a/lib/msan/msan_new_delete.cc +++ b/lib/msan/msan_new_delete.cc @@ -19,13 +19,6 @@ #include <stddef.h> -namespace __msan { -// This function is a no-op. We need it to make sure that object file -// with our replacements will actually be loaded from static MSan -// run-time library at link-time. -void ReplaceOperatorsNewAndDelete() { } -} - using namespace __msan; // NOLINT // Fake std::nothrow_t to avoid including <new>. diff --git a/lib/msan/msan_origin.h b/lib/msan/msan_origin.h index 1284c01bf2af..36c168b8521c 100644 --- a/lib/msan/msan_origin.h +++ b/lib/msan/msan_origin.h @@ -87,7 +87,7 @@ class Origin { CHECK(isChainedOrigin()); u32 prev_id; u32 stack_id = ChainedOriginDepotGet(getChainedId(), &prev_id); - *stack = StackDepotGet(stack_id); + if (stack) *stack = StackDepotGet(stack_id); return Origin(prev_id); } diff --git a/lib/msan/msan_poisoning.cc b/lib/msan/msan_poisoning.cc index 96411fdbc31b..92134f6a15b8 100644 --- a/lib/msan/msan_poisoning.cc +++ b/lib/msan/msan_poisoning.cc @@ -122,7 +122,7 @@ void CopyMemory(void *dst, const void *src, uptr size, StackTrace *stack) { void SetShadow(const void *ptr, uptr size, u8 value) { uptr PageSize = GetPageSizeCached(); uptr shadow_beg = MEM_TO_SHADOW(ptr); - uptr shadow_end = MEM_TO_SHADOW((uptr)ptr + size); + uptr shadow_end = shadow_beg + size; if (value || shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) { REAL(memset)((void *)shadow_beg, value, shadow_end - shadow_beg); diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cc index 33c28b2fba0e..ddb8070282a9 100644 --- a/lib/msan/msan_report.cc +++ b/lib/msan/msan_report.cc @@ -103,7 +103,7 @@ void ReportUMR(StackTrace *stack, u32 origin) { Decorator d; Printf("%s", d.Warning()); - Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n"); + Report("WARNING: MemorySanitizer: use-of-uninitialized-value\n"); Printf("%s", d.End()); stack->Print(); if (origin) { @@ -115,7 +115,7 @@ void ReportUMR(StackTrace *stack, u32 origin) { void ReportExpectedUMRNotFound(StackTrace *stack) { SpinMutexLock l(&CommonSanitizerReportMutex); - Printf(" WARNING: Expected use of uninitialized value not found\n"); + Printf("WARNING: Expected use of uninitialized value not found\n"); stack->Print(); } diff --git a/lib/msan/msan_thread.cc b/lib/msan/msan_thread.cc index e15a247c6bb8..0ba499350064 100644 --- a/lib/msan/msan_thread.cc +++ b/lib/msan/msan_thread.cc @@ -14,7 +14,7 @@ MsanThread *MsanThread::Create(thread_callback_t start_routine, MsanThread *thread = (MsanThread*)MmapOrDie(size, __func__); thread->start_routine_ = start_routine; thread->arg_ = arg; - thread->destructor_iterations_ = kPthreadDestructorIterations; + thread->destructor_iterations_ = GetPthreadDestructorIterations(); return thread; } diff --git a/lib/msan/tests/CMakeLists.txt b/lib/msan/tests/CMakeLists.txt index e008bd329cb4..bf16a16bcf20 100644 --- a/lib/msan/tests/CMakeLists.txt +++ b/lib/msan/tests/CMakeLists.txt @@ -33,6 +33,7 @@ set(MSAN_UNITTEST_COMMON_CFLAGS -Wno-deprecated-declarations -Wno-unused-variable -Wno-zero-length-array + -Wno-uninitialized -Werror=sign-compare ) set(MSAN_UNITTEST_INSTRUMENTED_CFLAGS @@ -70,7 +71,7 @@ macro(msan_compile obj_list source arch kind) endmacro() macro(msan_link_shared so_list so_name arch kind) - parse_arguments(SOURCE "OBJECTS;LINKFLAGS;DEPS" "" ${ARGN}) + cmake_parse_arguments(SOURCE "" "" "OBJECTS;LINKFLAGS;DEPS" ${ARGN}) set(output_so "${CMAKE_CURRENT_BINARY_DIR}/${so_name}.${arch}${kind}.so") get_target_flags_for_arch(${arch} TARGET_LINKFLAGS) if(NOT COMPILER_RT_STANDALONE_BUILD) diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 317f70cbc32e..00dd20a3d775 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -134,9 +134,12 @@ static bool TrackingOrigins() { __msan_set_origin(&x, sizeof(x), 0x1234); U4 origin = __msan_get_origin(&x); __msan_set_origin(&x, sizeof(x), 0); - return origin == 0x1234; + return __msan_origin_is_descendant_or_same(origin, 0x1234); } +#define EXPECT_ORIGIN(expected, origin) \ + EXPECT_TRUE(__msan_origin_is_descendant_or_same((origin), (expected))) + #define EXPECT_UMR(action) \ do { \ __msan_set_expect_umr(1); \ @@ -144,14 +147,13 @@ static bool TrackingOrigins() { __msan_set_expect_umr(0); \ } while (0) -#define EXPECT_UMR_O(action, origin) \ - do { \ - __msan_set_expect_umr(1); \ - action; \ - __msan_set_expect_umr(0); \ - if (TrackingOrigins()) \ - EXPECT_EQ(origin, __msan_get_umr_origin()); \ - } while (0) +#define EXPECT_UMR_O(action, origin) \ + do { \ + __msan_set_expect_umr(1); \ + action; \ + __msan_set_expect_umr(0); \ + if (TrackingOrigins()) EXPECT_ORIGIN(origin, __msan_get_umr_origin()); \ + } while (0) #define EXPECT_POISONED(x) ExpectPoisoned(x) @@ -166,8 +168,7 @@ void ExpectPoisoned(const T& t) { template<typename T> void ExpectPoisonedWithOrigin(const T& t, unsigned origin) { EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t))); - if (TrackingOrigins()) - EXPECT_EQ(origin, __msan_get_origin((void*)&t)); + if (TrackingOrigins()) EXPECT_ORIGIN(origin, __msan_get_origin((void *)&t)); } #define EXPECT_NOT_POISONED(x) EXPECT_EQ(true, TestForNotPoisoned((x))) @@ -3902,15 +3903,15 @@ TEST(VectorMaddTest, mmx_pmadd_wd) { #endif // defined(__clang__) TEST(MemorySanitizerOrigins, SetGet) { - EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins()); + EXPECT_EQ(TrackingOrigins(), !!__msan_get_track_origins()); if (!TrackingOrigins()) return; int x; __msan_set_origin(&x, sizeof(x), 1234); - EXPECT_EQ(1234U, __msan_get_origin(&x)); + EXPECT_ORIGIN(1234U, __msan_get_origin(&x)); __msan_set_origin(&x, sizeof(x), 5678); - EXPECT_EQ(5678U, __msan_get_origin(&x)); + EXPECT_ORIGIN(5678U, __msan_get_origin(&x)); __msan_set_origin(&x, sizeof(x), 0); - EXPECT_EQ(0U, __msan_get_origin(&x)); + EXPECT_ORIGIN(0U, __msan_get_origin(&x)); } namespace { @@ -3926,12 +3927,12 @@ TEST(MemorySanitizerOrigins, InitializedStoreDoesNotChangeOrigin) { S s; U4 origin = rand(); // NOLINT s.a = *GetPoisonedO<U2>(0, origin); - EXPECT_EQ(origin, __msan_get_origin(&s.a)); - EXPECT_EQ(origin, __msan_get_origin(&s.b)); + EXPECT_ORIGIN(origin, __msan_get_origin(&s.a)); + EXPECT_ORIGIN(origin, __msan_get_origin(&s.b)); s.b = 42; - EXPECT_EQ(origin, __msan_get_origin(&s.a)); - EXPECT_EQ(origin, __msan_get_origin(&s.b)); + EXPECT_ORIGIN(origin, __msan_get_origin(&s.a)); + EXPECT_ORIGIN(origin, __msan_get_origin(&s.b)); } } // namespace @@ -3947,7 +3948,8 @@ void BinaryOpOriginTest(BinaryOp op) { *z = op(*x, *y); U4 origin = __msan_get_origin(z); EXPECT_POISONED_O(*z, origin); - EXPECT_EQ(true, origin == ox || origin == oy); + EXPECT_EQ(true, __msan_origin_is_descendant_or_same(origin, ox) || + __msan_origin_is_descendant_or_same(origin, oy)); // y is poisoned, x is not. *x = 10101; @@ -3956,7 +3958,7 @@ void BinaryOpOriginTest(BinaryOp op) { __msan_set_origin(z, sizeof(*z), 0); *z = op(*x, *y); EXPECT_POISONED_O(*z, oy); - EXPECT_EQ(__msan_get_origin(z), oy); + EXPECT_ORIGIN(oy, __msan_get_origin(z)); // x is poisoned, y is not. *x = *GetPoisonedO<T>(0, ox); @@ -3965,7 +3967,7 @@ void BinaryOpOriginTest(BinaryOp op) { __msan_set_origin(z, sizeof(*z), 0); *z = op(*x, *y); EXPECT_POISONED_O(*z, ox); - EXPECT_EQ(__msan_get_origin(z), ox); + EXPECT_ORIGIN(ox, __msan_get_origin(z)); } template<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; } |