sanitizer_common_interceptors.inc revision 9eab858dfd995cb0432efa18edbcd0e791114be9
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
27348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#ifdef _WIN32
28348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#define va_copy(dst, src) ((dst) = (src))
29348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov#endif // _WIN32
30348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov
318ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#if SANITIZER_INTERCEPT_READ
326afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
3344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
34996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
356afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(read)(fd, ptr, count);
368530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
37996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
38c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
39996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
408530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
418530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
4244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ INTERCEPT_FUNCTION(read)
43c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
4444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_READ
458ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov#endif
468530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
47c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#if SANITIZER_INTERCEPT_PREAD
486afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
4944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
50996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
516afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
528530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
53996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
54c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
55996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
568530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
578530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
5844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD INTERCEPT_FUNCTION(pread)
59c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
6044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD
61c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov#endif
628530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
63b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany#if SANITIZER_INTERCEPT_PREAD64
646afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya SerebryanyINTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
6544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
66996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
676afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
688530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  if (res > 0)
69996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
70c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany  if (res >= 0 && fd >= 0)
71996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
728530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany  return res;
738530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany}
7444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
75c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
7644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PREAD64
771f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko#endif
788530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany
79c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_WRITE
80c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya SerebryanyINTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
8144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
82996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
83c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
84996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
85c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  SSIZE_T res = REAL(write)(fd, ptr, count);
86c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
87996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
88c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
89c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
9044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE INTERCEPT_FUNCTION(write)
91153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
9244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_WRITE
93153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
94153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
95c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE
96f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
9744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
98f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
99c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
100996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
101f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
102c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
103996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
104c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
105c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
10644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
107153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
10844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE
109153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
110153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
111c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PWRITE64
112f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry VyukovINTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
113f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov            OFF64_T offset) {
11444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
115f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
116c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (fd >= 0)
117996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
118f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
119c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (res > 0)
120996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
121c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
122c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
12344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
124153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#else
12544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PWRITE64
126153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany#endif
127153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany
128c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#if SANITIZER_INTERCEPT_PRCTL
12969b109a665247d424874253b412fe9b5253d1702Evgeniy StepanovINTERCEPTOR(int, prctl, int option,
13069b109a665247d424874253b412fe9b5253d1702Evgeniy Stepanov            unsigned long arg2, unsigned long arg3,   // NOLINT
13144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov            unsigned long arg4, unsigned long arg5) { // NOLINT
13244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  void *ctx;
133996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
134c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  static const int PR_SET_NAME = 15;
135c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
136c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  if (option == PR_SET_NAME) {
137c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    char buff[16];
13844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov    internal_strncpy(buff, (char *)arg2, 15);
139c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany    buff[15] = 0;
140996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
141c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  }
142c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany  return res;
143c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany}
14444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
145c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany#else
14644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_PRCTL
14744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#endif // SANITIZER_INTERCEPT_PRCTL
148996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
1499358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1509358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, localtime, unsigned long *timep) {
1519358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
1529358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
1539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(localtime)(timep);
1549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1559358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
1579358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
1589358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
1599358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
1609358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
1619358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
1629358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
1639358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(localtime_r)(timep, result);
1649358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1659358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
1679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
1689358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
1699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
1709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, gmtime, unsigned long *timep) {
1719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
1729358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
1739358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(gmtime)(timep);
1749358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1759358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1769358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
1779358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
1789358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
1799358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
1809358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
1819358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
1829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
1839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *res = REAL(gmtime_r)(timep, result);
1849358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1859358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
1879358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
1889358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
1899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
1909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime, unsigned long *timep) {
1919358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
1929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
1939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime)(timep);
1949358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
1959358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1969358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1979358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
1989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
1999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
2019358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
2039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(ctime_r)(timep, result);
2049358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
2069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2079358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2089358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2099358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, asctime, void *tm) {
2119358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
2139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime)(tm);
2149358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
2169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2179358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy StepanovINTERCEPTOR(char *, asctime_r, void *tm, char *result) {
2219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  void *ctx;
2229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
2239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  char *res = REAL(asctime_r)(tm, result);
2249358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  if (res) {
2259358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
2269358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  }
2289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  return res;
2299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov}
2309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS               \
2319358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(localtime);                 \
2329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(localtime_r);               \
2339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(gmtime);                    \
2349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(gmtime_r);                  \
2359358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(ctime);                     \
2369358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(ctime_r);                   \
2379358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(asctime);                   \
2389358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INTERCEPT_FUNCTION(asctime_r);
2399358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#else
2409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#define INIT_LOCALTIME_AND_FRIENDS
2419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
2429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov
243996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#if SANITIZER_INTERCEPT_SCANF
244996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2454f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common_interceptors_scanf.inc"
246996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
247c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
2484ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
2494ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
2504ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
2514ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list aq;                                                                \
2524ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_copy(aq, ap);                                                           \
2534ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = REAL(vname)(__VA_ARGS__);                                        \
2544ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    if (res > 0)                                                               \
255c5b4e86e848758856433da2e876c473dd31db55cEvgeniy Stepanov      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
2564ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(aq);                                                                \
2574ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
2584ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
259996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2604ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vscanf, const char *format, va_list ap)
261c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
262996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2634ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
264c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
265996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2664ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
267c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
268996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2699eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
2704ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
271c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
272996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
2734ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
2744ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov            va_list ap)
275c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
2764ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
2774ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
278c5b4e86e848758856433da2e876c473dd31db55cEvgeniy StepanovVSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
2799eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
2804ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
2814ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
2824ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  {                                                                            \
2834ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    void *ctx;                                                                 \
2844ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
2854ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_list ap;                                                                \
2864ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_start(ap, format);                                                      \
2874ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    int res = vname(__VA_ARGS__, ap);                                          \
2884ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    va_end(ap);                                                                \
2894ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov    return res;                                                                \
2904ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  }
2914ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
2924ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, scanf, const char *format, ...)
2934ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
2944ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
2954ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
2964ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
2974ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
2984ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
2994ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
3004ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3019eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#if SANITIZER_INTERCEPT_ISOC99_SCANF
3024ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
3034ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
3044ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3054ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
3064ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
3074ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov
3084ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovINTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
3094ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy StepanovSCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
3109eab858dfd995cb0432efa18edbcd0e791114be9Alexander Potapenko#endif
311996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
31244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define INIT_SCANF                                                             \
31344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(scanf);                                                   \
3144ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(sscanf);                                                  \
31544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(fscanf);                                                  \
31644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(vscanf);                                                  \
31744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INTERCEPT_FUNCTION(vsscanf);                                                 \
3184ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(vfscanf);                                                 \
3194ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
3204ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
3214ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
3224ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
3234ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
3244ae1adb49f34cf9a9ef854cf04348531608f0eadEvgeniy Stepanov  INTERCEPT_FUNCTION(__isoc99_vfscanf);
325996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
326996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#else
327996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define INIT_SCANF
328996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#endif
329996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov
33044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov#define SANITIZER_COMMON_INTERCEPTORS_INIT                                     \
33144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_READ;                                                                   \
33244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_PREAD;                                                                  \
33344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_PREAD64;                                                                \
33444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_PRCTL;                                                                  \
33544be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_WRITE;                                                                  \
33644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_PWRITE;                                                                 \
33744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov  INIT_PWRITE64;                                                               \
3389358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov  INIT_LOCALTIME_AND_FRIENDS;                                                  \
3394f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov  INIT_SCANF;
340