summaryrefslogtreecommitdiff
path: root/lib/msan/msan_interceptors.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/msan/msan_interceptors.cc')
-rw-r--r--lib/msan/msan_interceptors.cc336
1 files changed, 220 insertions, 116 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index b5d22baca08d..a7fe09b25ffb 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -22,6 +22,7 @@
#include "msan_thread.h"
#include "msan_poisoning.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
+#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "sanitizer_common/sanitizer_allocator_internal.h"
@@ -33,6 +34,11 @@
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
+#if SANITIZER_NETBSD
+#define gettimeofday __gettimeofday50
+#define getrusage __getrusage50
+#endif
+
#include <stdarg.h>
// ACHTUNG! No other system header includes in this file.
// Ideally, we should get rid of stdarg.h as well.
@@ -86,22 +92,21 @@ static void *AllocateFromLocalPool(uptr size_in_bytes) {
} while (0)
// Check that [x, x+n) range is unpoisoned.
-#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(); \
- } \
- } \
+#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(); \
+ } \
+ } \
} while (0)
// Check that [x, x+n) range is unpoisoned unless we are in a nested
@@ -109,7 +114,7 @@ static void *AllocateFromLocalPool(uptr size_in_bytes) {
#define CHECK_UNPOISONED(x, n) \
do { \
if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
- } while (0);
+ } while (0)
#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n) \
CHECK_UNPOISONED((x), \
@@ -118,7 +123,7 @@ static void *AllocateFromLocalPool(uptr size_in_bytes) {
#define CHECK_UNPOISONED_STRING(x, n) \
CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
void *file) {
ENSURE_MSAN_INITED();
@@ -134,16 +139,21 @@ INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
ENSURE_MSAN_INITED();
- CHECK_UNPOISONED_STRING(path, 0)
+ CHECK_UNPOISONED_STRING(path, 0);
SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
if (res > 0)
__msan_unpoison(buf, res);
return res;
}
+#if !SANITIZER_NETBSD
INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
return (char *)__msan_memcpy(dest, src, n) + n;
}
+#define MSAN_MAYBE_INTERCEPT_MEMPCPY INTERCEPT_FUNCTION(mempcpy)
+#else
+#define MSAN_MAYBE_INTERCEPT_MEMPCPY
+#endif
INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
ENSURE_MSAN_INITED();
@@ -168,7 +178,7 @@ INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {
GET_MALLOC_STACK_TRACE;
return msan_memalign(alignment, size, &stack);
@@ -183,6 +193,7 @@ INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {
return msan_aligned_alloc(alignment, size, &stack);
}
+#if !SANITIZER_NETBSD
INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {
GET_MALLOC_STACK_TRACE;
void *ptr = msan_memalign(alignment, size, &stack);
@@ -190,13 +201,17 @@ INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {
DTLS_on_libc_memalign(ptr, size);
return ptr;
}
+#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
+#else
+#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
+#endif
INTERCEPTOR(void *, valloc, SIZE_T size) {
GET_MALLOC_STACK_TRACE;
return msan_valloc(size, &stack);
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void *, pvalloc, SIZE_T size) {
GET_MALLOC_STACK_TRACE;
return msan_pvalloc(size, &stack);
@@ -212,7 +227,7 @@ INTERCEPTOR(void, free, void *ptr) {
MsanDeallocate(&stack, ptr);
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void, cfree, void *ptr) {
GET_MALLOC_STACK_TRACE;
if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
@@ -223,11 +238,17 @@ INTERCEPTOR(void, cfree, void *ptr) {
#define MSAN_MAYBE_INTERCEPT_CFREE
#endif
+#if !SANITIZER_NETBSD
INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
return __sanitizer_get_allocated_size(ptr);
}
+#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \
+ INTERCEPT_FUNCTION(malloc_usable_size)
+#else
+#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
+#endif
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
// This function actually returns a struct by value, but we can't unpoison a
// temporary! The following is equivalent on all supported platforms but
// aarch64 (which uses a different register for sret value). We have a test
@@ -246,7 +267,7 @@ INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
#define MSAN_MAYBE_INTERCEPT_MALLINFO
#endif
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, mallopt, int cmd, int value) {
return -1;
}
@@ -255,7 +276,7 @@ INTERCEPTOR(int, mallopt, int cmd, int value) {
#define MSAN_MAYBE_INTERCEPT_MALLOPT
#endif
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void, malloc_stats, void) {
// FIXME: implement, but don't call REAL(malloc_stats)!
}
@@ -286,6 +307,7 @@ INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { // NOLINT
return res;
}
+#if !SANITIZER_NETBSD
INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { // NOLINT
ENSURE_MSAN_INITED();
GET_STORE_STACK_TRACE;
@@ -295,6 +317,10 @@ INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { // NOLINT
CopyShadowAndOrigin(dest, src, n + 1, &stack);
return res;
}
+#define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy)
+#else
+#define MSAN_MAYBE_INTERCEPT_STPCPY
+#endif
INTERCEPTOR(char *, strdup, char *src) {
ENSURE_MSAN_INITED();
@@ -308,7 +334,7 @@ INTERCEPTOR(char *, strdup, char *src) {
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(char *, __strdup, char *src) {
ENSURE_MSAN_INITED();
GET_STORE_STACK_TRACE;
@@ -323,6 +349,7 @@ INTERCEPTOR(char *, __strdup, char *src) {
#define MSAN_MAYBE_INTERCEPT___STRDUP
#endif
+#if !SANITIZER_NETBSD
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
ENSURE_MSAN_INITED();
char *res = REAL(gcvt)(number, ndigit, buf);
@@ -330,6 +357,10 @@ INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
__msan_unpoison(buf, n + 1);
return res;
}
+#define MSAN_MAYBE_INTERCEPT_GCVT INTERCEPT_FUNCTION(gcvt)
+#else
+#define MSAN_MAYBE_INTERCEPT_GCVT
+#endif
INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT
ENSURE_MSAN_INITED();
@@ -386,6 +417,16 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT
INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc); \
}
+#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
#define INTERCEPTORS_STRTO(ret_type, func, char_type) \
INTERCEPTOR_STRTO(ret_type, func, char_type) \
INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) \
@@ -397,6 +438,7 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT
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)
+#endif
INTERCEPTORS_STRTO(double, strtod, char) // NOLINT
INTERCEPTORS_STRTO(float, strtof, char) // NOLINT
@@ -405,6 +447,7 @@ 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_BASE(u64, strtouq, char) // NOLINT
INTERCEPTORS_STRTO(double, wcstod, wchar_t) // NOLINT
INTERCEPTORS_STRTO(float, wcstof, wchar_t) // NOLINT
@@ -414,11 +457,17 @@ 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
+#if SANITIZER_NETBSD
+#define INTERCEPT_STRTO(func) \
+ INTERCEPT_FUNCTION(func); \
+ INTERCEPT_FUNCTION(func##_l);
+#else
#define INTERCEPT_STRTO(func) \
INTERCEPT_FUNCTION(func); \
INTERCEPT_FUNCTION(func##_l); \
INTERCEPT_FUNCTION(__##func##_l); \
INTERCEPT_FUNCTION(__##func##_internal);
+#endif
// FIXME: support *wprintf in common format interceptors.
@@ -457,6 +506,20 @@ INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
return res;
}
+#if SANITIZER_LINUX
+INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T n,
+ void *loc) {
+ ENSURE_MSAN_INITED();
+ CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
+ SIZE_T res = REAL(__strxfrm_l)(dest, src, n, loc);
+ if (res < n) __msan_unpoison(dest, res + 1);
+ return res;
+}
+#define MSAN_MAYBE_INTERCEPT___STRXFRM_L INTERCEPT_FUNCTION(__strxfrm_l)
+#else
+#define MSAN_MAYBE_INTERCEPT___STRXFRM_L
+#endif
+
#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
ENSURE_MSAN_INITED(); \
ret_type res = REAL(func)(s, __VA_ARGS__); \
@@ -473,7 +536,7 @@ INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
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,
@@ -495,7 +558,7 @@ INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
loc);
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
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,
@@ -513,7 +576,8 @@ INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
return res;
}
-INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
+INTERCEPTOR(SIZE_T, 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));
@@ -529,6 +593,7 @@ INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
return res;
}
+#if !SANITIZER_NETBSD
INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
ENSURE_MSAN_INITED();
GET_STORE_STACK_TRACE;
@@ -536,6 +601,10 @@ INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
return res;
}
+#define MSAN_MAYBE_INTERCEPT_WMEMPCPY INTERCEPT_FUNCTION(wmempcpy)
+#else
+#define MSAN_MAYBE_INTERCEPT_WMEMPCPY
+#endif
INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
CHECK(MEM_IS_APP(s));
@@ -569,6 +638,7 @@ INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
return res;
}
+#if !SANITIZER_NETBSD
INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
ENSURE_MSAN_INITED();
char *res = REAL(fcvt)(x, a, b, c);
@@ -577,6 +647,10 @@ INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
+#define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt)
+#else
+#define MSAN_MAYBE_INTERCEPT_FCVT
+#endif
INTERCEPTOR(char *, getenv, char *name) {
if (msan_init_is_running)
@@ -601,7 +675,7 @@ static void UnpoisonEnviron() {
INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
ENSURE_MSAN_INITED();
- CHECK_UNPOISONED_STRING(name, 0)
+ CHECK_UNPOISONED_STRING(name, 0);
int res = REAL(setenv)(name, value, overwrite);
if (!res) UnpoisonEnviron();
return res;
@@ -614,7 +688,7 @@ INTERCEPTOR(int, putenv, char *string) {
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
ENSURE_MSAN_INITED();
int res = REAL(__fxstat)(magic, fd, buf);
@@ -627,7 +701,7 @@ INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
#define MSAN_MAYBE_INTERCEPT___FXSTAT
#endif
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
ENSURE_MSAN_INITED();
int res = REAL(__fxstat64)(magic, fd, buf);
@@ -640,7 +714,7 @@ INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
#define MSAN_MAYBE_INTERCEPT___FXSTAT64
#endif
-#if SANITIZER_FREEBSD
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD
INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
ENSURE_MSAN_INITED();
int res = REAL(fstatat)(fd, pathname, buf, flags);
@@ -659,7 +733,7 @@ INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)
#endif
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
int flags) {
ENSURE_MSAN_INITED();
@@ -706,7 +780,7 @@ INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
ENSURE_MSAN_INITED();
char *res = REAL(fgets_unlocked)(s, size, stream);
@@ -729,7 +803,7 @@ INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
ENSURE_MSAN_INITED();
@@ -805,7 +879,7 @@ INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
int timeout) {
ENSURE_MSAN_INITED();
@@ -820,7 +894,7 @@ INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
#endif
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
int timeout, void *sigmask) {
ENSURE_MSAN_INITED();
@@ -909,7 +983,7 @@ INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
return res;
}
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
int fd, OFF64_T offset) {
ENSURE_MSAN_INITED();
@@ -983,59 +1057,13 @@ static void SignalAction(int signo, void *si, void *uc) {
cb(signo, si, uc);
}
-INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
- __sanitizer_sigaction *oldact) {
- ENSURE_MSAN_INITED();
- // FIXME: check that *act is unpoisoned.
- // That requires intercepting all of sigemptyset, sigfillset, etc.
- 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);
- pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;
- }
- }
- res = REAL(sigaction)(signo, pnew_act, oldact);
- if (res == 0 && oldact) {
- uptr cb = (uptr)oldact->sigaction;
- if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
- oldact->sigaction = (void (*)(int, void *, void *))old_cb;
- }
- }
- } else {
- res = REAL(sigaction)(signo, act, oldact);
- }
-
- if (res == 0 && oldact) {
- __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
- }
- return res;
-}
-
-INTERCEPTOR(int, signal, 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 REAL(signal)(signo, cb);
- } else {
- return REAL(signal)(signo, cb);
- }
+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));
}
extern "C" int pthread_attr_init(void *attr);
@@ -1080,6 +1108,11 @@ INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
return res;
}
+#if SANITIZER_NETBSD
+INTERCEPTOR(void, __libc_thr_keycreate, void *m, void (*dtor)(void *value)) \
+ ALIAS(WRAPPER_NAME(pthread_key_create));
+#endif
+
INTERCEPTOR(int, pthread_join, void *th, void **retval) {
ENSURE_MSAN_INITED();
int res = REAL(pthread_join)(th, retval);
@@ -1124,21 +1157,6 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
}
-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;
-}
-
static void BeforeFork() {
StackDepotLockAll();
ChainedOriginDepotLockAll();
@@ -1293,6 +1311,73 @@ int OnExit() {
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_common_interceptors.inc"
+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); \
+ return REAL(func)(signo, handler); \
+ }
+
+#include "sanitizer_common/sanitizer_signal_interceptors.inc"
+
+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);
+ pnew_act->sigaction = (decltype(pnew_act->sigaction))new_cb;
+ }
+ }
+ res = REAL(SIGACTION_SYMNAME)(signo, pnew_act, oldact);
+ if (res == 0 && oldact) {
+ uptr cb = (uptr)oldact->sigaction;
+ if (cb == (uptr)SignalAction || cb == (uptr)SignalHandler) {
+ oldact->sigaction = (decltype(oldact->sigaction))old_cb;
+ }
+ }
+ } else {
+ res = REAL(SIGACTION_SYMNAME)(signo, act, oldact);
+ }
+
+ 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;
+}
+
#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
do { \
@@ -1353,6 +1438,19 @@ static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
return cbdata->callback(info, size, cbdata->data);
}
+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;
+}
+
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);
@@ -1455,12 +1553,13 @@ void InitializeInterceptors() {
static int inited = 0;
CHECK_EQ(inited, 0);
InitializeCommonInterceptors();
+ InitializeSignalInterceptors();
INTERCEPT_FUNCTION(mmap);
MSAN_MAYBE_INTERCEPT_MMAP64;
INTERCEPT_FUNCTION(posix_memalign);
MSAN_MAYBE_INTERCEPT_MEMALIGN;
- INTERCEPT_FUNCTION(__libc_memalign);
+ MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
INTERCEPT_FUNCTION(valloc);
MSAN_MAYBE_INTERCEPT_PVALLOC;
INTERCEPT_FUNCTION(malloc);
@@ -1468,7 +1567,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(realloc);
INTERCEPT_FUNCTION(free);
MSAN_MAYBE_INTERCEPT_CFREE;
- INTERCEPT_FUNCTION(malloc_usable_size);
+ MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
MSAN_MAYBE_INTERCEPT_MALLINFO;
MSAN_MAYBE_INTERCEPT_MALLOPT;
MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
@@ -1476,18 +1575,18 @@ void InitializeInterceptors() {
MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
INTERCEPT_FUNCTION(readlink);
INTERCEPT_FUNCTION(memccpy);
- INTERCEPT_FUNCTION(mempcpy);
+ MSAN_MAYBE_INTERCEPT_MEMPCPY;
INTERCEPT_FUNCTION(bcopy);
INTERCEPT_FUNCTION(wmemset);
INTERCEPT_FUNCTION(wmemcpy);
- INTERCEPT_FUNCTION(wmempcpy);
+ MSAN_MAYBE_INTERCEPT_WMEMPCPY;
INTERCEPT_FUNCTION(wmemmove);
INTERCEPT_FUNCTION(strcpy); // NOLINT
- INTERCEPT_FUNCTION(stpcpy); // NOLINT
+ MSAN_MAYBE_INTERCEPT_STPCPY; // NOLINT
INTERCEPT_FUNCTION(strdup);
MSAN_MAYBE_INTERCEPT___STRDUP;
INTERCEPT_FUNCTION(strncpy); // NOLINT
- INTERCEPT_FUNCTION(gcvt);
+ MSAN_MAYBE_INTERCEPT_GCVT;
INTERCEPT_FUNCTION(strcat); // NOLINT
INTERCEPT_FUNCTION(strncat); // NOLINT
INTERCEPT_STRTO(strtod);
@@ -1497,6 +1596,7 @@ void InitializeInterceptors() {
INTERCEPT_STRTO(strtoul);
INTERCEPT_STRTO(strtoll);
INTERCEPT_STRTO(strtoull);
+ INTERCEPT_STRTO(strtouq);
INTERCEPT_STRTO(wcstod);
INTERCEPT_STRTO(wcstof);
INTERCEPT_STRTO(wcstold);
@@ -1513,6 +1613,7 @@ void InitializeInterceptors() {
#endif
INTERCEPT_FUNCTION(strxfrm);
INTERCEPT_FUNCTION(strxfrm_l);
+ MSAN_MAYBE_INTERCEPT___STRXFRM_L;
INTERCEPT_FUNCTION(strftime);
INTERCEPT_FUNCTION(strftime_l);
MSAN_MAYBE_INTERCEPT___STRFTIME_L;
@@ -1531,7 +1632,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(setenv);
INTERCEPT_FUNCTION(putenv);
INTERCEPT_FUNCTION(gettimeofday);
- INTERCEPT_FUNCTION(fcvt);
+ MSAN_MAYBE_INTERCEPT_FCVT;
MSAN_MAYBE_INTERCEPT___FXSTAT;
MSAN_INTERCEPT_FSTATAT;
MSAN_MAYBE_INTERCEPT___FXSTAT64;
@@ -1553,14 +1654,17 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(dlerror);
INTERCEPT_FUNCTION(dl_iterate_phdr);
INTERCEPT_FUNCTION(getrusage);
- INTERCEPT_FUNCTION(sigaction);
- INTERCEPT_FUNCTION(signal);
#if defined(__mips__)
INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2");
#else
INTERCEPT_FUNCTION(pthread_create);
#endif
INTERCEPT_FUNCTION(pthread_key_create);
+
+#if SANITIZER_NETBSD
+ INTERCEPT_FUNCTION(__libc_thr_keycreate);
+#endif
+
INTERCEPT_FUNCTION(pthread_join);
INTERCEPT_FUNCTION(tzset);
INTERCEPT_FUNCTION(__cxa_atexit);