Path: blob/main/contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp
35262 views
//===-- msan_interceptors.cpp ---------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of MemorySanitizer.9//10// Interceptors for standard library functions.11//12// FIXME: move as many interceptors as possible into13// sanitizer_common/sanitizer_common_interceptors.h14//===----------------------------------------------------------------------===//1516#define SANITIZER_COMMON_NO_REDEFINE_BUILTINS1718#include "interception/interception.h"19#include "msan.h"20#include "msan_chained_origin_depot.h"21#include "msan_dl.h"22#include "msan_origin.h"23#include "msan_poisoning.h"24#include "msan_report.h"25#include "msan_thread.h"26#include "sanitizer_common/sanitizer_allocator.h"27#include "sanitizer_common/sanitizer_allocator_dlsym.h"28#include "sanitizer_common/sanitizer_allocator_interface.h"29#include "sanitizer_common/sanitizer_atomic.h"30#include "sanitizer_common/sanitizer_common.h"31#include "sanitizer_common/sanitizer_errno.h"32#include "sanitizer_common/sanitizer_errno_codes.h"33#include "sanitizer_common/sanitizer_glibc_version.h"34#include "sanitizer_common/sanitizer_libc.h"35#include "sanitizer_common/sanitizer_linux.h"36#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"37#include "sanitizer_common/sanitizer_platform_limits_posix.h"38#include "sanitizer_common/sanitizer_stackdepot.h"39#include "sanitizer_common/sanitizer_tls_get_addr.h"40#include "sanitizer_common/sanitizer_vector.h"4142#if SANITIZER_NETBSD43#define fstat __fstat5044#define gettimeofday __gettimeofday5045#define getrusage __getrusage5046#define tzset __tzset5047#endif4849#include <stdarg.h>50// ACHTUNG! No other system header includes in this file.51// Ideally, we should get rid of stdarg.h as well.5253using namespace __msan;5455using __sanitizer::memory_order;56using __sanitizer::atomic_load;57using __sanitizer::atomic_store;58using __sanitizer::atomic_uintptr_t;5960DECLARE_REAL(SIZE_T, strlen, const char *s)61DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)62DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n)63DECLARE_REAL(void *, memset, void *dest, int c, uptr n)6465// True if this is a nested interceptor.66static THREADLOCAL int in_interceptor_scope;6768void __msan_scoped_disable_interceptor_checks() { ++in_interceptor_scope; }69void __msan_scoped_enable_interceptor_checks() { --in_interceptor_scope; }7071struct InterceptorScope {72InterceptorScope() { ++in_interceptor_scope; }73~InterceptorScope() { --in_interceptor_scope; }74};7576bool IsInInterceptorScope() {77return in_interceptor_scope;78}7980struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {81static bool UseImpl() { return !msan_inited; }82};8384#define ENSURE_MSAN_INITED() do { \85CHECK(!msan_init_is_running); \86if (!msan_inited) { \87__msan_init(); \88} \89} while (0)9091// Check that [x, x+n) range is unpoisoned.92#define CHECK_UNPOISONED_0(x, n) \93do { \94sptr __offset = __msan_test_shadow(x, n); \95if (__msan::IsInSymbolizerOrUnwider()) \96break; \97if (__offset >= 0 && __msan::flags()->report_umrs) { \98GET_CALLER_PC_BP; \99ReportUMRInsideAddressRange(__func__, x, n, __offset); \100__msan::PrintWarningWithOrigin( \101pc, bp, __msan_get_origin((const char *)x + __offset)); \102if (__msan::flags()->halt_on_error) { \103Printf("Exiting\n"); \104Die(); \105} \106} \107} while (0)108109// Check that [x, x+n) range is unpoisoned unless we are in a nested110// interceptor.111#define CHECK_UNPOISONED(x, n) \112do { \113if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \114} while (0)115116#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n) \117CHECK_UNPOISONED((x), \118common_flags()->strict_string_checks ? (len) + 1 : (n) )119120#define CHECK_UNPOISONED_STRING(x, n) \121CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))122123#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD124INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,125void *file) {126ENSURE_MSAN_INITED();127SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);128if (res > 0)129__msan_unpoison(ptr, res *size);130return res;131}132#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked)133#else134#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED135#endif136137#if !SANITIZER_NETBSD138INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {139return (char *)__msan_memcpy(dest, src, n) + n;140}141#define MSAN_MAYBE_INTERCEPT_MEMPCPY INTERCEPT_FUNCTION(mempcpy)142#else143#define MSAN_MAYBE_INTERCEPT_MEMPCPY144#endif145146INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {147ENSURE_MSAN_INITED();148void *res = REAL(memccpy)(dest, src, c, n);149CHECK(!res || (res >= dest && res <= (char *)dest + n));150SIZE_T sz = res ? (char *)res - (char *)dest : n;151CHECK_UNPOISONED(src, sz);152__msan_unpoison(dest, sz);153return res;154}155156INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {157return __msan_memmove(dest, src, n);158}159160INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {161GET_MALLOC_STACK_TRACE;162CHECK_NE(memptr, 0);163int res = msan_posix_memalign(memptr, alignment, size, &stack);164if (!res)165__msan_unpoison(memptr, sizeof(*memptr));166return res;167}168169#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD170INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {171GET_MALLOC_STACK_TRACE;172return msan_memalign(alignment, size, &stack);173}174#define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)175#else176#define MSAN_MAYBE_INTERCEPT_MEMALIGN177#endif178179INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {180GET_MALLOC_STACK_TRACE;181return msan_aligned_alloc(alignment, size, &stack);182}183184#if !SANITIZER_NETBSD185INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {186GET_MALLOC_STACK_TRACE;187void *ptr = msan_memalign(alignment, size, &stack);188if (ptr)189DTLS_on_libc_memalign(ptr, size);190return ptr;191}192#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)193#else194#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN195#endif196197INTERCEPTOR(void *, valloc, SIZE_T size) {198GET_MALLOC_STACK_TRACE;199return msan_valloc(size, &stack);200}201202#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD203INTERCEPTOR(void *, pvalloc, SIZE_T size) {204GET_MALLOC_STACK_TRACE;205return msan_pvalloc(size, &stack);206}207#define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)208#else209#define MSAN_MAYBE_INTERCEPT_PVALLOC210#endif211212INTERCEPTOR(void, free, void *ptr) {213if (UNLIKELY(!ptr))214return;215if (DlsymAlloc::PointerIsMine(ptr))216return DlsymAlloc::Free(ptr);217GET_MALLOC_STACK_TRACE;218MsanDeallocate(&stack, ptr);219}220221#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD222INTERCEPTOR(void, cfree, void *ptr) {223if (UNLIKELY(!ptr))224return;225if (DlsymAlloc::PointerIsMine(ptr))226return DlsymAlloc::Free(ptr);227GET_MALLOC_STACK_TRACE;228MsanDeallocate(&stack, ptr);229}230# define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)231#else232#define MSAN_MAYBE_INTERCEPT_CFREE233#endif234235#if !SANITIZER_NETBSD236INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {237return __sanitizer_get_allocated_size(ptr);238}239#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \240INTERCEPT_FUNCTION(malloc_usable_size)241#else242#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE243#endif244245#if (!SANITIZER_FREEBSD && !SANITIZER_NETBSD) || __GLIBC_PREREQ(2, 33)246template <class T>247static NOINLINE void clear_mallinfo(T *sret) {248ENSURE_MSAN_INITED();249internal_memset(sret, 0, sizeof(*sret));250__msan_unpoison(sret, sizeof(*sret));251}252#endif253254#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD255// Interceptors use NRVO and assume that sret will be pre-allocated in256// caller frame.257INTERCEPTOR(__sanitizer_struct_mallinfo, mallinfo,) {258__sanitizer_struct_mallinfo sret;259clear_mallinfo(&sret);260return sret;261}262# define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)263#else264# define MSAN_MAYBE_INTERCEPT_MALLINFO265#endif266267#if __GLIBC_PREREQ(2, 33)268INTERCEPTOR(__sanitizer_struct_mallinfo2, mallinfo2) {269__sanitizer_struct_mallinfo2 sret;270clear_mallinfo(&sret);271return sret;272}273# define MSAN_MAYBE_INTERCEPT_MALLINFO2 INTERCEPT_FUNCTION(mallinfo2)274#else275# define MSAN_MAYBE_INTERCEPT_MALLINFO2276#endif277278#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD279INTERCEPTOR(int, mallopt, int cmd, int value) {280return 0;281}282#define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)283#else284#define MSAN_MAYBE_INTERCEPT_MALLOPT285#endif286287#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD288INTERCEPTOR(void, malloc_stats, void) {289// FIXME: implement, but don't call REAL(malloc_stats)!290}291#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats)292#else293#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS294#endif295296INTERCEPTOR(char *, strcpy, char *dest, const char *src) {297ENSURE_MSAN_INITED();298GET_STORE_STACK_TRACE;299SIZE_T n = internal_strlen(src);300CHECK_UNPOISONED_STRING(src + n, 0);301char *res = REAL(strcpy)(dest, src);302CopyShadowAndOrigin(dest, src, n + 1, &stack);303return res;304}305306INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {307ENSURE_MSAN_INITED();308GET_STORE_STACK_TRACE;309SIZE_T copy_size = internal_strnlen(src, n);310if (copy_size < n)311copy_size++; // trailing \0312char *res = REAL(strncpy)(dest, src, n);313CopyShadowAndOrigin(dest, src, copy_size, &stack);314__msan_unpoison(dest + copy_size, n - copy_size);315return res;316}317318#if !SANITIZER_NETBSD319INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {320ENSURE_MSAN_INITED();321GET_STORE_STACK_TRACE;322SIZE_T n = internal_strlen(src);323CHECK_UNPOISONED_STRING(src + n, 0);324char *res = REAL(stpcpy)(dest, src);325CopyShadowAndOrigin(dest, src, n + 1, &stack);326return res;327}328329INTERCEPTOR(char *, stpncpy, char *dest, const char *src, SIZE_T n) {330ENSURE_MSAN_INITED();331GET_STORE_STACK_TRACE;332SIZE_T copy_size = Min(n, internal_strnlen(src, n) + 1);333char *res = REAL(stpncpy)(dest, src, n);334CopyShadowAndOrigin(dest, src, copy_size, &stack);335__msan_unpoison(dest + copy_size, n - copy_size);336return res;337}338# define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy)339# define MSAN_MAYBE_INTERCEPT_STPNCPY INTERCEPT_FUNCTION(stpncpy)340#else341#define MSAN_MAYBE_INTERCEPT_STPCPY342# define MSAN_MAYBE_INTERCEPT_STPNCPY343#endif344345INTERCEPTOR(char *, strdup, char *src) {346ENSURE_MSAN_INITED();347GET_STORE_STACK_TRACE;348// On FreeBSD strdup() leverages strlen().349InterceptorScope interceptor_scope;350SIZE_T n = internal_strlen(src);351CHECK_UNPOISONED_STRING(src + n, 0);352char *res = REAL(strdup)(src);353CopyShadowAndOrigin(res, src, n + 1, &stack);354return res;355}356357#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD358INTERCEPTOR(char *, __strdup, char *src) {359ENSURE_MSAN_INITED();360GET_STORE_STACK_TRACE;361SIZE_T n = internal_strlen(src);362CHECK_UNPOISONED_STRING(src + n, 0);363char *res = REAL(__strdup)(src);364CopyShadowAndOrigin(res, src, n + 1, &stack);365return res;366}367#define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup)368#else369#define MSAN_MAYBE_INTERCEPT___STRDUP370#endif371372#if !SANITIZER_NETBSD373INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {374ENSURE_MSAN_INITED();375char *res = REAL(gcvt)(number, ndigit, buf);376SIZE_T n = internal_strlen(buf);377__msan_unpoison(buf, n + 1);378return res;379}380#define MSAN_MAYBE_INTERCEPT_GCVT INTERCEPT_FUNCTION(gcvt)381#else382#define MSAN_MAYBE_INTERCEPT_GCVT383#endif384385INTERCEPTOR(char *, strcat, char *dest, const char *src) {386ENSURE_MSAN_INITED();387GET_STORE_STACK_TRACE;388SIZE_T src_size = internal_strlen(src);389SIZE_T dest_size = internal_strlen(dest);390CHECK_UNPOISONED_STRING(src + src_size, 0);391CHECK_UNPOISONED_STRING(dest + dest_size, 0);392char *res = REAL(strcat)(dest, src);393CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack);394return res;395}396397INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {398ENSURE_MSAN_INITED();399GET_STORE_STACK_TRACE;400SIZE_T dest_size = internal_strlen(dest);401SIZE_T copy_size = internal_strnlen(src, n);402CHECK_UNPOISONED_STRING(dest + dest_size, 0);403char *res = REAL(strncat)(dest, src, n);404CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);405__msan_unpoison(dest + dest_size + copy_size, 1); // \0406return res;407}408409// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to410// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.411#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \412ENSURE_MSAN_INITED(); \413ret_type res = REAL(func)(__VA_ARGS__); \414__msan_unpoison(endptr, sizeof(*endptr)); \415return res;416417// On s390x, long double return values are passed via implicit reference,418// which needs to be unpoisoned. We make the implicit pointer explicit.419#define INTERCEPTOR_STRTO_SRET_BODY(func, sret, ...) \420ENSURE_MSAN_INITED(); \421REAL(func)(sret, __VA_ARGS__); \422__msan_unpoison(sret, sizeof(*sret)); \423__msan_unpoison(endptr, sizeof(*endptr));424425#define INTERCEPTOR_STRTO(ret_type, func, char_type) \426INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \427INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \428}429430#define INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \431INTERCEPTOR(void, func, ret_type *sret, const char_type *nptr, \432char_type **endptr) { \433INTERCEPTOR_STRTO_SRET_BODY(func, sret, nptr, endptr); \434}435436#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \437INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \438int base) { \439INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base); \440}441442#define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type) \443INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \444void *loc) { \445INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \446}447448#define INTERCEPTOR_STRTO_SRET_LOC(ret_type, func, char_type) \449INTERCEPTOR(void, func, ret_type *sret, const char_type *nptr, \450char_type **endptr, void *loc) { \451INTERCEPTOR_STRTO_SRET_BODY(func, sret, nptr, endptr, loc); \452}453454#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type) \455INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \456int base, void *loc) { \457INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc); \458}459460#if SANITIZER_NETBSD461#define INTERCEPTORS_STRTO(ret_type, func, char_type) \462INTERCEPTOR_STRTO(ret_type, func, char_type) \463INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)464465#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type) \466INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \467INTERCEPTOR_STRTO_SRET_LOC(ret_type, func##_l, char_type)468469#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \470INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \471INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type)472473#else474#define INTERCEPTORS_STRTO(ret_type, func, char_type) \475INTERCEPTOR_STRTO(ret_type, func, char_type) \476INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) \477INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \478INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)479480#define INTERCEPTORS_STRTO_SRET(ret_type, func, char_type) \481INTERCEPTOR_STRTO_SRET(ret_type, func, char_type) \482INTERCEPTOR_STRTO_SRET_LOC(ret_type, func##_l, char_type) \483INTERCEPTOR_STRTO_SRET_LOC(ret_type, __##func##_l, char_type) \484INTERCEPTOR_STRTO_SRET_LOC(ret_type, __##func##_internal, char_type)485486#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \487INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \488INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) \489INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \490INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type)491#endif492493INTERCEPTORS_STRTO(double, strtod, char)494INTERCEPTORS_STRTO(float, strtof, char)495#ifdef __s390x__496INTERCEPTORS_STRTO_SRET(long double, strtold, char)497#else498INTERCEPTORS_STRTO(long double, strtold, char)499#endif500INTERCEPTORS_STRTO_BASE(long, strtol, char)501INTERCEPTORS_STRTO_BASE(long long, strtoll, char)502INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)503INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char)504INTERCEPTORS_STRTO_BASE(u64, strtouq, char)505506INTERCEPTORS_STRTO(double, wcstod, wchar_t)507INTERCEPTORS_STRTO(float, wcstof, wchar_t)508#ifdef __s390x__509INTERCEPTORS_STRTO_SRET(long double, wcstold, wchar_t)510#else511INTERCEPTORS_STRTO(long double, wcstold, wchar_t)512#endif513INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)514INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)515INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)516INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)517518#if SANITIZER_GLIBC519INTERCEPTORS_STRTO(double, __isoc23_strtod, char)520INTERCEPTORS_STRTO(float, __isoc23_strtof, char)521#ifdef __s390x__522INTERCEPTORS_STRTO_SRET(long double, __isoc23_strtold, char)523#else524INTERCEPTORS_STRTO(long double, __isoc23_strtold, char)525#endif526INTERCEPTORS_STRTO_BASE(long, __isoc23_strtol, char)527INTERCEPTORS_STRTO_BASE(long long, __isoc23_strtoll, char)528INTERCEPTORS_STRTO_BASE(unsigned long, __isoc23_strtoul, char)529INTERCEPTORS_STRTO_BASE(unsigned long long, __isoc23_strtoull, char)530INTERCEPTORS_STRTO_BASE(u64, __isoc23_strtouq, char)531532INTERCEPTORS_STRTO(double, __isoc23_wcstod, wchar_t)533INTERCEPTORS_STRTO(float, __isoc23_wcstof, wchar_t)534#ifdef __s390x__535INTERCEPTORS_STRTO_SRET(long double, __isoc23_wcstold, wchar_t)536#else537INTERCEPTORS_STRTO(long double, __isoc23_wcstold, wchar_t)538#endif539INTERCEPTORS_STRTO_BASE(long, __isoc23_wcstol, wchar_t)540INTERCEPTORS_STRTO_BASE(long long, __isoc23_wcstoll, wchar_t)541INTERCEPTORS_STRTO_BASE(unsigned long, __isoc23_wcstoul, wchar_t)542INTERCEPTORS_STRTO_BASE(unsigned long long, __isoc23_wcstoull, wchar_t)543#endif544545#if SANITIZER_NETBSD546#define INTERCEPT_STRTO(func) \547INTERCEPT_FUNCTION(func); \548INTERCEPT_FUNCTION(func##_l);549#else550#define INTERCEPT_STRTO(func) \551INTERCEPT_FUNCTION(func); \552INTERCEPT_FUNCTION(func##_l); \553INTERCEPT_FUNCTION(__##func##_l); \554INTERCEPT_FUNCTION(__##func##_internal);555556#define INTERCEPT_STRTO_VER(func, ver) \557INTERCEPT_FUNCTION_VER(func, ver); \558INTERCEPT_FUNCTION_VER(func##_l, ver); \559INTERCEPT_FUNCTION_VER(__##func##_l, ver); \560INTERCEPT_FUNCTION_VER(__##func##_internal, ver);561#endif562563564// FIXME: support *wprintf in common format interceptors.565INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {566ENSURE_MSAN_INITED();567int res = REAL(vswprintf)(str, size, format, ap);568if (res >= 0) {569__msan_unpoison(str, 4 * (res + 1));570}571return res;572}573574INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {575ENSURE_MSAN_INITED();576va_list ap;577va_start(ap, format);578int res = vswprintf(str, size, format, ap);579va_end(ap);580return res;581}582583#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \584ENSURE_MSAN_INITED(); \585InterceptorScope interceptor_scope; \586ret_type res = REAL(func)(s, __VA_ARGS__); \587if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1)); \588return res;589590INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,591__sanitizer_tm *tm) {592INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);593}594595INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,596__sanitizer_tm *tm, void *loc) {597INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);598}599600#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD601INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,602__sanitizer_tm *tm, void *loc) {603INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,604loc);605}606#define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l)607#else608#define MSAN_MAYBE_INTERCEPT___STRFTIME_L609#endif610611INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,612__sanitizer_tm *tm) {613INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);614}615616INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,617__sanitizer_tm *tm, void *loc) {618INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,619loc);620}621622#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD623INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,624__sanitizer_tm *tm, void *loc) {625INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,626loc);627}628#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l)629#else630#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L631#endif632633INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {634ENSURE_MSAN_INITED();635int res = REAL(mbtowc)(dest, src, n);636if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));637return res;638}639640INTERCEPTOR(SIZE_T, mbrtowc, wchar_t *dest, const char *src, SIZE_T n,641void *ps) {642ENSURE_MSAN_INITED();643SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);644if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));645return res;646}647648// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);649INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {650ENSURE_MSAN_INITED();651GET_STORE_STACK_TRACE;652wchar_t *res = REAL(wmemcpy)(dest, src, n);653CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);654return res;655}656657#if !SANITIZER_NETBSD658INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {659ENSURE_MSAN_INITED();660GET_STORE_STACK_TRACE;661wchar_t *res = REAL(wmempcpy)(dest, src, n);662CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);663return res;664}665#define MSAN_MAYBE_INTERCEPT_WMEMPCPY INTERCEPT_FUNCTION(wmempcpy)666#else667#define MSAN_MAYBE_INTERCEPT_WMEMPCPY668#endif669670INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {671CHECK(MEM_IS_APP(s));672ENSURE_MSAN_INITED();673wchar_t *res = REAL(wmemset)(s, c, n);674__msan_unpoison(s, n * sizeof(wchar_t));675return res;676}677678INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {679ENSURE_MSAN_INITED();680GET_STORE_STACK_TRACE;681wchar_t *res = REAL(wmemmove)(dest, src, n);682MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);683return res;684}685686INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {687ENSURE_MSAN_INITED();688int res = REAL(wcscmp)(s1, s2);689return res;690}691692INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {693ENSURE_MSAN_INITED();694int res = REAL(gettimeofday)(tv, tz);695if (tv)696__msan_unpoison(tv, 16);697if (tz)698__msan_unpoison(tz, 8);699return res;700}701702#if !SANITIZER_NETBSD703INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {704ENSURE_MSAN_INITED();705char *res = REAL(fcvt)(x, a, b, c);706__msan_unpoison(b, sizeof(*b));707__msan_unpoison(c, sizeof(*c));708if (res)709__msan_unpoison(res, internal_strlen(res) + 1);710return res;711}712#define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt)713#else714#define MSAN_MAYBE_INTERCEPT_FCVT715#endif716717INTERCEPTOR(char *, getenv, char *name) {718if (msan_init_is_running)719return REAL(getenv)(name);720ENSURE_MSAN_INITED();721char *res = REAL(getenv)(name);722if (res)723__msan_unpoison(res, internal_strlen(res) + 1);724return res;725}726727extern char **environ;728729static void UnpoisonEnviron() {730char **envp = environ;731for (; *envp; ++envp) {732__msan_unpoison(envp, sizeof(*envp));733__msan_unpoison(*envp, internal_strlen(*envp) + 1);734}735// Trailing NULL pointer.736__msan_unpoison(envp, sizeof(*envp));737}738739INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {740ENSURE_MSAN_INITED();741CHECK_UNPOISONED_STRING(name, 0);742int res = REAL(setenv)(name, value, overwrite);743if (!res) UnpoisonEnviron();744return res;745}746747INTERCEPTOR(int, putenv, char *string) {748ENSURE_MSAN_INITED();749int res = REAL(putenv)(string);750if (!res) UnpoisonEnviron();751return res;752}753754#define SANITIZER_STAT_LINUX (SANITIZER_LINUX && __GLIBC_PREREQ(2, 33))755#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX756INTERCEPTOR(int, fstat, int fd, void *buf) {757ENSURE_MSAN_INITED();758int res = REAL(fstat)(fd, buf);759if (!res)760__msan_unpoison(buf, __sanitizer::struct_stat_sz);761return res;762}763# define MSAN_MAYBE_INTERCEPT_FSTAT MSAN_INTERCEPT_FUNC(fstat)764#else765#define MSAN_MAYBE_INTERCEPT_FSTAT766#endif767768#if SANITIZER_STAT_LINUX769INTERCEPTOR(int, fstat64, int fd, void *buf) {770ENSURE_MSAN_INITED();771int res = REAL(fstat64)(fd, buf);772if (!res)773__msan_unpoison(buf, __sanitizer::struct_stat64_sz);774return res;775}776# define MSAN_MAYBE_INTERCEPT_FSTAT64 MSAN_INTERCEPT_FUNC(fstat64)777#else778# define MSAN_MAYBE_INTERCEPT_FSTAT64779#endif780781#if SANITIZER_GLIBC782INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {783ENSURE_MSAN_INITED();784int res = REAL(__fxstat)(magic, fd, buf);785if (!res)786__msan_unpoison(buf, __sanitizer::struct_stat_sz);787return res;788}789# define MSAN_MAYBE_INTERCEPT___FXSTAT MSAN_INTERCEPT_FUNC(__fxstat)790#else791#define MSAN_MAYBE_INTERCEPT___FXSTAT792#endif793794#if SANITIZER_GLIBC795INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {796ENSURE_MSAN_INITED();797int res = REAL(__fxstat64)(magic, fd, buf);798if (!res)799__msan_unpoison(buf, __sanitizer::struct_stat64_sz);800return res;801}802# define MSAN_MAYBE_INTERCEPT___FXSTAT64 MSAN_INTERCEPT_FUNC(__fxstat64)803#else804# define MSAN_MAYBE_INTERCEPT___FXSTAT64805#endif806807#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX808INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {809ENSURE_MSAN_INITED();810int res = REAL(fstatat)(fd, pathname, buf, flags);811if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);812return res;813}814# define MSAN_MAYBE_INTERCEPT_FSTATAT MSAN_INTERCEPT_FUNC(fstatat)815#else816# define MSAN_MAYBE_INTERCEPT_FSTATAT817#endif818819#if SANITIZER_STAT_LINUX820INTERCEPTOR(int, fstatat64, int fd, char *pathname, void *buf, int flags) {821ENSURE_MSAN_INITED();822int res = REAL(fstatat64)(fd, pathname, buf, flags);823if (!res)824__msan_unpoison(buf, __sanitizer::struct_stat64_sz);825return res;826}827# define MSAN_MAYBE_INTERCEPT_FSTATAT64 MSAN_INTERCEPT_FUNC(fstatat64)828#else829# define MSAN_MAYBE_INTERCEPT_FSTATAT64830#endif831832#if SANITIZER_GLIBC833INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,834int flags) {835ENSURE_MSAN_INITED();836int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);837if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);838return res;839}840# define MSAN_MAYBE_INTERCEPT___FXSTATAT MSAN_INTERCEPT_FUNC(__fxstatat)841#else842# define MSAN_MAYBE_INTERCEPT___FXSTATAT843#endif844845#if SANITIZER_GLIBC846INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,847int flags) {848ENSURE_MSAN_INITED();849int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);850if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);851return res;852}853# define MSAN_MAYBE_INTERCEPT___FXSTATAT64 MSAN_INTERCEPT_FUNC(__fxstatat64)854#else855# define MSAN_MAYBE_INTERCEPT___FXSTATAT64856#endif857858INTERCEPTOR(int, pipe, int pipefd[2]) {859if (msan_init_is_running)860return REAL(pipe)(pipefd);861ENSURE_MSAN_INITED();862int res = REAL(pipe)(pipefd);863if (!res)864__msan_unpoison(pipefd, sizeof(int[2]));865return res;866}867868INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {869ENSURE_MSAN_INITED();870int res = REAL(pipe2)(pipefd, flags);871if (!res)872__msan_unpoison(pipefd, sizeof(int[2]));873return res;874}875876INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {877ENSURE_MSAN_INITED();878int res = REAL(socketpair)(domain, type, protocol, sv);879if (!res)880__msan_unpoison(sv, sizeof(int[2]));881return res;882}883884#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD885INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {886ENSURE_MSAN_INITED();887char *res = REAL(fgets_unlocked)(s, size, stream);888if (res)889__msan_unpoison(s, internal_strlen(s) + 1);890return res;891}892#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)893#else894#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED895#endif896897#define INTERCEPTOR_GETRLIMIT_BODY(func, resource, rlim) \898if (msan_init_is_running) \899return REAL(getrlimit)(resource, rlim); \900ENSURE_MSAN_INITED(); \901int res = REAL(func)(resource, rlim); \902if (!res) \903__msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); \904return res905906INTERCEPTOR(int, getrlimit, int resource, void *rlim) {907INTERCEPTOR_GETRLIMIT_BODY(getrlimit, resource, rlim);908}909910#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD911INTERCEPTOR(int, __getrlimit, int resource, void *rlim) {912INTERCEPTOR_GETRLIMIT_BODY(__getrlimit, resource, rlim);913}914915INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {916if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);917ENSURE_MSAN_INITED();918int res = REAL(getrlimit64)(resource, rlim);919if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);920return res;921}922923INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit,924void *old_rlimit) {925if (msan_init_is_running)926return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);927ENSURE_MSAN_INITED();928CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz);929int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);930if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz);931return res;932}933934INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,935void *old_rlimit) {936if (msan_init_is_running)937return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);938ENSURE_MSAN_INITED();939CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz);940int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);941if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz);942return res;943}944945#define MSAN_MAYBE_INTERCEPT___GETRLIMIT INTERCEPT_FUNCTION(__getrlimit)946#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)947#define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit)948#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64)949#else950#define MSAN_MAYBE_INTERCEPT___GETRLIMIT951#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64952#define MSAN_MAYBE_INTERCEPT_PRLIMIT953#define MSAN_MAYBE_INTERCEPT_PRLIMIT64954#endif955956INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {957ENSURE_MSAN_INITED();958int res = REAL(gethostname)(name, len);959if (!res || (res == -1 && errno == errno_ENAMETOOLONG)) {960SIZE_T real_len = internal_strnlen(name, len);961if (real_len < len)962++real_len;963__msan_unpoison(name, real_len);964}965return res;966}967968#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD969INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,970int timeout) {971ENSURE_MSAN_INITED();972int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);973if (res > 0) {974__msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);975}976return res;977}978#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)979#else980#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT981#endif982983#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD984INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,985int timeout, void *sigmask) {986ENSURE_MSAN_INITED();987int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);988if (res > 0) {989__msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);990}991return res;992}993#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)994#else995#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT996#endif997998INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {999GET_MALLOC_STACK_TRACE;1000if (DlsymAlloc::Use())1001return DlsymAlloc::Callocate(nmemb, size);1002return msan_calloc(nmemb, size, &stack);1003}10041005INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {1006if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))1007return DlsymAlloc::Realloc(ptr, size);1008GET_MALLOC_STACK_TRACE;1009return msan_realloc(ptr, size, &stack);1010}10111012INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {1013GET_MALLOC_STACK_TRACE;1014return msan_reallocarray(ptr, nmemb, size, &stack);1015}10161017INTERCEPTOR(void *, malloc, SIZE_T size) {1018if (DlsymAlloc::Use())1019return DlsymAlloc::Allocate(size);1020GET_MALLOC_STACK_TRACE;1021return msan_malloc(size, &stack);1022}10231024void __msan_allocated_memory(const void *data, uptr size) {1025if (flags()->poison_in_malloc) {1026GET_MALLOC_STACK_TRACE;1027stack.tag = STACK_TRACE_TAG_POISON;1028PoisonMemory(data, size, &stack);1029}1030}10311032void __msan_copy_shadow(void *dest, const void *src, uptr n) {1033GET_STORE_STACK_TRACE;1034MoveShadowAndOrigin(dest, src, n, &stack);1035}10361037void __sanitizer_dtor_callback(const void *data, uptr size) {1038if (flags()->poison_in_dtor) {1039GET_MALLOC_STACK_TRACE;1040stack.tag = STACK_TRACE_TAG_POISON;1041PoisonMemory(data, size, &stack);1042}1043}10441045void __sanitizer_dtor_callback_fields(const void *data, uptr size) {1046if (flags()->poison_in_dtor) {1047GET_MALLOC_STACK_TRACE;1048stack.tag = STACK_TRACE_TAG_FIELDS;1049PoisonMemory(data, size, &stack);1050}1051}10521053void __sanitizer_dtor_callback_vptr(const void *data) {1054if (flags()->poison_in_dtor) {1055GET_MALLOC_STACK_TRACE;1056stack.tag = STACK_TRACE_TAG_VPTR;1057PoisonMemory(data, sizeof(void *), &stack);1058}1059}10601061template <class Mmap>1062static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,1063int prot, int flags, int fd, OFF64_T offset) {1064SIZE_T rounded_length = RoundUpTo(length, GetPageSize());1065void *end_addr = (char *)addr + (rounded_length - 1);1066if (addr && (!MEM_IS_APP(addr) || !MEM_IS_APP(end_addr))) {1067if (flags & map_fixed) {1068errno = errno_EINVAL;1069return (void *)-1;1070} else {1071addr = nullptr;1072}1073}1074void *res = real_mmap(addr, length, prot, flags, fd, offset);1075if (res != (void *)-1) {1076void *end_res = (char *)res + (rounded_length - 1);1077if (MEM_IS_APP(res) && MEM_IS_APP(end_res)) {1078__msan_unpoison(res, rounded_length);1079} else {1080// Application has attempted to map more memory than is supported by1081// MSAN. Act as if we ran out of memory.1082internal_munmap(res, length);1083errno = errno_ENOMEM;1084return (void *)-1;1085}1086}1087return res;1088}10891090INTERCEPTOR(int, getrusage, int who, void *usage) {1091ENSURE_MSAN_INITED();1092int res = REAL(getrusage)(who, usage);1093if (res == 0) {1094__msan_unpoison(usage, __sanitizer::struct_rusage_sz);1095}1096return res;1097}10981099class SignalHandlerScope {1100public:1101SignalHandlerScope() {1102if (MsanThread *t = GetCurrentThread())1103t->EnterSignalHandler();1104}1105~SignalHandlerScope() {1106if (MsanThread *t = GetCurrentThread())1107t->LeaveSignalHandler();1108}1109};11101111// sigactions_mu guarantees atomicity of sigaction() and signal() calls.1112// Access to sigactions[] is gone with relaxed atomics to avoid data race with1113// the signal handler.1114const int kMaxSignals = 1024;1115static atomic_uintptr_t sigactions[kMaxSignals];1116static StaticSpinMutex sigactions_mu;11171118static void SignalHandler(int signo) {1119SignalHandlerScope signal_handler_scope;1120ScopedThreadLocalStateBackup stlsb;1121UnpoisonParam(1);11221123typedef void (*signal_cb)(int x);1124signal_cb cb =1125(signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);1126cb(signo);1127}11281129static void SignalAction(int signo, void *si, void *uc) {1130SignalHandlerScope signal_handler_scope;1131ScopedThreadLocalStateBackup stlsb;1132UnpoisonParam(3);1133__msan_unpoison(si, sizeof(__sanitizer_sigaction));1134__msan_unpoison(uc, ucontext_t_sz(uc));11351136typedef void (*sigaction_cb)(int, void *, void *);1137sigaction_cb cb =1138(sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);1139cb(signo, si, uc);1140CHECK_UNPOISONED(uc, ucontext_t_sz(uc));1141}11421143static void read_sigaction(const __sanitizer_sigaction *act) {1144CHECK_UNPOISONED(&act->sa_flags, sizeof(act->sa_flags));1145if (act->sa_flags & __sanitizer::sa_siginfo)1146CHECK_UNPOISONED(&act->sigaction, sizeof(act->sigaction));1147else1148CHECK_UNPOISONED(&act->handler, sizeof(act->handler));1149CHECK_UNPOISONED(&act->sa_mask, sizeof(act->sa_mask));1150}11511152extern "C" int pthread_attr_init(void *attr);1153extern "C" int pthread_attr_destroy(void *attr);11541155static void *MsanThreadStartFunc(void *arg) {1156MsanThread *t = (MsanThread *)arg;1157SetCurrentThread(t);1158t->Init();1159SetSigProcMask(&t->starting_sigset_, nullptr);1160return t->ThreadStart();1161}11621163INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),1164void * param) {1165ENSURE_MSAN_INITED(); // for GetTlsSize()1166__sanitizer_pthread_attr_t myattr;1167if (!attr) {1168pthread_attr_init(&myattr);1169attr = &myattr;1170}11711172AdjustStackSize(attr);11731174MsanThread *t = MsanThread::Create(callback, param);1175ScopedBlockSignals block(&t->starting_sigset_);1176int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);11771178if (attr == &myattr)1179pthread_attr_destroy(&myattr);1180if (!res) {1181__msan_unpoison(th, __sanitizer::pthread_t_sz);1182}1183return res;1184}11851186INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,1187void (*dtor)(void *value)) {1188if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);1189ENSURE_MSAN_INITED();1190int res = REAL(pthread_key_create)(key, dtor);1191if (!res && key)1192__msan_unpoison(key, sizeof(*key));1193return res;1194}11951196#if SANITIZER_NETBSD1197INTERCEPTOR(int, __libc_thr_keycreate, __sanitizer_pthread_key_t *m,1198void (*dtor)(void *value))1199ALIAS(WRAP(pthread_key_create));1200#endif12011202INTERCEPTOR(int, pthread_join, void *thread, void **retval) {1203ENSURE_MSAN_INITED();1204int res = REAL(pthread_join)(thread, retval);1205if (!res && retval)1206__msan_unpoison(retval, sizeof(*retval));1207return res;1208}12091210#if SANITIZER_GLIBC1211INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **retval) {1212ENSURE_MSAN_INITED();1213int res = REAL(pthread_tryjoin_np)(thread, retval);1214if (!res && retval)1215__msan_unpoison(retval, sizeof(*retval));1216return res;1217}12181219INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **retval,1220const struct timespec *abstime) {1221int res = REAL(pthread_timedjoin_np)(thread, retval, abstime);1222if (!res && retval)1223__msan_unpoison(retval, sizeof(*retval));1224return res;1225}1226#endif12271228DEFINE_INTERNAL_PTHREAD_FUNCTIONS12291230extern char *tzname[2];12311232INTERCEPTOR(void, tzset, int fake) {1233ENSURE_MSAN_INITED();1234InterceptorScope interceptor_scope;1235REAL(tzset)(fake);1236if (tzname[0])1237__msan_unpoison(tzname[0], internal_strlen(tzname[0]) + 1);1238if (tzname[1])1239__msan_unpoison(tzname[1], internal_strlen(tzname[1]) + 1);1240return;1241}12421243struct MSanAtExitRecord {1244void (*func)(void *arg);1245void *arg;1246};12471248struct InterceptorContext {1249Mutex atexit_mu;1250Vector<struct MSanAtExitRecord *> AtExitStack;12511252InterceptorContext()1253: AtExitStack() {1254}1255};12561257alignas(64) static char interceptor_placeholder[sizeof(InterceptorContext)];1258InterceptorContext *interceptor_ctx() {1259return reinterpret_cast<InterceptorContext*>(&interceptor_placeholder[0]);1260}12611262void MSanAtExitWrapper() {1263MSanAtExitRecord *r;1264{1265Lock l(&interceptor_ctx()->atexit_mu);12661267uptr element = interceptor_ctx()->AtExitStack.Size() - 1;1268r = interceptor_ctx()->AtExitStack[element];1269interceptor_ctx()->AtExitStack.PopBack();1270}12711272UnpoisonParam(1);1273((void(*)())r->func)();1274InternalFree(r);1275}12761277void MSanCxaAtExitWrapper(void *arg) {1278UnpoisonParam(1);1279MSanAtExitRecord *r = (MSanAtExitRecord *)arg;1280// libc before 2.27 had race which caused occasional double handler execution1281// https://sourceware.org/ml/libc-alpha/2017-08/msg01204.html1282if (!r->func)1283return;1284r->func(r->arg);1285r->func = nullptr;1286}12871288static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso);12891290// Unpoison argument shadow for C++ module destructors.1291INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,1292void *dso_handle) {1293if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);1294return setup_at_exit_wrapper((void(*)())func, arg, dso_handle);1295}12961297// Unpoison argument shadow for C++ module destructors.1298INTERCEPTOR(int, atexit, void (*func)()) {1299// Avoid calling real atexit as it is unreachable on at least on Linux.1300if (msan_init_is_running)1301return REAL(__cxa_atexit)((void (*)(void *a))func, 0, 0);1302return setup_at_exit_wrapper((void(*)())func, 0, 0);1303}13041305static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) {1306ENSURE_MSAN_INITED();1307MSanAtExitRecord *r =1308(MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));1309r->func = (void(*)(void *a))f;1310r->arg = arg;1311int res;1312if (!dso) {1313// NetBSD does not preserve the 2nd argument if dso is equal to 01314// Store ctx in a local stack-like structure13151316Lock l(&interceptor_ctx()->atexit_mu);13171318res = REAL(__cxa_atexit)((void (*)(void *a))MSanAtExitWrapper, 0, 0);1319if (!res) {1320interceptor_ctx()->AtExitStack.PushBack(r);1321}1322} else {1323res = REAL(__cxa_atexit)(MSanCxaAtExitWrapper, r, dso);1324}1325return res;1326}13271328// NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly1329// with MSan.1330#if SANITIZER_LINUX1331INTERCEPTOR(int, openpty, int *aparent, int *aworker, char *name,1332const void *termp, const void *winp) {1333ENSURE_MSAN_INITED();1334InterceptorScope interceptor_scope;1335int res = REAL(openpty)(aparent, aworker, name, termp, winp);1336if (!res) {1337__msan_unpoison(aparent, sizeof(*aparent));1338__msan_unpoison(aworker, sizeof(*aworker));1339}1340return res;1341}1342#define MSAN_MAYBE_INTERCEPT_OPENPTY INTERCEPT_FUNCTION(openpty)1343#else1344#define MSAN_MAYBE_INTERCEPT_OPENPTY1345#endif13461347// NetBSD ships with forkpty(3) in -lutil, that needs to be prebuilt explicitly1348// with MSan.1349#if SANITIZER_LINUX1350INTERCEPTOR(int, forkpty, int *aparent, char *name, const void *termp,1351const void *winp) {1352ENSURE_MSAN_INITED();1353InterceptorScope interceptor_scope;1354int res = REAL(forkpty)(aparent, name, termp, winp);1355if (res != -1)1356__msan_unpoison(aparent, sizeof(*aparent));1357return res;1358}1359#define MSAN_MAYBE_INTERCEPT_FORKPTY INTERCEPT_FUNCTION(forkpty)1360#else1361#define MSAN_MAYBE_INTERCEPT_FORKPTY1362#endif13631364struct MSanInterceptorContext {1365bool in_interceptor_scope;1366};13671368namespace __msan {13691370int OnExit() {1371// FIXME: ask frontend whether we need to return failure.1372return 0;1373}13741375} // namespace __msan13761377// A version of CHECK_UNPOISONED using a saved scope value. Used in common1378// interceptors.1379#define CHECK_UNPOISONED_CTX(ctx, x, n) \1380do { \1381if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \1382CHECK_UNPOISONED_0(x, n); \1383} while (0)13841385#define MSAN_INTERCEPT_FUNC(name) \1386do { \1387if (!INTERCEPT_FUNCTION(name)) \1388VReport(1, "MemorySanitizer: failed to intercept '%s'\n", #name); \1389} while (0)13901391#define MSAN_INTERCEPT_FUNC_VER(name, ver) \1392do { \1393if (!INTERCEPT_FUNCTION_VER(name, ver)) \1394VReport(1, "MemorySanitizer: failed to intercept '%s@@%s'\n", #name, \1395ver); \1396} while (0)1397#define MSAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \1398do { \1399if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \1400VReport(1, "MemorySanitizer: failed to intercept '%s@@%s' or '%s'\n", \1401#name, ver, #name); \1402} while (0)14031404#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)1405#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \1406MSAN_INTERCEPT_FUNC_VER(name, ver)1407#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \1408MSAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver)1409#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \1410UnpoisonParam(count)1411#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \1412__msan_unpoison(ptr, size)1413#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \1414CHECK_UNPOISONED_CTX(ctx, ptr, size)1415#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \1416__msan_unpoison(ptr, size)1417#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \1418if (msan_init_is_running) \1419return REAL(func)(__VA_ARGS__); \1420ENSURE_MSAN_INITED(); \1421MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \1422ctx = (void *)&msan_ctx; \1423(void)ctx; \1424InterceptorScope interceptor_scope; \1425__msan_unpoison(__errno_location(), sizeof(int));1426#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \1427do { \1428} while (false)1429#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \1430do { \1431} while (false)1432#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \1433do { \1434} while (false)1435#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \1436do { \1437} while (false)1438#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \1439do { \1440} while (false) // FIXME1441#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \1442do { \1443} while (false) // FIXME1444#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)1445#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()1446#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \1447do { \1448link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle)); \1449if (filename && map) \1450ForEachMappedRegion(map, __msan_unpoison); \1451} while (false)14521453#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!msan_inited)14541455#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \1456if (MsanThread *t = GetCurrentThread()) { \1457*begin = t->tls_begin(); \1458*end = t->tls_end(); \1459} else { \1460*begin = *end = 0; \1461}14621463#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \1464{ \1465(void)ctx; \1466return __msan_memset(block, c, size); \1467}1468#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \1469{ \1470(void)ctx; \1471return __msan_memmove(to, from, size); \1472}1473#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \1474{ \1475(void)ctx; \1476return __msan_memcpy(to, from, size); \1477}14781479#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \1480do { \1481GET_STORE_STACK_TRACE; \1482CopyShadowAndOrigin(to, from, size, &stack); \1483__msan_unpoison(to + size, 1); \1484} while (false)14851486#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \1487offset) \1488do { \1489return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \1490} while (false)14911492#include "sanitizer_common/sanitizer_platform_interceptors.h"1493#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"1494#include "sanitizer_common/sanitizer_common_interceptors.inc"14951496static uptr signal_impl(int signo, uptr cb);1497static int sigaction_impl(int signo, const __sanitizer_sigaction *act,1498__sanitizer_sigaction *oldact);14991500#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signo, act, oldact) \1501{ return sigaction_impl(signo, act, oldact); }15021503#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \1504{ \1505handler = signal_impl(signo, handler); \1506InterceptorScope interceptor_scope; \1507return REAL(func)(signo, handler); \1508}15091510#define SIGNAL_INTERCEPTOR_ENTER() ENSURE_MSAN_INITED()15111512#include "sanitizer_common/sanitizer_signal_interceptors.inc"15131514static int sigaction_impl(int signo, const __sanitizer_sigaction *act,1515__sanitizer_sigaction *oldact) {1516ENSURE_MSAN_INITED();1517if (signo <= 0 || signo >= kMaxSignals) {1518errno = errno_EINVAL;1519return -1;1520}1521if (act) read_sigaction(act);1522int res;1523if (flags()->wrap_signals) {1524SpinMutexLock lock(&sigactions_mu);1525uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);1526__sanitizer_sigaction new_act;1527__sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;1528if (act) {1529REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));1530uptr cb = (uptr)pnew_act->sigaction;1531uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)1532? (uptr)SignalAction1533: (uptr)SignalHandler;1534if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {1535atomic_store(&sigactions[signo], cb, memory_order_relaxed);1536pnew_act->sigaction = (decltype(pnew_act->sigaction))new_cb;1537}1538}1539res = REAL(SIGACTION_SYMNAME)(signo, pnew_act, oldact);1540if (res == 0 && oldact) {1541uptr cb = (uptr)oldact->sigaction;1542if (cb == (uptr)SignalAction || cb == (uptr)SignalHandler) {1543oldact->sigaction = (decltype(oldact->sigaction))old_cb;1544}1545}1546} else {1547res = REAL(SIGACTION_SYMNAME)(signo, act, oldact);1548}15491550if (res == 0 && oldact) {1551__msan_unpoison(oldact, sizeof(__sanitizer_sigaction));1552}1553return res;1554}15551556static uptr signal_impl(int signo, uptr cb) {1557ENSURE_MSAN_INITED();1558if (signo <= 0 || signo >= kMaxSignals) {1559errno = errno_EINVAL;1560return -1;1561}1562if (flags()->wrap_signals) {1563SpinMutexLock lock(&sigactions_mu);1564if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {1565atomic_store(&sigactions[signo], cb, memory_order_relaxed);1566cb = (uptr)&SignalHandler;1567}1568}1569return cb;1570}15711572#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)1573#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \1574do { \1575} while (false)1576#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \1577do { \1578} while (false)1579#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)1580#include "sanitizer_common/sanitizer_common_syscalls.inc"1581#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"15821583INTERCEPTOR(const char *, strsignal, int sig) {1584void *ctx;1585COMMON_INTERCEPTOR_ENTER(ctx, strsignal, sig);1586const char *res = REAL(strsignal)(sig);1587if (res)1588__msan_unpoison(res, internal_strlen(res) + 1);1589return res;1590}15911592INTERCEPTOR(int, dladdr, void *addr, void *info) {1593void *ctx;1594COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info);1595int res = REAL(dladdr)(addr, info);1596if (res != 0)1597UnpoisonDllAddrInfo(info);1598return res;1599}16001601#if SANITIZER_GLIBC1602INTERCEPTOR(int, dladdr1, void *addr, void *info, void **extra_info,1603int flags) {1604void *ctx;1605COMMON_INTERCEPTOR_ENTER(ctx, dladdr1, addr, info, extra_info, flags);1606int res = REAL(dladdr1)(addr, info, extra_info, flags);1607if (res != 0) {1608UnpoisonDllAddrInfo(info);1609UnpoisonDllAddr1ExtraInfo(extra_info, flags);1610}1611return res;1612}1613# define MSAN_MAYBE_INTERCEPT_DLADDR1 MSAN_INTERCEPT_FUNC(dladdr1)1614#else1615#define MSAN_MAYBE_INTERCEPT_DLADDR11616#endif16171618INTERCEPTOR(char *, dlerror, int fake) {1619void *ctx;1620COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);1621char *res = REAL(dlerror)(fake);1622if (res)1623__msan_unpoison(res, internal_strlen(res) + 1);1624return res;1625}16261627typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,1628void *data);1629struct dl_iterate_phdr_data {1630dl_iterate_phdr_cb callback;1631void *data;1632};16331634static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,1635void *data) {1636if (info) {1637__msan_unpoison(info, size);1638if (info->dlpi_phdr && info->dlpi_phnum)1639__msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);1640if (info->dlpi_name)1641__msan_unpoison(info->dlpi_name, internal_strlen(info->dlpi_name) + 1);1642}1643dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;1644UnpoisonParam(3);1645return cbdata->callback(info, size, cbdata->data);1646}16471648INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {1649ENSURE_MSAN_INITED();1650void *p = REAL(shmat)(shmid, shmaddr, shmflg);1651if (p != (void *)-1) {1652__sanitizer_shmid_ds ds;1653int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);1654if (!res) {1655__msan_unpoison(p, ds.shm_segsz);1656}1657}1658return p;1659}16601661INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {1662void *ctx;1663COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);1664dl_iterate_phdr_data cbdata;1665cbdata.callback = callback;1666cbdata.data = data;1667int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);1668return res;1669}16701671// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);1672INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {1673ENSURE_MSAN_INITED();1674wchar_t *res = REAL(wcschr)(s, wc, ps);1675return res;1676}16771678// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);1679INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {1680ENSURE_MSAN_INITED();1681GET_STORE_STACK_TRACE;1682wchar_t *res = REAL(wcscpy)(dest, src);1683CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (internal_wcslen(src) + 1),1684&stack);1685return res;1686}16871688INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {1689ENSURE_MSAN_INITED();1690GET_STORE_STACK_TRACE;1691SIZE_T copy_size = internal_wcsnlen(src, n);1692if (copy_size < n) copy_size++; // trailing \01693wchar_t *res = REAL(wcsncpy)(dest, src, n);1694CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);1695__msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));1696return res;1697}16981699// These interface functions reside here so that they can use1700// REAL(memset), etc.1701void __msan_unpoison(const void *a, uptr size) {1702if (!MEM_IS_APP(a)) return;1703SetShadow(a, size, 0);1704}17051706void __msan_poison(const void *a, uptr size) {1707if (!MEM_IS_APP(a)) return;1708SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1);1709}17101711void __msan_poison_stack(void *a, uptr size) {1712if (!MEM_IS_APP(a)) return;1713SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1);1714}17151716void __msan_unpoison_param(uptr n) { UnpoisonParam(n); }17171718void __msan_clear_and_unpoison(void *a, uptr size) {1719REAL(memset)(a, 0, size);1720SetShadow(a, size, 0);1721}17221723void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {1724if (!msan_inited) return internal_memcpy(dest, src, n);1725if (msan_init_is_running || __msan::IsInSymbolizerOrUnwider())1726return REAL(memcpy)(dest, src, n);1727ENSURE_MSAN_INITED();1728GET_STORE_STACK_TRACE;1729void *res = REAL(memcpy)(dest, src, n);1730CopyShadowAndOrigin(dest, src, n, &stack);1731return res;1732}17331734void *__msan_memset(void *s, int c, SIZE_T n) {1735if (!msan_inited) return internal_memset(s, c, n);1736if (msan_init_is_running) return REAL(memset)(s, c, n);1737ENSURE_MSAN_INITED();1738void *res = REAL(memset)(s, c, n);1739__msan_unpoison(s, n);1740return res;1741}17421743void *__msan_memmove(void *dest, const void *src, SIZE_T n) {1744if (!msan_inited) return internal_memmove(dest, src, n);1745if (msan_init_is_running) return REAL(memmove)(dest, src, n);1746ENSURE_MSAN_INITED();1747GET_STORE_STACK_TRACE;1748void *res = REAL(memmove)(dest, src, n);1749MoveShadowAndOrigin(dest, src, n, &stack);1750return res;1751}17521753void __msan_unpoison_string(const char* s) {1754if (!MEM_IS_APP(s)) return;1755__msan_unpoison(s, internal_strlen(s) + 1);1756}17571758namespace __msan {17591760void InitializeInterceptors() {1761static int inited = 0;1762CHECK_EQ(inited, 0);17631764__interception::DoesNotSupportStaticLinking();17651766new(interceptor_ctx()) InterceptorContext();17671768InitializeCommonInterceptors();1769InitializeSignalInterceptors();17701771INTERCEPT_FUNCTION(posix_memalign);1772MSAN_MAYBE_INTERCEPT_MEMALIGN;1773MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;1774INTERCEPT_FUNCTION(valloc);1775MSAN_MAYBE_INTERCEPT_PVALLOC;1776INTERCEPT_FUNCTION(malloc);1777INTERCEPT_FUNCTION(calloc);1778INTERCEPT_FUNCTION(realloc);1779INTERCEPT_FUNCTION(reallocarray);1780INTERCEPT_FUNCTION(free);1781MSAN_MAYBE_INTERCEPT_CFREE;1782MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;1783MSAN_MAYBE_INTERCEPT_MALLINFO;1784MSAN_MAYBE_INTERCEPT_MALLINFO2;1785MSAN_MAYBE_INTERCEPT_MALLOPT;1786MSAN_MAYBE_INTERCEPT_MALLOC_STATS;1787INTERCEPT_FUNCTION(fread);1788MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;1789INTERCEPT_FUNCTION(memccpy);1790MSAN_MAYBE_INTERCEPT_MEMPCPY;1791INTERCEPT_FUNCTION(bcopy);1792INTERCEPT_FUNCTION(wmemset);1793INTERCEPT_FUNCTION(wmemcpy);1794MSAN_MAYBE_INTERCEPT_WMEMPCPY;1795INTERCEPT_FUNCTION(wmemmove);1796INTERCEPT_FUNCTION(strcpy);1797MSAN_MAYBE_INTERCEPT_STPCPY;1798MSAN_MAYBE_INTERCEPT_STPNCPY;1799INTERCEPT_FUNCTION(strdup);1800MSAN_MAYBE_INTERCEPT___STRDUP;1801INTERCEPT_FUNCTION(strncpy);1802MSAN_MAYBE_INTERCEPT_GCVT;1803INTERCEPT_FUNCTION(strcat);1804INTERCEPT_FUNCTION(strncat);1805INTERCEPT_STRTO(strtod);1806INTERCEPT_STRTO(strtof);1807#ifdef SANITIZER_NLDBL_VERSION1808INTERCEPT_STRTO_VER(strtold, SANITIZER_NLDBL_VERSION);1809#else1810INTERCEPT_STRTO(strtold);1811#endif1812INTERCEPT_STRTO(strtol);1813INTERCEPT_STRTO(strtoul);1814INTERCEPT_STRTO(strtoll);1815INTERCEPT_STRTO(strtoull);1816INTERCEPT_STRTO(strtouq);1817INTERCEPT_STRTO(wcstod);1818INTERCEPT_STRTO(wcstof);1819#ifdef SANITIZER_NLDBL_VERSION1820INTERCEPT_STRTO_VER(wcstold, SANITIZER_NLDBL_VERSION);1821#else1822INTERCEPT_STRTO(wcstold);1823#endif1824INTERCEPT_STRTO(wcstol);1825INTERCEPT_STRTO(wcstoul);1826INTERCEPT_STRTO(wcstoll);1827INTERCEPT_STRTO(wcstoull);1828#if SANITIZER_GLIBC1829INTERCEPT_STRTO(__isoc23_strtod);1830INTERCEPT_STRTO(__isoc23_strtof);1831INTERCEPT_STRTO(__isoc23_strtold);1832INTERCEPT_STRTO(__isoc23_strtol);1833INTERCEPT_STRTO(__isoc23_strtoul);1834INTERCEPT_STRTO(__isoc23_strtoll);1835INTERCEPT_STRTO(__isoc23_strtoull);1836INTERCEPT_STRTO(__isoc23_strtouq);1837INTERCEPT_STRTO(__isoc23_wcstod);1838INTERCEPT_STRTO(__isoc23_wcstof);1839INTERCEPT_STRTO(__isoc23_wcstold);1840INTERCEPT_STRTO(__isoc23_wcstol);1841INTERCEPT_STRTO(__isoc23_wcstoul);1842INTERCEPT_STRTO(__isoc23_wcstoll);1843INTERCEPT_STRTO(__isoc23_wcstoull);1844#endif18451846#ifdef SANITIZER_NLDBL_VERSION1847INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION);1848INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION);1849#else1850INTERCEPT_FUNCTION(vswprintf);1851INTERCEPT_FUNCTION(swprintf);1852#endif1853INTERCEPT_FUNCTION(strftime);1854INTERCEPT_FUNCTION(strftime_l);1855MSAN_MAYBE_INTERCEPT___STRFTIME_L;1856INTERCEPT_FUNCTION(wcsftime);1857INTERCEPT_FUNCTION(wcsftime_l);1858MSAN_MAYBE_INTERCEPT___WCSFTIME_L;1859INTERCEPT_FUNCTION(mbtowc);1860INTERCEPT_FUNCTION(mbrtowc);1861INTERCEPT_FUNCTION(wcslen);1862INTERCEPT_FUNCTION(wcsnlen);1863INTERCEPT_FUNCTION(wcschr);1864INTERCEPT_FUNCTION(wcscpy);1865INTERCEPT_FUNCTION(wcsncpy);1866INTERCEPT_FUNCTION(wcscmp);1867INTERCEPT_FUNCTION(getenv);1868INTERCEPT_FUNCTION(setenv);1869INTERCEPT_FUNCTION(putenv);1870INTERCEPT_FUNCTION(gettimeofday);1871MSAN_MAYBE_INTERCEPT_FCVT;1872MSAN_MAYBE_INTERCEPT_FSTAT;1873MSAN_MAYBE_INTERCEPT_FSTAT64;1874MSAN_MAYBE_INTERCEPT___FXSTAT;1875MSAN_MAYBE_INTERCEPT_FSTATAT;1876MSAN_MAYBE_INTERCEPT_FSTATAT64;1877MSAN_MAYBE_INTERCEPT___FXSTATAT;1878MSAN_MAYBE_INTERCEPT___FXSTAT64;1879MSAN_MAYBE_INTERCEPT___FXSTATAT64;1880INTERCEPT_FUNCTION(pipe);1881INTERCEPT_FUNCTION(pipe2);1882INTERCEPT_FUNCTION(socketpair);1883MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;1884INTERCEPT_FUNCTION(getrlimit);1885MSAN_MAYBE_INTERCEPT___GETRLIMIT;1886MSAN_MAYBE_INTERCEPT_GETRLIMIT64;1887MSAN_MAYBE_INTERCEPT_PRLIMIT;1888MSAN_MAYBE_INTERCEPT_PRLIMIT64;1889INTERCEPT_FUNCTION(gethostname);1890MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;1891MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;1892INTERCEPT_FUNCTION(strsignal);1893INTERCEPT_FUNCTION(dladdr);1894MSAN_MAYBE_INTERCEPT_DLADDR1;1895INTERCEPT_FUNCTION(dlerror);1896INTERCEPT_FUNCTION(dl_iterate_phdr);1897INTERCEPT_FUNCTION(getrusage);1898#if defined(__mips__)1899INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2");1900#else1901INTERCEPT_FUNCTION(pthread_create);1902#endif1903INTERCEPT_FUNCTION(pthread_join);1904INTERCEPT_FUNCTION(pthread_key_create);1905#if SANITIZER_GLIBC1906INTERCEPT_FUNCTION(pthread_tryjoin_np);1907INTERCEPT_FUNCTION(pthread_timedjoin_np);1908#endif19091910#if SANITIZER_NETBSD1911INTERCEPT_FUNCTION(__libc_thr_keycreate);1912#endif19131914INTERCEPT_FUNCTION(pthread_join);1915INTERCEPT_FUNCTION(tzset);1916INTERCEPT_FUNCTION(atexit);1917INTERCEPT_FUNCTION(__cxa_atexit);1918INTERCEPT_FUNCTION(shmat);1919MSAN_MAYBE_INTERCEPT_OPENPTY;1920MSAN_MAYBE_INTERCEPT_FORKPTY;19211922inited = 1;1923}1924} // namespace __msan192519261927