sanitizer_common_interceptors.inc revision 4ce6f79a13d9e22003324dca842d03108b333a58
14f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
28530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
38530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//                     The LLVM Compiler Infrastructure
48530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
58530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// This file is distributed under the University of Illinois Open Source
68530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// License. See LICENSE.TXT for details.
78530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
88530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//===----------------------------------------------------------------------===//
98530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
108530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// Common function interceptors for tools like AddressSanitizer,
118530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// ThreadSanitizer, MemorySanitizer, etc.
128530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//
138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// This file should be included into the tool's interceptor file,
148530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// which has to define it's own macros:
158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_ENTER
168530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_READ_RANGE
178530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//   COMMON_INTERCEPTOR_WRITE_RANGE
18c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_ACQUIRE
19c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany//   COMMON_INTERCEPTOR_FD_RELEASE
20c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany//   COMMON_INTERCEPTOR_SET_THREAD_NAME
218530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany//===----------------------------------------------------------------------===//
226afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany#include "interception/interception.h"
2374737d595c4e3638b980bd88b0492247ae4318faAlexey Samsonov#include "sanitizer_platform_interceptors.h"
24b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany
25996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#include <stdarg.h>
26996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2730e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#if SANITIZER_WINDOWS
28348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#define va_copy(dst, src) ((dst) = (src))
29348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#endif // _WIN32
30348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov
31be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#if SANITIZER_INTERCEPT_STRCASECMP
32be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovstatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
33be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c1_low = ToLower(c1);
34be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  int c2_low = ToLower(c2);
35be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return c1_low - c2_low;
36be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
37be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
38be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
39be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
40be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
41be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
42be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
43be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  for (i = 0; ; i++) {
44be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
45be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
46be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
47be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov      break;
48be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
49be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
50be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
51be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
52be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
53be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
54be52366ff2500f11133fd6089f349e93bd5f4822Dmitry VyukovINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
55be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  void *ctx;
56be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
57be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  unsigned char c1 = 0, c2 = 0;
58be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  uptr i;
59be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  for (i = 0; i < n; i++) {
60be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c1 = (unsigned char)s1[i];
61be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    c2 = (unsigned char)s2[i];
62be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
63be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov      break;
64be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  }
65be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
66be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
67be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov  return CharCaseCmp(c1, c2);
68be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov}
69be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
70be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
71be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
72be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#else
73be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRCASECMP
74be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#define INIT_STRNCASECMP
75be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov#endif
76be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov
777cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#if SANITIZER_INTERCEPT_FREXP
787cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(double, frexp, double x, int *exp) {
797cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
807cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
817cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  double res = REAL(frexp)(x, exp);
827cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
837cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
847cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
857cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
86ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
87ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#else
88ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXP
89ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#endif // SANITIZER_INTERCEPT_FREXP
90ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov
91ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#if SANITIZER_INTERCEPT_FREXPF_FREXPL
927cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(float, frexpf, float x, int *exp) {
937cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
947cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
957cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  float res = REAL(frexpf)(x, exp);
967cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
977cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
987cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
997cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
1007cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovINTERCEPTOR(long double, frexpl, long double x, int *exp) {
1017cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  void *ctx;
1027cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
1037cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  long double res = REAL(frexpl)(x, exp);
1047cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
1057cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  return res;
1067cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov}
1077cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
108ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXPF_FREXPL                       \
1097cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  INTERCEPT_FUNCTION(frexpf);                    \
1107cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov  INTERCEPT_FUNCTION(frexpl)
1117cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov#else
112ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#define INIT_FREXPF_FREXPL
113ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
1147cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov
1158ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#if SANITIZER_INTERCEPT_READ
1166afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
11744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
118996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
1196afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(read)(fd, ptr, count);
1208530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
121996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
122c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
123996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1248530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
1258530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
12644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ INTERCEPT_FUNCTION(read)
127c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
12844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ
1298ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#endif
1308530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
131c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#if SANITIZER_INTERCEPT_PREAD
1326afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
13344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
134996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
1356afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
1368530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
137996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
138c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
139996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1408530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
1418530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
14244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD INTERCEPT_FUNCTION(pread)
143c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
14444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD
145c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#endif
1468530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
147b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany#if SANITIZER_INTERCEPT_PREAD64
1486afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
14944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
150996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
1516afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
1528530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
153996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
154c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
155996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1568530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
1578530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
15844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
159c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
16044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64
1611f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko#endif
1628530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
163c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_WRITE
164c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya SerebryanyINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
16544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
166996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
167c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
168996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
169c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  SSIZE_T res = REAL(write)(fd, ptr, count);
170c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
171996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
172c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
173c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
17444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE INTERCEPT_FUNCTION(write)
175153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
17644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE
177153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
178153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
179c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE
180f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
18144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
182f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
183c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
184996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
185f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
186c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
187996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
188c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
189c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
19044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
191153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
19244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE
193153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
194153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
195c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE64
196f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
197f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov            OFF64_T offset) {
19844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
199f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
200c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
201996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
202f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
203c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
204996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
205c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
206c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
20744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
208153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
20944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64
210153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
211153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
212c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PRCTL
21369b109a665247d424874253b412fe9b5253d1702Evgeniy StepanovINTERCEPTOR(int, prctl, int option,
21469b109a665247d424874253b412fe9b5253d1702Evgeniy Stepanov            unsigned long arg2, unsigned long arg3,   // NOLINT
21544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov            unsigned long arg4, unsigned long arg5) { // NOLINT
21644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
217996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
218c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  static const int PR_SET_NAME = 15;
219c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
220c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (option == PR_SET_NAME) {
221c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    char buff[16];
22244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov    internal_strncpy(buff, (char *)arg2, 15);
223c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    buff[15] = 0;
224996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
225c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  }
226c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
227c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
22844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
229c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
23044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL
23144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#endif // SANITIZER_INTERCEPT_PRCTL
232996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
233fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
234fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#if SANITIZER_INTERCEPT_TIME
235fef660506e9e5703fedfee01d614abd4b741c738Evgeniy StepanovINTERCEPTOR(unsigned long, time, unsigned long *t) {
236fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  void *ctx;
237fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
238fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  unsigned long res = REAL(time)(t);
23915832c2afc4f04fa558160441d1b01fb3f0ec08bAlexander Potapenko  if (t && res != (unsigned long)-1) {
240fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
241fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  }
242fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  return res;
243fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov}
244fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#define INIT_TIME                                \
245fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov  INTERCEPT_FUNCTION(time);
246fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#else
247fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#define INIT_TIME
248fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov#endif // SANITIZER_INTERCEPT_TIME
249fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
250fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov
2519358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
2529358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, localtime, unsigned long *timep) {
2539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
2559358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(localtime)(timep);
2569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2579358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
2589358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
2599358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2609358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2619358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2629358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
2639358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2649358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
2659358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(localtime_r)(timep, result);
2669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
2689358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
2699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2729358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, gmtime, unsigned long *timep) {
2739358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2749358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
2759358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(gmtime)(timep);
2769358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2779358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
2789358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
2799358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2809358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2819358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
2839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2849358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
2859358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(gmtime_r)(timep, result);
2869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2879358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
2889358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
2899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2919358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime, unsigned long *timep) {
2939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2949358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
2959358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime)(timep);
2969358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2979358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
2989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3019358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
3039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3049358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
3059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime_r)(timep, result);
3069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3079358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
3089358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3099358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3119358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, asctime, void *tm) {
3139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3149358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
3159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime)(tm);
3169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3179358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
3189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, asctime_r, void *tm, char *result) {
3239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
3249358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
3259358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime_r)(tm, result);
3269358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
3279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
3289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
3309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
3319358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
3329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS               \
3339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(localtime);                 \
3349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(localtime_r);               \
3359358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(gmtime);                    \
3369358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(gmtime_r);                  \
3379358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(ctime);                     \
3389358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(ctime_r);                   \
3399358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(asctime);                   \
3409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(asctime_r);
3419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#else
3429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS
3439358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
3449358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
345996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANF
346996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
3474f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common_interceptors_scanf.inc"
348996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
349c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
3504ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
3514ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
3524ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
3534ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list aq;                                                                \
3544ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_copy(aq, ap);                                                           \
3554ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = REAL(vname)(__VA_ARGS__);                                        \
3564ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    if (res > 0)                                                               \
357c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
3584ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(aq);                                                                \
3594ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
3604ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
361996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
3624ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vscanf, const char *format, va_list ap)
363c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
364996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
3654ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
366c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
367996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
3684ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
369c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
370996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
3719eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
3724ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
373c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
374996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
3754ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
3764ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov            va_list ap)
377c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
3784ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3794ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
380c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
3819eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
3824ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3834ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
3844ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
3854ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
3864ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
3874ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list ap;                                                                \
3884ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_start(ap, format);                                                      \
3894ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = vname(__VA_ARGS__, ap);                                          \
3904ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(ap);                                                                \
3914ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
3924ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
3934ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3944ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, scanf, const char *format, ...)
3954ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
3964ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3974ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
3984ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
3994ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
4004ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
4014ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
4024ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
4039eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
4044ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
4054ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
4064ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
4074ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
4084ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
4094ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
4104ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
4114ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
4129eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif
413996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
41444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_SCANF                                                             \
41544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(scanf);                                                   \
4164ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(sscanf);                                                  \
41744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(fscanf);                                                  \
41844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(vscanf);                                                  \
41944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(vsscanf);                                                 \
4204ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(vfscanf);                                                 \
4214ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
4224ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
4234ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
4244ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
4254ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
4264ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vfscanf);
427996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
428996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#else
429996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define INIT_SCANF
430996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#endif
431996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
432745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
4334e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#if SANITIZER_INTERCEPT_IOCTL
434745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov#include "sanitizer_common_interceptors_ioctl.inc"
4354e95e949c335dd92b193ff270754e31d144e53bfEvgeniy StepanovINTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
4364e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  void *ctx;
4374e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
4384e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
4394e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  CHECK(ioctl_initialized);
4404e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
4414e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // Note: TSan does not use common flags, and they are zero-initialized.
4424e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // This effectively disables ioctl handling in TSan.
4434e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (!common_flags()->handle_ioctl)
4444e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    return REAL(ioctl)(d, request, arg);
4454e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
4464e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  const ioctl_desc *desc = ioctl_lookup(request);
4474e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (!desc)
4484e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    Printf("WARNING: unknown ioctl %x\n", request);
4494e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov
4504e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (desc)
4514e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    ioctl_common_pre(ctx, desc, d, request, arg);
4524e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  int res = REAL(ioctl)(d, request, arg);
4534e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  // FIXME: some ioctls have different return values for success and failure.
4544e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  if (desc && res != -1)
4554e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov    ioctl_common_post(ctx, desc, res, d, request, arg);
4564e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov  return res;
4574e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov}
4584ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov#define INIT_IOCTL \
4594ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov  ioctl_init();    \
4604ce6f79a13d9e22003324dca842d03108b333a58Evgeniy Stepanov  INTERCEPT_FUNCTION(ioctl);
4614e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#else
4624e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#define INIT_IOCTL
4634e95e949c335dd92b193ff270754e31d144e53bfEvgeniy Stepanov#endif
464745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
465745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov
466103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
467e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(void *, getpwnam, const char *name) {
468e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
469e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
470e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
471e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *res = REAL(getpwnam)(name);
472e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (res != 0)
473e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
474e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
475e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
476e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(void *, getpwuid, u32 uid) {
477e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
478e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
479e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *res = REAL(getpwuid)(uid);
480e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (res != 0)
481e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
482e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
483e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
484103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(void *, getgrnam, const char *name) {
485103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
486103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
487103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
488103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *res = REAL(getgrnam)(name);
489103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (res != 0)
490103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
491103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
492103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
493103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(void *, getgrgid, u32 gid) {
494103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
495103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
496103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *res = REAL(getgrgid)(gid);
497103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (res != 0)
498103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
499103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
500103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
501103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS                  \
502103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwnam);                    \
503103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwuid);                    \
504103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrnam);                    \
505103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrgid);
506e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
507103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_AND_FRIENDS
508e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
509e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
510e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
511103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
512e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
513e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
514e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
515e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
516e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
517e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
518e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
519e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
520e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
521e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
522e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
523e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
524e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
525e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
526e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
527e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
528e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
529e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
530e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
531e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
532e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
533e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
534e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
535103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
536103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
537103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
538103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
539103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
540103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
541103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
542103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
543103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
544103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
545103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
546103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
547103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy StepanovINTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
548103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    char *buf, SIZE_T buflen, void **result) {
549103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  void *ctx;
550103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
551103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
552103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  if (!res) {
553103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
554103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
555103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  }
556103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  return res;
557103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov}
558103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS                \
559103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwnam_r);                  \
560103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getpwuid_r);                  \
561103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrnam_r);                  \
562103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov  INTERCEPT_FUNCTION(getgrgid_r);
563e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
564103a63ed3fb5511516b55ce1ee4f33290209f3d8Evgeniy Stepanov#define INIT_GETPWNAM_R_AND_FRIENDS
565e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
566e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
567e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
568e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_CLOCK_GETTIME
569e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
570e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
571e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
572e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_getres)(clk_id, tp);
5737cdae1683c9c2fcd4473a5862c90c64be3a8c5fdEvgeniy Stepanov  if (!res && tp) {
574e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
575e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
576e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
577e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
578e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
579e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
580e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
581e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(clock_gettime)(clk_id, tp);
582e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
583e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
584e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
585e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
586e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
587e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
588e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
589e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
590e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
591e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return REAL(clock_settime)(clk_id, tp);
592e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
593e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_CLOCK_GETTIME                         \
594e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(clock_getres);                \
595e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(clock_gettime);               \
596e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(clock_settime);
597e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
598e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_CLOCK_GETTIME
599e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
600e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
601e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
602e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETITIMER
603e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, getitimer, int which, void *curr_value) {
604e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
605e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
606e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(getitimer)(which, curr_value);
607e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res) {
608e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
609e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
610e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
611e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
612e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy StepanovINTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
613e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  void *ctx;
614e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
615e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
616e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  int res = REAL(setitimer)(which, new_value, old_value);
617e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  if (!res && old_value) {
618e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
619e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  }
620e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  return res;
621e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov}
622e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_GETITIMER                             \
623e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(getitimer);                   \
624e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov  INTERCEPT_FUNCTION(setitimer);
625e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#else
626e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#define INIT_GETITIMER
627e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov#endif
628e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
629e4bdda51b3469aa0f6ef6f6c4656419effa48038Evgeniy Stepanov
630a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#if SANITIZER_INTERCEPT_GLOB
631a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanovstruct sanitizer_glob_t {
632a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  SIZE_T gl_pathc;
633a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  char **gl_pathv;
634a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov};
635a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
636a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanovstatic void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) {
637a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
638a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  // +1 for NULL pointer at the end.
639a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
640a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov      ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
641a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
642a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    char *p = pglob->gl_pathv[i];
643a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
644a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  }
645a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
646a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
647a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob, const char *pattern, int flags,
648a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
649a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            sanitizer_glob_t *pglob) {
650a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
651a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
652a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob)(pattern, flags, errfunc, pglob);
653a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  if (res == 0)
654a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    unpoison_glob_t(ctx, pglob);
655a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
656a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
657a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
658a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy StepanovINTERCEPTOR(int, glob64, const char *pattern, int flags,
659a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            int (*errfunc)(const char *epath, int eerrno),
660a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov            sanitizer_glob_t *pglob) {
661a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  void *ctx;
662a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
663a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
664a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  if (res == 0)
665a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov    unpoison_glob_t(ctx, pglob);
666a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  return res;
667a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov}
668a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#define INIT_GLOB                               \
669a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  INTERCEPT_FUNCTION(glob);                     \
670a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov  INTERCEPT_FUNCTION(glob64);
671a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#else // SANITIZER_INTERCEPT_GLOB
672a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#define INIT_GLOB
673a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov#endif // SANITIZER_INTERCEPT_GLOB
674a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
675a1c2a5547d815a4ce116f04ebd3cef1716ab791cEvgeniy Stepanov
676897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#if SANITIZER_INTERCEPT_WAIT
6776a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
6786a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
6796a659dfd8e717a598f54867aa36c2e4af09d031bAlexander Potapenko// details.
6806a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
681897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
682897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
683897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait)(status);
684f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
685897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
686897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
687897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
68830e970f769ccf11e61e472c6f8b22f8e866c592fKostya SerebryanyINTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
68930e970f769ccf11e61e472c6f8b22f8e866c592fKostya Serebryany  int options) {
690897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
691897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
692897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitid)(idtype, id, infop, options);
693f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && infop)
694897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
695897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
696897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
6976a659dfd8e717a598f54867aa36c2e4af09d031bAlexander PotapenkoINTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
698897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
699897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
700897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(waitpid)(pid, status, options);
701f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov  if (res != -1 && status)
702897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
703897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
704897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
705897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
706897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
707897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
708897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait3)(status, options, rusage);
709897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
710f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov    if (status)
711f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
712897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    if (rusage)
713897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
714897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
715897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
716897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
717897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy StepanovINTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
718897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  void *ctx;
719897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
720897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  int res = REAL(wait4)(pid, status, options, rusage);
721897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  if (res != -1) {
722f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov    if (status)
723f82eb24b61f8c0f23396ed5ba68f5ace7656e986Dmitry Vyukov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
724897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov    if (rusage)
725897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
726897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  }
727897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  return res;
728897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov}
729897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#define INIT_WAIT                                \
730897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(wait);                      \
731897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(waitid);                    \
732897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(waitpid);                   \
733897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(wait3);                     \
734897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov  INTERCEPT_FUNCTION(wait4);
735897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#else
736897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#define INIT_WAIT
737897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov#endif
738897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
7399530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#if SANITIZER_INTERCEPT_INET
7409530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
7419530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
7429530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
7439530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  uptr sz = __sanitizer_in_addr_sz(af);
7449530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
7459530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
7469530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  char *res = REAL(inet_ntop)(af, src, dst, size);
7479530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (res)
7489530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
7499530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
7509530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
7519530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy StepanovINTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
7529530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  void *ctx;
7539530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
7549530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  // FIXME: figure out read size based on the address family.
7559530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  int res = REAL(inet_pton)(af, src, dst);
7569530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  if (res == 1) {
7579530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    uptr sz = __sanitizer_in_addr_sz(af);
7589530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
7599530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  }
7609530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  return res;
7619530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov}
7629530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#define INIT_INET                                \
7639530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  INTERCEPT_FUNCTION(inet_ntop);                 \
7649530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov  INTERCEPT_FUNCTION(inet_pton);
7659530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#else
7669530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#define INIT_INET
7679530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov#endif
7689530eb721dfacdf2c3f46d408e22d3f7cf8be667Evgeniy Stepanov
76956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
77056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy StepanovINTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
77156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  void *ctx;
77256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
77356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  int res = REAL(pthread_getschedparam)(thread, policy, param);
77456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  if (res == 0) {
77556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
77656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
77756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  }
77856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  return res;
77956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov}
78056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
78156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#else
78256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define INIT_PTHREAD_GETSCHEDPARAM
78356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#endif
784897a4ae31f5c55255c78854b69b4cd4a4e3c7c39Evgeniy Stepanov
785447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETADDRINFO
786447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy StepanovINTERCEPTOR(int, getaddrinfo, char *node, char *service,
787447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo *hints,
788447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov            struct __sanitizer_addrinfo **out) {
789447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  void *ctx;
790447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
791447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
792447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (service)
793447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
794447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  if (hints)
795447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
796447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  int res = REAL(getaddrinfo)(node, service, hints, out);
7973538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov  if (res == 0 && out) {
7983538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
799447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    struct __sanitizer_addrinfo *p = *out;
800447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    while (p) {
8013538eb8a245ea4d17824d8a53feb8cecd3358762Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
802447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_addr)
803512c616cacf70ca029a2bf719a482b902f3687cdEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
804447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      if (p->ai_canonname)
805447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
806447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov                                       REAL(strlen)(p->ai_canonname) + 1);
807447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov      p = p->ai_next;
808447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov    }
809447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  }
810447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  return res;
811447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov}
812447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
813447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#else
814447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#define INIT_GETADDRINFO
815447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov#endif
816447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
8179f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKNAME
8189f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy StepanovINTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
8199f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  void *ctx;
8209f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
8219f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
8229f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int addrlen_in = *addrlen;
8239f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  int res = REAL(getsockname)(sock_fd, addr, addrlen);
8249f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  if (res == 0) {
8259f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
8269f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  }
8279f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  return res;
8289f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov}
8299f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
8309f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#else
8319f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#define INIT_GETSOCKNAME
8329f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov#endif
833447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov
83433b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
8350a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanovstatic void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
8360a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
8370a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (h->h_name)
8380a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
8390a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  char **p = h->h_aliases;
8400a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
8410a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
8420a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
8430a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
8440a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
8450a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
8460a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  p = h->h_addr_list;
8470a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  while (*p) {
8480a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
8490a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    ++p;
8500a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
8510a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(
8520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
8530a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
85433b1485c3f1ea5a8089473ab1bb962d7bfb41d72Evgeniy Stepanov#endif
8550a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
8560a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME
8570a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
8580a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
8590a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
8600a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
8610a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
8620a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
8630a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
8640a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
8650a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
8660a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            int type) {
8670a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
8680a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
8690a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
8700a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
8710a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
8720a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
8730a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
8740a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
8750a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostent) {
8760a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
8770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent);
8780a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostent)();
8790a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
8800a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
8810a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
8820a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
8830a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
8840a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
8850a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
8860a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
8870a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res) write_hostent(ctx, res);
8880a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
8890a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
8900a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME           \
8910a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostent);    \
8920a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyaddr); \
8930a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname); \
8940a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname2);
8950a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
8960a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME
8970a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
8980a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
8990a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
9000a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
9010a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
9020a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
9030a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
9040a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           h_errnop);
9050a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
9060a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
9070a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
9080a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
9090a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
9100a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
9110a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
9120a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
9130a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
9140a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
9150a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
9160a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
9170a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
9180a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
9190a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
9200a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
9210a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
9220a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           buflen, result, h_errnop);
9230a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
9240a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
9250a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                                  h_errnop);
9260a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
9270a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
9280a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
9290a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
9300a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
9310a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
9320a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
9330a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
9340a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
9350a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
9360a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
9370a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
9380a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
9390a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            int *h_errnop) {
9400a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
9410a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
9420a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           h_errnop);
9430a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
9440a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
9450a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
9460a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
9470a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
9480a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
9490a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
9500a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
9510a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
9520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
9530a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
9540a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
9550a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy StepanovINTERCEPTOR(int, gethostbyname2_r, char *name, int af,
9560a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
9570a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov            __sanitizer_hostent **result, int *h_errnop) {
9580a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  void *ctx;
9590a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
9600a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov                           result, h_errnop);
9610a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  int res =
9620a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
9630a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  if (res == 0) {
9640a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (result) {
9650a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
9660a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      if (*result) write_hostent(ctx, *result);
9670a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    }
9680a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov    if (h_errnop)
9690a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
9700a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  }
9710a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  return res;
9720a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov}
9730a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME_R           \
9740a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostent_r);    \
9750a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyaddr_r); \
9760a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname_r); \
9770a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INTERCEPT_FUNCTION(gethostbyname2_r);
9780a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#else
9790a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#define INIT_GETHOSTBYNAME_R
9800a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov#endif
9810a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov
982f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETSOCKOPT
983f32be42523a199674ea665a499db131591e64e08Evgeniy StepanovINTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
984f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov            int *optlen) {
985f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  void *ctx;
986f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
987f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov                           optlen);
988f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
989f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
990f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  if (res == 0)
991f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
992f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  return res;
993f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov}
994f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
995f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#else
996f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#define INIT_GETSOCKOPT
997f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov#endif
998f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov
9999d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT
10009d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
10019d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
10029d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
10039d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  unsigned addrlen0;
10049d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
10059d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
10069d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
10079d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
10089d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept)(fd, addr, addrlen);
10099d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
10109d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (fd >= 0)
10119d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
10129d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
10139d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
10149d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
10159d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
10169d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
10179d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
10189d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
10199d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT
10209d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
10219d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
10229d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#if SANITIZER_INTERCEPT_ACCEPT4
10239d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy StepanovINTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
10249d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  void *ctx;
10259d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
10269d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  unsigned addrlen0;
10279d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (addrlen) {
10289d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
10299d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    addrlen0 = *addrlen;
10309d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
10319d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
10329d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  if (fd2 >= 0) {
10339d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (fd >= 0)
10349d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
10359d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov    if (addr && addrlen)
10369d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
10379d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  }
10389d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  return fd2;
10399d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov}
10409d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
10419d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#else
10429d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define INIT_ACCEPT4
10439d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#endif
10449d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov
1045c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#if SANITIZER_INTERCEPT_MODF
1046c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(double, modf, double x, double *iptr) {
1047c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
1048c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1049c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  double res = REAL(modf)(x, iptr);
1050c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
1051c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1052c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
1053c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
1054c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
1055c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(float, modff, float x, float *iptr) {
1056c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
1057c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1058c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  float res = REAL(modff)(x, iptr);
1059c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
1060c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1061c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
1062c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
1063c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
1064c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy StepanovINTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1065c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  void *ctx;
1066c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1067c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  long double res = REAL(modfl)(x, iptr);
1068c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  if (iptr) {
1069c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1070c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  }
1071c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  return res;
1072c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov}
1073c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#define INIT_MODF            \
1074c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INTERCEPT_FUNCTION(modf);  \
1075c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INTERCEPT_FUNCTION(modff); \
1076c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INTERCEPT_FUNCTION(modfl);
1077c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#else
1078c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#define INIT_MODF
1079c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov#endif
1080c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov
10819666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#if SANITIZER_INTERCEPT_RECVMSG
10829666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanovstatic void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg) {
10839666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
10849666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (msg->msg_name)
10859666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name,
10869666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov                                   REAL(strlen)((char *)msg->msg_name) + 1);
10879666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (msg->msg_iov)
10889666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, msg->msg_iovlen);
10899666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  for (SIZE_T i = 0; i < msg->msg_iovlen; ++i)
10909666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov[i].iov_base,
10919666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov                                   msg->msg_iov[i].iov_len);
10929666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (msg->msg_control)
10939666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
10949666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
10959666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
10969666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy StepanovINTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
10979666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov            int flags) {
10989666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  void *ctx;
10999666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
11009666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
11019666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  if (res >= 0) {
11029666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
11039666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov    if (msg) write_msghdr(ctx, msg);
11049666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  }
11059666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  return res;
11069666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov}
11079666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
11089666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#else
11099666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#define INIT_RECVMSG
11109666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov#endif
11119666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov
1112bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#if SANITIZER_INTERCEPT_GETPEERNAME
1113bc33e138d82759074f8333239f96506027731e20Evgeniy StepanovINTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1114bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  void *ctx;
1115bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1116bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  unsigned addr_sz;
1117bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (addrlen) addr_sz = *addrlen;
1118bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  int res = REAL(getpeername)(sockfd, addr, addrlen);
1119bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  if (!res && addr && addrlen)
1120bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1121bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  return res;
1122bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov}
1123bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1124bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#else
1125bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#define INIT_GETPEERNAME
1126bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov#endif
1127bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov
112856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov#define SANITIZER_COMMON_INTERCEPTORS_INIT \
112956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_STRCASECMP;                         \
113056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_STRNCASECMP;                        \
113156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_READ;                               \
113256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PREAD;                              \
113356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PREAD64;                            \
113456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PRCTL;                              \
113556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_WRITE;                              \
113656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PWRITE;                             \
113756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_PWRITE64;                           \
113856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_LOCALTIME_AND_FRIENDS;              \
113956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_SCANF;                              \
114056d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_FREXP;                              \
114156d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_FREXPF_FREXPL;                      \
114256d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GETPWNAM_AND_FRIENDS;               \
114356d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GETPWNAM_R_AND_FRIENDS;             \
114456d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_CLOCK_GETTIME;                      \
114556d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GETITIMER;                          \
114656d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_TIME;                               \
114756d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_GLOB;                               \
114856d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_WAIT;                               \
114956d3472104dd9fec6578e02f4895f3254e038e8eEvgeniy Stepanov  INIT_INET;                               \
1150447ef19d1b8cebbeaba49e4be22ac721448dcf3eEvgeniy Stepanov  INIT_PTHREAD_GETSCHEDPARAM;              \
11519f58c5c60a56d9c39d36b5313dc87ad4bb713163Evgeniy Stepanov  INIT_GETADDRINFO;                        \
11520a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INIT_GETSOCKNAME;                        \
11530a2cc37712a452525f9f03b3bf67b1f0a97c8d3aEvgeniy Stepanov  INIT_GETHOSTBYNAME;                      \
1154f32be42523a199674ea665a499db131591e64e08Evgeniy Stepanov  INIT_GETHOSTBYNAME_R;                    \
11559d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  INIT_GETSOCKOPT;                         \
11569d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov  INIT_ACCEPT;                             \
1157c87088b54f7438d589119d314853a5f3b00d02b5Evgeniy Stepanov  INIT_ACCEPT4;                            \
11589666d89b628867b2c790d5415f0371fdb4050b0cEvgeniy Stepanov  INIT_MODF;                               \
1159bc33e138d82759074f8333239f96506027731e20Evgeniy Stepanov  INIT_RECVMSG;                            \
1160745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov  INIT_GETPEERNAME;                        \
1161745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov  INIT_IOCTL;
1162