summaryrefslogtreecommitdiff
path: root/compiler-rt/lib/msan
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /compiler-rt/lib/msan
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'compiler-rt/lib/msan')
-rw-r--r--compiler-rt/lib/msan/msan.cpp43
-rw-r--r--compiler-rt/lib/msan/msan.h14
-rw-r--r--compiler-rt/lib/msan/msan_allocator.cpp14
-rw-r--r--compiler-rt/lib/msan/msan_interceptors.cpp44
-rw-r--r--compiler-rt/lib/msan/msan_interface_internal.h6
-rw-r--r--compiler-rt/lib/msan/msan_origin.h2
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 {