2012-12-11 20:27:27 +08:00
|
|
|
//===-- msan_interceptors.cc ----------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// 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"
|
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"
|
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"
|
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"
|
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-03-11 08:45:49 +08:00
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if SANITIZER_FREEBSD
|
|
|
|
#define __errno_location __error
|
|
|
|
#endif
|
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
// True if this is a nested interceptor.
|
|
|
|
static THREADLOCAL int in_interceptor_scope;
|
|
|
|
|
2014-02-10 17:37:03 +08:00
|
|
|
extern "C" int *__errno_location(void);
|
|
|
|
|
2013-05-22 20:50:26 +08:00
|
|
|
struct InterceptorScope {
|
|
|
|
InterceptorScope() { ++in_interceptor_scope; }
|
|
|
|
~InterceptorScope() { --in_interceptor_scope; }
|
|
|
|
};
|
|
|
|
|
|
|
|
bool IsInInterceptorScope() {
|
|
|
|
return in_interceptor_scope;
|
|
|
|
}
|
|
|
|
|
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.
|
2014-11-14 06:40:59 +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); \
|
|
|
|
} 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))
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T res = REAL(fread)(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
|
|
|
#if !SANITIZER_FREEBSD
|
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
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2015-04-07 02:00:26 +08:00
|
|
|
CHECK_UNPOISONED_STRING(path, 0)
|
2012-12-13 14:31:40 +08:00
|
|
|
SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
|
2012-12-11 20:27:27 +08:00
|
|
|
if (res > 0)
|
|
|
|
__msan_unpoison(buf, res);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
return __msan_memcpy(dest, src, n);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
return __msan_memmove(dest, src, n);
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
|
2012-12-11 20:27:27 +08:00
|
|
|
return __msan_memset(s, c, n);
|
|
|
|
}
|
|
|
|
|
2013-07-04 21:19:41 +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_EQ(alignment & (alignment - 1), 0);
|
|
|
|
CHECK_NE(memptr, 0);
|
2015-10-01 08:22:21 +08:00
|
|
|
*memptr = MsanReallocate(&stack, nullptr, size, alignment, false);
|
2013-04-23 21:27:36 +08:00
|
|
|
CHECK_NE(*memptr, 0);
|
|
|
|
__msan_unpoison(memptr, sizeof(*memptr));
|
2012-12-11 20:27:27 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2013-09-02 17:24:53 +08:00
|
|
|
INTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
CHECK_EQ(boundary & (boundary - 1), 0);
|
2015-10-01 08:22:21 +08:00
|
|
|
void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
|
2014-07-04 15:30:34 +08:00
|
|
|
return ptr;
|
|
|
|
}
|
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
|
|
|
|
|
|
|
INTERCEPTOR(void *, aligned_alloc, SIZE_T boundary, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
CHECK_EQ(boundary & (boundary - 1), 0);
|
2015-10-01 08:22:21 +08:00
|
|
|
void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
|
2013-09-02 17:24:53 +08:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2014-06-25 19:30:35 +08:00
|
|
|
INTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
CHECK_EQ(boundary & (boundary - 1), 0);
|
2015-10-01 08:22:21 +08:00
|
|
|
void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
|
2016-01-14 08:04:37 +08:00
|
|
|
DTLS_on_libc_memalign(ptr, size);
|
2014-06-25 19:30:35 +08:00
|
|
|
return ptr;
|
|
|
|
}
|
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;
|
2015-10-01 08:22:21 +08:00
|
|
|
void *ptr = MsanReallocate(&stack, nullptr, size, GetPageSizeCached(), false);
|
2013-09-02 17:24:53 +08:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2013-09-02 17:24:53 +08:00
|
|
|
INTERCEPTOR(void *, pvalloc, SIZE_T size) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
|
|
|
uptr PageSize = GetPageSizeCached();
|
|
|
|
size = RoundUpTo(size, PageSize);
|
|
|
|
if (size == 0) {
|
|
|
|
// pvalloc(0) should allocate one page.
|
|
|
|
size = PageSize;
|
|
|
|
}
|
2015-10-01 08:22:21 +08:00
|
|
|
void *ptr = MsanReallocate(&stack, nullptr, size, PageSize, false);
|
2013-09-02 17:24:53 +08:00
|
|
|
return ptr;
|
|
|
|
}
|
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;
|
2015-10-01 08:22:21 +08:00
|
|
|
if (!ptr) return;
|
2013-09-16 19:03:31 +08:00
|
|
|
MsanDeallocate(&stack, ptr);
|
2012-12-11 20:27:27 +08:00
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(void, cfree, void *ptr) {
|
|
|
|
GET_MALLOC_STACK_TRACE;
|
2015-10-01 08:22:21 +08:00
|
|
|
if (!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
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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.
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
|
2015-09-16 23:12:25 +08:00
|
|
|
#ifdef __aarch64__
|
|
|
|
uptr r8;
|
|
|
|
asm volatile("mov %0,x8" : "=r" (r8));
|
|
|
|
sret = reinterpret_cast<__sanitizer_mallinfo*>(r8);
|
|
|
|
#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
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPTOR(int, mallopt, int cmd, int value) {
|
|
|
|
return -1;
|
|
|
|
}
|
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
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(char *, strcpy, char *dest, const char *src) { // NOLINT
|
|
|
|
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);
|
2012-12-11 20:27:27 +08:00
|
|
|
char *res = REAL(strcpy)(dest, src); // NOLINT
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n + 1, &stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { // NOLINT
|
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
|
|
|
|
char *res = REAL(strncpy)(dest, src, n); // NOLINT
|
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;
|
|
|
|
}
|
|
|
|
|
2013-07-01 23:19:37 +08:00
|
|
|
INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { // NOLINT
|
|
|
|
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);
|
2013-07-01 23:19:37 +08:00
|
|
|
char *res = REAL(stpcpy)(dest, src); // NOLINT
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, n + 1, &stack);
|
2013-07-01 23:19:37 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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
|
|
|
|
|
|
|
INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
|
|
|
|
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 strndup() leverages strnlen().
|
|
|
|
InterceptorScope interceptor_scope;
|
2013-03-14 19:10:36 +08:00
|
|
|
SIZE_T copy_size = REAL(strnlen)(src, n);
|
|
|
|
char *res = REAL(strndup)(src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(res, src, copy_size, &stack);
|
2013-03-14 19:10:36 +08:00
|
|
|
__msan_unpoison(res + copy_size, 1); // \0
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2013-03-14 19:10:36 +08:00
|
|
|
INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
|
|
|
|
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 copy_size = REAL(strnlen)(src, n);
|
|
|
|
char *res = REAL(__strndup)(src, n);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(res, src, copy_size, &stack);
|
2013-03-14 19:10:36 +08:00
|
|
|
__msan_unpoison(res + copy_size, 1); // \0
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___STRNDUP INTERCEPT_FUNCTION(__strndup)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___STRNDUP
|
|
|
|
#endif
|
2013-03-14 19:10:36 +08:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT
|
|
|
|
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);
|
2012-12-11 20:27:27 +08:00
|
|
|
char *res = REAL(strcat)(dest, src); // NOLINT
|
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;
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT
|
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);
|
2012-12-11 20:27:27 +08:00
|
|
|
char *res = REAL(strncat)(dest, src, n); // NOLINT
|
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
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
INTERCEPTORS_STRTO(double, strtod, char) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO(float, strtof, char) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO(long double, strtold, char) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(long, strtol, char) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(long long, strtoll, char) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char) // NOLINT
|
|
|
|
|
|
|
|
INTERCEPTORS_STRTO(double, wcstod, wchar_t) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO(float, wcstof, wchar_t) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO(long double, wcstold, wchar_t) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t) // NOLINT
|
|
|
|
INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t) // NOLINT
|
|
|
|
|
|
|
|
#define INTERCEPT_STRTO(func) \
|
|
|
|
INTERCEPT_FUNCTION(func); \
|
|
|
|
INTERCEPT_FUNCTION(func##_l); \
|
|
|
|
INTERCEPT_FUNCTION(__##func##_l); \
|
|
|
|
INTERCEPT_FUNCTION(__##func##_internal);
|
|
|
|
|
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-05-08 20:04:01 +08:00
|
|
|
INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
|
|
|
|
SIZE_T res = REAL(strxfrm)(dest, src, n);
|
|
|
|
if (res < n) __msan_unpoison(dest, res + 1);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
|
|
|
|
void *loc) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
|
|
|
|
SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);
|
|
|
|
if (res < n) __msan_unpoison(dest, res + 1);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-04-14 22:59:42 +08:00
|
|
|
#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
|
|
|
|
ENSURE_MSAN_INITED(); \
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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);
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
|
|
|
|
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
|
|
|
INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2012-12-13 14:31:40 +08:00
|
|
|
SIZE_T res = REAL(wcslen)(s);
|
2012-12-11 20:27:27 +08:00
|
|
|
CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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();
|
2014-03-18 21:45:19 +08:00
|
|
|
GET_STORE_STACK_TRACE;
|
2012-12-11 20:27:27 +08:00
|
|
|
wchar_t *res = REAL(wcscpy)(dest, src);
|
2015-01-22 00:42:30 +08:00
|
|
|
CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
|
|
|
|
&stack);
|
2012-12-11 20:27:27 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2015-04-07 02:00:26 +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;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__fxstat)(magic, fd, buf);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__fxstat64)(magic, fd, buf);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat64_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTAT64
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2015-01-19 21:22:33 +08:00
|
|
|
#if SANITIZER_FREEBSD
|
|
|
|
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
|
2013-09-09 21:40:41 +08:00
|
|
|
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;
|
|
|
|
}
|
2015-01-19 21:22:33 +08:00
|
|
|
# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)
|
2014-11-26 18:51:49 +08:00
|
|
|
#endif
|
2013-09-09 21:40:41 +08:00
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2013-09-09 21:40:41 +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;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___FXSTATAT64
|
|
|
|
#endif
|
2013-09-09 21:40:41 +08:00
|
|
|
|
2015-01-19 21:22:33 +08:00
|
|
|
#if SANITIZER_FREEBSD
|
|
|
|
INTERCEPTOR(int, stat, char *path, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(stat)(path, buf);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
# define MSAN_INTERCEPT_STAT INTERCEPT_FUNCTION(stat)
|
|
|
|
#else
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, __xstat, int magic, char *path, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__xstat)(magic, path, buf);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2015-01-19 21:22:33 +08:00
|
|
|
# define MSAN_INTERCEPT_STAT INTERCEPT_FUNCTION(__xstat)
|
2014-11-26 18:51:49 +08:00
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__xstat64)(magic, path, buf);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat64_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___XSTAT64 INTERCEPT_FUNCTION(__xstat64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___XSTAT64
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__lxstat)(magic, path, buf);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___LXSTAT INTERCEPT_FUNCTION(__lxstat)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___LXSTAT
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__lxstat64)(magic, path, buf);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(buf, __sanitizer::struct_stat64_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT___LXSTAT64 INTERCEPT_FUNCTION(__lxstat64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT___LXSTAT64
|
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
2012-12-11 20:27:27 +08:00
|
|
|
INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
char *res = REAL(fgets)(s, size, stream);
|
|
|
|
if (res)
|
|
|
|
__msan_unpoison(s, REAL(strlen)(s) + 1);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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
|
|
|
|
|
|
|
INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
|
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(getrlimit)(resource, rlim);
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(getrlimit)(resource, rlim);
|
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
#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
|
|
|
|
2014-12-22 22:42:24 +08:00
|
|
|
#if SANITIZER_FREEBSD
|
|
|
|
// FreeBSD's <sys/utsname.h> define uname() as
|
|
|
|
// static __inline int uname(struct utsname *name) {
|
|
|
|
// return __xuname(SYS_NMLN, (void*)name);
|
|
|
|
// }
|
|
|
|
INTERCEPTOR(int, __xuname, int size, void *utsname) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(__xuname)(size, utsname);
|
|
|
|
if (!res)
|
|
|
|
__msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname)
|
|
|
|
#else
|
|
|
|
INTERCEPTOR(int, uname, struct utsname *utsname) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
int res = REAL(uname)(utsname);
|
2014-12-22 22:42:24 +08:00
|
|
|
if (!res)
|
2013-02-19 17:19:16 +08:00
|
|
|
__msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
|
2012-12-11 20:27:27 +08:00
|
|
|
return res;
|
|
|
|
}
|
2014-12-22 22:42:24 +08:00
|
|
|
#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname)
|
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
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;
|
2014-12-13 04:07:35 +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.
|
2012-12-13 14:31:40 +08:00
|
|
|
const SIZE_T kCallocPoolSize = 1024;
|
2012-12-11 20:27:27 +08:00
|
|
|
static uptr calloc_memory_for_dlsym[kCallocPoolSize];
|
2012-12-13 14:31:40 +08:00
|
|
|
static SIZE_T allocated;
|
|
|
|
SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
|
2012-12-11 20:27:27 +08:00
|
|
|
void *mem = (void*)&calloc_memory_for_dlsym[allocated];
|
|
|
|
allocated += size_in_words;
|
|
|
|
CHECK(allocated < kCallocPoolSize);
|
|
|
|
return mem;
|
|
|
|
}
|
2014-12-13 04:07:35 +08:00
|
|
|
return MsanCalloc(&stack, nmemb, size);
|
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;
|
|
|
|
return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
|
|
|
|
}
|
|
|
|
|
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;
|
2015-10-01 08:22:21 +08:00
|
|
|
return MsanReallocate(&stack, nullptr, size, sizeof(u64), false);
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
|
|
|
|
int fd, OFF_T offset) {
|
2014-11-27 22:28:57 +08:00
|
|
|
if (msan_init_is_running)
|
|
|
|
return REAL(mmap)(addr, length, prot, flags, fd, offset);
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-01-27 17:12:22 +08:00
|
|
|
if (addr && !MEM_IS_APP(addr)) {
|
2014-02-10 17:37:03 +08:00
|
|
|
if (flags & map_fixed) {
|
|
|
|
*__errno_location() = errno_EINVAL;
|
|
|
|
return (void *)-1;
|
|
|
|
} else {
|
2015-10-01 08:22:21 +08:00
|
|
|
addr = nullptr;
|
2014-02-10 17:37:03 +08:00
|
|
|
}
|
2014-01-27 17:12:22 +08:00
|
|
|
}
|
2012-12-11 20:27:27 +08:00
|
|
|
void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
|
|
|
|
if (res != (void*)-1)
|
|
|
|
__msan_unpoison(res, RoundUpTo(length, GetPageSize()));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2014-11-26 18:51:49 +08:00
|
|
|
#if !SANITIZER_FREEBSD
|
2012-12-13 14:31:40 +08:00
|
|
|
INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
|
|
|
|
int fd, OFF64_T offset) {
|
2012-12-11 20:27:27 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-02-14 17:49:29 +08:00
|
|
|
if (addr && !MEM_IS_APP(addr)) {
|
|
|
|
if (flags & map_fixed) {
|
|
|
|
*__errno_location() = errno_EINVAL;
|
|
|
|
return (void *)-1;
|
|
|
|
} else {
|
2015-10-01 08:22:21 +08:00
|
|
|
addr = nullptr;
|
2014-02-14 17:49:29 +08:00
|
|
|
}
|
|
|
|
}
|
2012-12-11 20:27:27 +08:00
|
|
|
void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
|
|
|
|
if (res != (void*)-1)
|
|
|
|
__msan_unpoison(res, RoundUpTo(length, GetPageSize()));
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-26 18:51:49 +08:00
|
|
|
#define MSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
|
|
|
|
#else
|
|
|
|
#define MSAN_MAYBE_INTERCEPT_MMAP64
|
|
|
|
#endif
|
2012-12-11 20:27:27 +08:00
|
|
|
|
2013-01-17 21:42:17 +08:00
|
|
|
struct dlinfo {
|
|
|
|
char *dli_fname;
|
|
|
|
void *dli_fbase;
|
|
|
|
char *dli_sname;
|
|
|
|
void *dli_saddr;
|
|
|
|
};
|
|
|
|
|
|
|
|
INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-01-23 16:43:12 +08:00
|
|
|
INTERCEPTOR(char *, dlerror, int fake) {
|
2013-11-01 00:58:44 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2014-01-23 16:43:12 +08:00
|
|
|
char *res = REAL(dlerror)(fake);
|
2015-10-01 08:22:21 +08:00
|
|
|
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
|
2013-11-01 00:58:44 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-05-17 20:51:13 +08:00
|
|
|
typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
|
|
|
|
void *data);
|
2013-05-16 21:00:25 +08:00
|
|
|
struct dl_iterate_phdr_data {
|
|
|
|
dl_iterate_phdr_cb callback;
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
|
2013-05-17 20:51:13 +08:00
|
|
|
static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
|
|
|
|
void *data) {
|
|
|
|
if (info) {
|
2013-05-16 21:00:25 +08:00
|
|
|
__msan_unpoison(info, size);
|
2015-09-09 07:14:44 +08:00
|
|
|
if (info->dlpi_phdr && info->dlpi_phnum)
|
|
|
|
__msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
|
2013-05-17 20:51:13 +08:00
|
|
|
if (info->dlpi_name)
|
|
|
|
__msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
|
|
|
|
}
|
2013-05-16 21:00:25 +08:00
|
|
|
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
|
2013-06-27 15:50:56 +08:00
|
|
|
UnpoisonParam(3);
|
2014-11-18 18:33:15 +08:00
|
|
|
return cbdata->callback(info, size, cbdata->data);
|
2013-05-16 21:00:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
|
|
|
|
__sanitizer_sigaction *oldact) {
|
2013-04-01 22:47:21 +08:00
|
|
|
ENSURE_MSAN_INITED();
|
2013-04-04 14:52:40 +08:00
|
|
|
// FIXME: check that *act is unpoisoned.
|
2013-04-01 22:47:21 +08:00
|
|
|
// That requires intercepting all of sigemptyset, sigfillset, etc.
|
2013-04-05 19:59:16 +08:00
|
|
|
int res;
|
|
|
|
if (flags()->wrap_signals) {
|
|
|
|
SpinMutexLock lock(&sigactions_mu);
|
|
|
|
CHECK_LT(signo, kMaxSignals);
|
2013-08-27 19:34:05 +08:00
|
|
|
uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
|
2013-04-05 19:59:16 +08:00
|
|
|
__sanitizer_sigaction new_act;
|
2015-10-01 08:22:21 +08:00
|
|
|
__sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;
|
2013-04-05 19:59:16 +08:00
|
|
|
if (act) {
|
2014-07-11 16:57:57 +08:00
|
|
|
REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));
|
2014-01-31 19:29:51 +08:00
|
|
|
uptr cb = (uptr)pnew_act->sigaction;
|
2013-08-27 19:10:04 +08:00
|
|
|
uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
|
|
|
|
? (uptr)SignalAction
|
|
|
|
: (uptr)SignalHandler;
|
2013-04-05 19:59:16 +08:00
|
|
|
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
2013-08-27 19:34:05 +08:00
|
|
|
atomic_store(&sigactions[signo], cb, memory_order_relaxed);
|
2014-01-31 19:29:51 +08:00
|
|
|
pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;
|
2013-04-05 19:59:16 +08:00
|
|
|
}
|
2013-04-04 16:22:52 +08:00
|
|
|
}
|
2013-04-05 19:59:16 +08:00
|
|
|
res = REAL(sigaction)(signo, pnew_act, oldact);
|
|
|
|
if (res == 0 && oldact) {
|
2014-01-31 19:29:51 +08:00
|
|
|
uptr cb = (uptr)oldact->sigaction;
|
2013-04-05 20:58:07 +08:00
|
|
|
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
2014-01-31 19:29:51 +08:00
|
|
|
oldact->sigaction = (void (*)(int, void *, void *))old_cb;
|
2013-04-05 20:58:07 +08:00
|
|
|
}
|
2013-04-05 19:59:16 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
res = REAL(sigaction)(signo, act, oldact);
|
2013-04-04 16:22:52 +08:00
|
|
|
}
|
2013-04-05 19:59:16 +08:00
|
|
|
|
2013-04-04 16:22:52 +08:00
|
|
|
if (res == 0 && oldact) {
|
2013-08-27 19:10:04 +08:00
|
|
|
__msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
|
2013-04-01 22:47:21 +08:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2013-04-04 16:22:52 +08:00
|
|
|
INTERCEPTOR(int, signal, int signo, uptr cb) {
|
|
|
|
ENSURE_MSAN_INITED();
|
2013-04-05 19:59:16 +08:00
|
|
|
if (flags()->wrap_signals) {
|
|
|
|
CHECK_LT(signo, kMaxSignals);
|
|
|
|
SpinMutexLock lock(&sigactions_mu);
|
|
|
|
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
2013-08-27 19:34:05 +08:00
|
|
|
atomic_store(&sigactions[signo], cb, memory_order_relaxed);
|
2013-04-05 19:59:16 +08:00
|
|
|
cb = (uptr) SignalHandler;
|
|
|
|
}
|
|
|
|
return REAL(signal)(signo, cb);
|
|
|
|
} else {
|
|
|
|
return REAL(signal)(signo, cb);
|
2013-04-04 16:22:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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();
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
void MSanAtExitWrapper(void *arg) {
|
|
|
|
UnpoisonParam(1);
|
|
|
|
MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
|
2014-11-18 18:33:15 +08:00
|
|
|
r->func(r->arg);
|
2013-09-27 19:32:21 +08:00
|
|
|
InternalFree(r);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
MSanAtExitRecord *r =
|
|
|
|
(MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
|
|
|
|
r->func = func;
|
|
|
|
r->arg = arg;
|
|
|
|
return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
|
|
|
|
}
|
|
|
|
|
2013-10-29 10:48:49 +08:00
|
|
|
DECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf)
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-08-19 04:36:48 +08:00
|
|
|
INTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name,
|
|
|
|
const void *termp, const void *winp) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
InterceptorScope interceptor_scope;
|
|
|
|
int res = REAL(openpty)(amaster, aslave, name, termp, winp);
|
|
|
|
if (!res) {
|
|
|
|
__msan_unpoison(amaster, sizeof(*amaster));
|
|
|
|
__msan_unpoison(aslave, sizeof(*aslave));
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp,
|
|
|
|
const void *winp) {
|
|
|
|
ENSURE_MSAN_INITED();
|
|
|
|
InterceptorScope interceptor_scope;
|
|
|
|
int res = REAL(forkpty)(amaster, name, termp, winp);
|
|
|
|
if (res != -1)
|
|
|
|
__msan_unpoison(amaster, sizeof(*amaster));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2013-12-05 20:04:51 +08:00
|
|
|
#define MSAN_INTERCEPT_FUNC(name) \
|
|
|
|
do { \
|
|
|
|
if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \
|
|
|
|
VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \
|
2013-11-11 19:28:30 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
|
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; \
|
|
|
|
}
|
|
|
|
|
[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"
|
|
|
|
// Msan needs custom handling of these:
|
|
|
|
#undef SANITIZER_INTERCEPT_MEMSET
|
|
|
|
#undef SANITIZER_INTERCEPT_MEMMOVE
|
|
|
|
#undef SANITIZER_INTERCEPT_MEMCPY
|
2013-01-18 21:01:18 +08:00
|
|
|
#include "sanitizer_common/sanitizer_common_interceptors.inc"
|
2013-01-18 14:43:13 +08:00
|
|
|
|
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"
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2014-05-07 21:24:28 +08:00
|
|
|
InitializeCommonInterceptors();
|
2013-01-18 14:43:13 +08:00
|
|
|
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(mmap);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_MMAP64;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(posix_memalign);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_MEMALIGN;
|
2014-06-25 19:30:35 +08:00
|
|
|
INTERCEPT_FUNCTION(__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);
|
|
|
|
INTERCEPT_FUNCTION(free);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_CFREE;
|
2014-03-27 21:29:29 +08:00
|
|
|
INTERCEPT_FUNCTION(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;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(readlink);
|
|
|
|
INTERCEPT_FUNCTION(memcpy);
|
2013-11-02 07:49:48 +08:00
|
|
|
INTERCEPT_FUNCTION(memccpy);
|
2013-07-02 22:49:24 +08:00
|
|
|
INTERCEPT_FUNCTION(mempcpy);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(memset);
|
|
|
|
INTERCEPT_FUNCTION(memmove);
|
2013-07-04 21:19:41 +08:00
|
|
|
INTERCEPT_FUNCTION(bcopy);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wmemset);
|
|
|
|
INTERCEPT_FUNCTION(wmemcpy);
|
2013-07-02 22:49:24 +08:00
|
|
|
INTERCEPT_FUNCTION(wmempcpy);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(wmemmove);
|
|
|
|
INTERCEPT_FUNCTION(strcpy); // NOLINT
|
2013-07-01 23:19:37 +08:00
|
|
|
INTERCEPT_FUNCTION(stpcpy); // NOLINT
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(strdup);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___STRDUP;
|
2013-03-14 19:10:36 +08:00
|
|
|
INTERCEPT_FUNCTION(strndup);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___STRNDUP;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(strncpy); // NOLINT
|
|
|
|
INTERCEPT_FUNCTION(gcvt);
|
|
|
|
INTERCEPT_FUNCTION(strcat); // NOLINT
|
|
|
|
INTERCEPT_FUNCTION(strncat); // NOLINT
|
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);
|
|
|
|
INTERCEPT_STRTO(wcstod);
|
|
|
|
INTERCEPT_STRTO(wcstof);
|
|
|
|
INTERCEPT_STRTO(wcstold);
|
|
|
|
INTERCEPT_STRTO(wcstol);
|
|
|
|
INTERCEPT_STRTO(wcstoul);
|
|
|
|
INTERCEPT_STRTO(wcstoll);
|
|
|
|
INTERCEPT_STRTO(wcstoull);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(vswprintf);
|
|
|
|
INTERCEPT_FUNCTION(swprintf);
|
2014-05-08 20:04:01 +08:00
|
|
|
INTERCEPT_FUNCTION(strxfrm);
|
|
|
|
INTERCEPT_FUNCTION(strxfrm_l);
|
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);
|
|
|
|
INTERCEPT_FUNCTION(wcschr);
|
|
|
|
INTERCEPT_FUNCTION(wcscpy);
|
|
|
|
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);
|
|
|
|
INTERCEPT_FUNCTION(fcvt);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___FXSTAT;
|
2015-01-19 21:22:33 +08:00
|
|
|
MSAN_INTERCEPT_FSTATAT;
|
|
|
|
MSAN_INTERCEPT_STAT;
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT___LXSTAT;
|
|
|
|
MSAN_MAYBE_INTERCEPT___FXSTAT64;
|
|
|
|
MSAN_MAYBE_INTERCEPT___FXSTATAT64;
|
|
|
|
MSAN_MAYBE_INTERCEPT___XSTAT64;
|
|
|
|
MSAN_MAYBE_INTERCEPT___LXSTAT64;
|
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);
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(fgets);
|
2014-11-26 18:51:49 +08:00
|
|
|
MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
|
2012-12-14 19:52:02 +08:00
|
|
|
INTERCEPT_FUNCTION(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;
|
2014-12-22 22:42:24 +08:00
|
|
|
MSAN_INTERCEPT_UNAME;
|
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);
|
2013-04-01 22:47:21 +08:00
|
|
|
INTERCEPT_FUNCTION(sigaction);
|
2013-04-04 16:22:52 +08:00
|
|
|
INTERCEPT_FUNCTION(signal);
|
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);
|
2013-07-30 20:54:34 +08:00
|
|
|
INTERCEPT_FUNCTION(pthread_join);
|
2013-09-13 19:27:38 +08:00
|
|
|
INTERCEPT_FUNCTION(tzset);
|
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);
|
2015-08-19 04:36:48 +08:00
|
|
|
INTERCEPT_FUNCTION(openpty);
|
|
|
|
INTERCEPT_FUNCTION(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
|