aboutsummaryrefslogtreecommitdiff
path: root/lib/msan
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-09-06 18:41:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-09-06 18:41:23 +0000
commitf31bcc68c72371a2bf63aead9f3373a1ff2053b6 (patch)
treeb259e5d585da0f8cde9579939a74d5ef44c72abd /lib/msan
parentcd2dd3df15523e2be8d2bbace27641d6ac9fa40d (diff)
downloadsrc-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.txt20
-rw-r--r--lib/msan/msan.cc44
-rw-r--r--lib/msan/msan.h27
-rw-r--r--lib/msan/msan.syms.extra1
-rw-r--r--lib/msan/msan_allocator.cc9
-rw-r--r--lib/msan/msan_interceptors.cc30
-rw-r--r--lib/msan/msan_interface_internal.h7
-rw-r--r--lib/msan/msan_linux.cc43
-rw-r--r--lib/msan/msan_new_delete.cc7
-rw-r--r--lib/msan/msan_origin.h2
-rw-r--r--lib/msan/msan_poisoning.cc2
-rw-r--r--lib/msan/msan_report.cc4
-rw-r--r--lib/msan/msan_thread.cc2
-rw-r--r--lib/msan/tests/CMakeLists.txt3
-rw-r--r--lib/msan/tests/msan_test.cc46
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; }