178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===-- msan_interceptors.cc ----------------------------------------------===//
278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//                     The LLVM Compiler Infrastructure
478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// This file is distributed under the University of Illinois Open Source
678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// License. See LICENSE.TXT for details.
778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===----------------------------------------------------------------------===//
978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
1078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// This file is a part of MemorySanitizer.
1178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//
1278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Interceptors for standard library functions.
138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
148530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// FIXME: move as many interceptors as possible into
158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// sanitizer_common/sanitizer_common_interceptors.h
1678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===----------------------------------------------------------------------===//
1778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "interception/interception.h"
1978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "msan.h"
202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "msan_chained_origin_depot.h"
212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "msan_origin.h"
222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "msan_thread.h"
2386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "msan_poisoning.h"
249358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#include "sanitizer_common/sanitizer_platform_limits_posix.h"
2565199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany#include "sanitizer_common/sanitizer_allocator.h"
266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "sanitizer_common/sanitizer_allocator_interface.h"
27cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov#include "sanitizer_common/sanitizer_allocator_internal.h"
28e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov#include "sanitizer_common/sanitizer_atomic.h"
2978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_common.h"
30887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov#include "sanitizer_common/sanitizer_stackdepot.h"
3178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_libc.h"
32b9bf700ae7fe59e25976e0abe9636150f3a39cd2Evgeniy Stepanov#include "sanitizer_common/sanitizer_linux.h"
336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "sanitizer_common/sanitizer_tls_get_addr.h"
3478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include <stdarg.h>
3678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// ACHTUNG! No other system header includes in this file.
3778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Ideally, we should get rid of stdarg.h as well.
3878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovusing namespace __msan;
4078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
41e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::memory_order;
42e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::atomic_load;
43e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::atomic_store;
44e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovusing __sanitizer::atomic_uintptr_t;
45e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov
46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarDECLARE_REAL(SIZE_T, strlen, const char *s)
47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarDECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
4986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_FREEBSD
5086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define __errno_location __error
5186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
5286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
53447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// True if this is a nested interceptor.
54447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovstatic THREADLOCAL int in_interceptor_scope;
55447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" int *__errno_location(void);
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
58447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovstruct InterceptorScope {
59447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  InterceptorScope() { ++in_interceptor_scope; }
60447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  ~InterceptorScope() { --in_interceptor_scope; }
61447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov};
62447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
63447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovbool IsInInterceptorScope() {
64447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  return in_interceptor_scope;
65447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
66447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
6778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#define ENSURE_MSAN_INITED() do { \
688028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  CHECK(!msan_init_is_running); \
6978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!msan_inited) { \
7078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_init(); \
7178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  } \
7278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} while (0)
7378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
74447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// Check that [x, x+n) range is unpoisoned.
756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define CHECK_UNPOISONED_0(x, n)                                               \
766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  do {                                                                         \
776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    sptr offset = __msan_test_shadow(x, n);                                    \
786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    if (__msan::IsInSymbolizer())                                              \
796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      break;                                                                   \
806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    if (offset >= 0 && __msan::flags()->report_umrs) {                         \
816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      GET_CALLER_PC_BP_SP;                                                     \
826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      (void) sp;                                                               \
836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      ReportUMRInsideAddressRange(__func__, x, n, offset);                     \
846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      __msan::PrintWarningWithOrigin(                                          \
856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines          pc, bp, __msan_get_origin((const char *)x + offset));                \
866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      if (__msan::flags()->halt_on_error) {                                    \
876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines        Printf("Exiting\n");                                                   \
886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines        Die();                                                                 \
896d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      }                                                                        \
906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    }                                                                          \
9178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  } while (0)
9278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
93447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// Check that [x, x+n) range is unpoisoned unless we are in a nested
94447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov// interceptor.
95341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define CHECK_UNPOISONED(x, n)                             \
96341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  do {                                                     \
97341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
98341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  } while (0);
99447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
100259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n)               \
101259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED((x),                                         \
102259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    common_flags()->strict_string_checks ? (len) + 1 : (n) )
103259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
104259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar#define CHECK_UNPOISONED_STRING(x, n)                           \
105259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar    CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))
106259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar
1076afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
10878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
1096afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
11078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
11178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(ptr, res *size);
11278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
11378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
11478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
11586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
1166afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
11778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov            void *file) {
11878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
1196afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
12078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
12178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(ptr, res *size);
12278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
12378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
12486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked)
12586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
12686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
12786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
12878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1296afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
13078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
131259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(path, 0)
1326afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
13378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0)
13478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(buf, res);
13578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
13678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
13778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1386afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
13978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return __msan_memcpy(dest, src, n);
14078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
14178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
142353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy StepanovINTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
143353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  return (char *)__msan_memcpy(dest, src, n) + n;
144353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov}
145353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov
1465492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy StepanovINTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
1475492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  ENSURE_MSAN_INITED();
1485492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  void *res = REAL(memccpy)(dest, src, c, n);
1495492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  CHECK(!res || (res >= dest && res <= (char *)dest + n));
1505492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  SIZE_T sz = res ? (char *)res - (char *)dest : n;
1515492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  CHECK_UNPOISONED(src, sz);
1525492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  __msan_unpoison(dest, sz);
1535492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  return res;
1545492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov}
1555492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov
1566afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
15778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return __msan_memmove(dest, src, n);
15878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
15978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
1606afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
16178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return __msan_memset(s, c, n);
16278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
16378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
164ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy StepanovINTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
165ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  return __msan_memmove(dest, src, n);
166ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov}
167ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov
1686afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
16978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
17078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_EQ(alignment & (alignment - 1), 0);
17178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_NE(memptr, 0);
172799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  *memptr = MsanReallocate(&stack, nullptr, size, alignment, false);
173b6c8e47a72d526232f4d3e3b36232f30f8818733Evgeniy Stepanov  CHECK_NE(*memptr, 0);
174b6c8e47a72d526232f4d3e3b36232f30f8818733Evgeniy Stepanov  __msan_unpoison(memptr, sizeof(*memptr));
17578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return 0;
17678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
17778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
17886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
17997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy StepanovINTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) {
18097160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
18197160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  CHECK_EQ(boundary & (boundary - 1), 0);
182799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
18397160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  return ptr;
18497160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov}
18586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
18686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
18786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MEMALIGN
18886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
18997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov
1906a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR(void *, aligned_alloc, SIZE_T boundary, SIZE_T size) {
1916a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  GET_MALLOC_STACK_TRACE;
1926a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  CHECK_EQ(boundary & (boundary - 1), 0);
193799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
1946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return ptr;
1956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
1966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
1976a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) {
1986a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  GET_MALLOC_STACK_TRACE;
1996a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  CHECK_EQ(boundary & (boundary - 1), 0);
200799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
201c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  DTLS_on_libc_memalign(ptr, size);
2026a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return ptr;
2036a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
2042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
20597160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy StepanovINTERCEPTOR(void *, valloc, SIZE_T size) {
20697160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
207799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ptr = MsanReallocate(&stack, nullptr, size, GetPageSizeCached(), false);
20897160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  return ptr;
20997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov}
21097160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov
21186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
21297160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy StepanovINTERCEPTOR(void *, pvalloc, SIZE_T size) {
21397160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
21497160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  uptr PageSize = GetPageSizeCached();
21597160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  size = RoundUpTo(size, PageSize);
21697160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  if (size == 0) {
21797160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov    // pvalloc(0) should allocate one page.
21897160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov    size = PageSize;
21997160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  }
220799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  void *ptr = MsanReallocate(&stack, nullptr, size, PageSize, false);
22197160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  return ptr;
22297160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov}
22386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
22486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
22586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_PVALLOC
22686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
22797160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov
22878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(void, free, void *ptr) {
229effdc7e483708cfa4dc597c21f246c5dbc09daa0Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
230799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (!ptr) return;
231effdc7e483708cfa4dc597c21f246c5dbc09daa0Evgeniy Stepanov  MsanDeallocate(&stack, ptr);
23278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
23378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
23486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
2352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, cfree, void *ptr) {
2362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_MALLOC_STACK_TRACE;
237799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (!ptr) return;
2382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MsanDeallocate(&stack, ptr);
2392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
24086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
24186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
24286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_CFREE
24386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
2466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return __sanitizer_get_allocated_size(ptr);
2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
24986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This function actually returns a struct by value, but we can't unpoison a
251799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// temporary! The following is equivalent on all supported platforms but
252799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// aarch64 (which uses a different register for sret value).  We have a test
253799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// to confirm that.
2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
255799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#ifdef __aarch64__
256799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  uptr r8;
257799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  asm volatile("mov %0,x8" : "=r" (r8));
258799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  sret = reinterpret_cast<__sanitizer_mallinfo*>(r8);
259799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif
2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(memset)(sret, 0, sizeof(*sret));
2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(sret, sizeof(*sret));
2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
26386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
26486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
26586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MALLINFO
26686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
26886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, mallopt, int cmd, int value) {
2702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return -1;
2712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
27286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
27386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
27486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MALLOPT
27586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
2762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
27786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
2782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, malloc_stats, void) {
2792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // FIXME: implement, but don't call REAL(malloc_stats)!
2802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
28186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats)
28286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
28386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
28486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
2852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
28678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
28778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2896afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T n = REAL(strlen)(src);
290259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(src + n, 0);
29178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strcpy)(dest, src);  // NOLINT
29286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, n + 1, &stack);
29378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
29478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
29578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
2966afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
29778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
2982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
2996afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T copy_size = REAL(strnlen)(src, n);
30078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (copy_size < n)
30178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    copy_size++;  // trailing \0
30278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strncpy)(dest, src, n);  // NOLINT
30386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, copy_size, &stack);
3046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  __msan_unpoison(dest + copy_size, n - copy_size);
30578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
30678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
30778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3084bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy StepanovINTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
3094bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  ENSURE_MSAN_INITED();
3102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3114bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  SIZE_T n = REAL(strlen)(src);
312259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(src + n, 0);
3134bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  char *res = REAL(stpcpy)(dest, src);  // NOLINT
31486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, n + 1, &stack);
3154bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  return res;
3164bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov}
3174bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov
31878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, strdup, char *src) {
31978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
3202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
32186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // On FreeBSD strdup() leverages strlen().
32286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  InterceptorScope interceptor_scope;
3236afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T n = REAL(strlen)(src);
324259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(src + n, 0);
32578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strdup)(src);
32686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(res, src, n + 1, &stack);
32778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
32878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
32978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
33086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
3318aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy StepanovINTERCEPTOR(char *, __strdup, char *src) {
3328aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  ENSURE_MSAN_INITED();
3332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3348aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  SIZE_T n = REAL(strlen)(src);
335259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(src + n, 0);
3368aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  char *res = REAL(__strdup)(src);
33786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(res, src, n + 1, &stack);
3388aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  return res;
3398aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov}
34086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup)
34186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
34286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___STRDUP
34386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
3448aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov
3458aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy StepanovINTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
3468aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  ENSURE_MSAN_INITED();
3472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
34886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // On FreeBSD strndup() leverages strnlen().
34986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  InterceptorScope interceptor_scope;
3508aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  SIZE_T copy_size = REAL(strnlen)(src, n);
3518aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  char *res = REAL(strndup)(src, n);
35286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(res, src, copy_size, &stack);
3538aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  __msan_unpoison(res + copy_size, 1); // \0
3548aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  return res;
3558aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov}
3568aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov
35786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
3588aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy StepanovINTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
3598aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  ENSURE_MSAN_INITED();
3602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3618aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  SIZE_T copy_size = REAL(strnlen)(src, n);
3628aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  char *res = REAL(__strndup)(src, n);
36386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(res, src, copy_size, &stack);
3648aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  __msan_unpoison(res + copy_size, 1); // \0
3658aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  return res;
3668aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov}
36786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___STRNDUP INTERCEPT_FUNCTION(__strndup)
36886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
36986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___STRNDUP
37086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
3718aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov
3726afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
37378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
37478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(gcvt)(number, ndigit, buf);
3756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  SIZE_T n = REAL(strlen)(buf);
3766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  __msan_unpoison(buf, n + 1);
37778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
37878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
37978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
38078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
38178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
3822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3836afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T src_size = REAL(strlen)(src);
3846afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T dest_size = REAL(strlen)(dest);
385259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(src + src_size, 0);
386259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(dest + dest_size, 0);
38778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strcat)(dest, src);  // NOLINT
38886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack);
38978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
39078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
39178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
3926afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
39378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
3942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
3956afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T dest_size = REAL(strlen)(dest);
3962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T copy_size = REAL(strnlen)(src, n);
397259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(dest + dest_size, 0);
39878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(strncat)(dest, src, n);  // NOLINT
39986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);
4002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(dest + dest_size + copy_size, 1); // \0
40178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
40278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
40378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
4052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
4062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
4072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();                             \
4082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ret_type res = REAL(func)(__VA_ARGS__);           \
4096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  __msan_unpoison(endptr, sizeof(*endptr));         \
41078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
41178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
41286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPTOR_STRTO(ret_type, func, char_type)                       \
41386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \
41486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr);                  \
41578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
41678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
41786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)                \
41886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
41986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines              int base) {                                                \
42086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base);          \
42178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
42278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
42386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type)                 \
42486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
42586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines              void *loc) {                                               \
42686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc);           \
42778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
42878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
42986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type)            \
43086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
43186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines              int base, void *loc) {                                     \
4322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc);     \
433e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  }
434e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
43586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPTORS_STRTO(ret_type, func, char_type)      \
43686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO(ret_type, func, char_type)             \
43786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)     \
43886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \
43986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)
44086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
44186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type)      \
44286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)             \
44386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type)     \
44486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \
44586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type)
44686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
44786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO(double, strtod, char)                     // NOLINT
44886277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO(float, strtof, char)                      // NOLINT
44986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO(long double, strtold, char)               // NOLINT
45086277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(long, strtol, char)                  // NOLINT
45186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(long long, strtoll, char)            // NOLINT
45286277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)        // NOLINT
45386277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char)  // NOLINT
45486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
45586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO(double, wcstod, wchar_t)                     // NOLINT
45686277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO(float, wcstof, wchar_t)                      // NOLINT
45786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO(long double, wcstold, wchar_t)               // NOLINT
45886277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)                  // NOLINT
45986277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)            // NOLINT
46086277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)        // NOLINT
46186277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)  // NOLINT
46286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
46386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define INTERCEPT_STRTO(func) \
46486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_FUNCTION(func); \
46586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_FUNCTION(func##_l); \
46686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_FUNCTION(__##func##_l); \
46786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_FUNCTION(__##func##_internal);
46886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
4692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
4702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: support *wprintf in common format interceptors.
4712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
4720797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  ENSURE_MSAN_INITED();
4732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(vswprintf)(str, size, format, ap);
4746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (res >= 0) {
4752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    __msan_unpoison(str, 4 * (res + 1));
4760797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  }
4770797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  return res;
4780797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov}
4790797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov
4802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
4810797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  ENSURE_MSAN_INITED();
4820797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  va_list ap;
4830797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  va_start(ap, format);
4842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = vswprintf(str, size, format, ap);
4850797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  va_end(ap);
4860797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov  return res;
4870797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov}
4880797ed4bfc4adaa1436dbd153b276ed9c917f1b7Evgeniy Stepanov
4892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {
49078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
4912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
4922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T res = REAL(strxfrm)(dest, src, n);
4932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res < n) __msan_unpoison(dest, res + 1);
49478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
49578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
49678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
4972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
4982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            void *loc) {
49978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
5012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);
5022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (res < n) __msan_unpoison(dest, res + 1);
50378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
50478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
50578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
5072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();                                              \
5082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ret_type res = REAL(func)(s, __VA_ARGS__);                         \
5092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1));          \
51078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
51178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
5132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm) {
5142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);
51578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
51678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
5182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
5192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
52078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
52178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
52286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
5232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
5242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
5252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
5262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            loc);
52778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
52886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l)
52986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
53086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___STRFTIME_L
53186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
53278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
534e4f9f8a1296768a7a6b6646a3b241a379f4a5e15Evgeniy Stepanov            __sanitizer_tm *tm) {
5352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);
5362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
5372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
5382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
5392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
5402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,
5412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            loc);
5422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
5432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
54486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
5452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
5462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines            __sanitizer_tm *tm, void *loc) {
5472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
5482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                            loc);
54978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
55086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l)
55186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
55286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L
55386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
55478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
555801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
556801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  ENSURE_MSAN_INITED();
557801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  int res = REAL(mbtowc)(dest, src, n);
558801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
559801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
560801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
561801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
562801448950d645813efb398575bbc62b48e5b1dfcEvgeniy StepanovINTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
563801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  ENSURE_MSAN_INITED();
564801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
565801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
566801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  return res;
567801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov}
568801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov
5696afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
57078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5716afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SIZE_T res = REAL(wcslen)(s);
57278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
57378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
57478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
57578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
57678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
57778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
57878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
57978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wcschr)(s, wc, ps);
58078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
58178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
58278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
58378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
58478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
58578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
58778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wcscpy)(dest, src);
58886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
58986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                      &stack);
59078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
59178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
59278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
5936afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
5946afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
59578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
5962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
59778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wmemcpy)(dest, src, n);
59886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
59978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
60078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
60178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
602353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy StepanovINTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
603353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  ENSURE_MSAN_INITED();
6042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
605353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  wchar_t *res = REAL(wmempcpy)(dest, src, n);
60686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
607353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  return res;
608353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov}
609353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov
6106afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
61178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK(MEM_IS_APP(s));
61278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
61386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  wchar_t *res = REAL(wmemset)(s, c, n);
61478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  __msan_unpoison(s, n * sizeof(wchar_t));
61578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
61678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
61778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
6186afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
61978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
6202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
62178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  wchar_t *res = REAL(wmemmove)(dest, src, n);
62286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
62378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
62478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
62578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
62678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
62778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
62878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(wcscmp)(s1, s2);
62978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
63078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
63178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
63278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
63378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
63478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(gettimeofday)(tv, tz);
63578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (tv)
63678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(tv, 16);
63778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (tz)
63878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(tz, 8);
63978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
64078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
64178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
64278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
64378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
64478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(fcvt)(x, a, b, c);
6456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  __msan_unpoison(b, sizeof(*b));
6466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  __msan_unpoison(c, sizeof(*c));
6476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
64878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
64978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
65078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
65178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, getenv, char *name) {
65286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (msan_init_is_running)
65386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return REAL(getenv)(name);
65478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
65578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(getenv)(name);
6566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
65778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
65878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
65978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
660534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanovextern char **environ;
661534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
662534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanovstatic void UnpoisonEnviron() {
663534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  char **envp = environ;
664534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  for (; *envp; ++envp) {
665534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov    __msan_unpoison(envp, sizeof(*envp));
666534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov    __msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
667534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  }
668534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  // Trailing NULL pointer.
669534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  __msan_unpoison(envp, sizeof(*envp));
670534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov}
671534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
672534e2ba5188e1a74b340f9507755806357835f62Evgeniy StepanovINTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
673534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  ENSURE_MSAN_INITED();
674259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CHECK_UNPOISONED_STRING(name, 0)
675534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  int res = REAL(setenv)(name, value, overwrite);
676534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  if (!res) UnpoisonEnviron();
677534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  return res;
678534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov}
679534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
680534e2ba5188e1a74b340f9507755806357835f62Evgeniy StepanovINTERCEPTOR(int, putenv, char *string) {
681534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  ENSURE_MSAN_INITED();
682534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  int res = REAL(putenv)(string);
683534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  if (!res) UnpoisonEnviron();
684534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  return res;
685534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov}
686534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov
68786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
68878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
68978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
69078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__fxstat)(magic, fd, buf);
69178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
6929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat_sz);
69378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
69478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
69586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat)
69686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
69786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___FXSTAT
69886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
69978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
70086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
70178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
70278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
70378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(__fxstat64)(magic, fd, buf);
70478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
7059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
70678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
70778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
70886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64)
70986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
71086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___FXSTAT64
71186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
71278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
71386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_FREEBSD
71486277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
71586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ENSURE_MSAN_INITED();
71686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  int res = REAL(fstatat)(fd, pathname, buf, flags);
71786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
71886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  return res;
71986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
72086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat)
72186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
722bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy StepanovINTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
723bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov            int flags) {
724bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  ENSURE_MSAN_INITED();
725bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);
726bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
727bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  return res;
728bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov}
72986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)
73086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
731bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov
73286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
733bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy StepanovINTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
734bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov            int flags) {
735bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  ENSURE_MSAN_INITED();
736bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);
737bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
738bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov  return res;
739bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov}
74086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64)
74186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
74286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT___FXSTATAT64
74386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
744bb22942b91bf0855da4a9da132c77f325b187b84Evgeniy Stepanov
74578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, pipe, int pipefd[2]) {
74678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (msan_init_is_running)
74778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return REAL(pipe)(pipefd);
74878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
74978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(pipe)(pipefd);
75078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
75178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(pipefd, sizeof(int[2]));
75278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
75378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
75478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
755134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy StepanovINTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
756134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  ENSURE_MSAN_INITED();
757134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  int res = REAL(pipe2)(pipefd, flags);
758134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  if (!res)
759134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov    __msan_unpoison(pipefd, sizeof(int[2]));
760134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  return res;
761134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov}
762134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov
763134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy StepanovINTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
764134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  ENSURE_MSAN_INITED();
765134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  int res = REAL(socketpair)(domain, type, protocol, sv);
766134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  if (!res)
767134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov    __msan_unpoison(sv, sizeof(int[2]));
768134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  return res;
769134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov}
770134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov
77178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
77278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
77378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(fgets)(s, size, stream);
77478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res)
77578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(s, REAL(strlen)(s) + 1);
77678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
77778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
77878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
77986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
78078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
78178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
78278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  char *res = REAL(fgets_unlocked)(s, size, stream);
78378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res)
78478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(s, REAL(strlen)(s) + 1);
78578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
78678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
78786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)
78886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
78986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
79086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
79178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
79278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, getrlimit, int resource, void *rlim) {
79378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (msan_init_is_running)
79478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return REAL(getrlimit)(resource, rlim);
79578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
79678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(getrlimit)(resource, rlim);
79778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!res)
7989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
79978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
80078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
80178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
80286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
80378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
804c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
80578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
80678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(getrlimit64)(resource, rlim);
807c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
80878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
80978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
810c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
811c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit,
812c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar            void *old_rlimit) {
813c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (msan_init_is_running)
814c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
815c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ENSURE_MSAN_INITED();
816c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz);
817c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
818c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz);
819c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
820c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
821c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
822c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
823c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar            void *old_rlimit) {
824c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (msan_init_is_running)
825c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
826c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ENSURE_MSAN_INITED();
827c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz);
828c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
829c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz);
830c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
831c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
832c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
83386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)
834c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit)
835c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64)
83686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
83786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
838c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define MSAN_MAYBE_INTERCEPT_PRLIMIT
839c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define MSAN_MAYBE_INTERCEPT_PRLIMIT64
84086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
84178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
84286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_FREEBSD
84386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// FreeBSD's <sys/utsname.h> define uname() as
84486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// static __inline int uname(struct utsname *name) {
84586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines//   return __xuname(SYS_NMLN, (void*)name);
84686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// }
84786277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, __xuname, int size, void *utsname) {
84886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ENSURE_MSAN_INITED();
84986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  int res = REAL(__xuname)(size, utsname);
85086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (!res)
85186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
85286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  return res;
85386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
85486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname)
85586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
85686277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, uname, struct utsname *utsname) {
85778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
85878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(uname)(utsname);
85986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (!res)
8609358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
86178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
86278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
86386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname)
86486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
86578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
86695d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy StepanovINTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
86795d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  ENSURE_MSAN_INITED();
86895d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  int res = REAL(gethostname)(name, len);
86995d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  if (!res) {
87095d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov    SIZE_T real_len = REAL(strnlen)(name, len);
87195d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov    if (real_len < len)
87295d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov      ++real_len;
87395d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov    __msan_unpoison(name, real_len);
87495d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  }
87595d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  return res;
87695d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov}
87795d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov
87886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
87978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
88078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    int timeout) {
88178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
88278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
88378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0) {
8849358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
88578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
88678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
88778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
88886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)
88986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
89086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
89186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
89278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
89386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
89478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovINTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
89578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    int timeout, void *sigmask) {
89678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
89778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
89878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res > 0) {
8999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
90078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
90178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
90278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
90386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)
90486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
90586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
90686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
90778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
9086afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
90978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
91086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (UNLIKELY(!msan_inited)) {
91178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
9126afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    const SIZE_T kCallocPoolSize = 1024;
91378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    static uptr calloc_memory_for_dlsym[kCallocPoolSize];
9146afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    static SIZE_T allocated;
9156afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany    SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
91678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    void *mem = (void*)&calloc_memory_for_dlsym[allocated];
91778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    allocated += size_in_words;
91878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    CHECK(allocated < kCallocPoolSize);
91978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    return mem;
92078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  }
92186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  return MsanCalloc(&stack, nmemb, size);
92278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
92378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
9246afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
92578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
92678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
92778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
92878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
9296afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, malloc, SIZE_T size) {
93078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  GET_MALLOC_STACK_TRACE;
931799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return MsanReallocate(&stack, nullptr, size, sizeof(u64), false);
93278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
93378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
93486277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid __msan_allocated_memory(const void *data, uptr size) {
935887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov  GET_MALLOC_STACK_TRACE;
93686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (flags()->poison_in_malloc) {
93786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    stack.tag = STACK_TRACE_TAG_POISON;
93886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    PoisonMemory(data, size, &stack);
939887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov  }
940887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov}
941887a5feeb59a515e2fc291ceb8451dc569936124Evgeniy Stepanov
942799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarvoid __msan_copy_shadow(void *dest, const void *src, uptr n) {
943799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  GET_STORE_STACK_TRACE;
944799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  MoveShadowAndOrigin(dest, src, n, &stack);
945799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
946799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
947799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarvoid __sanitizer_dtor_callback(const void *data, uptr size) {
948799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  GET_MALLOC_STACK_TRACE;
949799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (flags()->poison_in_dtor) {
950799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    stack.tag = STACK_TRACE_TAG_POISON;
951799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    PoisonMemory(data, size, &stack);
952799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
953799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
954799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
9556afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
9566afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany            int fd, OFF_T offset) {
95786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  if (msan_init_is_running)
95886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    return REAL(mmap)(addr, length, prot, flags, fd, offset);
95978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
9602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (addr && !MEM_IS_APP(addr)) {
9612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (flags & map_fixed) {
9622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      *__errno_location() = errno_EINVAL;
9632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      return (void *)-1;
9642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
965799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      addr = nullptr;
9662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
9672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
96878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
96978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res != (void*)-1)
97078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
97178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
97278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
97378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
97486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !SANITIZER_FREEBSD
9756afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
9766afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany            int fd, OFF64_T offset) {
97778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  ENSURE_MSAN_INITED();
9782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (addr && !MEM_IS_APP(addr)) {
9792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (flags & map_fixed) {
9802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      *__errno_location() = errno_EINVAL;
9812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      return (void *)-1;
9822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    } else {
983799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      addr = nullptr;
9842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
9852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
98678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
98778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (res != (void*)-1)
98878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov    __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
98978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  return res;
99078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
99186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
99286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
99386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define MSAN_MAYBE_INTERCEPT_MMAP64
99486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
99578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
996e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy StepanovINTERCEPTOR(int, getrusage, int who, void *usage) {
997e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  ENSURE_MSAN_INITED();
998e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  int res = REAL(getrusage)(who, usage);
999e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  if (res == 0) {
10009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
1001e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  }
1002e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  return res;
1003e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov}
1004e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov
10052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesclass SignalHandlerScope {
10062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines public:
10072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SignalHandlerScope() {
10082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (MsanThread *t = GetCurrentThread())
10092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      t->EnterSignalHandler();
10102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
10112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ~SignalHandlerScope() {
10122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if (MsanThread *t = GetCurrentThread())
10132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      t->LeaveSignalHandler();
10142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  }
10152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
10162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1017e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov// sigactions_mu guarantees atomicity of sigaction() and signal() calls.
1018e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov// Access to sigactions[] is gone with relaxed atomics to avoid data race with
1019e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov// the signal handler.
102006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovconst int kMaxSignals = 1024;
1021e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanovstatic atomic_uintptr_t sigactions[kMaxSignals];
102206658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovstatic StaticSpinMutex sigactions_mu;
102306658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
102406658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovstatic void SignalHandler(int signo) {
10252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SignalHandlerScope signal_handler_scope;
10260e38a67cd2d877e8680d65878c86c9e7e4fa4b1dEvgeniy Stepanov  ScopedThreadLocalStateBackup stlsb;
102791659d56bab07fb82ac0edad18c04b333680fd62Evgeniy Stepanov  UnpoisonParam(1);
102891659d56bab07fb82ac0edad18c04b333680fd62Evgeniy Stepanov
1029a27bdf70ca24202dce21cf7c1a387aeaa400d889Kostya Serebryany  typedef void (*signal_cb)(int x);
1030e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov  signal_cb cb =
1031e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov      (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
10326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  cb(signo);
103306658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov}
103406658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
103506658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanovstatic void SignalAction(int signo, void *si, void *uc) {
10362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SignalHandlerScope signal_handler_scope;
10370e38a67cd2d877e8680d65878c86c9e7e4fa4b1dEvgeniy Stepanov  ScopedThreadLocalStateBackup stlsb;
1038c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonov  UnpoisonParam(3);
1039b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov  __msan_unpoison(si, sizeof(__sanitizer_sigaction));
1040072770202bb1002172abe9a4b1eeb7f2d2fb004fEvgeniy Stepanov  __msan_unpoison(uc, __sanitizer::ucontext_t_sz);
104106658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
104206658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  typedef void (*sigaction_cb)(int, void *, void *);
1043e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov  sigaction_cb cb =
1044e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov      (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
10456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  cb(signo, si, uc);
104606658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov}
104706658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
104806658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy StepanovINTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
104906658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov            __sanitizer_sigaction *oldact) {
1050e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  ENSURE_MSAN_INITED();
1051583025ddc52988cdcedb5dee57e0d66a0c586340Kostya Serebryany  // FIXME: check that *act is unpoisoned.
1052e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  // That requires intercepting all of sigemptyset, sigfillset, etc.
1053a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  int res;
1054a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  if (flags()->wrap_signals) {
1055a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    SpinMutexLock lock(&sigactions_mu);
1056a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    CHECK_LT(signo, kMaxSignals);
1057e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov    uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
1058a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    __sanitizer_sigaction new_act;
1059799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    __sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;
1060a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    if (act) {
10616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));
10622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      uptr cb = (uptr)pnew_act->sigaction;
1063b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov      uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
1064b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov                        ? (uptr)SignalAction
1065b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov                        : (uptr)SignalHandler;
1066a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
1067e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov        atomic_store(&sigactions[signo], cb, memory_order_relaxed);
10682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;
1069a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov      }
107006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov    }
1071a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    res = REAL(sigaction)(signo, pnew_act, oldact);
1072a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    if (res == 0 && oldact) {
10732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      uptr cb = (uptr)oldact->sigaction;
1074cd3049da150124156502b1a8c05e4c4887786cc5Evgeniy Stepanov      if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
10752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        oldact->sigaction = (void (*)(int, void *, void *))old_cb;
1076cd3049da150124156502b1a8c05e4c4887786cc5Evgeniy Stepanov      }
1077a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    }
1078a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  } else {
1079a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    res = REAL(sigaction)(signo, act, oldact);
108006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  }
1081a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov
108206658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  if (res == 0 && oldact) {
1083b32d1bfc59592bc57d74a1e940881354b4788eaeEvgeniy Stepanov    __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
1084e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
1085e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
1086e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
1087e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
108806658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy StepanovINTERCEPTOR(int, signal, int signo, uptr cb) {
108906658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  ENSURE_MSAN_INITED();
1090a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  if (flags()->wrap_signals) {
1091a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    CHECK_LT(signo, kMaxSignals);
1092a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    SpinMutexLock lock(&sigactions_mu);
1093a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
1094e0a871284c7496b91add2956531d1a9e65b7bc88Evgeniy Stepanov      atomic_store(&sigactions[signo], cb, memory_order_relaxed);
1095a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov      cb = (uptr) SignalHandler;
1096a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    }
1097a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    return REAL(signal)(signo, cb);
1098a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov  } else {
1099a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov    return REAL(signal)(signo, cb);
110006658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  }
110106658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov}
110206658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov
110310fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanovextern "C" int pthread_attr_init(void *attr);
110410fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanovextern "C" int pthread_attr_destroy(void *attr);
11057c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
11067c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanovstatic void *MsanThreadStartFunc(void *arg) {
11072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MsanThread *t = (MsanThread *)arg;
11082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SetCurrentThread(t);
11092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return t->ThreadStart();
11107c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov}
111110fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov
111210fd3227546d17c7411241a45ebc143b2031c78dEvgeniy StepanovINTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
111310fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov            void * param) {
111410fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  ENSURE_MSAN_INITED(); // for GetTlsSize()
111510fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  __sanitizer_pthread_attr_t myattr;
1116799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (!attr) {
111710fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov    pthread_attr_init(&myattr);
111810fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov    attr = &myattr;
111910fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  }
1120b9bf700ae7fe59e25976e0abe9636150f3a39cd2Evgeniy Stepanov
11212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  AdjustStackSize(attr);
112210fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov
11232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MsanThread *t = MsanThread::Create(callback, param);
11247c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
11252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);
11267c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
112710fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  if (attr == &myattr)
112810fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov    pthread_attr_destroy(&myattr);
1129e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
1130e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    __msan_unpoison(th, __sanitizer::pthread_t_sz);
1131e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
113210fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  return res;
113310fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov}
113410fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov
1135eaca82cf249021afa31dbc970278f2f28ea2a1aaTimur IskhodzhanovINTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
1136eaca82cf249021afa31dbc970278f2f28ea2a1aaTimur Iskhodzhanov            void (*dtor)(void *value)) {
11372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);
1138737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  ENSURE_MSAN_INITED();
1139737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  int res = REAL(pthread_key_create)(key, dtor);
1140737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  if (!res && key)
1141737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov    __msan_unpoison(key, sizeof(*key));
1142737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  return res;
1143737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov}
1144737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov
11456567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy StepanovINTERCEPTOR(int, pthread_join, void *th, void **retval) {
11466567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  ENSURE_MSAN_INITED();
11476567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  int res = REAL(pthread_join)(th, retval);
11486567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  if (!res && retval)
11496567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov    __msan_unpoison(retval, sizeof(*retval));
11506567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  return res;
11516567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov}
11526567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov
11537b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanovextern char *tzname[2];
11547b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov
11552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void, tzset, int fake) {
11567b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  ENSURE_MSAN_INITED();
11572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  REAL(tzset)(fake);
11587b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  if (tzname[0])
11597b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov    __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);
11607b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  if (tzname[1])
11617b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov    __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);
11627b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  return;
11637b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov}
11647b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov
1165cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanovstruct MSanAtExitRecord {
1166cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  void (*func)(void *arg);
1167cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  void *arg;
1168cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov};
1169cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov
1170cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanovvoid MSanAtExitWrapper(void *arg) {
1171cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  UnpoisonParam(1);
1172cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
11736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  r->func(r->arg);
1174cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  InternalFree(r);
1175cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov}
1176cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov
1177cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov// Unpoison argument shadow for C++ module destructors.
1178cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy StepanovINTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
1179cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov            void *dso_handle) {
1180cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
1181cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  ENSURE_MSAN_INITED();
1182cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  MSanAtExitRecord *r =
1183cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov      (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
1184cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  r->func = func;
1185cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  r->arg = arg;
1186cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
1187cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov}
1188cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov
1189f3603890015c130420def39d67a02c2fdafc6f84Evgeniy StepanovDECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf)
1190f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov
1191f3603890015c130420def39d67a02c2fdafc6f84Evgeniy StepanovINTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
1192f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  ENSURE_MSAN_INITED();
1193f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  void *p = REAL(shmat)(shmid, shmaddr, shmflg);
1194f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  if (p != (void *)-1) {
1195f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    __sanitizer_shmid_ds ds;
1196f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);
1197f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    if (!res) {
1198f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov      __msan_unpoison(p, ds.shm_segsz);
1199f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov    }
1200f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  }
1201f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  return p;
1202f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov}
1203f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov
12046d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void BeforeFork() {
12056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  StackDepotLockAll();
12066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ChainedOriginDepotLockAll();
1207548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1208548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov
12096d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void AfterFork() {
12106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ChainedOriginDepotUnlockAll();
12116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  StackDepotUnlockAll();
1212548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1213548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov
12146d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(int, fork, void) {
12156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ENSURE_MSAN_INITED();
12166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  BeforeFork();
12176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  int pid = REAL(fork)();
12186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  AfterFork();
12196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return pid;
1220548559d8f5a889d98f50e06bc7c736182a53ec39Evgeniy Stepanov}
1221f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov
1222799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name,
1223799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            const void *termp, const void *winp) {
1224799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  ENSURE_MSAN_INITED();
1225799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  InterceptorScope interceptor_scope;
1226799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(openpty)(amaster, aslave, name, termp, winp);
1227799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (!res) {
1228799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    __msan_unpoison(amaster, sizeof(*amaster));
1229799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    __msan_unpoison(aslave, sizeof(*aslave));
1230799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  }
1231799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
1232799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
1233799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
1234799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga NainarINTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp,
1235799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar            const void *winp) {
1236799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  ENSURE_MSAN_INITED();
1237799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  InterceptorScope interceptor_scope;
1238799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  int res = REAL(forkpty)(amaster, name, termp, winp);
1239799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (res != -1)
1240799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    __msan_unpoison(amaster, sizeof(*amaster));
1241799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  return res;
1242799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar}
1243799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar
1244447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanovstruct MSanInterceptorContext {
1245447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  bool in_interceptor_scope;
1246447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov};
1247447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
12488cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukovnamespace __msan {
12498cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukov
12508cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukovint OnExit() {
125114dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  // FIXME: ask frontend whether we need to return failure.
125214dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov  return 0;
125314dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov}
125414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov
1255799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} // namespace __msan
12568cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukov
1257a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov// A version of CHECK_UNPOISONED using a saved scope value. Used in common
12585b2afc3e655f32c8b9d4b7c8b0ad31681f16cf06Evgeniy Stepanov// interceptors.
1259341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#define CHECK_UNPOISONED_CTX(ctx, x, n)                         \
1260341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  do {                                                          \
1261341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
1262341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov      CHECK_UNPOISONED_0(x, n);                                 \
1263341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  } while (0)
1264447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
12652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define MSAN_INTERCEPT_FUNC(name)                                       \
12662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  do {                                                                  \
12672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                     \
12682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines      VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \
1269a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov  } while (0)
1270a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov
1271c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define MSAN_INTERCEPT_FUNC_VER(name, ver)                                    \
1272c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  do {                                                                        \
1273c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name)))                  \
1274c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      VReport(                                                                \
1275c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar          1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
1276c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  } while (0)
1277c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1278a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
1279c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#define COMMON_INTERCEPT_FUNCTION_VER(name, ver)                          \
1280c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  MSAN_INTERCEPT_FUNC_VER(name, ver)
12812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count)  \
12823fa122e6a8e12db6583793861f6cf776fe1c98a0Evgeniy Stepanov  UnpoisonParam(count)
1283996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
1284447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  __msan_unpoison(ptr, size)
1285447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
1286341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  CHECK_UNPOISONED_CTX(ctx, ptr, size)
12872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \
12880586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov  __msan_unpoison(ptr, size)
12891161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                  \
12901161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  if (msan_init_is_running) return REAL(func)(__VA_ARGS__);       \
1291c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ENSURE_MSAN_INITED();                                           \
12921161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  MSanInterceptorContext msan_ctx = {IsInInterceptorScope()};     \
12931161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  ctx = (void *)&msan_ctx;                                        \
12941161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  (void)ctx;                                                      \
12951161eb4bff61908074699f6459eabce25839f966Evgeniy Stepanov  InterceptorScope interceptor_scope;                             \
1296c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */
129786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
129886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  do {                                            \
129986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  } while (false)
1300447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
1301447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  do {                                         \
130282a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov  } while (false)
13039d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
13049d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  do {                                         \
13059d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  } while (false)
13069d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
13079d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  do {                                                      \
13089d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  } while (false)
130982a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
13109d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  do {                                                \
13119d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  } while (false)  // FIXME
13125cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
13135cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  do {                                                         \
13145cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov  } while (false)  // FIXME
1315e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
131614dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
1317799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)                    \
1318799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  do {                                                                         \
1319799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle));                   \
1320799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    if (filename && map)                                                       \
1321799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar      ForEachMappedRegion(map, __msan_unpoison);                               \
132286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  } while (false)
13232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1324cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
1325cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (MsanThread *t = GetCurrentThread()) {                                    \
1326cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    *begin = t->tls_begin();                                                   \
1327cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    *end = t->tls_end();                                                       \
1328cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  } else {                                                                     \
1329cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    *begin = *end = 0;                                                         \
1330cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  }
1331cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
1332c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include "sanitizer_common/sanitizer_platform_interceptors.h"
1333c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Msan needs custom handling of these:
1334c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#undef SANITIZER_INTERCEPT_MEMSET
1335c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#undef SANITIZER_INTERCEPT_MEMMOVE
1336c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#undef SANITIZER_INTERCEPT_MEMCPY
13374f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_interceptors.inc"
1338c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany
13392887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
13406b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
13416b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  do {                                       \
13426b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  } while (false)
13436b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
13446b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  do {                                       \
13456b85945cae8265323e98e4e88c0de66d462f69c6Alexey Samsonov  } while (false)
13462887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
13472887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov#include "sanitizer_common/sanitizer_common_syscalls.inc"
13482887a64cb7b82fc2dcbe4b1fcc33562077ec371aEvgeniy Stepanov
1349c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstruct dlinfo {
1350c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *dli_fname;
1351c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *dli_fbase;
1352c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *dli_sname;
1353c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *dli_saddr;
1354c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar};
1355c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1356c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
1357c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
1358c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info);
1359c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(dladdr)(addr, info);
1360c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res != 0) {
1361c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    __msan_unpoison(info, sizeof(*info));
1362c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (info->dli_fname)
1363c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
1364c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (info->dli_sname)
1365c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
1366c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
1367c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
1368c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
1369c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1370c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(char *, dlerror, int fake) {
1371c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
1372c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);
1373c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char *res = REAL(dlerror)(fake);
1374c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
1375c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
1376c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
1377c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1378c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainartypedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
1379c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                  void *data);
1380c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstruct dl_iterate_phdr_data {
1381c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  dl_iterate_phdr_cb callback;
1382c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *data;
1383c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar};
1384c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1385c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
1386c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                                   void *data) {
1387c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (info) {
1388c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    __msan_unpoison(info, size);
1389c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (info->dlpi_phdr && info->dlpi_phnum)
1390c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      __msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
1391c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    if (info->dlpi_name)
1392c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar      __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
1393c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  }
1394c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
1395c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  UnpoisonParam(3);
1396c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return cbdata->callback(info, size, cbdata->data);
1397c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
1398c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
1399c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarINTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
1400c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  void *ctx;
1401c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);
1402c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  dl_iterate_phdr_data cbdata;
1403c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cbdata.callback = callback;
1404c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cbdata.data = data;
1405c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
1406c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return res;
1407c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
1408c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
140978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// These interface functions reside here so that they can use
14106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// REAL(memset), etc.
141111347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_unpoison(const void *a, uptr size) {
141278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(a)) return;
141386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  SetShadow(a, size, 0);
141478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
141578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
141611347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_poison(const void *a, uptr size) {
141778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(a)) return;
141886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1);
141978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
142078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
142178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_poison_stack(void *a, uptr size) {
142278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  if (!MEM_IS_APP(a)) return;
142386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1);
142478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
142578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
142678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_clear_and_unpoison(void *a, uptr size) {
14276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  REAL(memset)(a, 0, size);
142886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  SetShadow(a, size, 0);
14292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
14302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
14322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!msan_inited) return internal_memcpy(dest, src, n);
1433799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  if (msan_init_is_running || __msan::IsInSymbolizer())
1434799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar    return REAL(memcpy)(dest, src, n);
14352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();
14362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
14376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  void *res = REAL(memcpy)(dest, src, n);
143886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  CopyShadowAndOrigin(dest, src, n, &stack);
14392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
14402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
14412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__msan_memset(void *s, int c, SIZE_T n) {
14432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!msan_inited) return internal_memset(s, c, n);
14442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(memset)(s, c, n);
14452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();
14466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  void *res = REAL(memset)(s, c, n);
14472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(s, n);
14482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
144978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
145078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov
14512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__msan_memmove(void *dest, const void *src, SIZE_T n) {
14522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!msan_inited) return internal_memmove(dest, src, n);
14532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (msan_init_is_running) return REAL(memmove)(dest, src, n);
14542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ENSURE_MSAN_INITED();
14552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  GET_STORE_STACK_TRACE;
14562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  void *res = REAL(memmove)(dest, src, n);
145786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MoveShadowAndOrigin(dest, src, n, &stack);
14582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
14592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
14602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __msan_unpoison_string(const char* s) {
14622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!MEM_IS_APP(s)) return;
14632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  __msan_unpoison(s, REAL(strlen)(s) + 1);
14642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
14652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
14662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __msan {
14672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
146878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid InitializeInterceptors() {
146978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  static int inited = 0;
147078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  CHECK_EQ(inited, 0);
14712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  InitializeCommonInterceptors();
1472c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany
14738028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(mmap);
147486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_MMAP64;
14758028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(posix_memalign);
147686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_MEMALIGN;
14776a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  INTERCEPT_FUNCTION(__libc_memalign);
147897160a83ae2dad479cd93a3cb1dfbc06958f69a1Evgeniy Stepanov  INTERCEPT_FUNCTION(valloc);
147986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_PVALLOC;
14808028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(malloc);
14818028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(calloc);
14828028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(realloc);
14838028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(free);
148486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_CFREE;
14852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(malloc_usable_size);
148686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_MALLINFO;
148786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_MALLOPT;
148886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
14898028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fread);
149086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
14918028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(readlink);
14928028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(memcpy);
14935492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9Evgeniy Stepanov  INTERCEPT_FUNCTION(memccpy);
1494353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  INTERCEPT_FUNCTION(mempcpy);
14958028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(memset);
14968028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(memmove);
1497ff6c9fb3ee83529dc28cd60a3797a8b783f3e892Evgeniy Stepanov  INTERCEPT_FUNCTION(bcopy);
14988028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wmemset);
14998028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wmemcpy);
1500353c99693581d49509a553bb8d0cc9c68f43aa79Evgeniy Stepanov  INTERCEPT_FUNCTION(wmempcpy);
15018028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wmemmove);
15028028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strcpy);  // NOLINT
15034bbbe136fe6a19a8288a6d92af29075756dd8fa5Evgeniy Stepanov  INTERCEPT_FUNCTION(stpcpy);  // NOLINT
15048028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strdup);
150586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___STRDUP;
15068aa1ae03e339ee9365c05dcf831f59b3a817bd84Evgeniy Stepanov  INTERCEPT_FUNCTION(strndup);
150786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___STRNDUP;
15088028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strncpy);  // NOLINT
15098028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(gcvt);
15108028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strcat);  // NOLINT
15118028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strncat);  // NOLINT
151286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtod);
151386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtof);
151486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtold);
151586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtol);
151686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtoul);
151786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtoll);
151886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(strtoull);
151986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstod);
152086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstof);
152186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstold);
152286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstol);
152386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstoul);
152486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstoll);
152586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  INTERCEPT_STRTO(wcstoull);
1526c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef SANITIZER_NLDBL_VERSION
1527c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION);
1528c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION);
1529c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
15308028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(vswprintf);
15318028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(swprintf);
1532c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
15332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strxfrm);
15342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strxfrm_l);
15358028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(strftime);
15362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(strftime_l);
153786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___STRFTIME_L;
15382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(wcsftime);
15392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  INTERCEPT_FUNCTION(wcsftime_l);
154086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___WCSFTIME_L;
1541801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INTERCEPT_FUNCTION(mbtowc);
1542801448950d645813efb398575bbc62b48e5b1dfcEvgeniy Stepanov  INTERCEPT_FUNCTION(mbrtowc);
15438028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcslen);
15448028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcschr);
15458028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcscpy);
15468028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(wcscmp);
15478028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(getenv);
1548534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  INTERCEPT_FUNCTION(setenv);
1549534e2ba5188e1a74b340f9507755806357835f62Evgeniy Stepanov  INTERCEPT_FUNCTION(putenv);
15508028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(gettimeofday);
15518028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fcvt);
155286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___FXSTAT;
155386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_INTERCEPT_FSTATAT;
155486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___FXSTAT64;
155586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT___FXSTATAT64;
15568028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(pipe);
1557134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  INTERCEPT_FUNCTION(pipe2);
1558134fe8ae5090d39aa2d37a5db5298e49467399c8Evgeniy Stepanov  INTERCEPT_FUNCTION(socketpair);
15598028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(fgets);
156086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
15618028c713085dd36688950f5c7c4342dc126ef206Alexey Samsonov  INTERCEPT_FUNCTION(getrlimit);
156286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
1563c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  MSAN_MAYBE_INTERCEPT_PRLIMIT;
1564c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  MSAN_MAYBE_INTERCEPT_PRLIMIT64;
156586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_INTERCEPT_UNAME;
156695d058800ebe11a9fda03b10455500aa4a5b3edbEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostname);
156786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
156886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
1569e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  INTERCEPT_FUNCTION(dladdr);
1570ae7db43b4e8341c0f1c3166ffcf2b7c2aa7391f7Evgeniy Stepanov  INTERCEPT_FUNCTION(dlerror);
15712bba4efbf0df4bfac8e0aac1a924ba763dd9c468Evgeniy Stepanov  INTERCEPT_FUNCTION(dl_iterate_phdr);
1572e03345ba3da0450f7ff1410de6a2a00fd304089dEvgeniy Stepanov  INTERCEPT_FUNCTION(getrusage);
1573e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(sigaction);
157406658ea68c4912fffafef6e65f36dce7faa4a174Evgeniy Stepanov  INTERCEPT_FUNCTION(signal);
1575c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if defined(__mips__)
1576c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2");
1577c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else
157810fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov  INTERCEPT_FUNCTION(pthread_create);
1579c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
1580737da2f031badfad5bc5b762cc50d789fbcb6ef8Evgeniy Stepanov  INTERCEPT_FUNCTION(pthread_key_create);
15816567092b06b37195cd93d57204bcbfe6843b2a48Evgeniy Stepanov  INTERCEPT_FUNCTION(pthread_join);
15827b6360891accaccfc3520be601272e50372f786aEvgeniy Stepanov  INTERCEPT_FUNCTION(tzset);
1583cfc29de659f3abbb9273fb0fb1c9a3cd5400c81bEvgeniy Stepanov  INTERCEPT_FUNCTION(__cxa_atexit);
1584f3603890015c130420def39d67a02c2fdafc6f84Evgeniy Stepanov  INTERCEPT_FUNCTION(shmat);
15856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  INTERCEPT_FUNCTION(fork);
1586799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INTERCEPT_FUNCTION(openpty);
1587799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar  INTERCEPT_FUNCTION(forkpty);
15887c6bd4060e60f5b148cc629c8791c2a8bf3d3347Evgeniy Stepanov
158978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov  inited = 1;
159078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov}
1591799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} // namespace __msan
1592