2019-08-01 22:08:18 +08:00
|
|
|
//===-- msan_interceptors.cpp ---------------------------------------------===//
|
2012-12-11 20:27:27 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2012-12-11 20:27:27 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file is a part of MemorySanitizer.
|
|
|
|
//
|
|
|
|
// Interceptors for standard library functions.
|
2012-12-12 17:54:35 +08:00
|
|
|
//
|
|
|
|
// FIXME: move as many interceptors as possible into
|
|
|
|
// sanitizer_common/sanitizer_common_interceptors.h
|
2012-12-11 20:27:27 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-11-18 18:33:15 +08:00
|
|
|
#include "interception/interception.h"
|
2012-12-11 20:27:27 +08:00
|
|
|
#include "msan.h"
|
2014-05-21 17:02:13 +08:00
|
|
|
#include "msan_chained_origin_depot.h"
|
|
|
|
#include "msan_origin.h"
|
2018-06-09 07:31:42 +08:00
|
|
|
#include "msan_report.h"
|
2014-04-04 17:47:41 +08:00
|
|
|
#include "msan_thread.h"
|
2015-01-22 00:42:30 +08:00
|
|
|
#include "msan_poisoning.h"
|
2013-02-19 17:19:16 +08:00
|
|
|
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
|
2017-12-07 05:32:57 +08:00
|
|
|
#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
|
2013-01-25 19:46:22 +08:00
|
|
|
#include "sanitizer_common/sanitizer_allocator.h"
|
2014-07-08 01:39:31 +08:00
|
|
|
#include "sanitizer_common/sanitizer_allocator_interface.h"
|
2013-09-27 19:32:21 +08:00
|
|
|
#include "sanitizer_common/sanitizer_allocator_internal.h"
|
2013-08-27 19:34:05 +08:00
|
|
|
#include "sanitizer_common/sanitizer_atomic.h"
|
2012-12-11 20:27:27 +08:00
|
|
|
#include "sanitizer_common/sanitizer_common.h"
|
2017-07-06 08:50:57 +08:00
|
|
|
#include "sanitizer_common/sanitizer_errno.h"
|
2013-01-28 21:52:49 +08:00
|
|
|
#include "sanitizer_common/sanitizer_stackdepot.h"
|
2012-12-11 20:27:27 +08:00
|
|
|
#include "sanitizer_common/sanitizer_libc.h"
|
2013-03-19 17:30:52 +08:00
|
|
|
#include "sanitizer_common/sanitizer_linux.h"
|
2014-06-25 19:30:35 +08:00
|
|
|
#include "sanitizer_common/sanitizer_tls_get_addr.h"
|
2018-11-10 10:17:32 +08:00
|
|
|
#include "sanitizer_common/sanitizer_vector.h"
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2017-12-07 05:32:57 +08:00
|
|
|
#if SANITIZER_NETBSD
|
2018-01-04 06:28:39 +08:00
|
|
|
#define fstat __fstat50
|
2017-12-07 05:32:57 +08:00
|
|
|
#define gettimeofday __gettimeofday50
|
|
|
|
#define getrusage __getrusage50
|
2018-10-30 16:16:14 +08:00
|
|
|
#define tzset __tzset50
|
2017-12-07 05:32:57 +08:00
|
|
|
#endif
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
#include <stdarg.h>
|
|
|
|
// ACHTUNG! No other system header includes in this file.
|
|
|
|
// Ideally, we should get rid of stdarg.h as well.
|
|
|
|
|
|
|
|
using namespace __msan;
|
|
|
|
|
2013-08-27 19:34:05 +08:00
|
|
|
using __sanitizer::memory_order;
|
|
|
|
using __sanitizer::atomic_load;
|
|
|
|
using __sanitizer::atomic_store;
|
|
|
|
using __sanitizer::atomic_uintptr_t;
|
|
|
|
|
2016-03-11 08:45:49 +08:00
|
|
|
DECLARE_REAL(SIZE_T, strlen, const char *s)
|
2016-03-24 05:24:28 +08:00
|
|
|
DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
|
2016-12-23 06:02:26 +08:00
|
|
|
DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n)
|
|
|
|
DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
|
2016-03-11 08:45:49 +08:00
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
// True if this is a nested interceptor.
|
|
|
|
static THREADLOCAL int in_interceptor_scope;
|
|
|
|
|
2018-07-07 01:10:51 +08:00
|
|
|
void __msan_scoped_disable_interceptor_checks() { ++in_interceptor_scope; }
|
|
|
|
void __msan_scoped_enable_interceptor_checks() { --in_interceptor_scope; }
|
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
struct InterceptorScope {
|
|
|
|
InterceptorScope() { ++in_interceptor_scope; }
|
|
|
|
~InterceptorScope() { --in_interceptor_scope; }
|
|
|
|
};
|
|
|
|
|
|
|
|
bool IsInInterceptorScope() {
|
|
|
|
return in_interceptor_scope;
|
|
|
|
}
|
|
|
|
|
2016-09-23 15:40:55 +08:00
|
|
|
static uptr allocated_for_dlsym;
|
|
|
|
static const uptr kDlsymAllocPoolSize = 1024;
|
|
|
|
static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
|
|
|
|
|
|
|
|
static bool IsInDlsymAllocPool(const void *ptr) {
|
|
|
|
uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
|
|
|
|
return off < sizeof(alloc_memory_for_dlsym);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *AllocateFromLocalPool(uptr size_in_bytes) {
|
|
|
|
uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
|
|
|
|
void *mem = (void *)&alloc_memory_for_dlsym[allocated_for_dlsym];
|
|
|
|
allocated_for_dlsym += size_in_words;
|
|
|
|
CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
|
|
|
|
return mem;
|
|
|
|
}
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
#define ENSURE_MSAN_INITED() do { \
|
2012-12-14 19:52:02 +08:00
|
|
|
CHECK(!msan_init_is_running); \
|
2012-12-11 20:27:27 +08:00
|
|
|
if (!msan_inited) { \
|
|
|
|
__msan_init(); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
// Check that [x, x+n) range is unpoisoned.
|
2017-11-28 07:25:38 +08:00
|
|
|
#define CHECK_UNPOISONED_0(x, n) \
|
|
|
|
do { \
|
|
|
|
sptr __offset = __msan_test_shadow(x, n); \
|
|
|
|
if (__msan::IsInSymbolizer()) break; \
|
|
|
|
if (__offset >= 0 && __msan::flags()->report_umrs) { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
|
|
|
(void)sp; \
|
|
|
|
ReportUMRInsideAddressRange(__func__, x, n, __offset); \
|
|
|
|
__msan::PrintWarningWithOrigin( \
|
|
|
|
pc, bp, __msan_get_origin((const char *)x + __offset)); \
|
|
|
|
if (__msan::flags()->halt_on_error) { \
|
|
|
|
Printf("Exiting\n"); \
|
|
|
|
Die(); \
|
|
|
|
} \
|
|
|
|
} \
|
2012-12-11 20:27:27 +08:00
|
|
|
} while (0)
|
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
// Check that [x, x+n) range is unpoisoned unless we are in a nested
|
|
|
|
// interceptor.
|
2013-06-28 19:02:43 +08:00
|
|
|
#define CHECK_UNPOISONED(x, n) \
|
|
|
|
do { \
|
|
|
|
if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
|
2017-09-02 08:09:57 +08:00
|
|
|
} while (0)
|
2013-05-22 20:50:26 +08:00
|
|
|
|
2015-04-07 02:00:26 +08:00
|
|
|
#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))
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
|
2012-12-11 20:27:27 +08:00
|
|
|
void *file) {
|
|
|
|
ENSURE_MSAN_INITED();
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
|
2012-12-11 20:27:27 +08:00
|
|
|
if (res > 0)
|
|
|
|
__msan_unpoison(ptr, res *size);
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2013-07-02 22:49:24 +08:00
|
|
|
INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
|
|
|
|
return (char *)__msan_memcpy(dest, src, n) + n;
|
|
|
|
}
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MEMPCPY INTERCEPT_FUNCTION(mempcpy)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MEMPCPY
|
|
|
|
#endif
|
2013-07-02 22:49:24 +08:00
|
|
|
|
2013-11-02 07:49:48 +08:00
|
|
|
INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
void *res = REAL(memccpy)(dest, src, c, n);
|
|
|
|
CHECK(!res || (res >= dest && res <= (char *)dest + n));
|
|
|
|
SIZE_T sz = res ? (char *)res - (char *)dest : n;
|
|
|
|
CHECK_UNPOISONED(src, sz);
|
|
|
|
__msan_unpoison(dest, sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2016-12-16 04:11:12 +08:00
|
|
|
INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
|
|
|
|
return __msan_memmove(dest, src, n);
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
|
2012-12-11 20:27:27 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
CHECK_NE(memptr, 0);
|
2017-07-19 03:11:04 +08:00
|
|
|
int res = msan_posix_memalign(memptr, alignment, size, &stack);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(memptr, sizeof(*memptr));
|
|
|
|
return res;
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2017-07-19 03:11:04 +08:00
|
|
|
INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {
|
2013-09-02 17:24:53 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_memalign(alignment, size, &stack);
|
2014-07-04 15:30:34 +08:00
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MEMALIGN
|
|
|
|
#endif
|
2014-07-04 15:30:34 +08:00
|
|
|
|
2017-07-19 03:11:04 +08:00
|
|
|
INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
|
2014-07-04 15:30:34 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_aligned_alloc(alignment, size, &stack);
|
2013-09-02 17:24:53 +08:00
|
|
|
}
|
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2017-07-19 03:11:04 +08:00
|
|
|
INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {
|
2014-06-25 19:30:35 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2017-07-19 03:11:04 +08:00
|
|
|
void *ptr = msan_memalign(alignment, size, &stack);
|
|
|
|
if (ptr)
|
|
|
|
DTLS_on_libc_memalign(ptr, size);
|
2014-06-25 19:30:35 +08:00
|
|
|
return ptr;
|
|
|
|
}
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
|
|
|
|
#endif
|
2014-01-24 17:14:11 +08:00
|
|
|
|
2013-09-02 17:24:53 +08:00
|
|
|
INTERCEPTOR(void *, valloc, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_valloc(size, &stack);
|
2013-09-02 17:24:53 +08:00
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2013-09-02 17:24:53 +08:00
|
|
|
INTERCEPTOR(void *, pvalloc, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_pvalloc(size, &stack);
|
2013-09-02 17:24:53 +08:00
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_PVALLOC
|
|
|
|
#endif
|
2013-09-02 17:24:53 +08:00
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(void, free, void *ptr) {
|
2013-09-16 19:03:31 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2016-09-23 15:40:55 +08:00
|
|
|
if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
|
2013-09-16 19:03:31 +08:00
|
|
|
MsanDeallocate(&stack, ptr);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(void, cfree, void *ptr) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
2016-09-23 15:40:55 +08:00
|
|
|
if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
|
2014-03-27 21:29:29 +08:00
|
|
|
MsanDeallocate(&stack, ptr);
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_CFREE
|
|
|
|
#endif
|
2014-03-27 21:29:29 +08:00
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
|
2014-07-08 01:39:31 +08:00
|
|
|
return __sanitizer_get_allocated_size(ptr);
|
2014-03-27 21:29:29 +08:00
|
|
|
}
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \
|
|
|
|
INTERCEPT_FUNCTION(malloc_usable_size)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
|
|
|
|
#endif
|
2014-03-27 21:29:29 +08:00
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
// This function actually returns a struct by value, but we can't unpoison a
|
2015-09-16 23:12:25 +08:00
|
|
|
// temporary! The following is equivalent on all supported platforms but
|
|
|
|
// aarch64 (which uses a different register for sret value). We have a test
|
|
|
|
// to confirm that.
|
2018-08-14 05:07:27 +08:00
|
|
|
INTERCEPTOR(void, mallinfo, __sanitizer_struct_mallinfo *sret) {
|
2015-09-16 23:12:25 +08:00
|
|
|
#ifdef __aarch64__
|
|
|
|
uptr r8;
|
|
|
|
asm volatile("mov %0,x8" : "=r" (r8));
|
2018-08-14 05:07:27 +08:00
|
|
|
sret = reinterpret_cast<__sanitizer_struct_mallinfo*>(r8);
|
2015-09-16 23:12:25 +08:00
|
|
|
#endif
|
2014-03-27 21:29:29 +08:00
|
|
|
REAL(memset)(sret, 0, sizeof(*sret));
|
|
|
|
__msan_unpoison(sret, sizeof(*sret));
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLINFO
|
|
|
|
#endif
|
2014-03-27 21:29:29 +08:00
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(int, mallopt, int cmd, int value) {
|
2018-10-26 06:15:44 +08:00
|
|
|
return 0;
|
2014-03-27 21:29:29 +08:00
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLOPT
|
|
|
|
#endif
|
2014-03-27 21:29:29 +08:00
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(void, malloc_stats, void) {
|
|
|
|
// FIXME: implement, but don't call REAL(malloc_stats)!
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
|
|
|
|
#endif
|
2014-03-27 21:29:29 +08:00
|
|
|
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTOR(char *, strcpy, char *dest, const char *src) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T n = REAL(strlen)(src);
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(src + n, 0);
|
2019-09-12 07:19:48 +08:00
|
|
|
char *res = REAL(strcpy)(dest, src);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n + 1, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T copy_size = REAL(strnlen)(src, n);
|
2012-12-11 20:27:27 +08:00
|
|
|
if (copy_size < n)
|
|
|
|
copy_size++; // trailing \0
|
2019-09-12 07:19:48 +08:00
|
|
|
char *res = REAL(strncpy)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, copy_size, &stack);
|
2014-07-22 08:10:08 +08:00
|
|
|
__msan_unpoison(dest + copy_size, n - copy_size);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {
|
2013-07-01 23:19:37 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2013-07-01 23:19:37 +08:00
|
|
|
SIZE_T n = REAL(strlen)(src);
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(src + n, 0);
|
2019-09-12 07:19:48 +08:00
|
|
|
char *res = REAL(stpcpy)(dest, src);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n + 1, &stack);
|
2013-07-01 23:19:37 +08:00
|
|
|
return res;
|
|
|
|
}
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_STPCPY
|
|
|
|
#endif
|
2013-07-01 23:19:37 +08:00
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(char *, strdup, char *src) {
|
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2015-01-14 22:59:46 +08:00
|
|
|
// On FreeBSD strdup() leverages strlen().
|
|
|
|
InterceptorScope interceptor_scope;
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T n = REAL(strlen)(src);
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(src + n, 0);
|
2012-12-11 20:27:27 +08:00
|
|
|
char *res = REAL(strdup)(src);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(res, src, n + 1, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2013-03-14 19:10:36 +08:00
|
|
|
INTERCEPTOR(char *, __strdup, char *src) {
|
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2013-03-14 19:10:36 +08:00
|
|
|
SIZE_T n = REAL(strlen)(src);
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(src + n, 0);
|
2013-03-14 19:10:36 +08:00
|
|
|
char *res = REAL(__strdup)(src);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(res, src, n + 1, &stack);
|
2013-03-14 19:10:36 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___STRDUP
|
|
|
|
#endif
|
2013-03-14 19:10:36 +08:00
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
char *res = REAL(gcvt)(number, ndigit, buf);
|
2014-11-18 18:33:15 +08:00
|
|
|
SIZE_T n = REAL(strlen)(buf);
|
|
|
|
__msan_unpoison(buf, n + 1);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2017-12-06 09:43:38 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_GCVT INTERCEPT_FUNCTION(gcvt)
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_GCVT
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTOR(char *, strcat, char *dest, const char *src) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T src_size = REAL(strlen)(src);
|
|
|
|
SIZE_T dest_size = REAL(strlen)(dest);
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(src + src_size, 0);
|
|
|
|
CHECK_UNPOISONED_STRING(dest + dest_size, 0);
|
2019-09-12 07:19:48 +08:00
|
|
|
char *res = REAL(strcat)(dest, src);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T dest_size = REAL(strlen)(dest);
|
2013-12-14 00:31:59 +08:00
|
|
|
SIZE_T copy_size = REAL(strnlen)(src, n);
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(dest + dest_size, 0);
|
2019-09-12 07:19:48 +08:00
|
|
|
char *res = REAL(strncat)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);
|
2013-12-14 00:31:59 +08:00
|
|
|
__msan_unpoison(dest + dest_size + copy_size, 1); // \0
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-01-28 21:45:58 +08:00
|
|
|
// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
|
|
|
|
// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
|
|
|
|
#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
|
|
|
|
ENSURE_MSAN_INITED(); \
|
|
|
|
ret_type res = REAL(func)(__VA_ARGS__); \
|
2014-11-18 18:33:15 +08:00
|
|
|
__msan_unpoison(endptr, sizeof(*endptr)); \
|
2014-01-28 21:45:58 +08:00
|
|
|
return res;
|
|
|
|
|
2014-12-08 18:41:28 +08:00
|
|
|
#define INTERCEPTOR_STRTO(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \
|
|
|
|
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2014-12-08 18:41:28 +08:00
|
|
|
#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
|
|
|
|
int base) { \
|
|
|
|
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base); \
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2014-12-08 18:41:28 +08:00
|
|
|
#define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
|
|
|
|
void *loc) { \
|
|
|
|
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2014-12-08 18:41:28 +08:00
|
|
|
#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
|
|
|
|
int base, void *loc) { \
|
2014-01-28 21:45:58 +08:00
|
|
|
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc); \
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2017-12-14 09:20:16 +08:00
|
|
|
#if SANITIZER_NETBSD
|
|
|
|
#define INTERCEPTORS_STRTO(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)
|
|
|
|
|
|
|
|
#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type)
|
|
|
|
|
|
|
|
#else
|
2014-12-08 18:41:28 +08:00
|
|
|
#define INTERCEPTORS_STRTO(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)
|
|
|
|
|
|
|
|
#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \
|
|
|
|
INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type)
|
2017-12-14 09:20:16 +08:00
|
|
|
#endif
|
2014-12-08 18:41:28 +08:00
|
|
|
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTORS_STRTO(double, strtod, char)
|
|
|
|
INTERCEPTORS_STRTO(float, strtof, char)
|
|
|
|
INTERCEPTORS_STRTO(long double, strtold, char)
|
|
|
|
INTERCEPTORS_STRTO_BASE(long, strtol, char)
|
|
|
|
INTERCEPTORS_STRTO_BASE(long long, strtoll, char)
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char)
|
|
|
|
INTERCEPTORS_STRTO_BASE(u64, strtouq, char)
|
|
|
|
|
|
|
|
INTERCEPTORS_STRTO(double, wcstod, wchar_t)
|
|
|
|
INTERCEPTORS_STRTO(float, wcstof, wchar_t)
|
|
|
|
INTERCEPTORS_STRTO(long double, wcstold, wchar_t)
|
|
|
|
INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)
|
|
|
|
INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)
|
2014-12-08 18:41:28 +08:00
|
|
|
|
2017-12-14 09:20:16 +08:00
|
|
|
#if SANITIZER_NETBSD
|
|
|
|
#define INTERCEPT_STRTO(func) \
|
|
|
|
INTERCEPT_FUNCTION(func); \
|
|
|
|
INTERCEPT_FUNCTION(func##_l);
|
|
|
|
#else
|
2014-12-08 18:41:28 +08:00
|
|
|
#define INTERCEPT_STRTO(func) \
|
|
|
|
INTERCEPT_FUNCTION(func); \
|
|
|
|
INTERCEPT_FUNCTION(func##_l); \
|
|
|
|
INTERCEPT_FUNCTION(__##func##_l); \
|
|
|
|
INTERCEPT_FUNCTION(__##func##_internal);
|
2017-12-14 09:20:16 +08:00
|
|
|
#endif
|
2014-12-08 18:41:28 +08:00
|
|
|
|
2013-10-14 19:52:40 +08:00
|
|
|
|
2014-05-08 17:50:59 +08:00
|
|
|
// FIXME: support *wprintf in common format interceptors.
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(vswprintf)(str, size, format, ap);
|
2014-11-18 18:33:15 +08:00
|
|
|
if (res >= 0) {
|
2012-12-11 20:27:27 +08:00
|
|
|
__msan_unpoison(str, 4 * (res + 1));
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
|
|
|
int res = vswprintf(str, size, format, ap);
|
|
|
|
va_end(ap);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-04-14 22:59:42 +08:00
|
|
|
#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
|
|
|
|
ENSURE_MSAN_INITED(); \
|
2018-02-15 10:48:20 +08:00
|
|
|
InterceptorScope interceptor_scope; \
|
2014-04-14 22:59:42 +08:00
|
|
|
ret_type res = REAL(func)(s, __VA_ARGS__); \
|
|
|
|
if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1)); \
|
|
|
|
return res;
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
|
2013-11-02 09:01:35 +08:00
|
|
|
__sanitizer_tm *tm) {
|
2014-04-14 22:59:42 +08:00
|
|
|
INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
|
|
|
|
__sanitizer_tm *tm, void *loc) {
|
|
|
|
INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
|
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2014-04-14 22:59:42 +08:00
|
|
|
INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
|
|
|
|
__sanitizer_tm *tm, void *loc) {
|
|
|
|
INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
|
|
|
|
loc);
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___STRFTIME_L
|
|
|
|
#endif
|
2014-04-14 22:59:42 +08:00
|
|
|
|
|
|
|
INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
|
|
|
|
__sanitizer_tm *tm) {
|
|
|
|
INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
|
|
|
|
__sanitizer_tm *tm, void *loc) {
|
|
|
|
INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,
|
|
|
|
loc);
|
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2014-04-14 22:59:42 +08:00
|
|
|
INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
|
|
|
|
__sanitizer_tm *tm, void *loc) {
|
|
|
|
INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
|
|
|
|
loc);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-07-02 21:34:44 +08:00
|
|
|
INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(mbtowc)(dest, src, n);
|
|
|
|
if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-12-01 06:15:39 +08:00
|
|
|
INTERCEPTOR(SIZE_T, mbrtowc, wchar_t *dest, const char *src, SIZE_T n,
|
|
|
|
void *ps) {
|
2013-07-02 21:34:44 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
|
|
|
|
if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
|
|
|
|
INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-11 20:27:27 +08:00
|
|
|
wchar_t *res = REAL(wmemcpy)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2013-07-02 22:49:24 +08:00
|
|
|
INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
|
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2013-07-02 22:49:24 +08:00
|
|
|
wchar_t *res = REAL(wmempcpy)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
|
2013-07-02 22:49:24 +08:00
|
|
|
return res;
|
|
|
|
}
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_WMEMPCPY INTERCEPT_FUNCTION(wmempcpy)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_WMEMPCPY
|
|
|
|
#endif
|
2013-07-02 22:49:24 +08:00
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
CHECK(MEM_IS_APP(s));
|
|
|
|
ENSURE_MSAN_INITED();
|
2014-11-25 02:17:04 +08:00
|
|
|
wchar_t *res = REAL(wmemset)(s, c, n);
|
2012-12-11 20:27:27 +08:00
|
|
|
__msan_unpoison(s, n * sizeof(wchar_t));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-11 20:27:27 +08:00
|
|
|
wchar_t *res = REAL(wmemmove)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(wcscmp)(s1, s2);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(gettimeofday)(tv, tz);
|
|
|
|
if (tv)
|
|
|
|
__msan_unpoison(tv, 16);
|
|
|
|
if (tz)
|
|
|
|
__msan_unpoison(tz, 8);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
char *res = REAL(fcvt)(x, a, b, c);
|
2014-11-18 18:33:15 +08:00
|
|
|
__msan_unpoison(b, sizeof(*b));
|
|
|
|
__msan_unpoison(c, sizeof(*c));
|
|
|
|
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2017-12-06 09:44:41 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt)
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_FCVT
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
|
|
|
INTERCEPTOR(char *, getenv, char *name) {
|
2014-11-27 22:28:57 +08:00
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(getenv)(name);
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
char *res = REAL(getenv)(name);
|
2014-11-18 18:33:15 +08:00
|
|
|
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-08-01 19:14:14 +08:00
|
|
|
extern char **environ;
|
|
|
|
|
|
|
|
static void UnpoisonEnviron() {
|
|
|
|
char **envp = environ;
|
|
|
|
for (; *envp; ++envp) {
|
|
|
|
__msan_unpoison(envp, sizeof(*envp));
|
|
|
|
__msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
|
|
|
|
}
|
|
|
|
// Trailing NULL pointer.
|
|
|
|
__msan_unpoison(envp, sizeof(*envp));
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
|
|
|
|
ENSURE_MSAN_INITED();
|
2017-09-02 08:09:57 +08:00
|
|
|
CHECK_UNPOISONED_STRING(name, 0);
|
2013-08-01 19:14:14 +08:00
|
|
|
int res = REAL(setenv)(name, value, overwrite);
|
|
|
|
if (!res) UnpoisonEnviron();
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, putenv, char *string) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(putenv)(string);
|
|
|
|
if (!res) UnpoisonEnviron();
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Adding Msan support to FreeBSD
Summary:
Enabling the memory sanitizer support for FreeBSD, most of unit tests are compatible.
- Adding fstat and stressor_r interceptors.
- Updating the struct link_map access since most likely the struct Obj_Entry had been updated since.
- Disabling few unit tests until further work is needed (or we can assume it can work in real world code).
Patch by: David CARLIER
Reviewers: vitalybuka, krytarowski
Reviewed By: vitalybuka
Subscribers: eugenis, dim, srhines, emaste, kubamracek, mgorny, fedor.sergeev, hintonda, llvm-commits, #sanitizers
Differential Revision: https://reviews.llvm.org/D43080
llvm-svn: 326644
2018-03-03 19:43:11 +08:00
|
|
|
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
|
2018-01-04 06:28:39 +08:00
|
|
|
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
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2016-05-20 00:03:10 +08:00
|
|
|
INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__fxstat)(magic, fd, buf);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT
|
|
|
|
#endif
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2016-05-20 00:03:10 +08:00
|
|
|
INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__fxstat64)(magic, fd, buf);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat64_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT64
|
|
|
|
#endif
|
|
|
|
|
2017-12-14 09:20:16 +08:00
|
|
|
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
|
2016-05-20 00:03:10 +08:00
|
|
|
INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(fstatat)(fd, pathname, buf, flags);
|
|
|
|
if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat)
|
|
|
|
#else
|
|
|
|
INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
|
|
|
|
int flags) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);
|
|
|
|
if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)
|
|
|
|
#endif
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2016-05-20 00:03:10 +08:00
|
|
|
INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
|
|
|
|
int flags) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);
|
|
|
|
if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTATAT64
|
|
|
|
#endif
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, pipe, int pipefd[2]) {
|
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(pipe)(pipefd);
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(pipe)(pipefd);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(pipefd, sizeof(int[2]));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-04-08 21:45:12 +08:00
|
|
|
INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(pipe2)(pipefd, flags);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(pipefd, sizeof(int[2]));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(socketpair)(domain, type, protocol, sv);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(sv, sizeof(int[2]));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
char *res = REAL(fgets_unlocked)(s, size, stream);
|
|
|
|
if (res)
|
|
|
|
__msan_unpoison(s, REAL(strlen)(s) + 1);
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2019-10-01 01:49:48 +08:00
|
|
|
#define INTERCEPTOR_GETRLIMIT_BODY(func, resource, rlim) \
|
|
|
|
if (msan_init_is_running) \
|
|
|
|
return REAL(getrlimit)(resource, rlim); \
|
|
|
|
ENSURE_MSAN_INITED(); \
|
|
|
|
int res = REAL(func)(resource, rlim); \
|
|
|
|
if (!res) \
|
|
|
|
__msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); \
|
|
|
|
return res
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
|
2019-10-01 01:49:48 +08:00
|
|
|
INTERCEPTOR_GETRLIMIT_BODY(getrlimit, resource, rlim);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2019-10-01 01:49:48 +08:00
|
|
|
INTERCEPTOR(int, __getrlimit, int resource, void *rlim) {
|
|
|
|
INTERCEPTOR_GETRLIMIT_BODY(__getrlimit, resource, rlim);
|
|
|
|
}
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
|
2016-02-17 09:26:57 +08:00
|
|
|
if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(getrlimit64)(resource, rlim);
|
2016-02-17 09:26:57 +08:00
|
|
|
if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit,
|
|
|
|
void *old_rlimit) {
|
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz);
|
|
|
|
int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
|
|
|
|
if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2016-02-17 09:26:57 +08:00
|
|
|
|
|
|
|
INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
|
|
|
|
void *old_rlimit) {
|
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz);
|
|
|
|
int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
|
|
|
|
if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-10-01 01:49:48 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___GETRLIMIT INTERCEPT_FUNCTION(__getrlimit)
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)
|
2016-02-17 09:26:57 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit)
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64)
|
2014-11-26 18:51:49 +08:00
|
|
|
#else
|
2019-10-01 01:49:48 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___GETRLIMIT
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
|
2016-02-17 09:26:57 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_PRLIMIT
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64
|
2014-11-26 18:51:49 +08:00
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-01-23 18:43:38 +08:00
|
|
|
INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(gethostname)(name, len);
|
|
|
|
if (!res) {
|
|
|
|
SIZE_T real_len = REAL(strnlen)(name, len);
|
|
|
|
if (real_len < len)
|
|
|
|
++real_len;
|
|
|
|
__msan_unpoison(name, real_len);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
|
|
|
|
int timeout) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
|
|
|
|
if (res > 0) {
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2017-10-26 01:09:05 +08:00
|
|
|
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
|
|
|
|
int timeout, void *sigmask) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
|
|
|
|
if (res > 0) {
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
|
2012-12-11 20:27:27 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2016-09-23 15:40:55 +08:00
|
|
|
if (UNLIKELY(!msan_inited))
|
2012-12-11 20:27:27 +08:00
|
|
|
// Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
|
2016-09-23 15:40:55 +08:00
|
|
|
return AllocateFromLocalPool(nmemb * size);
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_calloc(nmemb, size, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
|
2012-12-11 20:27:27 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2016-09-23 15:40:55 +08:00
|
|
|
if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
|
|
|
|
uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
|
|
|
|
uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
|
2016-09-26 16:11:21 +08:00
|
|
|
void *new_ptr;
|
|
|
|
if (UNLIKELY(!msan_inited)) {
|
|
|
|
new_ptr = AllocateFromLocalPool(copy_size);
|
|
|
|
} else {
|
|
|
|
copy_size = size;
|
2017-07-19 03:11:04 +08:00
|
|
|
new_ptr = msan_malloc(copy_size, &stack);
|
2016-09-26 16:11:21 +08:00
|
|
|
}
|
2016-09-23 15:40:55 +08:00
|
|
|
internal_memcpy(new_ptr, ptr, copy_size);
|
|
|
|
return new_ptr;
|
|
|
|
}
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_realloc(ptr, size, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2019-05-02 01:33:01 +08:00
|
|
|
INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
return msan_reallocarray(ptr, nmemb, size, &stack);
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, malloc, SIZE_T size) {
|
2012-12-11 20:27:27 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2016-09-23 15:40:55 +08:00
|
|
|
if (UNLIKELY(!msan_inited))
|
|
|
|
// Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
|
|
|
|
return AllocateFromLocalPool(size);
|
2017-07-19 03:11:04 +08:00
|
|
|
return msan_malloc(size, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2015-01-22 21:33:16 +08:00
|
|
|
void __msan_allocated_memory(const void *data, uptr size) {
|
2013-01-28 21:52:49 +08:00
|
|
|
GET_MALLOC_STACK_TRACE;
|
2015-01-22 21:33:16 +08:00
|
|
|
if (flags()->poison_in_malloc) {
|
|
|
|
stack.tag = STACK_TRACE_TAG_POISON;
|
|
|
|
PoisonMemory(data, size, &stack);
|
2013-01-28 21:52:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-13 07:20:24 +08:00
|
|
|
void __msan_copy_shadow(void *dest, const void *src, uptr n) {
|
|
|
|
GET_STORE_STACK_TRACE;
|
|
|
|
MoveShadowAndOrigin(dest, src, n, &stack);
|
|
|
|
}
|
|
|
|
|
2015-07-18 07:28:00 +08:00
|
|
|
void __sanitizer_dtor_callback(const void *data, uptr size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
if (flags()->poison_in_dtor) {
|
|
|
|
stack.tag = STACK_TRACE_TAG_POISON;
|
|
|
|
PoisonMemory(data, size, &stack);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-07 08:13:54 +08:00
|
|
|
template <class Mmap>
|
|
|
|
static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
|
|
|
|
int prot, int flags, int fd, OFF64_T offset) {
|
2020-03-20 04:19:28 +08:00
|
|
|
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))) {
|
2014-02-14 17:49:29 +08:00
|
|
|
if (flags & map_fixed) {
|
2017-07-06 08:50:57 +08:00
|
|
|
errno = errno_EINVAL;
|
2014-02-14 17:49:29 +08:00
|
|
|
return (void *)-1;
|
|
|
|
} else {
|
2015-10-01 08:22:21 +08:00
|
|
|
addr = nullptr;
|
2014-02-14 17:49:29 +08:00
|
|
|
}
|
|
|
|
}
|
2018-03-07 08:13:54 +08:00
|
|
|
void *res = real_mmap(addr, length, prot, flags, fd, offset);
|
2020-03-20 04:19:28 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-01-17 21:42:17 +08:00
|
|
|
INTERCEPTOR(int, getrusage, int who, void *usage) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(getrusage)(who, usage);
|
|
|
|
if (res == 0) {
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(usage, __sanitizer::struct_rusage_sz);
|
2013-01-17 21:42:17 +08:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-04-23 22:01:57 +08:00
|
|
|
class SignalHandlerScope {
|
|
|
|
public:
|
2014-05-08 05:23:12 +08:00
|
|
|
SignalHandlerScope() {
|
|
|
|
if (MsanThread *t = GetCurrentThread())
|
|
|
|
t->EnterSignalHandler();
|
|
|
|
}
|
|
|
|
~SignalHandlerScope() {
|
|
|
|
if (MsanThread *t = GetCurrentThread())
|
|
|
|
t->LeaveSignalHandler();
|
|
|
|
}
|
2014-04-23 22:01:57 +08:00
|
|
|
};
|
|
|
|
|
2013-08-27 19:34:05 +08:00
|
|
|
// sigactions_mu guarantees atomicity of sigaction() and signal() calls.
|
|
|
|
// Access to sigactions[] is gone with relaxed atomics to avoid data race with
|
|
|
|
// the signal handler.
|
2013-04-04 16:22:52 +08:00
|
|
|
const int kMaxSignals = 1024;
|
2013-08-27 19:34:05 +08:00
|
|
|
static atomic_uintptr_t sigactions[kMaxSignals];
|
2013-04-04 16:22:52 +08:00
|
|
|
static StaticSpinMutex sigactions_mu;
|
|
|
|
|
|
|
|
static void SignalHandler(int signo) {
|
2014-04-23 22:01:57 +08:00
|
|
|
SignalHandlerScope signal_handler_scope;
|
2013-08-27 22:08:15 +08:00
|
|
|
ScopedThreadLocalStateBackup stlsb;
|
2013-08-27 20:59:39 +08:00
|
|
|
UnpoisonParam(1);
|
|
|
|
|
2013-04-05 22:40:25 +08:00
|
|
|
typedef void (*signal_cb)(int x);
|
2013-08-27 19:34:05 +08:00
|
|
|
signal_cb cb =
|
|
|
|
(signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
|
2014-11-18 18:33:15 +08:00
|
|
|
cb(signo);
|
2013-04-04 16:22:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void SignalAction(int signo, void *si, void *uc) {
|
2014-04-23 22:01:57 +08:00
|
|
|
SignalHandlerScope signal_handler_scope;
|
2013-08-27 22:08:15 +08:00
|
|
|
ScopedThreadLocalStateBackup stlsb;
|
2013-06-27 15:50:56 +08:00
|
|
|
UnpoisonParam(3);
|
2013-08-27 19:10:04 +08:00
|
|
|
__msan_unpoison(si, sizeof(__sanitizer_sigaction));
|
2013-04-04 17:03:56 +08:00
|
|
|
__msan_unpoison(uc, __sanitizer::ucontext_t_sz);
|
2013-04-04 16:22:52 +08:00
|
|
|
|
|
|
|
typedef void (*sigaction_cb)(int, void *, void *);
|
2013-08-27 19:34:05 +08:00
|
|
|
sigaction_cb cb =
|
|
|
|
(sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
|
2014-11-18 18:33:15 +08:00
|
|
|
cb(signo, si, uc);
|
2013-04-04 16:22:52 +08:00
|
|
|
}
|
|
|
|
|
2017-09-06 05:08:56 +08:00
|
|
|
static void read_sigaction(const __sanitizer_sigaction *act) {
|
|
|
|
CHECK_UNPOISONED(&act->sa_flags, sizeof(act->sa_flags));
|
|
|
|
if (act->sa_flags & __sanitizer::sa_siginfo)
|
|
|
|
CHECK_UNPOISONED(&act->sigaction, sizeof(act->sigaction));
|
|
|
|
else
|
|
|
|
CHECK_UNPOISONED(&act->handler, sizeof(act->handler));
|
|
|
|
CHECK_UNPOISONED(&act->sa_mask, sizeof(act->sa_mask));
|
|
|
|
}
|
|
|
|
|
2013-03-13 17:01:40 +08:00
|
|
|
extern "C" int pthread_attr_init(void *attr);
|
|
|
|
extern "C" int pthread_attr_destroy(void *attr);
|
2013-10-22 22:31:30 +08:00
|
|
|
|
|
|
|
static void *MsanThreadStartFunc(void *arg) {
|
2014-04-04 17:47:41 +08:00
|
|
|
MsanThread *t = (MsanThread *)arg;
|
|
|
|
SetCurrentThread(t);
|
|
|
|
return t->ThreadStart();
|
2013-10-22 22:31:30 +08:00
|
|
|
}
|
2013-03-13 17:01:40 +08:00
|
|
|
|
|
|
|
INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
|
|
|
|
void * param) {
|
|
|
|
ENSURE_MSAN_INITED(); // for GetTlsSize()
|
|
|
|
__sanitizer_pthread_attr_t myattr;
|
2015-10-01 08:22:21 +08:00
|
|
|
if (!attr) {
|
2013-03-13 17:01:40 +08:00
|
|
|
pthread_attr_init(&myattr);
|
|
|
|
attr = &myattr;
|
|
|
|
}
|
2013-03-19 17:30:52 +08:00
|
|
|
|
2014-02-24 16:53:26 +08:00
|
|
|
AdjustStackSize(attr);
|
2013-03-13 17:01:40 +08:00
|
|
|
|
2014-04-04 17:47:41 +08:00
|
|
|
MsanThread *t = MsanThread::Create(callback, param);
|
2013-10-22 22:31:30 +08:00
|
|
|
|
2014-04-04 17:47:41 +08:00
|
|
|
int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);
|
2013-10-22 22:31:30 +08:00
|
|
|
|
2013-03-13 17:01:40 +08:00
|
|
|
if (attr == &myattr)
|
|
|
|
pthread_attr_destroy(&myattr);
|
2013-04-01 22:47:21 +08:00
|
|
|
if (!res) {
|
|
|
|
__msan_unpoison(th, __sanitizer::pthread_t_sz);
|
|
|
|
}
|
2013-03-13 17:01:40 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-07-16 00:11:39 +08:00
|
|
|
INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
|
|
|
|
void (*dtor)(void *value)) {
|
2014-04-04 17:47:41 +08:00
|
|
|
if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);
|
2013-07-05 20:31:07 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(pthread_key_create)(key, dtor);
|
|
|
|
if (!res && key)
|
|
|
|
__msan_unpoison(key, sizeof(*key));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-12-06 09:16:49 +08:00
|
|
|
#if SANITIZER_NETBSD
|
2019-11-04 08:10:59 +08:00
|
|
|
INTERCEPTOR(int, __libc_thr_keycreate, __sanitizer_pthread_key_t *m,
|
|
|
|
void (*dtor)(void *value))
|
|
|
|
ALIAS(WRAPPER_NAME(pthread_key_create));
|
2017-12-06 09:16:49 +08:00
|
|
|
#endif
|
|
|
|
|
2013-07-30 20:54:34 +08:00
|
|
|
INTERCEPTOR(int, pthread_join, void *th, void **retval) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(pthread_join)(th, retval);
|
|
|
|
if (!res && retval)
|
|
|
|
__msan_unpoison(retval, sizeof(*retval));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-09-13 19:27:38 +08:00
|
|
|
extern char *tzname[2];
|
|
|
|
|
2014-01-23 16:43:12 +08:00
|
|
|
INTERCEPTOR(void, tzset, int fake) {
|
2013-09-13 19:27:38 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2018-11-04 23:30:38 +08:00
|
|
|
InterceptorScope interceptor_scope;
|
2014-01-23 16:43:12 +08:00
|
|
|
REAL(tzset)(fake);
|
2013-09-13 19:27:38 +08:00
|
|
|
if (tzname[0])
|
|
|
|
__msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);
|
|
|
|
if (tzname[1])
|
|
|
|
__msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-27 19:32:21 +08:00
|
|
|
struct MSanAtExitRecord {
|
|
|
|
void (*func)(void *arg);
|
|
|
|
void *arg;
|
|
|
|
};
|
|
|
|
|
2018-11-10 10:17:32 +08:00
|
|
|
struct InterceptorContext {
|
|
|
|
BlockingMutex atexit_mu;
|
|
|
|
Vector<struct MSanAtExitRecord *> AtExitStack;
|
|
|
|
|
|
|
|
InterceptorContext()
|
|
|
|
: AtExitStack() {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static ALIGNED(64) char interceptor_placeholder[sizeof(InterceptorContext)];
|
|
|
|
InterceptorContext *interceptor_ctx() {
|
|
|
|
return reinterpret_cast<InterceptorContext*>(&interceptor_placeholder[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MSanAtExitWrapper() {
|
|
|
|
MSanAtExitRecord *r;
|
|
|
|
{
|
|
|
|
BlockingMutexLock l(&interceptor_ctx()->atexit_mu);
|
|
|
|
|
|
|
|
uptr element = interceptor_ctx()->AtExitStack.Size() - 1;
|
|
|
|
r = interceptor_ctx()->AtExitStack[element];
|
|
|
|
interceptor_ctx()->AtExitStack.PopBack();
|
|
|
|
}
|
|
|
|
|
|
|
|
UnpoisonParam(1);
|
|
|
|
((void(*)())r->func)();
|
|
|
|
InternalFree(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MSanCxaAtExitWrapper(void *arg) {
|
2013-09-27 19:32:21 +08:00
|
|
|
UnpoisonParam(1);
|
|
|
|
MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
|
2019-02-14 10:51:55 +08:00
|
|
|
// libc before 2.27 had race which caused occasional double handler execution
|
|
|
|
// https://sourceware.org/ml/libc-alpha/2017-08/msg01204.html
|
|
|
|
if (!r->func)
|
|
|
|
return;
|
2014-11-18 18:33:15 +08:00
|
|
|
r->func(r->arg);
|
2019-02-14 10:51:55 +08:00
|
|
|
r->func = nullptr;
|
2013-09-27 19:32:21 +08:00
|
|
|
}
|
|
|
|
|
2018-11-10 10:17:32 +08:00
|
|
|
static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso);
|
|
|
|
|
2013-09-27 19:32:21 +08:00
|
|
|
// Unpoison argument shadow for C++ module destructors.
|
|
|
|
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
|
|
|
|
void *dso_handle) {
|
|
|
|
if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
|
2018-11-10 10:17:32 +08:00
|
|
|
return setup_at_exit_wrapper((void(*)())func, arg, dso_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unpoison argument shadow for C++ module destructors.
|
|
|
|
INTERCEPTOR(int, atexit, void (*func)()) {
|
|
|
|
// Avoid calling real atexit as it is unrechable on at least on Linux.
|
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(__cxa_atexit)((void (*)(void *a))func, 0, 0);
|
|
|
|
return setup_at_exit_wrapper((void(*)())func, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) {
|
2013-09-27 19:32:21 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
MSanAtExitRecord *r =
|
|
|
|
(MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
|
2018-11-10 10:17:32 +08:00
|
|
|
r->func = (void(*)(void *a))f;
|
2013-09-27 19:32:21 +08:00
|
|
|
r->arg = arg;
|
2018-11-10 10:17:32 +08:00
|
|
|
int res;
|
|
|
|
if (!dso) {
|
|
|
|
// NetBSD does not preserve the 2nd argument if dso is equal to 0
|
|
|
|
// Store ctx in a local stack-like structure
|
|
|
|
|
|
|
|
BlockingMutexLock l(&interceptor_ctx()->atexit_mu);
|
|
|
|
|
|
|
|
res = REAL(__cxa_atexit)((void (*)(void *a))MSanAtExitWrapper, 0, 0);
|
|
|
|
if (!res) {
|
|
|
|
interceptor_ctx()->AtExitStack.PushBack(r);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
res = REAL(__cxa_atexit)(MSanCxaAtExitWrapper, r, dso);
|
|
|
|
}
|
|
|
|
return res;
|
2013-09-27 19:32:21 +08:00
|
|
|
}
|
|
|
|
|
2014-09-04 18:36:14 +08:00
|
|
|
static void BeforeFork() {
|
|
|
|
StackDepotLockAll();
|
|
|
|
ChainedOriginDepotLockAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void AfterFork() {
|
|
|
|
ChainedOriginDepotUnlockAll();
|
|
|
|
StackDepotUnlockAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, fork, void) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
BeforeFork();
|
|
|
|
int pid = REAL(fork)();
|
|
|
|
AfterFork();
|
|
|
|
return pid;
|
|
|
|
}
|
|
|
|
|
2018-02-20 23:43:07 +08:00
|
|
|
// NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly
|
|
|
|
// with MSan.
|
|
|
|
#if SANITIZER_LINUX
|
2019-04-11 07:23:17 +08:00
|
|
|
INTERCEPTOR(int, openpty, int *aparent, int *aworker, char *name,
|
2015-08-19 04:36:48 +08:00
|
|
|
const void *termp, const void *winp) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
InterceptorScope interceptor_scope;
|
2019-04-11 07:23:17 +08:00
|
|
|
int res = REAL(openpty)(aparent, aworker, name, termp, winp);
|
2015-08-19 04:36:48 +08:00
|
|
|
if (!res) {
|
2019-04-11 07:23:17 +08:00
|
|
|
__msan_unpoison(aparent, sizeof(*aparent));
|
|
|
|
__msan_unpoison(aworker, sizeof(*aworker));
|
2015-08-19 04:36:48 +08:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2018-02-20 23:43:07 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_OPENPTY INTERCEPT_FUNCTION(openpty)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_OPENPTY
|
|
|
|
#endif
|
2015-08-19 04:36:48 +08:00
|
|
|
|
2018-02-20 23:43:07 +08:00
|
|
|
// NetBSD ships with forkpty(3) in -lutil, that needs to be prebuilt explicitly
|
|
|
|
// with MSan.
|
|
|
|
#if SANITIZER_LINUX
|
2019-04-11 07:23:17 +08:00
|
|
|
INTERCEPTOR(int, forkpty, int *aparent, char *name, const void *termp,
|
2015-08-19 04:36:48 +08:00
|
|
|
const void *winp) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
InterceptorScope interceptor_scope;
|
2019-04-11 07:23:17 +08:00
|
|
|
int res = REAL(forkpty)(aparent, name, termp, winp);
|
2015-08-19 04:36:48 +08:00
|
|
|
if (res != -1)
|
2019-04-11 07:23:17 +08:00
|
|
|
__msan_unpoison(aparent, sizeof(*aparent));
|
2015-08-19 04:36:48 +08:00
|
|
|
return res;
|
|
|
|
}
|
2018-02-20 23:43:07 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_FORKPTY INTERCEPT_FUNCTION(forkpty)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_FORKPTY
|
|
|
|
#endif
|
2015-08-19 04:36:48 +08:00
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
struct MSanInterceptorContext {
|
|
|
|
bool in_interceptor_scope;
|
|
|
|
};
|
|
|
|
|
2013-10-03 23:43:59 +08:00
|
|
|
namespace __msan {
|
|
|
|
|
|
|
|
int OnExit() {
|
2013-10-03 23:22:29 +08:00
|
|
|
// FIXME: ask frontend whether we need to return failure.
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-01 08:22:21 +08:00
|
|
|
} // namespace __msan
|
2013-10-03 23:43:59 +08:00
|
|
|
|
2013-11-11 19:28:30 +08:00
|
|
|
// A version of CHECK_UNPOISONED using a saved scope value. Used in common
|
2013-05-23 19:51:47 +08:00
|
|
|
// interceptors.
|
2013-06-28 19:02:43 +08:00
|
|
|
#define CHECK_UNPOISONED_CTX(ctx, x, n) \
|
|
|
|
do { \
|
|
|
|
if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
|
|
|
|
CHECK_UNPOISONED_0(x, n); \
|
|
|
|
} while (0)
|
2013-05-22 20:50:26 +08:00
|
|
|
|
2019-05-17 07:46:15 +08:00
|
|
|
#define MSAN_INTERCEPT_FUNC(name) \
|
|
|
|
do { \
|
|
|
|
if (!INTERCEPT_FUNCTION(name)) \
|
|
|
|
VReport(1, "MemorySanitizer: failed to intercept '%s'\n'", #name); \
|
2013-11-11 19:28:30 +08:00
|
|
|
} while (0)
|
|
|
|
|
2019-05-17 07:46:15 +08:00
|
|
|
#define MSAN_INTERCEPT_FUNC_VER(name, ver) \
|
|
|
|
do { \
|
|
|
|
if (!INTERCEPT_FUNCTION_VER(name, ver)) \
|
|
|
|
VReport(1, "MemorySanitizer: failed to intercept '%s@@%s'\n", #name, \
|
|
|
|
#ver); \
|
2016-04-28 05:24:21 +08:00
|
|
|
} while (0)
|
|
|
|
|
2013-11-11 19:28:30 +08:00
|
|
|
#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
|
2016-04-28 05:24:21 +08:00
|
|
|
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
|
|
|
|
MSAN_INTERCEPT_FUNC_VER(name, ver)
|
2014-03-06 21:26:09 +08:00
|
|
|
#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \
|
2013-07-09 20:07:59 +08:00
|
|
|
UnpoisonParam(count)
|
2013-01-18 19:17:23 +08:00
|
|
|
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
|
2013-05-22 20:50:26 +08:00
|
|
|
__msan_unpoison(ptr, size)
|
|
|
|
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
|
2013-06-28 19:02:43 +08:00
|
|
|
CHECK_UNPOISONED_CTX(ctx, ptr, size)
|
2014-03-06 21:26:09 +08:00
|
|
|
#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \
|
2013-10-03 22:12:09 +08:00
|
|
|
__msan_unpoison(ptr, size)
|
2013-10-24 21:20:34 +08:00
|
|
|
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
|
|
|
|
if (msan_init_is_running) return REAL(func)(__VA_ARGS__); \
|
2016-02-17 15:12:18 +08:00
|
|
|
ENSURE_MSAN_INITED(); \
|
2013-10-24 21:20:34 +08:00
|
|
|
MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \
|
|
|
|
ctx = (void *)&msan_ctx; \
|
|
|
|
(void)ctx; \
|
|
|
|
InterceptorScope interceptor_scope; \
|
2016-02-17 15:12:18 +08:00
|
|
|
__msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */
|
2015-01-21 16:54:01 +08:00
|
|
|
#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
|
|
|
|
do { \
|
|
|
|
} while (false)
|
2013-05-22 20:50:26 +08:00
|
|
|
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
|
|
|
|
do { \
|
2013-01-18 21:12:56 +08:00
|
|
|
} while (false)
|
2013-05-29 17:09:58 +08:00
|
|
|
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
|
|
|
|
do { \
|
|
|
|
} while (false)
|
|
|
|
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
|
|
|
|
do { \
|
|
|
|
} while (false)
|
2013-01-18 21:12:56 +08:00
|
|
|
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
|
2013-05-29 17:09:58 +08:00
|
|
|
do { \
|
|
|
|
} while (false) // FIXME
|
2013-10-29 18:30:39 +08:00
|
|
|
#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
|
|
|
|
do { \
|
|
|
|
} while (false) // FIXME
|
2013-08-12 21:19:53 +08:00
|
|
|
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
|
2013-10-03 23:22:29 +08:00
|
|
|
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
|
2015-11-19 08:55:45 +08:00
|
|
|
#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
|
|
|
|
do { \
|
|
|
|
link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle)); \
|
|
|
|
if (filename && map) \
|
|
|
|
ForEachMappedRegion(map, __msan_unpoison); \
|
2015-01-30 20:43:52 +08:00
|
|
|
} while (false)
|
2014-05-27 20:37:52 +08:00
|
|
|
|
2015-05-16 08:34:15 +08:00
|
|
|
#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \
|
|
|
|
if (MsanThread *t = GetCurrentThread()) { \
|
|
|
|
*begin = t->tls_begin(); \
|
|
|
|
*end = t->tls_end(); \
|
|
|
|
} else { \
|
|
|
|
*begin = *end = 0; \
|
|
|
|
}
|
|
|
|
|
2016-12-23 06:02:26 +08:00
|
|
|
#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
|
|
|
|
{ \
|
|
|
|
(void)ctx; \
|
2019-03-02 09:33:52 +08:00
|
|
|
return __msan_memset(block, c, size); \
|
2016-12-23 06:02:26 +08:00
|
|
|
}
|
|
|
|
#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
|
|
|
|
{ \
|
|
|
|
(void)ctx; \
|
2019-03-02 09:33:52 +08:00
|
|
|
return __msan_memmove(to, from, size); \
|
2016-12-23 06:02:26 +08:00
|
|
|
}
|
|
|
|
#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
|
|
|
|
{ \
|
|
|
|
(void)ctx; \
|
2019-03-02 09:33:52 +08:00
|
|
|
return __msan_memcpy(to, from, size); \
|
2016-12-23 06:02:26 +08:00
|
|
|
}
|
|
|
|
|
2017-06-28 06:52:38 +08:00
|
|
|
#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
|
|
|
|
do { \
|
|
|
|
GET_STORE_STACK_TRACE; \
|
|
|
|
CopyShadowAndOrigin(to, from, size, &stack); \
|
|
|
|
__msan_unpoison(to + size, 1); \
|
2017-06-01 17:37:22 +08:00
|
|
|
} while (false)
|
|
|
|
|
2018-03-07 08:13:54 +08:00
|
|
|
#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)
|
|
|
|
|
[sanitizer] Add memset, memmove, and memcpy to the common interceptors
Summary:
Currently, sanitizer_common_interceptors.inc has an implicit, undocumented
assumption that the sanitizer including it has previously declared
interceptors for memset and memmove. Since the memset, memmove, and memcpy
routines require interception by many sanitizers, we add them to the
set of common interceptions, both to address the undocumented assumption
and to speed future tool development. They are intercepted under a new
flag intercept_intrin.
The tsan interceptors are removed in favor of the new common versions. The
asan and msan interceptors for these are more complex (they incur extra
interception steps and their function bodies are exposed to the compiler)
so they opt out of the common versions and keep their own.
Reviewers: vitalybuka
Subscribers: zhaoqin, llvm-commits, kcc
Differential Revision: http://reviews.llvm.org/D18465
llvm-svn: 264451
2016-03-26 03:33:45 +08:00
|
|
|
#include "sanitizer_common/sanitizer_platform_interceptors.h"
|
2013-01-18 21:01:18 +08:00
|
|
|
#include "sanitizer_common/sanitizer_common_interceptors.inc"
|
2013-01-18 14:43:13 +08:00
|
|
|
|
2017-11-10 10:06:59 +08:00
|
|
|
static uptr signal_impl(int signo, uptr cb);
|
|
|
|
static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
|
|
|
|
__sanitizer_sigaction *oldact);
|
|
|
|
|
|
|
|
#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signo, act, oldact) \
|
|
|
|
{ return sigaction_impl(signo, act, oldact); }
|
|
|
|
|
|
|
|
#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \
|
|
|
|
{ \
|
|
|
|
handler = signal_impl(signo, handler); \
|
2018-06-07 15:55:20 +08:00
|
|
|
InterceptorScope interceptor_scope; \
|
2017-11-10 10:06:59 +08:00
|
|
|
return REAL(func)(signo, handler); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "sanitizer_common/sanitizer_signal_interceptors.inc"
|
2017-11-10 10:06:50 +08:00
|
|
|
|
|
|
|
static int sigaction_impl(int signo, const __sanitizer_sigaction *act,
|
|
|
|
__sanitizer_sigaction *oldact) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
if (act) read_sigaction(act);
|
|
|
|
int res;
|
|
|
|
if (flags()->wrap_signals) {
|
|
|
|
SpinMutexLock lock(&sigactions_mu);
|
|
|
|
CHECK_LT(signo, kMaxSignals);
|
|
|
|
uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
|
|
|
|
__sanitizer_sigaction new_act;
|
|
|
|
__sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;
|
|
|
|
if (act) {
|
|
|
|
REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));
|
|
|
|
uptr cb = (uptr)pnew_act->sigaction;
|
|
|
|
uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
|
|
|
|
? (uptr)SignalAction
|
|
|
|
: (uptr)SignalHandler;
|
|
|
|
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
|
|
|
atomic_store(&sigactions[signo], cb, memory_order_relaxed);
|
2017-11-10 12:27:47 +08:00
|
|
|
pnew_act->sigaction = (decltype(pnew_act->sigaction))new_cb;
|
2017-11-10 10:06:50 +08:00
|
|
|
}
|
|
|
|
}
|
2017-12-07 05:32:57 +08:00
|
|
|
res = REAL(SIGACTION_SYMNAME)(signo, pnew_act, oldact);
|
2017-11-10 10:06:50 +08:00
|
|
|
if (res == 0 && oldact) {
|
|
|
|
uptr cb = (uptr)oldact->sigaction;
|
2017-11-11 11:03:34 +08:00
|
|
|
if (cb == (uptr)SignalAction || cb == (uptr)SignalHandler) {
|
2017-11-10 12:27:47 +08:00
|
|
|
oldact->sigaction = (decltype(oldact->sigaction))old_cb;
|
2017-11-10 10:06:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-12-07 05:32:57 +08:00
|
|
|
res = REAL(SIGACTION_SYMNAME)(signo, act, oldact);
|
2017-11-10 10:06:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (res == 0 && oldact) {
|
|
|
|
__msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uptr signal_impl(int signo, uptr cb) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
if (flags()->wrap_signals) {
|
|
|
|
CHECK_LT(signo, kMaxSignals);
|
|
|
|
SpinMutexLock lock(&sigactions_mu);
|
|
|
|
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
|
|
|
atomic_store(&sigactions[signo], cb, memory_order_relaxed);
|
|
|
|
cb = (uptr)&SignalHandler;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cb;
|
|
|
|
}
|
|
|
|
|
2013-04-11 22:37:04 +08:00
|
|
|
#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
|
2013-09-19 16:35:16 +08:00
|
|
|
#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
|
|
|
|
do { \
|
|
|
|
} while (false)
|
|
|
|
#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
|
|
|
|
do { \
|
|
|
|
} while (false)
|
2013-04-11 22:37:04 +08:00
|
|
|
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
|
|
|
|
#include "sanitizer_common/sanitizer_common_syscalls.inc"
|
Add NetBSD syscall hooks skeleton in sanitizers
Summary:
Implement the skeleton of NetBSD syscall hooks for use with sanitizers.
Add a script that generates the rules to handle syscalls
on NetBSD: generate_netbsd_syscalls.awk. It has been written
in NetBSD awk(1) (patched nawk) and is compatible with gawk.
Generate lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
that is a public header for applications, and included as:
<sanitizer_common/sanitizer_platform_limits_netbsd.h>.
Generate sanitizer_syscalls_netbsd.inc that defines all the
syscall rules for NetBSD. This file is modeled after the Linux
specific file: sanitizer_common_syscalls.inc.
Start recognizing NetBSD syscalls with existing sanitizers:
ASan, ESan, HWASan, TSan, MSan.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, vitalybuka, kcc, dvyukov, eugenis
Reviewed By: vitalybuka
Subscribers: hintonda, kubamracek, mgorny, llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D42048
llvm-svn: 325206
2018-02-15 10:43:02 +08:00
|
|
|
#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
|
2013-04-11 22:37:04 +08:00
|
|
|
|
2016-04-26 06:25:49 +08:00
|
|
|
struct dlinfo {
|
|
|
|
char *dli_fname;
|
|
|
|
void *dli_fbase;
|
|
|
|
char *dli_sname;
|
|
|
|
void *dli_saddr;
|
|
|
|
};
|
|
|
|
|
|
|
|
INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
|
|
|
|
void *ctx;
|
|
|
|
COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info);
|
|
|
|
int res = REAL(dladdr)(addr, info);
|
|
|
|
if (res != 0) {
|
|
|
|
__msan_unpoison(info, sizeof(*info));
|
|
|
|
if (info->dli_fname)
|
|
|
|
__msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
|
|
|
|
if (info->dli_sname)
|
|
|
|
__msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(char *, dlerror, int fake) {
|
|
|
|
void *ctx;
|
|
|
|
COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);
|
|
|
|
char *res = REAL(dlerror)(fake);
|
|
|
|
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
|
|
|
|
void *data);
|
|
|
|
struct dl_iterate_phdr_data {
|
|
|
|
dl_iterate_phdr_cb callback;
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
|
|
|
|
void *data) {
|
|
|
|
if (info) {
|
|
|
|
__msan_unpoison(info, size);
|
|
|
|
if (info->dlpi_phdr && info->dlpi_phnum)
|
|
|
|
__msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
|
|
|
|
if (info->dlpi_name)
|
|
|
|
__msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
|
|
|
|
}
|
|
|
|
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
|
|
|
|
UnpoisonParam(3);
|
|
|
|
return cbdata->callback(info, size, cbdata->data);
|
|
|
|
}
|
|
|
|
|
2017-12-07 05:32:57 +08:00
|
|
|
INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
void *p = REAL(shmat)(shmid, shmaddr, shmflg);
|
|
|
|
if (p != (void *)-1) {
|
|
|
|
__sanitizer_shmid_ds ds;
|
|
|
|
int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);
|
|
|
|
if (!res) {
|
|
|
|
__msan_unpoison(p, ds.shm_segsz);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2016-04-26 06:25:49 +08:00
|
|
|
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
|
|
|
|
void *ctx;
|
|
|
|
COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);
|
|
|
|
dl_iterate_phdr_data cbdata;
|
|
|
|
cbdata.callback = callback;
|
|
|
|
cbdata.data = data;
|
|
|
|
int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-06-28 06:52:38 +08:00
|
|
|
// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
|
|
|
|
INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
wchar_t *res = REAL(wcschr)(s, wc, ps);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
|
|
|
|
INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
GET_STORE_STACK_TRACE;
|
|
|
|
wchar_t *res = REAL(wcscpy)(dest, src);
|
|
|
|
CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
|
|
|
|
&stack);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
|
2017-06-28 06:52:38 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
GET_STORE_STACK_TRACE;
|
|
|
|
SIZE_T copy_size = REAL(wcsnlen)(src, n);
|
|
|
|
if (copy_size < n) copy_size++; // trailing \0
|
2019-09-12 07:19:48 +08:00
|
|
|
wchar_t *res = REAL(wcsncpy)(dest, src, n);
|
2017-06-28 06:52:38 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
|
|
|
|
__msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
// These interface functions reside here so that they can use
|
2014-07-11 16:57:57 +08:00
|
|
|
// REAL(memset), etc.
|
2013-04-23 21:34:19 +08:00
|
|
|
void __msan_unpoison(const void *a, uptr size) {
|
2012-12-11 20:27:27 +08:00
|
|
|
if (!MEM_IS_APP(a)) return;
|
2015-01-22 00:42:30 +08:00
|
|
|
SetShadow(a, size, 0);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2013-04-23 21:34:19 +08:00
|
|
|
void __msan_poison(const void *a, uptr size) {
|
2012-12-11 20:27:27 +08:00
|
|
|
if (!MEM_IS_APP(a)) return;
|
2015-01-22 00:42:30 +08:00
|
|
|
SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void __msan_poison_stack(void *a, uptr size) {
|
|
|
|
if (!MEM_IS_APP(a)) return;
|
2015-01-22 00:42:30 +08:00
|
|
|
SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2019-05-10 05:50:57 +08:00
|
|
|
void __msan_unpoison_param(uptr n) { UnpoisonParam(n); }
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
void __msan_clear_and_unpoison(void *a, uptr size) {
|
2014-07-11 16:57:57 +08:00
|
|
|
REAL(memset)(a, 0, size);
|
2015-01-22 00:42:30 +08:00
|
|
|
SetShadow(a, size, 0);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2014-03-18 21:45:19 +08:00
|
|
|
void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
|
2014-04-04 17:47:41 +08:00
|
|
|
if (!msan_inited) return internal_memcpy(dest, src, n);
|
2015-06-27 16:39:12 +08:00
|
|
|
if (msan_init_is_running || __msan::IsInSymbolizer())
|
|
|
|
return REAL(memcpy)(dest, src, n);
|
2014-03-18 21:45:19 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
GET_STORE_STACK_TRACE;
|
2014-07-11 16:57:57 +08:00
|
|
|
void *res = REAL(memcpy)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n, &stack);
|
2014-03-18 21:45:19 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *__msan_memset(void *s, int c, SIZE_T n) {
|
2014-04-04 17:47:41 +08:00
|
|
|
if (!msan_inited) return internal_memset(s, c, n);
|
|
|
|
if (msan_init_is_running) return REAL(memset)(s, c, n);
|
2014-03-18 21:45:19 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-07-11 16:57:57 +08:00
|
|
|
void *res = REAL(memset)(s, c, n);
|
2014-03-18 21:45:19 +08:00
|
|
|
__msan_unpoison(s, n);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
|
2014-04-04 17:47:41 +08:00
|
|
|
if (!msan_inited) return internal_memmove(dest, src, n);
|
|
|
|
if (msan_init_is_running) return REAL(memmove)(dest, src, n);
|
2014-03-18 21:45:19 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
GET_STORE_STACK_TRACE;
|
|
|
|
void *res = REAL(memmove)(dest, src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
MoveShadowAndOrigin(dest, src, n, &stack);
|
2014-03-18 21:45:19 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-03-21 18:12:17 +08:00
|
|
|
void __msan_unpoison_string(const char* s) {
|
|
|
|
if (!MEM_IS_APP(s)) return;
|
|
|
|
__msan_unpoison(s, REAL(strlen)(s) + 1);
|
|
|
|
}
|
|
|
|
|
2014-03-18 21:45:19 +08:00
|
|
|
namespace __msan {
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
void InitializeInterceptors() {
|
|
|
|
static int inited = 0;
|
|
|
|
CHECK_EQ(inited, 0);
|
2018-11-10 10:17:32 +08:00
|
|
|
|
|
|
|
new(interceptor_ctx()) InterceptorContext();
|
|
|
|
|
2014-05-07 21:24:28 +08:00
|
|
|
InitializeCommonInterceptors();
|
2017-11-10 10:06:59 +08:00
|
|
|
InitializeSignalInterceptors();
|
2013-01-18 14:43:13 +08:00
|
|
|
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(posix_memalign);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_MEMALIGN;
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
|
2013-09-02 17:24:53 +08:00
|
|
|
INTERCEPT_FUNCTION(valloc);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_PVALLOC;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(malloc);
|
|
|
|
INTERCEPT_FUNCTION(calloc);
|
|
|
|
INTERCEPT_FUNCTION(realloc);
|
2019-05-02 01:33:01 +08:00
|
|
|
INTERCEPT_FUNCTION(reallocarray);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(free);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_CFREE;
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_MALLINFO;
|
|
|
|
MSAN_MAYBE_INTERCEPT_MALLOPT;
|
|
|
|
MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(fread);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
|
2013-11-02 07:49:48 +08:00
|
|
|
INTERCEPT_FUNCTION(memccpy);
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_MEMPCPY;
|
2016-12-16 04:11:12 +08:00
|
|
|
INTERCEPT_FUNCTION(bcopy);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wmemset);
|
|
|
|
INTERCEPT_FUNCTION(wmemcpy);
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_WMEMPCPY;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wmemmove);
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPT_FUNCTION(strcpy);
|
|
|
|
MSAN_MAYBE_INTERCEPT_STPCPY;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(strdup);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___STRDUP;
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPT_FUNCTION(strncpy);
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_GCVT;
|
2019-09-12 07:19:48 +08:00
|
|
|
INTERCEPT_FUNCTION(strcat);
|
|
|
|
INTERCEPT_FUNCTION(strncat);
|
2014-12-08 18:41:28 +08:00
|
|
|
INTERCEPT_STRTO(strtod);
|
|
|
|
INTERCEPT_STRTO(strtof);
|
|
|
|
INTERCEPT_STRTO(strtold);
|
|
|
|
INTERCEPT_STRTO(strtol);
|
|
|
|
INTERCEPT_STRTO(strtoul);
|
|
|
|
INTERCEPT_STRTO(strtoll);
|
|
|
|
INTERCEPT_STRTO(strtoull);
|
2017-12-06 06:07:26 +08:00
|
|
|
INTERCEPT_STRTO(strtouq);
|
2014-12-08 18:41:28 +08:00
|
|
|
INTERCEPT_STRTO(wcstod);
|
|
|
|
INTERCEPT_STRTO(wcstof);
|
|
|
|
INTERCEPT_STRTO(wcstold);
|
|
|
|
INTERCEPT_STRTO(wcstol);
|
|
|
|
INTERCEPT_STRTO(wcstoul);
|
|
|
|
INTERCEPT_STRTO(wcstoll);
|
|
|
|
INTERCEPT_STRTO(wcstoull);
|
2016-04-28 05:24:21 +08:00
|
|
|
#ifdef SANITIZER_NLDBL_VERSION
|
|
|
|
INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION);
|
|
|
|
INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION);
|
|
|
|
#else
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(vswprintf);
|
|
|
|
INTERCEPT_FUNCTION(swprintf);
|
2016-04-28 05:24:21 +08:00
|
|
|
#endif
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(strftime);
|
2014-04-14 22:59:42 +08:00
|
|
|
INTERCEPT_FUNCTION(strftime_l);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___STRFTIME_L;
|
2014-04-14 22:59:42 +08:00
|
|
|
INTERCEPT_FUNCTION(wcsftime);
|
|
|
|
INTERCEPT_FUNCTION(wcsftime_l);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___WCSFTIME_L;
|
2013-07-02 21:34:44 +08:00
|
|
|
INTERCEPT_FUNCTION(mbtowc);
|
|
|
|
INTERCEPT_FUNCTION(mbrtowc);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wcslen);
|
2017-03-15 07:48:37 +08:00
|
|
|
INTERCEPT_FUNCTION(wcsnlen);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wcschr);
|
|
|
|
INTERCEPT_FUNCTION(wcscpy);
|
2017-03-15 07:48:37 +08:00
|
|
|
INTERCEPT_FUNCTION(wcsncpy);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wcscmp);
|
|
|
|
INTERCEPT_FUNCTION(getenv);
|
2013-08-01 19:14:14 +08:00
|
|
|
INTERCEPT_FUNCTION(setenv);
|
|
|
|
INTERCEPT_FUNCTION(putenv);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(gettimeofday);
|
Disable absent functions in MSan/NetBSD interceptors
Summary:
Disable for NetBSD missing functions missing in this OS:
- mempcpy,
- __libc_memalign,
- malloc_usable_size,
- stpcpy,
- gcvt,
- wmempcpy,
- fcvt.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, dvyukov, eugenis, vitalybuka, kcc
Reviewed By: vitalybuka
Subscribers: llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40764
llvm-svn: 319866
2017-12-06 09:03:11 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_FCVT;
|
2018-01-04 06:28:39 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_FSTAT;
|
2016-05-20 00:03:10 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___FXSTAT;
|
|
|
|
MSAN_INTERCEPT_FSTATAT;
|
|
|
|
MSAN_MAYBE_INTERCEPT___FXSTAT64;
|
|
|
|
MSAN_MAYBE_INTERCEPT___FXSTATAT64;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(pipe);
|
2013-04-08 21:45:12 +08:00
|
|
|
INTERCEPT_FUNCTION(pipe2);
|
|
|
|
INTERCEPT_FUNCTION(socketpair);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(getrlimit);
|
2019-10-01 01:49:48 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___GETRLIMIT;
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
|
2016-02-17 09:26:57 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_PRLIMIT;
|
|
|
|
MSAN_MAYBE_INTERCEPT_PRLIMIT64;
|
2013-01-23 18:43:38 +08:00
|
|
|
INTERCEPT_FUNCTION(gethostname);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
|
|
|
|
MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
|
2013-01-17 21:42:17 +08:00
|
|
|
INTERCEPT_FUNCTION(dladdr);
|
2013-11-01 00:58:44 +08:00
|
|
|
INTERCEPT_FUNCTION(dlerror);
|
2013-05-16 21:00:25 +08:00
|
|
|
INTERCEPT_FUNCTION(dl_iterate_phdr);
|
2013-01-17 21:42:17 +08:00
|
|
|
INTERCEPT_FUNCTION(getrusage);
|
2016-02-26 13:56:54 +08:00
|
|
|
#if defined(__mips__)
|
|
|
|
INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2");
|
|
|
|
#else
|
2013-03-13 17:01:40 +08:00
|
|
|
INTERCEPT_FUNCTION(pthread_create);
|
2016-02-26 13:56:54 +08:00
|
|
|
#endif
|
2013-07-05 20:31:07 +08:00
|
|
|
INTERCEPT_FUNCTION(pthread_key_create);
|
2017-12-06 09:16:49 +08:00
|
|
|
|
|
|
|
#if SANITIZER_NETBSD
|
|
|
|
INTERCEPT_FUNCTION(__libc_thr_keycreate);
|
|
|
|
#endif
|
|
|
|
|
2013-07-30 20:54:34 +08:00
|
|
|
INTERCEPT_FUNCTION(pthread_join);
|
2013-09-13 19:27:38 +08:00
|
|
|
INTERCEPT_FUNCTION(tzset);
|
2018-11-10 10:17:32 +08:00
|
|
|
INTERCEPT_FUNCTION(atexit);
|
2013-09-27 19:32:21 +08:00
|
|
|
INTERCEPT_FUNCTION(__cxa_atexit);
|
2013-10-29 10:48:49 +08:00
|
|
|
INTERCEPT_FUNCTION(shmat);
|
2014-09-04 18:36:14 +08:00
|
|
|
INTERCEPT_FUNCTION(fork);
|
2018-02-20 23:43:07 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_OPENPTY;
|
|
|
|
MSAN_MAYBE_INTERCEPT_FORKPTY;
|
2013-10-22 22:31:30 +08:00
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
inited = 1;
|
|
|
|
}
|
2015-10-01 08:22:21 +08:00
|
|
|
} // namespace __msan
|