aboutsummaryrefslogtreecommitdiff
path: root/lib/msan
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:48 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:48 +0000
commit93c1b73a09a52d4a265f683bf1954b08bb430049 (patch)
tree5543464d74945196cc890e9d9099e5d0660df7eb /lib/msan
parent0d8e7490d6e8a13a8f0977d9b7771803b9f64ea0 (diff)
downloadsrc-93c1b73a09a52d4a265f683bf1954b08bb430049.tar.gz
src-93c1b73a09a52d4a265f683bf1954b08bb430049.zip
Vendor import of compiler-rt trunk r338150:vendor/compiler-rt/compiler-rt-trunk-r338150
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=336817 svn path=/vendor/compiler-rt/compiler-rt-trunk-r338150/; revision=336818; tag=vendor/compiler-rt/compiler-rt-trunk-r338150
Diffstat (limited to 'lib/msan')
-rw-r--r--lib/msan/.clang-format1
-rw-r--r--lib/msan/CMakeLists.txt24
-rw-r--r--lib/msan/msan.cc15
-rw-r--r--lib/msan/msan.h21
-rw-r--r--lib/msan/msan_allocator.cc48
-rw-r--r--lib/msan/msan_interceptors.cc136
-rw-r--r--lib/msan/msan_interface_internal.h6
-rw-r--r--lib/msan/msan_linux.cc3
-rw-r--r--lib/msan/msan_new_delete.cc5
-rw-r--r--lib/msan/msan_poisoning.cc3
-rw-r--r--lib/msan/msan_report.cc5
-rw-r--r--lib/msan/msan_report.h34
-rw-r--r--lib/msan/tests/CMakeLists.txt8
-rw-r--r--lib/msan/tests/msan_test.cc145
14 files changed, 272 insertions, 182 deletions
diff --git a/lib/msan/.clang-format b/lib/msan/.clang-format
index f6cb8ad931f5..560308c91dee 100644
--- a/lib/msan/.clang-format
+++ b/lib/msan/.clang-format
@@ -1 +1,2 @@
BasedOnStyle: Google
+AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt
index 598ae54588c1..15cc513c20e9 100644
--- a/lib/msan/CMakeLists.txt
+++ b/lib/msan/CMakeLists.txt
@@ -15,10 +15,26 @@ set(MSAN_RTL_SOURCES
set(MSAN_RTL_CXX_SOURCES
msan_new_delete.cc)
+set(MSAN_RTL_HEADERS
+ msan.h
+ msan_allocator.h
+ msan_chained_origin_depot.h
+ msan_flags.h
+ msan_flags.inc
+ msan_interface_internal.h
+ msan_origin.h
+ msan_poisoning.h
+ msan_report.h
+ msan_thread.h)
set(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC -ftls-model=initial-exec MSAN_RTL_CFLAGS)
+endif()
append_rtti_flag(OFF MSAN_RTL_CFLAGS)
-append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)
+if(NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)
+endif()
# Prevent clang from generating libc calls.
append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding MSAN_RTL_CFLAGS)
@@ -35,7 +51,10 @@ foreach(arch ${MSAN_SUPPORTED_ARCH})
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
+ $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
+ ADDITIONAL_HEADERS ${MSAN_RTL_HEADERS}
CFLAGS ${MSAN_RTL_CFLAGS}
PARENT_TARGET msan)
add_compiler_rt_runtime(clang_rt.msan_cxx
@@ -43,11 +62,12 @@ foreach(arch ${MSAN_SUPPORTED_ARCH})
ARCHS ${arch}
SOURCES ${MSAN_RTL_CXX_SOURCES}
$<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
+ ADDITIONAL_HEADERS ${MSAN_RTL_HEADERS}
CFLAGS ${MSAN_RTL_CFLAGS}
PARENT_TARGET msan)
list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch}
clang_rt.msan_cxx-${arch})
- if(UNIX)
+ if(SANITIZER_USE_SYMBOLS)
add_sanitizer_rt_symbols(clang_rt.msan
ARCHS ${arch}
EXTRA msan.syms.extra)
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index e6226ba7670f..06bcbdf88691 100644
--- a/lib/msan/msan.cc
+++ b/lib/msan/msan.cc
@@ -15,6 +15,7 @@
#include "msan.h"
#include "msan_chained_origin_depot.h"
#include "msan_origin.h"
+#include "msan_report.h"
#include "msan_thread.h"
#include "msan_poisoning.h"
#include "sanitizer_common/sanitizer_atomic.h"
@@ -379,6 +380,14 @@ static void MsanOnDeadlySignal(int signo, void *siginfo, void *context) {
HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
}
+static void MsanCheckFailed(const char *file, int line, const char *cond,
+ u64 v1, u64 v2) {
+ Report("MemorySanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
+ line, cond, (uptr)v1, (uptr)v2);
+ PRINT_CURRENT_STACK_CHECK();
+ Die();
+}
+
void __msan_init() {
CHECK(!msan_init_is_running);
if (msan_inited) return;
@@ -386,14 +395,18 @@ void __msan_init() {
SanitizerToolName = "MemorySanitizer";
AvoidCVE_2016_2143();
- InitTlsSize();
CacheBinaryName();
+ CheckASLR();
InitializeFlags();
+ // Install tool-specific callbacks in sanitizer_common.
+ SetCheckFailedCallback(MsanCheckFailed);
+
__sanitizer_set_report_path(common_flags()->log_path);
InitializeInterceptors();
+ InitTlsSize();
InstallDeadlySignalHandlers(MsanOnDeadlySignal);
InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
diff --git a/lib/msan/msan.h b/lib/msan/msan.h
index cbae444127ee..4c2e9f9e24a0 100644
--- a/lib/msan/msan.h
+++ b/lib/msan/msan.h
@@ -316,14 +316,6 @@ void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
void *context, bool request_fast_unwind);
-void ReportUMR(StackTrace *stack, u32 origin);
-void ReportExpectedUMRNotFound(StackTrace *stack);
-void ReportStats();
-void ReportAtExitStatistics();
-void DescribeMemoryRange(const void *x, uptr size);
-void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
- uptr offset);
-
// Unpoison first n function arguments.
void UnpoisonParam(uptr n);
void UnpoisonThreadLocalState();
@@ -356,14 +348,23 @@ const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
common_flags()->fast_unwind_on_malloc); \
}
+#define GET_STORE_STACK_TRACE \
+ GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
+
#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
BufferedStackTrace stack; \
if (msan_inited) \
GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr, \
common_flags()->fast_unwind_on_fatal)
-#define GET_STORE_STACK_TRACE \
- GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
+#define GET_FATAL_STACK_TRACE_HERE \
+ GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
+
+#define PRINT_CURRENT_STACK_CHECK() \
+ { \
+ GET_FATAL_STACK_TRACE_HERE; \
+ stack.Print(); \
+ }
class ScopedThreadLocalStateBackup {
public:
diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc
index 0f9942324931..36f0497a9d83 100644
--- a/lib/msan/msan_allocator.cc
+++ b/lib/msan/msan_allocator.cc
@@ -15,6 +15,7 @@
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_checks.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
+#include "sanitizer_common/sanitizer_allocator_report.h"
#include "sanitizer_common/sanitizer_errno.h"
#include "msan.h"
#include "msan_allocator.h"
@@ -119,7 +120,7 @@ typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
static Allocator allocator;
static AllocatorCache fallback_allocator_cache;
-static SpinMutex fallback_mutex;
+static StaticSpinMutex fallback_mutex;
void MsanAllocatorInit() {
SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null);
@@ -139,9 +140,11 @@ void MsanThreadLocalMallocStorage::CommitBack() {
static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment,
bool zeroise) {
if (size > kMaxAllowedMallocSize) {
- Report("WARNING: MemorySanitizer failed to allocate %p bytes\n",
- (void *)size);
- return Allocator::FailureHandler::OnBadRequest();
+ if (AllocatorMayReturnNull()) {
+ Report("WARNING: MemorySanitizer failed to allocate 0x%zx bytes\n", size);
+ return nullptr;
+ }
+ ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack);
}
MsanThread *t = GetCurrentThread();
void *allocated;
@@ -153,6 +156,12 @@ static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment,
AllocatorCache *cache = &fallback_allocator_cache;
allocated = allocator.Allocate(cache, size, alignment);
}
+ if (UNLIKELY(!allocated)) {
+ SetAllocatorOutOfMemory();
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportOutOfMemory(size, stack);
+ }
Metadata *meta =
reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
meta->requested_size = size;
@@ -222,6 +231,15 @@ void *MsanReallocate(StackTrace *stack, void *old_p, uptr new_size,
return new_p;
}
+void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportCallocOverflow(nmemb, size, stack);
+ }
+ return MsanAllocate(stack, nmemb * size, sizeof(u64), true);
+}
+
static uptr AllocationSize(const void *p) {
if (!p) return 0;
const void *beg = allocator.GetBlockBegin(p);
@@ -235,9 +253,7 @@ void *msan_malloc(uptr size, StackTrace *stack) {
}
void *msan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
- if (UNLIKELY(CheckForCallocOverflow(size, nmemb)))
- return SetErrnoOnNull(Allocator::FailureHandler::OnBadRequest());
- return SetErrnoOnNull(MsanAllocate(stack, nmemb * size, sizeof(u64), true));
+ return SetErrnoOnNull(MsanCalloc(stack, nmemb, size));
}
void *msan_realloc(void *ptr, uptr size, StackTrace *stack) {
@@ -258,7 +274,9 @@ void *msan_pvalloc(uptr size, StackTrace *stack) {
uptr PageSize = GetPageSizeCached();
if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
errno = errno_ENOMEM;
- return Allocator::FailureHandler::OnBadRequest();
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportPvallocOverflow(size, stack);
}
// pvalloc(0) should allocate one page.
size = size ? RoundUpTo(size, PageSize) : PageSize;
@@ -268,7 +286,9 @@ void *msan_pvalloc(uptr size, StackTrace *stack) {
void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
errno = errno_EINVAL;
- return Allocator::FailureHandler::OnBadRequest();
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportInvalidAlignedAllocAlignment(size, alignment, stack);
}
return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false));
}
@@ -276,7 +296,9 @@ void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
void *msan_memalign(uptr alignment, uptr size, StackTrace *stack) {
if (UNLIKELY(!IsPowerOfTwo(alignment))) {
errno = errno_EINVAL;
- return Allocator::FailureHandler::OnBadRequest();
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportInvalidAllocationAlignment(alignment, stack);
}
return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false));
}
@@ -284,11 +306,13 @@ void *msan_memalign(uptr alignment, uptr size, StackTrace *stack) {
int msan_posix_memalign(void **memptr, uptr alignment, uptr size,
StackTrace *stack) {
if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
- Allocator::FailureHandler::OnBadRequest();
- return errno_EINVAL;
+ if (AllocatorMayReturnNull())
+ return errno_EINVAL;
+ ReportInvalidPosixMemalignAlignment(alignment, stack);
}
void *ptr = MsanAllocate(stack, size, alignment, false);
if (UNLIKELY(!ptr))
+ // OOM error is already taken care of by MsanAllocate.
return errno_ENOMEM;
CHECK(IsAligned((uptr)ptr, alignment));
*memptr = ptr;
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index a7fe09b25ffb..b3429bcf06b5 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -19,6 +19,7 @@
#include "msan.h"
#include "msan_chained_origin_depot.h"
#include "msan_origin.h"
+#include "msan_report.h"
#include "msan_thread.h"
#include "msan_poisoning.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
@@ -35,6 +36,7 @@
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#if SANITIZER_NETBSD
+#define fstat __fstat50
#define gettimeofday __gettimeofday50
#define getrusage __getrusage50
#endif
@@ -58,6 +60,9 @@ DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
// True if this is a nested interceptor.
static THREADLOCAL int in_interceptor_scope;
+void __msan_scoped_disable_interceptor_checks() { ++in_interceptor_scope; }
+void __msan_scoped_enable_interceptor_checks() { --in_interceptor_scope; }
+
struct InterceptorScope {
InterceptorScope() { ++in_interceptor_scope; }
~InterceptorScope() { --in_interceptor_scope; }
@@ -137,15 +142,6 @@ INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
#endif
-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);
- return res;
-}
-
#if !SANITIZER_NETBSD
INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
return (char *)__msan_memcpy(dest, src, n) + n;
@@ -489,39 +485,9 @@ INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
return res;
}
-INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {
- ENSURE_MSAN_INITED();
- CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
- SIZE_T res = REAL(strxfrm)(dest, src, n);
- if (res < n) __msan_unpoison(dest, res + 1);
- return res;
-}
-
-INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
- void *loc) {
- ENSURE_MSAN_INITED();
- CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
- SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);
- if (res < n) __msan_unpoison(dest, res + 1);
- return res;
-}
-
-#if SANITIZER_LINUX
-INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T n,
- void *loc) {
- ENSURE_MSAN_INITED();
- CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
- SIZE_T res = REAL(__strxfrm_l)(dest, src, n, loc);
- if (res < n) __msan_unpoison(dest, res + 1);
- return res;
-}
-#define MSAN_MAYBE_INTERCEPT___STRXFRM_L INTERCEPT_FUNCTION(__strxfrm_l)
-#else
-#define MSAN_MAYBE_INTERCEPT___STRXFRM_L
-#endif
-
#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
ENSURE_MSAN_INITED(); \
+ InterceptorScope interceptor_scope; \
ret_type res = REAL(func)(s, __VA_ARGS__); \
if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1)); \
return res;
@@ -688,6 +654,19 @@ INTERCEPTOR(int, putenv, char *string) {
return res;
}
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD
+INTERCEPTOR(int, fstat, int fd, void *buf) {
+ ENSURE_MSAN_INITED();
+ int res = REAL(fstat)(fd, buf);
+ if (!res)
+ __msan_unpoison(buf, __sanitizer::struct_stat_sz);
+ return res;
+}
+#define MSAN_MAYBE_INTERCEPT_FSTAT INTERCEPT_FUNCTION(fstat)
+#else
+#define MSAN_MAYBE_INTERCEPT_FSTAT
+#endif
+
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
ENSURE_MSAN_INITED();
@@ -772,14 +751,6 @@ INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
return res;
}
-INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
- ENSURE_MSAN_INITED();
- char *res = REAL(fgets)(s, size, stream);
- if (res)
- __msan_unpoison(s, REAL(strlen)(s) + 1);
- return res;
-}
-
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
ENSURE_MSAN_INITED();
@@ -964,11 +935,9 @@ void __sanitizer_dtor_callback(const void *data, uptr size) {
}
}
-INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
- int fd, OFF_T offset) {
- if (msan_init_is_running)
- return REAL(mmap)(addr, length, prot, flags, fd, offset);
- ENSURE_MSAN_INITED();
+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)) {
if (flags & map_fixed) {
errno = errno_EINVAL;
@@ -977,34 +946,11 @@ INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
addr = nullptr;
}
}
- void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
- if (res != (void*)-1)
- __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
+ void *res = real_mmap(addr, length, prot, flags, fd, offset);
+ if (res != (void *)-1) __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
return res;
}
-#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
-INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
- int fd, OFF64_T offset) {
- ENSURE_MSAN_INITED();
- if (addr && !MEM_IS_APP(addr)) {
- if (flags & map_fixed) {
- errno = errno_EINVAL;
- return (void *)-1;
- } else {
- addr = nullptr;
- }
- }
- void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
- if (res != (void*)-1)
- __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
- return res;
-}
-#define MSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
-#else
-#define MSAN_MAYBE_INTERCEPT_MMAP64
-#endif
-
INTERCEPTOR(int, getrusage, int who, void *usage) {
ENSURE_MSAN_INITED();
int res = REAL(getrusage)(who, usage);
@@ -1175,6 +1121,9 @@ INTERCEPTOR(int, fork, void) {
return pid;
}
+// NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly
+// with MSan.
+#if SANITIZER_LINUX
INTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name,
const void *termp, const void *winp) {
ENSURE_MSAN_INITED();
@@ -1186,7 +1135,14 @@ INTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name,
}
return res;
}
+#define MSAN_MAYBE_INTERCEPT_OPENPTY INTERCEPT_FUNCTION(openpty)
+#else
+#define MSAN_MAYBE_INTERCEPT_OPENPTY
+#endif
+// NetBSD ships with forkpty(3) in -lutil, that needs to be prebuilt explicitly
+// with MSan.
+#if SANITIZER_LINUX
INTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp,
const void *winp) {
ENSURE_MSAN_INITED();
@@ -1196,6 +1152,10 @@ INTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp,
__msan_unpoison(amaster, sizeof(*amaster));
return res;
}
+#define MSAN_MAYBE_INTERCEPT_FORKPTY INTERCEPT_FUNCTION(forkpty)
+#else
+#define MSAN_MAYBE_INTERCEPT_FORKPTY
+#endif
struct MSanInterceptorContext {
bool in_interceptor_scope;
@@ -1308,6 +1268,12 @@ int OnExit() {
__msan_unpoison(to + size, 1); \
} while (false)
+#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \
+ offset) \
+ do { \
+ return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \
+ } while (false)
+
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_common_interceptors.inc"
@@ -1321,6 +1287,7 @@ static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \
{ \
handler = signal_impl(signo, handler); \
+ InterceptorScope interceptor_scope; \
return REAL(func)(signo, handler); \
}
@@ -1387,6 +1354,7 @@ static uptr signal_impl(int signo, uptr cb) {
} while (false)
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
#include "sanitizer_common/sanitizer_common_syscalls.inc"
+#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
struct dlinfo {
char *dli_fname;
@@ -1555,8 +1523,6 @@ void InitializeInterceptors() {
InitializeCommonInterceptors();
InitializeSignalInterceptors();
- INTERCEPT_FUNCTION(mmap);
- MSAN_MAYBE_INTERCEPT_MMAP64;
INTERCEPT_FUNCTION(posix_memalign);
MSAN_MAYBE_INTERCEPT_MEMALIGN;
MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
@@ -1573,7 +1539,6 @@ void InitializeInterceptors() {
MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
INTERCEPT_FUNCTION(fread);
MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
- INTERCEPT_FUNCTION(readlink);
INTERCEPT_FUNCTION(memccpy);
MSAN_MAYBE_INTERCEPT_MEMPCPY;
INTERCEPT_FUNCTION(bcopy);
@@ -1611,9 +1576,6 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(vswprintf);
INTERCEPT_FUNCTION(swprintf);
#endif
- INTERCEPT_FUNCTION(strxfrm);
- INTERCEPT_FUNCTION(strxfrm_l);
- MSAN_MAYBE_INTERCEPT___STRXFRM_L;
INTERCEPT_FUNCTION(strftime);
INTERCEPT_FUNCTION(strftime_l);
MSAN_MAYBE_INTERCEPT___STRFTIME_L;
@@ -1633,6 +1595,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(putenv);
INTERCEPT_FUNCTION(gettimeofday);
MSAN_MAYBE_INTERCEPT_FCVT;
+ MSAN_MAYBE_INTERCEPT_FSTAT;
MSAN_MAYBE_INTERCEPT___FXSTAT;
MSAN_INTERCEPT_FSTATAT;
MSAN_MAYBE_INTERCEPT___FXSTAT64;
@@ -1640,7 +1603,6 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(pipe);
INTERCEPT_FUNCTION(pipe2);
INTERCEPT_FUNCTION(socketpair);
- INTERCEPT_FUNCTION(fgets);
MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
INTERCEPT_FUNCTION(getrlimit);
MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
@@ -1670,8 +1632,8 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(__cxa_atexit);
INTERCEPT_FUNCTION(shmat);
INTERCEPT_FUNCTION(fork);
- INTERCEPT_FUNCTION(openpty);
- INTERCEPT_FUNCTION(forkpty);
+ MSAN_MAYBE_INTERCEPT_OPENPTY;
+ MSAN_MAYBE_INTERCEPT_FORKPTY;
inited = 1;
}
diff --git a/lib/msan/msan_interface_internal.h b/lib/msan/msan_interface_internal.h
index c6990db243c1..9a67cbc9b5f8 100644
--- a/lib/msan/msan_interface_internal.h
+++ b/lib/msan/msan_interface_internal.h
@@ -174,6 +174,12 @@ void __msan_set_death_callback(void (*callback)(void));
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_copy_shadow(void *dst, const void *src, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __msan_scoped_disable_interceptor_checks();
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __msan_scoped_enable_interceptor_checks();
} // extern "C"
#endif // MSAN_INTERFACE_INTERNAL_H
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc
index 4e6321fcb918..385a650c4afc 100644
--- a/lib/msan/msan_linux.cc
+++ b/lib/msan/msan_linux.cc
@@ -16,6 +16,7 @@
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
#include "msan.h"
+#include "msan_report.h"
#include "msan_thread.h"
#include <elf.h>
@@ -142,7 +143,7 @@ bool InitShadow(bool init_origins) {
if (map) {
if (!CheckMemoryRangeAvailability(start, size))
return false;
- if ((uptr)MmapFixedNoReserve(start, size, kMemoryLayout[i].name) != start)
+ if (!MmapFixedNoReserve(start, size, kMemoryLayout[i].name))
return false;
if (common_flags()->use_madv_dontdump)
DontDumpShadowMemory(start, size);
diff --git a/lib/msan/msan_new_delete.cc b/lib/msan/msan_new_delete.cc
index 5cc76e4bc08c..a0959aec5eb0 100644
--- a/lib/msan/msan_new_delete.cc
+++ b/lib/msan/msan_new_delete.cc
@@ -15,6 +15,7 @@
#include "msan.h"
#include "interception/interception.h"
#include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_allocator_report.h"
#if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
@@ -33,12 +34,12 @@ namespace std {
#define OPERATOR_NEW_BODY(nothrow) \
GET_MALLOC_STACK_TRACE; \
void *res = msan_malloc(size, &stack);\
- if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\
+ if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
return res
#define OPERATOR_NEW_BODY_ALIGN(nothrow) \
GET_MALLOC_STACK_TRACE;\
void *res = msan_memalign((uptr)align, size, &stack);\
- if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\
+ if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
return res;
INTERCEPTOR_ATTRIBUTE
diff --git a/lib/msan/msan_poisoning.cc b/lib/msan/msan_poisoning.cc
index 92134f6a15b8..7420d946928b 100644
--- a/lib/msan/msan_poisoning.cc
+++ b/lib/msan/msan_poisoning.cc
@@ -139,7 +139,8 @@ void SetShadow(const void *ptr, uptr size, u8 value) {
if (page_end != shadow_end) {
REAL(memset)((void *)page_end, 0, shadow_end - page_end);
}
- MmapFixedNoReserve(page_beg, page_end - page_beg);
+ if (!MmapFixedNoReserve(page_beg, page_end - page_beg))
+ Die();
}
}
}
diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cc
index 28c9bbabb3e9..2f0cc8d370ee 100644
--- a/lib/msan/msan_report.cc
+++ b/lib/msan/msan_report.cc
@@ -15,6 +15,7 @@
#include "msan.h"
#include "msan_chained_origin_depot.h"
#include "msan_origin.h"
+#include "msan_report.h"
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
@@ -30,8 +31,8 @@ namespace __msan {
class Decorator: public __sanitizer::SanitizerCommonDecorator {
public:
Decorator() : SanitizerCommonDecorator() { }
- const char *Origin() { return Magenta(); }
- const char *Name() { return Green(); }
+ const char *Origin() const { return Magenta(); }
+ const char *Name() const { return Green(); }
};
static void DescribeStackOrigin(const char *so, uptr pc) {
diff --git a/lib/msan/msan_report.h b/lib/msan/msan_report.h
new file mode 100644
index 000000000000..73840e417505
--- /dev/null
+++ b/lib/msan/msan_report.h
@@ -0,0 +1,34 @@
+//===-- msan_report.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of MemorySanitizer. MSan-private header for error
+/// reporting functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef MSAN_REPORT_H
+#define MSAN_REPORT_H
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+
+namespace __msan {
+
+void ReportUMR(StackTrace *stack, u32 origin);
+void ReportExpectedUMRNotFound(StackTrace *stack);
+void ReportStats();
+void ReportAtExitStatistics();
+void DescribeMemoryRange(const void *x, uptr size);
+void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
+ uptr offset);
+
+} // namespace __msan
+
+#endif // MSAN_REPORT_H
diff --git a/lib/msan/tests/CMakeLists.txt b/lib/msan/tests/CMakeLists.txt
index b460231783b8..e9f4e34bfe61 100644
--- a/lib/msan/tests/CMakeLists.txt
+++ b/lib/msan/tests/CMakeLists.txt
@@ -37,6 +37,9 @@ set(MSAN_UNITTEST_COMMON_CFLAGS
-Werror=sign-compare
-Wno-gnu-zero-variadic-macro-arguments
)
+# Remove -stdlib= which is unused when passing -nostdinc++.
+string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+
set(MSAN_UNITTEST_INSTRUMENTED_CFLAGS
${MSAN_UNITTEST_COMMON_CFLAGS}
-fsanitize=memory
@@ -106,7 +109,7 @@ macro(add_msan_tests_for_arch arch kind cflags)
DEPS ${MSAN_INST_LOADABLE_OBJECTS})
set(MSAN_TEST_OBJECTS ${MSAN_INST_TEST_OBJECTS} ${MSAN_INST_GTEST})
- set(MSAN_TEST_DEPS ${MSAN_TEST_OBJECTS} libcxx_msan_${arch}
+ set(MSAN_TEST_DEPS ${MSAN_TEST_OBJECTS} libcxx_msan_${arch}-build
${MSAN_LOADABLE_SO})
if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND MSAN_TEST_DEPS msan)
@@ -128,7 +131,8 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_LIBCXX_PATH)
set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../libcxx_msan_${arch})
add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX}
DEPS ${MSAN_RUNTIME_LIBRARIES}
- CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS})
+ CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS}
+ USE_TOOLCHAIN)
set(MSAN_LIBCXX_SO ${LIBCXX_PREFIX}/lib/libc++.so)
add_msan_tests_for_arch(${arch} "" "")
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index 074a2f609eda..29260f16e704 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -65,16 +65,15 @@ int shmdt(const void *);
#include <sys/ipc.h>
#include <sys/shm.h>
-#if !defined(__FreeBSD__)
-# include <malloc.h>
-# include <sys/sysinfo.h>
-# include <sys/vfs.h>
-# include <mntent.h>
-# include <netinet/ether.h>
-# if defined(__linux__)
-# include <sys/uio.h>
-# endif
-#else
+#if defined(__NetBSD__)
+# include <signal.h>
+# include <netinet/in.h>
+# include <sys/uio.h>
+# include <sys/mount.h>
+# include <sys/sysctl.h>
+# include <net/if.h>
+# include <net/if_ether.h>
+#elif defined(__FreeBSD__)
# include <signal.h>
# include <netinet/in.h>
# include <pthread_np.h>
@@ -90,6 +89,15 @@ extern "C" {
// ordinary function, we can declare it here to complete the tests.
void *mempcpy(void *dest, const void *src, size_t n);
}
+#else
+# include <malloc.h>
+# include <sys/sysinfo.h>
+# include <sys/vfs.h>
+# include <mntent.h>
+# include <netinet/ether.h>
+# if defined(__linux__)
+# include <sys/uio.h>
+# endif
#endif
#if defined(__i386__) || defined(__x86_64__)
@@ -103,8 +111,7 @@ void *mempcpy(void *dest, const void *src, size_t n);
# include <immintrin.h>
#endif
-// On FreeBSD procfs is not enabled by default.
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__)
# define FILE_TO_READ "/bin/cat"
# define DIR_TO_READ "/bin"
# define SUBFILE_TO_READ "cat"
@@ -717,6 +724,13 @@ TEST(MemorySanitizer, readlink) {
delete [] x;
}
+TEST(MemorySanitizer, readlinkat) {
+ char *x = new char[1000];
+ readlinkat(AT_FDCWD, SYMLINK_TO_READ, x, 1000);
+ EXPECT_NOT_POISONED(x[0]);
+ delete[] x;
+}
+
TEST(MemorySanitizer, stat) {
struct stat* st = new struct stat;
int res = stat(FILE_TO_READ, st);
@@ -738,6 +752,7 @@ TEST(MemorySanitizer, fstatat) {
close(dirfd);
}
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, statfs) {
struct statfs st;
int res = statfs("/", &st);
@@ -746,6 +761,7 @@ TEST(MemorySanitizer, statfs) {
EXPECT_NOT_POISONED(st.f_bfree);
EXPECT_NOT_POISONED(st.f_namelen);
}
+#endif
TEST(MemorySanitizer, statvfs) {
struct statvfs st;
@@ -822,8 +838,7 @@ TEST(MemorySanitizer, poll) {
close(pipefd[1]);
}
-// There is no ppoll() on FreeBSD.
-#if !defined (__FreeBSD__)
+#if !defined (__FreeBSD__) && !defined (__NetBSD__)
TEST(MemorySanitizer, ppoll) {
int* pipefd = new int[2];
int res = pipe(pipefd);
@@ -1161,6 +1176,7 @@ TEST(MemorySanitizer, gethostbyaddr) {
EXPECT_HOSTENT_NOT_POISONED(he);
}
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, gethostent_r) {
char buf[2000];
struct hostent he;
@@ -1173,7 +1189,9 @@ TEST(MemorySanitizer, gethostent_r) {
EXPECT_HOSTENT_NOT_POISONED(result);
EXPECT_NOT_POISONED(err);
}
+#endif
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, gethostbyname_r) {
char buf[2000];
struct hostent he;
@@ -1186,7 +1204,9 @@ TEST(MemorySanitizer, gethostbyname_r) {
EXPECT_HOSTENT_NOT_POISONED(result);
EXPECT_NOT_POISONED(err);
}
+#endif
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, gethostbyname_r_bad_host_name) {
char buf[2000];
struct hostent he;
@@ -1196,7 +1216,9 @@ TEST(MemorySanitizer, gethostbyname_r_bad_host_name) {
ASSERT_EQ((struct hostent *)0, result);
EXPECT_NOT_POISONED(err);
}
+#endif
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, gethostbyname_r_erange) {
char buf[5];
struct hostent he;
@@ -1206,7 +1228,9 @@ TEST(MemorySanitizer, gethostbyname_r_erange) {
ASSERT_EQ(ERANGE, errno);
EXPECT_NOT_POISONED(err);
}
+#endif
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, gethostbyname2_r) {
char buf[2000];
struct hostent he;
@@ -1220,7 +1244,9 @@ TEST(MemorySanitizer, gethostbyname2_r) {
EXPECT_HOSTENT_NOT_POISONED(result);
EXPECT_NOT_POISONED(err);
}
+#endif
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, gethostbyaddr_r) {
char buf[2000];
struct hostent he;
@@ -1236,6 +1262,7 @@ TEST(MemorySanitizer, gethostbyaddr_r) {
EXPECT_HOSTENT_NOT_POISONED(result);
EXPECT_NOT_POISONED(err);
}
+#endif
TEST(MemorySanitizer, getsockopt) {
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -1262,8 +1289,7 @@ TEST(MemorySanitizer, getcwd_gnu) {
free(res);
}
-// There's no get_current_dir_name() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, get_current_dir_name) {
char* res = get_current_dir_name();
ASSERT_TRUE(res != NULL);
@@ -1281,8 +1307,7 @@ TEST(MemorySanitizer, shmctl) {
ASSERT_GT(res, -1);
EXPECT_NOT_POISONED(ds);
- // FreeBSD does not support shmctl(IPC_INFO) and shmctl(SHM_INFO).
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
struct shminfo si;
res = shmctl(id, IPC_INFO, (struct shmid_ds *)&si);
ASSERT_GT(res, -1);
@@ -1330,8 +1355,7 @@ TEST(MemorySanitizer, shmat) {
ASSERT_GT(res, -1);
}
-// There's no random_r() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, random_r) {
int32_t x;
char z[64];
@@ -1411,8 +1435,7 @@ TEST(MemorySanitizer, realpath_null) {
free(res);
}
-// There's no canonicalize_file_name() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, canonicalize_file_name) {
const char* relpath = ".";
char* res = canonicalize_file_name(relpath);
@@ -1870,8 +1893,7 @@ TEST(MemorySanitizer, modfl) {
EXPECT_NOT_POISONED(y);
}
-// There's no sincos() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, sincos) {
double s, c;
sincos(0.2, &s, &c);
@@ -1880,8 +1902,7 @@ TEST(MemorySanitizer, sincos) {
}
#endif
-// There's no sincosf() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, sincosf) {
float s, c;
sincosf(0.2, &s, &c);
@@ -1890,8 +1911,7 @@ TEST(MemorySanitizer, sincosf) {
}
#endif
-// There's no sincosl() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, sincosl) {
long double s, c;
sincosl(0.2, &s, &c);
@@ -1953,8 +1973,7 @@ TEST(MemorySanitizer, lgammaf_r) {
EXPECT_NOT_POISONED(sgn);
}
-// There's no lgammal_r() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, lgammal_r) {
int sgn;
long double res = lgammal_r(1.1, &sgn);
@@ -1963,8 +1982,7 @@ TEST(MemorySanitizer, lgammal_r) {
}
#endif
-// There's no drand48_r() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, drand48_r) {
struct drand48_data buf;
srand48_r(0, &buf);
@@ -1974,8 +1992,7 @@ TEST(MemorySanitizer, drand48_r) {
}
#endif
-// There's no lrand48_r() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, lrand48_r) {
struct drand48_data buf;
srand48_r(0, &buf);
@@ -2260,7 +2277,7 @@ TEST(MemorySanitizer, localtime_r) {
EXPECT_NE(0U, strlen(time.tm_zone));
}
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
/* Creates a temporary file with contents similar to /etc/fstab to be used
with getmntent{_r}. */
class TempFstabFile {
@@ -2298,8 +2315,7 @@ class TempFstabFile {
};
#endif
-// There's no getmntent() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, getmntent) {
TempFstabFile fstabtmp;
ASSERT_TRUE(fstabtmp.Create());
@@ -2317,8 +2333,7 @@ TEST(MemorySanitizer, getmntent) {
}
#endif
-// There's no getmntent_r() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, getmntent_r) {
TempFstabFile fstabtmp;
ASSERT_TRUE(fstabtmp.Create());
@@ -2338,6 +2353,7 @@ TEST(MemorySanitizer, getmntent_r) {
}
#endif
+#if !defined(__NetBSD__)
TEST(MemorySanitizer, ether) {
const char *asc = "11:22:33:44:55:66";
struct ether_addr *paddr = ether_aton(asc);
@@ -2356,6 +2372,7 @@ TEST(MemorySanitizer, ether) {
ASSERT_EQ(s, buf);
ASSERT_NE(0U, strlen(buf));
}
+#endif
TEST(MemorySanitizer, mmap) {
const int size = 4096;
@@ -2376,8 +2393,7 @@ TEST(MemorySanitizer, mmap) {
}
}
-// There's no fcvt() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
// FIXME: enable and add ecvt.
// FIXME: check why msandr does nt handle fcvt.
TEST(MemorySanitizer, fcvt) {
@@ -2395,8 +2411,7 @@ TEST(MemorySanitizer, fcvt) {
}
#endif
-// There's no fcvt_long() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, fcvt_long) {
int a, b;
break_optimization(&a);
@@ -2471,11 +2486,15 @@ void SigactionHandler(int signo, siginfo_t* si, void* uc) {
ASSERT_TRUE(si != NULL);
EXPECT_NOT_POISONED(si->si_errno);
EXPECT_NOT_POISONED(si->si_pid);
-#if __linux__
-# if defined(__x86_64__)
+#ifdef _UC_MACHINE_PC
+ EXPECT_NOT_POISONED(_UC_MACHINE_PC((ucontext_t*)uc));
+#else
+# if __linux__
+# if defined(__x86_64__)
EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_RIP]);
-# elif defined(__i386__)
+# elif defined(__i386__)
EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_EIP]);
+# endif
# endif
#endif
++cnt;
@@ -3005,7 +3024,9 @@ TEST(MemorySanitizer, LongStruct) {
EXPECT_POISONED(s2.a8);
}
-#ifdef __GLIBC__
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+#define MSAN_TEST_PRLIMIT 0
+#elif defined(__GLIBC__)
#define MSAN_TEST_PRLIMIT __GLIBC_PREREQ(2, 13)
#else
#define MSAN_TEST_PRLIMIT 1
@@ -3056,9 +3077,13 @@ TEST(MemorySanitizer, getrusage) {
EXPECT_NOT_POISONED(usage.ru_nivcsw);
}
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__)
static void GetProgramPath(char *buf, size_t sz) {
+#if defined(__FreeBSD__)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+#elif defined(__NetBSD__)
+ int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
+#endif
int res = sysctl(mib, 4, buf, &sz, NULL, 0);
ASSERT_EQ(0, res);
}
@@ -3180,8 +3205,7 @@ TEST(MemorySanitizer, dlopenFailed) {
#endif // MSAN_TEST_DISABLE_DLOPEN
-// There's no sched_getaffinity() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, sched_getaffinity) {
cpu_set_t mask;
int res = sched_getaffinity(getpid(), sizeof(mask), &mask);
@@ -3329,12 +3353,14 @@ TEST(MemorySanitizer, pthread_attr_get) {
EXPECT_NOT_POISONED(v);
EXPECT_NOT_POISONED(w);
}
+#if !defined(__NetBSD__)
{
cpu_set_t v;
res = pthread_attr_getaffinity_np(&attr, sizeof(v), &v);
ASSERT_EQ(0, res);
EXPECT_NOT_POISONED(v);
}
+#endif
res = pthread_attr_destroy(&attr);
ASSERT_EQ(0, res);
}
@@ -3426,8 +3452,7 @@ TEST(MemorySanitizer, posix_memalign) {
free(p);
}
-// There's no memalign() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, memalign) {
void *p = memalign(4096, 13);
EXPECT_EQ(0U, (uintptr_t)p % 4096);
@@ -3442,8 +3467,7 @@ TEST(MemorySanitizer, valloc) {
free(a);
}
-// There's no pvalloc() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, pvalloc) {
uintptr_t PageSize = GetPageSize();
void *p = pvalloc(PageSize + 100);
@@ -3500,8 +3524,7 @@ TEST(MemorySanitizer, gethostname) {
EXPECT_NOT_POISONED(strlen(buf));
}
-// There's no sysinfo() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, sysinfo) {
struct sysinfo info;
int res = sysinfo(&info);
@@ -3598,8 +3621,7 @@ TEST(MemorySanitizer, getpwent_r) {
EXPECT_NOT_POISONED(pwdres);
}
-// There's no fgetpwent() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, fgetpwent) {
FILE *fp = fopen("/etc/passwd", "r");
struct passwd *p = fgetpwent(fp);
@@ -3622,8 +3644,7 @@ TEST(MemorySanitizer, getgrent) {
EXPECT_NOT_POISONED(p->gr_gid);
}
-// There's no fgetgrent() on FreeBSD.
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, fgetgrent) {
FILE *fp = fopen("/etc/group", "r");
struct group *grp = fgetgrent(fp);
@@ -3654,7 +3675,6 @@ TEST(MemorySanitizer, getgrent_r) {
EXPECT_NOT_POISONED(grpres);
}
-// There's no fgetgrent_r() on FreeBSD and NetBSD.
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
TEST(MemorySanitizer, fgetgrent_r) {
FILE *fp = fopen("/etc/group", "r");
@@ -4037,7 +4057,6 @@ typedef U4 V2x32 __attribute__((__vector_size__(8)));
typedef U2 V4x16 __attribute__((__vector_size__(8)));
typedef U1 V8x8 __attribute__((__vector_size__(8)));
-
V8x16 shift_sse2_left_scalar(V8x16 x, U4 y) {
return _mm_slli_epi16(x, y);
}
@@ -4385,12 +4404,14 @@ void MemCpyTest() {
EXPECT_POISONED_O(y[N/2], ox);
EXPECT_POISONED_O(y[N-1], ox);
EXPECT_NOT_POISONED(x);
+#if !defined(__NetBSD__)
void *res = mempcpy(q, x, N * sizeof(T));
ASSERT_EQ(q + N, res);
EXPECT_POISONED_O(q[0], ox);
EXPECT_POISONED_O(q[N/2], ox);
EXPECT_POISONED_O(q[N-1], ox);
EXPECT_NOT_POISONED(x);
+#endif
memmove(z, x, N * sizeof(T));
EXPECT_POISONED_O(z[0], ox);
EXPECT_POISONED_O(z[N/2], ox);