diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:48 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:48 +0000 |
commit | 93c1b73a09a52d4a265f683bf1954b08bb430049 (patch) | |
tree | 5543464d74945196cc890e9d9099e5d0660df7eb /lib/msan | |
parent | 0d8e7490d6e8a13a8f0977d9b7771803b9f64ea0 (diff) | |
download | src-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-format | 1 | ||||
-rw-r--r-- | lib/msan/CMakeLists.txt | 24 | ||||
-rw-r--r-- | lib/msan/msan.cc | 15 | ||||
-rw-r--r-- | lib/msan/msan.h | 21 | ||||
-rw-r--r-- | lib/msan/msan_allocator.cc | 48 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 136 | ||||
-rw-r--r-- | lib/msan/msan_interface_internal.h | 6 | ||||
-rw-r--r-- | lib/msan/msan_linux.cc | 3 | ||||
-rw-r--r-- | lib/msan/msan_new_delete.cc | 5 | ||||
-rw-r--r-- | lib/msan/msan_poisoning.cc | 3 | ||||
-rw-r--r-- | lib/msan/msan_report.cc | 5 | ||||
-rw-r--r-- | lib/msan/msan_report.h | 34 | ||||
-rw-r--r-- | lib/msan/tests/CMakeLists.txt | 8 | ||||
-rw-r--r-- | lib/msan/tests/msan_test.cc | 145 |
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); |