Evgeniy Stepanov | 4f32c0b | 2013-01-18 13:01:18 +0000 | [diff] [blame] | 1 | //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // Common function interceptors for tools like AddressSanitizer, |
| 11 | // ThreadSanitizer, MemorySanitizer, etc. |
| 12 | // |
| 13 | // This file should be included into the tool's interceptor file, |
| 14 | // which has to define it's own macros: |
| 15 | // COMMON_INTERCEPTOR_ENTER |
| 16 | // COMMON_INTERCEPTOR_READ_RANGE |
| 17 | // COMMON_INTERCEPTOR_WRITE_RANGE |
Dmitry Vyukov | 0586dcc | 2013-10-03 14:12:09 +0000 | [diff] [blame] | 18 | // COMMON_INTERCEPTOR_INITIALIZE_RANGE |
Kostya Serebryany | c803319 | 2013-01-17 13:09:00 +0000 | [diff] [blame] | 19 | // COMMON_INTERCEPTOR_FD_ACQUIRE |
| 20 | // COMMON_INTERCEPTOR_FD_RELEASE |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 21 | // COMMON_INTERCEPTOR_FD_ACCESS |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 22 | // COMMON_INTERCEPTOR_SET_THREAD_NAME |
Dmitry Vyukov | 14dd980 | 2013-10-03 15:22:29 +0000 | [diff] [blame] | 23 | // COMMON_INTERCEPTOR_ON_EXIT |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 24 | // COMMON_INTERCEPTOR_MUTEX_LOCK |
| 25 | // COMMON_INTERCEPTOR_MUTEX_UNLOCK |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 26 | //===----------------------------------------------------------------------===// |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 27 | #include "interception/interception.h" |
Alexey Samsonov | 74737d5 | 2012-12-13 08:50:16 +0000 | [diff] [blame] | 28 | #include "sanitizer_platform_interceptors.h" |
Kostya Serebryany | b1cc4e4 | 2012-12-13 05:27:08 +0000 | [diff] [blame] | 29 | |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 30 | #include <stdarg.h> |
| 31 | |
Evgeniy Stepanov | 30e110e | 2013-03-19 14:54:17 +0000 | [diff] [blame] | 32 | #if SANITIZER_WINDOWS |
Evgeniy Stepanov | 348bd12 | 2013-02-11 14:08:12 +0000 | [diff] [blame] | 33 | #define va_copy(dst, src) ((dst) = (src)) |
| 34 | #endif // _WIN32 |
| 35 | |
Dmitry Vyukov | 0586dcc | 2013-10-03 14:12:09 +0000 | [diff] [blame] | 36 | #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 37 | #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) |
Dmitry Vyukov | 0586dcc | 2013-10-03 14:12:09 +0000 | [diff] [blame] | 38 | #endif |
| 39 | |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 40 | #ifndef COMMON_INTERCEPTOR_FD_ACCESS |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 41 | #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) |
| 42 | #endif |
| 43 | |
| 44 | #ifndef COMMON_INTERCEPTOR_MUTEX_LOCK |
| 45 | #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) |
| 46 | #endif |
| 47 | |
| 48 | #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK |
| 49 | #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 50 | #endif |
| 51 | |
Alexey Samsonov | 67505a8 | 2013-07-16 12:51:53 +0000 | [diff] [blame] | 52 | #if SANITIZER_INTERCEPT_STRCMP |
| 53 | static inline int CharCmpX(unsigned char c1, unsigned char c2) { |
| 54 | return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; |
| 55 | } |
| 56 | |
| 57 | INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { |
| 58 | void *ctx; |
| 59 | COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); |
| 60 | unsigned char c1, c2; |
| 61 | uptr i; |
| 62 | for (i = 0; ; i++) { |
| 63 | c1 = (unsigned char)s1[i]; |
| 64 | c2 = (unsigned char)s2[i]; |
| 65 | if (c1 != c2 || c1 == '\0') break; |
| 66 | } |
| 67 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); |
| 68 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); |
| 69 | return CharCmpX(c1, c2); |
| 70 | } |
| 71 | |
| 72 | INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { |
| 73 | void *ctx; |
| 74 | COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); |
| 75 | unsigned char c1 = 0, c2 = 0; |
| 76 | uptr i; |
| 77 | for (i = 0; i < size; i++) { |
| 78 | c1 = (unsigned char)s1[i]; |
| 79 | c2 = (unsigned char)s2[i]; |
| 80 | if (c1 != c2 || c1 == '\0') break; |
| 81 | } |
| 82 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); |
| 83 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); |
| 84 | return CharCmpX(c1, c2); |
| 85 | } |
| 86 | |
| 87 | #define INIT_STRCMP INTERCEPT_FUNCTION(strcmp) |
| 88 | #define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp) |
| 89 | #else |
| 90 | #define INIT_STRCMP |
| 91 | #define INIT_STRNCMP |
| 92 | #endif |
| 93 | |
Dmitry Vyukov | be52366 | 2013-03-26 12:40:23 +0000 | [diff] [blame] | 94 | #if SANITIZER_INTERCEPT_STRCASECMP |
| 95 | static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { |
| 96 | int c1_low = ToLower(c1); |
| 97 | int c2_low = ToLower(c2); |
| 98 | return c1_low - c2_low; |
| 99 | } |
| 100 | |
| 101 | INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { |
| 102 | void *ctx; |
| 103 | COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); |
| 104 | unsigned char c1 = 0, c2 = 0; |
| 105 | uptr i; |
| 106 | for (i = 0; ; i++) { |
| 107 | c1 = (unsigned char)s1[i]; |
| 108 | c2 = (unsigned char)s2[i]; |
| 109 | if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') |
| 110 | break; |
| 111 | } |
| 112 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); |
| 113 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); |
| 114 | return CharCaseCmp(c1, c2); |
| 115 | } |
| 116 | |
| 117 | INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { |
| 118 | void *ctx; |
| 119 | COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); |
| 120 | unsigned char c1 = 0, c2 = 0; |
| 121 | uptr i; |
| 122 | for (i = 0; i < n; i++) { |
| 123 | c1 = (unsigned char)s1[i]; |
| 124 | c2 = (unsigned char)s2[i]; |
| 125 | if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') |
| 126 | break; |
| 127 | } |
| 128 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); |
| 129 | COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); |
| 130 | return CharCaseCmp(c1, c2); |
| 131 | } |
| 132 | |
| 133 | #define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) |
| 134 | #define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) |
| 135 | #else |
| 136 | #define INIT_STRCASECMP |
| 137 | #define INIT_STRNCASECMP |
| 138 | #endif |
| 139 | |
Evgeniy Stepanov | 7cbbb29 | 2013-03-14 11:34:39 +0000 | [diff] [blame] | 140 | #if SANITIZER_INTERCEPT_FREXP |
| 141 | INTERCEPTOR(double, frexp, double x, int *exp) { |
| 142 | void *ctx; |
| 143 | COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); |
| 144 | double res = REAL(frexp)(x, exp); |
| 145 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); |
| 146 | return res; |
| 147 | } |
| 148 | |
Alexey Samsonov | ff5d1fc | 2013-03-15 14:02:21 +0000 | [diff] [blame] | 149 | #define INIT_FREXP INTERCEPT_FUNCTION(frexp); |
| 150 | #else |
| 151 | #define INIT_FREXP |
| 152 | #endif // SANITIZER_INTERCEPT_FREXP |
| 153 | |
| 154 | #if SANITIZER_INTERCEPT_FREXPF_FREXPL |
Evgeniy Stepanov | 7cbbb29 | 2013-03-14 11:34:39 +0000 | [diff] [blame] | 155 | INTERCEPTOR(float, frexpf, float x, int *exp) { |
| 156 | void *ctx; |
| 157 | COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); |
| 158 | float res = REAL(frexpf)(x, exp); |
| 159 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); |
| 160 | return res; |
| 161 | } |
| 162 | |
| 163 | INTERCEPTOR(long double, frexpl, long double x, int *exp) { |
| 164 | void *ctx; |
| 165 | COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); |
| 166 | long double res = REAL(frexpl)(x, exp); |
| 167 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); |
| 168 | return res; |
| 169 | } |
| 170 | |
Alexey Samsonov | ff5d1fc | 2013-03-15 14:02:21 +0000 | [diff] [blame] | 171 | #define INIT_FREXPF_FREXPL \ |
Evgeniy Stepanov | 7cbbb29 | 2013-03-14 11:34:39 +0000 | [diff] [blame] | 172 | INTERCEPT_FUNCTION(frexpf); \ |
| 173 | INTERCEPT_FUNCTION(frexpl) |
| 174 | #else |
Alexey Samsonov | ff5d1fc | 2013-03-15 14:02:21 +0000 | [diff] [blame] | 175 | #define INIT_FREXPF_FREXPL |
| 176 | #endif // SANITIZER_INTERCEPT_FREXPF_FREXPL |
Evgeniy Stepanov | 7cbbb29 | 2013-03-14 11:34:39 +0000 | [diff] [blame] | 177 | |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 178 | #if SI_NOT_WINDOWS |
| 179 | static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, |
| 180 | SIZE_T iovlen, SIZE_T maxlen) { |
| 181 | for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { |
| 182 | SSIZE_T sz = Min(iovec[i].iov_len, maxlen); |
| 183 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); |
| 184 | maxlen -= sz; |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, |
| 189 | SIZE_T iovlen, SIZE_T maxlen) { |
| 190 | COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); |
| 191 | for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { |
| 192 | SSIZE_T sz = Min(iovec[i].iov_len, maxlen); |
| 193 | COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); |
| 194 | maxlen -= sz; |
| 195 | } |
| 196 | } |
| 197 | #endif |
| 198 | |
Alexey Samsonov | 8ffd877 | 2012-12-13 08:36:13 +0000 | [diff] [blame] | 199 | #if SANITIZER_INTERCEPT_READ |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 200 | INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 201 | void *ctx; |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 202 | COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 203 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 204 | SSIZE_T res = REAL(read)(fd, ptr, count); |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 205 | if (res > 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 206 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); |
Kostya Serebryany | c803319 | 2013-01-17 13:09:00 +0000 | [diff] [blame] | 207 | if (res >= 0 && fd >= 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 208 | COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 209 | return res; |
| 210 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 211 | #define INIT_READ INTERCEPT_FUNCTION(read) |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 212 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 213 | #define INIT_READ |
Alexey Samsonov | 8ffd877 | 2012-12-13 08:36:13 +0000 | [diff] [blame] | 214 | #endif |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 215 | |
Alexey Samsonov | c333dff | 2012-12-13 08:10:23 +0000 | [diff] [blame] | 216 | #if SANITIZER_INTERCEPT_PREAD |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 217 | INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 218 | void *ctx; |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 219 | COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 220 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 221 | SSIZE_T res = REAL(pread)(fd, ptr, count, offset); |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 222 | if (res > 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 223 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); |
Kostya Serebryany | c803319 | 2013-01-17 13:09:00 +0000 | [diff] [blame] | 224 | if (res >= 0 && fd >= 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 225 | COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 226 | return res; |
| 227 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 228 | #define INIT_PREAD INTERCEPT_FUNCTION(pread) |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 229 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 230 | #define INIT_PREAD |
Alexey Samsonov | c333dff | 2012-12-13 08:10:23 +0000 | [diff] [blame] | 231 | #endif |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 232 | |
Kostya Serebryany | b1cc4e4 | 2012-12-13 05:27:08 +0000 | [diff] [blame] | 233 | #if SANITIZER_INTERCEPT_PREAD64 |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 234 | INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 235 | void *ctx; |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 236 | COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 237 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Kostya Serebryany | 6afa1b0 | 2012-12-13 06:31:40 +0000 | [diff] [blame] | 238 | SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 239 | if (res > 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 240 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); |
Kostya Serebryany | c803319 | 2013-01-17 13:09:00 +0000 | [diff] [blame] | 241 | if (res >= 0 && fd >= 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 242 | COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 243 | return res; |
| 244 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 245 | #define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) |
Alexey Samsonov | c333dff | 2012-12-13 08:10:23 +0000 | [diff] [blame] | 246 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 247 | #define INIT_PREAD64 |
Alexander Potapenko | 1f5e23e | 2012-12-12 11:52:26 +0000 | [diff] [blame] | 248 | #endif |
Kostya Serebryany | 8530e2b | 2012-12-12 09:54:35 +0000 | [diff] [blame] | 249 | |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 250 | #if SANITIZER_INTERCEPT_READV |
| 251 | INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, |
| 252 | int iovcnt) { |
| 253 | void *ctx; |
| 254 | COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 255 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 256 | SSIZE_T res = REAL(readv)(fd, iov, iovcnt); |
| 257 | if (res > 0) write_iovec(ctx, iov, iovcnt, res); |
| 258 | if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
| 259 | return res; |
| 260 | } |
| 261 | #define INIT_READV INTERCEPT_FUNCTION(readv) |
| 262 | #else |
| 263 | #define INIT_READV |
| 264 | #endif |
| 265 | |
| 266 | #if SANITIZER_INTERCEPT_PREADV |
| 267 | INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, |
| 268 | OFF_T offset) { |
| 269 | void *ctx; |
| 270 | COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 271 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 272 | SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); |
| 273 | if (res > 0) write_iovec(ctx, iov, iovcnt, res); |
| 274 | if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
| 275 | return res; |
| 276 | } |
| 277 | #define INIT_PREADV INTERCEPT_FUNCTION(preadv) |
| 278 | #else |
| 279 | #define INIT_PREADV |
| 280 | #endif |
| 281 | |
| 282 | #if SANITIZER_INTERCEPT_PREADV64 |
| 283 | INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, |
| 284 | OFF64_T offset) { |
| 285 | void *ctx; |
| 286 | COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 287 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 288 | SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); |
| 289 | if (res > 0) write_iovec(ctx, iov, iovcnt, res); |
| 290 | if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
| 291 | return res; |
| 292 | } |
| 293 | #define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) |
| 294 | #else |
| 295 | #define INIT_PREADV64 |
| 296 | #endif |
| 297 | |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 298 | #if SANITIZER_INTERCEPT_WRITE |
| 299 | INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 300 | void *ctx; |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 301 | COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 302 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 303 | if (fd >= 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 304 | COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 305 | SSIZE_T res = REAL(write)(fd, ptr, count); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 306 | // FIXME: this check should be _before_ the call to REAL(write), not after |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 307 | if (res > 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 308 | COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 309 | return res; |
| 310 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 311 | #define INIT_WRITE INTERCEPT_FUNCTION(write) |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 312 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 313 | #define INIT_WRITE |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 314 | #endif |
| 315 | |
| 316 | #if SANITIZER_INTERCEPT_PWRITE |
Dmitry Vyukov | f0c846b | 2013-01-24 07:44:21 +0000 | [diff] [blame] | 317 | INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 318 | void *ctx; |
Dmitry Vyukov | f0c846b | 2013-01-24 07:44:21 +0000 | [diff] [blame] | 319 | COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 320 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 321 | if (fd >= 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 322 | COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); |
Dmitry Vyukov | f0c846b | 2013-01-24 07:44:21 +0000 | [diff] [blame] | 323 | SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 324 | if (res > 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 325 | COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 326 | return res; |
| 327 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 328 | #define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 329 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 330 | #define INIT_PWRITE |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 331 | #endif |
| 332 | |
| 333 | #if SANITIZER_INTERCEPT_PWRITE64 |
Dmitry Vyukov | f0c846b | 2013-01-24 07:44:21 +0000 | [diff] [blame] | 334 | INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, |
| 335 | OFF64_T offset) { |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 336 | void *ctx; |
Dmitry Vyukov | f0c846b | 2013-01-24 07:44:21 +0000 | [diff] [blame] | 337 | COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 338 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 339 | if (fd >= 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 340 | COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); |
Dmitry Vyukov | f0c846b | 2013-01-24 07:44:21 +0000 | [diff] [blame] | 341 | SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 342 | if (res > 0) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 343 | COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 344 | return res; |
| 345 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 346 | #define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 347 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 348 | #define INIT_PWRITE64 |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 349 | #endif |
| 350 | |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 351 | #if SANITIZER_INTERCEPT_WRITEV |
| 352 | INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, |
| 353 | int iovcnt) { |
| 354 | void *ctx; |
| 355 | COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 356 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 357 | if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); |
| 358 | SSIZE_T res = REAL(writev)(fd, iov, iovcnt); |
| 359 | if (res > 0) read_iovec(ctx, iov, iovcnt, res); |
| 360 | return res; |
| 361 | } |
| 362 | #define INIT_WRITEV INTERCEPT_FUNCTION(writev) |
| 363 | #else |
| 364 | #define INIT_WRITEV |
| 365 | #endif |
| 366 | |
| 367 | #if SANITIZER_INTERCEPT_PWRITEV |
| 368 | INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, |
| 369 | OFF_T offset) { |
| 370 | void *ctx; |
| 371 | COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 372 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 373 | if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); |
| 374 | SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); |
| 375 | if (res > 0) read_iovec(ctx, iov, iovcnt, res); |
| 376 | return res; |
| 377 | } |
| 378 | #define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) |
| 379 | #else |
| 380 | #define INIT_PWRITEV |
| 381 | #endif |
| 382 | |
| 383 | #if SANITIZER_INTERCEPT_PWRITEV64 |
| 384 | INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, |
| 385 | OFF64_T offset) { |
| 386 | void *ctx; |
| 387 | COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); |
Dmitry Vyukov | 67f5544 | 2013-10-11 14:13:11 +0000 | [diff] [blame] | 388 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 389 | if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); |
| 390 | SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); |
| 391 | if (res > 0) read_iovec(ctx, iov, iovcnt, res); |
| 392 | return res; |
| 393 | } |
| 394 | #define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) |
| 395 | #else |
| 396 | #define INIT_PWRITEV64 |
| 397 | #endif |
| 398 | |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 399 | #if SANITIZER_INTERCEPT_PRCTL |
Evgeniy Stepanov | 69b109a | 2013-02-20 11:06:07 +0000 | [diff] [blame] | 400 | INTERCEPTOR(int, prctl, int option, |
| 401 | unsigned long arg2, unsigned long arg3, // NOLINT |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 402 | unsigned long arg4, unsigned long arg5) { // NOLINT |
| 403 | void *ctx; |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 404 | COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 405 | static const int PR_SET_NAME = 15; |
| 406 | int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); |
| 407 | if (option == PR_SET_NAME) { |
| 408 | char buff[16]; |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 409 | internal_strncpy(buff, (char *)arg2, 15); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 410 | buff[15] = 0; |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 411 | COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 412 | } |
| 413 | return res; |
| 414 | } |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 415 | #define INIT_PRCTL INTERCEPT_FUNCTION(prctl) |
Kostya Serebryany | c20b321 | 2013-01-18 06:43:13 +0000 | [diff] [blame] | 416 | #else |
Evgeniy Stepanov | 44be70b | 2013-02-11 15:22:34 +0000 | [diff] [blame] | 417 | #define INIT_PRCTL |
| 418 | #endif // SANITIZER_INTERCEPT_PRCTL |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 419 | |
Evgeniy Stepanov | fef6605 | 2013-04-08 08:25:22 +0000 | [diff] [blame] | 420 | |
| 421 | #if SANITIZER_INTERCEPT_TIME |
| 422 | INTERCEPTOR(unsigned long, time, unsigned long *t) { |
| 423 | void *ctx; |
| 424 | COMMON_INTERCEPTOR_ENTER(ctx, time, t); |
| 425 | unsigned long res = REAL(time)(t); |
Alexander Potapenko | 15832c2 | 2013-04-10 15:13:00 +0000 | [diff] [blame] | 426 | if (t && res != (unsigned long)-1) { |
Evgeniy Stepanov | fef6605 | 2013-04-08 08:25:22 +0000 | [diff] [blame] | 427 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); |
| 428 | } |
| 429 | return res; |
| 430 | } |
| 431 | #define INIT_TIME \ |
| 432 | INTERCEPT_FUNCTION(time); |
| 433 | #else |
| 434 | #define INIT_TIME |
| 435 | #endif // SANITIZER_INTERCEPT_TIME |
| 436 | |
| 437 | |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 438 | #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 439 | static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { |
| 440 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); |
Dmitry Vyukov | 0586dcc | 2013-10-03 14:12:09 +0000 | [diff] [blame] | 441 | if (tm->tm_zone) { |
| 442 | // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone |
| 443 | // can point to shared memory and tsan would report a data race. |
| 444 | COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone, |
| 445 | REAL(strlen(tm->tm_zone)) + 1); |
| 446 | } |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 447 | } |
| 448 | |
| 449 | INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 450 | void *ctx; |
| 451 | COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 452 | __sanitizer_tm *res = REAL(localtime)(timep); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 453 | if (res) { |
| 454 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 455 | unpoison_tm(ctx, res); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 456 | } |
| 457 | return res; |
| 458 | } |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 459 | INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 460 | void *ctx; |
| 461 | COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 462 | __sanitizer_tm *res = REAL(localtime_r)(timep, result); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 463 | if (res) { |
| 464 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 465 | unpoison_tm(ctx, res); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 466 | } |
| 467 | return res; |
| 468 | } |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 469 | INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 470 | void *ctx; |
| 471 | COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 472 | __sanitizer_tm *res = REAL(gmtime)(timep); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 473 | if (res) { |
| 474 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 475 | unpoison_tm(ctx, res); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 476 | } |
| 477 | return res; |
| 478 | } |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 479 | INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 480 | void *ctx; |
| 481 | COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 482 | __sanitizer_tm *res = REAL(gmtime_r)(timep, result); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 483 | if (res) { |
| 484 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 485 | unpoison_tm(ctx, res); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 486 | } |
| 487 | return res; |
| 488 | } |
| 489 | INTERCEPTOR(char *, ctime, unsigned long *timep) { |
| 490 | void *ctx; |
| 491 | COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); |
| 492 | char *res = REAL(ctime)(timep); |
| 493 | if (res) { |
| 494 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); |
| 495 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 496 | } |
| 497 | return res; |
| 498 | } |
| 499 | INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { |
| 500 | void *ctx; |
| 501 | COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); |
| 502 | char *res = REAL(ctime_r)(timep, result); |
| 503 | if (res) { |
| 504 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); |
| 505 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 506 | } |
| 507 | return res; |
| 508 | } |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 509 | INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 510 | void *ctx; |
| 511 | COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); |
| 512 | char *res = REAL(asctime)(tm); |
| 513 | if (res) { |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 514 | COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 515 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 516 | } |
| 517 | return res; |
| 518 | } |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 519 | INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 520 | void *ctx; |
| 521 | COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); |
| 522 | char *res = REAL(asctime_r)(tm, result); |
| 523 | if (res) { |
Evgeniy Stepanov | cf39032 | 2013-10-02 14:30:03 +0000 | [diff] [blame] | 524 | COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); |
Evgeniy Stepanov | 9358c58 | 2013-02-19 09:19:16 +0000 | [diff] [blame] | 525 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 526 | } |
| 527 | return res; |
| 528 | } |
| 529 | #define INIT_LOCALTIME_AND_FRIENDS \ |
| 530 | INTERCEPT_FUNCTION(localtime); \ |
| 531 | INTERCEPT_FUNCTION(localtime_r); \ |
| 532 | INTERCEPT_FUNCTION(gmtime); \ |
| 533 | INTERCEPT_FUNCTION(gmtime_r); \ |
| 534 | INTERCEPT_FUNCTION(ctime); \ |
| 535 | INTERCEPT_FUNCTION(ctime_r); \ |
| 536 | INTERCEPT_FUNCTION(asctime); \ |
| 537 | INTERCEPT_FUNCTION(asctime_r); |
| 538 | #else |
| 539 | #define INIT_LOCALTIME_AND_FRIENDS |
| 540 | #endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS |
| 541 | |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 542 | #if SANITIZER_INTERCEPT_SCANF |
| 543 | |
Evgeniy Stepanov | 4f32c0b | 2013-01-18 13:01:18 +0000 | [diff] [blame] | 544 | #include "sanitizer_common_interceptors_scanf.inc" |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 545 | |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 546 | #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 547 | { \ |
| 548 | void *ctx; \ |
| 549 | COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ |
| 550 | va_list aq; \ |
| 551 | va_copy(aq, ap); \ |
| 552 | int res = REAL(vname)(__VA_ARGS__); \ |
| 553 | if (res > 0) \ |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 554 | scanf_common(ctx, res, allowGnuMalloc, format, aq); \ |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 555 | va_end(aq); \ |
| 556 | return res; \ |
| 557 | } |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 558 | |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 559 | INTERCEPTOR(int, vscanf, const char *format, va_list ap) |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 560 | VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 561 | |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 562 | INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 563 | VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 564 | |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 565 | INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 566 | VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 567 | |
Alexander Potapenko | 9eab858 | 2013-02-20 15:27:58 +0000 | [diff] [blame] | 568 | #if SANITIZER_INTERCEPT_ISOC99_SCANF |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 569 | INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 570 | VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 571 | |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 572 | INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, |
| 573 | va_list ap) |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 574 | VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 575 | |
| 576 | INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) |
Evgeniy Stepanov | c5b4e86 | 2013-02-12 14:29:34 +0000 | [diff] [blame] | 577 | VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) |
Alexander Potapenko | 9eab858 | 2013-02-20 15:27:58 +0000 | [diff] [blame] | 578 | #endif // SANITIZER_INTERCEPT_ISOC99_SCANF |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 579 | |
| 580 | #define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ |
| 581 | { \ |
| 582 | void *ctx; \ |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 583 | va_list ap; \ |
| 584 | va_start(ap, format); \ |
Dmitry Vyukov | 1c571df | 2013-09-26 18:38:54 +0000 | [diff] [blame] | 585 | COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 586 | int res = vname(__VA_ARGS__, ap); \ |
| 587 | va_end(ap); \ |
| 588 | return res; \ |
| 589 | } |
| 590 | |
| 591 | INTERCEPTOR(int, scanf, const char *format, ...) |
| 592 | SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) |
| 593 | |
| 594 | INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) |
| 595 | SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) |
| 596 | |
| 597 | INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) |
| 598 | SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) |
| 599 | |
Alexander Potapenko | 9eab858 | 2013-02-20 15:27:58 +0000 | [diff] [blame] | 600 | #if SANITIZER_INTERCEPT_ISOC99_SCANF |
Evgeniy Stepanov | 4ae1adb | 2013-02-12 11:34:52 +0000 | [diff] [blame] | 601 | INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) |
| 602 | SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) |
| 603 | |
| 604 | INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) |
| 605 | SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) |
| 606 | |
| 607 | INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) |
| 608 | SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) |
Alexander Potapenko | 9eab858 | 2013-02-20 15:27:58 +0000 | [diff] [blame] | 609 | #endif |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 610 | |
Evgeniy Stepanov | ba15077 | 2013-08-22 13:59:15 +0000 | [diff] [blame] | 611 | #endif |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 612 | |
Evgeniy Stepanov | ba15077 | 2013-08-22 13:59:15 +0000 | [diff] [blame] | 613 | #if SANITIZER_INTERCEPT_SCANF |
| 614 | #define INIT_SCANF \ |
| 615 | INTERCEPT_FUNCTION(scanf); \ |
| 616 | INTERCEPT_FUNCTION(sscanf); \ |
| 617 | INTERCEPT_FUNCTION(fscanf); \ |
| 618 | INTERCEPT_FUNCTION(vscanf); \ |
| 619 | INTERCEPT_FUNCTION(vsscanf); \ |
| 620 | INTERCEPT_FUNCTION(vfscanf); |
Evgeniy Stepanov | 996c4f2 | 2013-01-18 11:17:23 +0000 | [diff] [blame] | 621 | #else |
| 622 | #define INIT_SCANF |
| 623 | #endif |
| 624 | |
Evgeniy Stepanov | ba15077 | 2013-08-22 13:59:15 +0000 | [diff] [blame] | 625 | #if SANITIZER_INTERCEPT_ISOC99_SCANF |
| 626 | #define INIT_ISOC99_SCANF \ |
| 627 | INTERCEPT_FUNCTION(__isoc99_scanf); \ |
| 628 | INTERCEPT_FUNCTION(__isoc99_sscanf); \ |
| 629 | INTERCEPT_FUNCTION(__isoc99_fscanf); \ |
| 630 | INTERCEPT_FUNCTION(__isoc99_vscanf); \ |
| 631 | INTERCEPT_FUNCTION(__isoc99_vsscanf); \ |
| 632 | INTERCEPT_FUNCTION(__isoc99_vfscanf); |
| 633 | #else |
| 634 | #define INIT_ISOC99_SCANF |
| 635 | #endif |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 636 | |
Evgeniy Stepanov | 4e95e94 | 2013-06-07 13:19:33 +0000 | [diff] [blame] | 637 | #if SANITIZER_INTERCEPT_IOCTL |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 638 | #include "sanitizer_common_interceptors_ioctl.inc" |
Evgeniy Stepanov | 4e95e94 | 2013-06-07 13:19:33 +0000 | [diff] [blame] | 639 | INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { |
| 640 | void *ctx; |
| 641 | COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); |
| 642 | |
| 643 | CHECK(ioctl_initialized); |
| 644 | |
| 645 | // Note: TSan does not use common flags, and they are zero-initialized. |
| 646 | // This effectively disables ioctl handling in TSan. |
| 647 | if (!common_flags()->handle_ioctl) |
| 648 | return REAL(ioctl)(d, request, arg); |
| 649 | |
| 650 | const ioctl_desc *desc = ioctl_lookup(request); |
| 651 | if (!desc) |
| 652 | Printf("WARNING: unknown ioctl %x\n", request); |
| 653 | |
| 654 | if (desc) |
| 655 | ioctl_common_pre(ctx, desc, d, request, arg); |
| 656 | int res = REAL(ioctl)(d, request, arg); |
| 657 | // FIXME: some ioctls have different return values for success and failure. |
| 658 | if (desc && res != -1) |
| 659 | ioctl_common_post(ctx, desc, res, d, request, arg); |
| 660 | return res; |
| 661 | } |
Evgeniy Stepanov | 4ce6f79 | 2013-06-07 14:56:54 +0000 | [diff] [blame] | 662 | #define INIT_IOCTL \ |
| 663 | ioctl_init(); \ |
| 664 | INTERCEPT_FUNCTION(ioctl); |
Evgeniy Stepanov | 4e95e94 | 2013-06-07 13:19:33 +0000 | [diff] [blame] | 665 | #else |
| 666 | #define INIT_IOCTL |
| 667 | #endif |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 668 | |
| 669 | |
Evgeniy Stepanov | 103a63e | 2013-04-23 12:01:20 +0000 | [diff] [blame] | 670 | #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 671 | INTERCEPTOR(void *, getpwnam, const char *name) { |
| 672 | void *ctx; |
| 673 | COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); |
| 674 | COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); |
| 675 | void *res = REAL(getpwnam)(name); |
| 676 | if (res != 0) |
| 677 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); |
| 678 | return res; |
| 679 | } |
| 680 | INTERCEPTOR(void *, getpwuid, u32 uid) { |
| 681 | void *ctx; |
| 682 | COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); |
| 683 | void *res = REAL(getpwuid)(uid); |
| 684 | if (res != 0) |
| 685 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); |
| 686 | return res; |
| 687 | } |
Evgeniy Stepanov | 103a63e | 2013-04-23 12:01:20 +0000 | [diff] [blame] | 688 | INTERCEPTOR(void *, getgrnam, const char *name) { |
| 689 | void *ctx; |
| 690 | COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); |
| 691 | COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); |
| 692 | void *res = REAL(getgrnam)(name); |
| 693 | if (res != 0) |
| 694 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); |
| 695 | return res; |
| 696 | } |
| 697 | INTERCEPTOR(void *, getgrgid, u32 gid) { |
| 698 | void *ctx; |
| 699 | COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); |
| 700 | void *res = REAL(getgrgid)(gid); |
| 701 | if (res != 0) |
| 702 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); |
| 703 | return res; |
| 704 | } |
| 705 | #define INIT_GETPWNAM_AND_FRIENDS \ |
| 706 | INTERCEPT_FUNCTION(getpwnam); \ |
| 707 | INTERCEPT_FUNCTION(getpwuid); \ |
| 708 | INTERCEPT_FUNCTION(getgrnam); \ |
| 709 | INTERCEPT_FUNCTION(getgrgid); |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 710 | #else |
Evgeniy Stepanov | 103a63e | 2013-04-23 12:01:20 +0000 | [diff] [blame] | 711 | #define INIT_GETPWNAM_AND_FRIENDS |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 712 | #endif |
| 713 | |
| 714 | |
Evgeniy Stepanov | 103a63e | 2013-04-23 12:01:20 +0000 | [diff] [blame] | 715 | #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 716 | INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, |
| 717 | char *buf, SIZE_T buflen, void **result) { |
| 718 | void *ctx; |
| 719 | COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); |
| 720 | COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); |
| 721 | int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); |
| 722 | if (!res) { |
| 723 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); |
| 724 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); |
| 725 | } |
| 726 | return res; |
| 727 | } |
| 728 | INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, |
| 729 | char *buf, SIZE_T buflen, void **result) { |
| 730 | void *ctx; |
| 731 | COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); |
| 732 | int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); |
| 733 | if (!res) { |
| 734 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); |
| 735 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); |
| 736 | } |
| 737 | return res; |
| 738 | } |
Evgeniy Stepanov | 103a63e | 2013-04-23 12:01:20 +0000 | [diff] [blame] | 739 | INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, |
| 740 | char *buf, SIZE_T buflen, void **result) { |
| 741 | void *ctx; |
| 742 | COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); |
| 743 | COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); |
| 744 | int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); |
| 745 | if (!res) { |
| 746 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); |
| 747 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); |
| 748 | } |
| 749 | return res; |
| 750 | } |
| 751 | INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, |
| 752 | char *buf, SIZE_T buflen, void **result) { |
| 753 | void *ctx; |
| 754 | COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); |
| 755 | int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); |
| 756 | if (!res) { |
| 757 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); |
| 758 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); |
| 759 | } |
| 760 | return res; |
| 761 | } |
| 762 | #define INIT_GETPWNAM_R_AND_FRIENDS \ |
| 763 | INTERCEPT_FUNCTION(getpwnam_r); \ |
| 764 | INTERCEPT_FUNCTION(getpwuid_r); \ |
| 765 | INTERCEPT_FUNCTION(getgrnam_r); \ |
| 766 | INTERCEPT_FUNCTION(getgrgid_r); |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 767 | #else |
Evgeniy Stepanov | 103a63e | 2013-04-23 12:01:20 +0000 | [diff] [blame] | 768 | #define INIT_GETPWNAM_R_AND_FRIENDS |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 769 | #endif |
| 770 | |
| 771 | |
| 772 | #if SANITIZER_INTERCEPT_CLOCK_GETTIME |
| 773 | INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { |
| 774 | void *ctx; |
| 775 | COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); |
| 776 | int res = REAL(clock_getres)(clk_id, tp); |
Evgeniy Stepanov | 7cdae16 | 2013-04-23 11:48:31 +0000 | [diff] [blame] | 777 | if (!res && tp) { |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 778 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); |
| 779 | } |
| 780 | return res; |
| 781 | } |
| 782 | INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { |
| 783 | void *ctx; |
| 784 | COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); |
| 785 | int res = REAL(clock_gettime)(clk_id, tp); |
| 786 | if (!res) { |
| 787 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); |
| 788 | } |
| 789 | return res; |
| 790 | } |
| 791 | INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { |
| 792 | void *ctx; |
| 793 | COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); |
| 794 | COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); |
| 795 | return REAL(clock_settime)(clk_id, tp); |
| 796 | } |
| 797 | #define INIT_CLOCK_GETTIME \ |
| 798 | INTERCEPT_FUNCTION(clock_getres); \ |
| 799 | INTERCEPT_FUNCTION(clock_gettime); \ |
| 800 | INTERCEPT_FUNCTION(clock_settime); |
| 801 | #else |
| 802 | #define INIT_CLOCK_GETTIME |
| 803 | #endif |
| 804 | |
| 805 | |
| 806 | #if SANITIZER_INTERCEPT_GETITIMER |
| 807 | INTERCEPTOR(int, getitimer, int which, void *curr_value) { |
| 808 | void *ctx; |
| 809 | COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); |
| 810 | int res = REAL(getitimer)(which, curr_value); |
Evgeniy Stepanov | 39d68ed | 2013-08-06 09:54:33 +0000 | [diff] [blame] | 811 | if (!res && curr_value) { |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 812 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); |
| 813 | } |
| 814 | return res; |
| 815 | } |
| 816 | INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { |
| 817 | void *ctx; |
| 818 | COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); |
Evgeniy Stepanov | 39d68ed | 2013-08-06 09:54:33 +0000 | [diff] [blame] | 819 | if (new_value) |
| 820 | COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); |
Evgeniy Stepanov | e4bdda5 | 2013-04-01 14:47:21 +0000 | [diff] [blame] | 821 | int res = REAL(setitimer)(which, new_value, old_value); |
| 822 | if (!res && old_value) { |
| 823 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); |
| 824 | } |
| 825 | return res; |
| 826 | } |
| 827 | #define INIT_GETITIMER \ |
| 828 | INTERCEPT_FUNCTION(getitimer); \ |
| 829 | INTERCEPT_FUNCTION(setitimer); |
| 830 | #else |
| 831 | #define INIT_GETITIMER |
| 832 | #endif |
| 833 | |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 834 | #if SANITIZER_INTERCEPT_GLOB |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 835 | static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 836 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); |
| 837 | // +1 for NULL pointer at the end. |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 838 | if (pglob->gl_pathv) |
| 839 | COMMON_INTERCEPTOR_WRITE_RANGE( |
| 840 | ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 841 | for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { |
| 842 | char *p = pglob->gl_pathv[i]; |
| 843 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); |
| 844 | } |
| 845 | } |
| 846 | |
Timur Iskhodzhanov | eaca82c | 2013-07-15 16:11:39 +0000 | [diff] [blame] | 847 | static THREADLOCAL __sanitizer_glob_t* pglob_copy; |
Evgeniy Stepanov | 3fa122e | 2013-07-09 12:07:59 +0000 | [diff] [blame] | 848 | static THREADLOCAL void* glob_ctx; |
| 849 | |
| 850 | static void wrapped_gl_closedir(void *dir) { |
| 851 | COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); |
| 852 | pglob_copy->gl_closedir(dir); |
| 853 | } |
| 854 | |
| 855 | static void *wrapped_gl_readdir(void *dir) { |
| 856 | COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); |
| 857 | return pglob_copy->gl_readdir(dir); |
| 858 | } |
| 859 | |
| 860 | static void *wrapped_gl_opendir(const char *s) { |
| 861 | COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); |
| 862 | COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); |
| 863 | return pglob_copy->gl_opendir(s); |
| 864 | } |
| 865 | |
| 866 | static int wrapped_gl_lstat(const char *s, void *st) { |
| 867 | COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); |
| 868 | COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); |
| 869 | return pglob_copy->gl_lstat(s, st); |
| 870 | } |
| 871 | |
| 872 | static int wrapped_gl_stat(const char *s, void *st) { |
| 873 | COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); |
| 874 | COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); |
| 875 | return pglob_copy->gl_stat(s, st); |
| 876 | } |
| 877 | |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 878 | INTERCEPTOR(int, glob, const char *pattern, int flags, |
| 879 | int (*errfunc)(const char *epath, int eerrno), |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 880 | __sanitizer_glob_t *pglob) { |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 881 | void *ctx; |
| 882 | COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); |
Evgeniy Stepanov | 3fa122e | 2013-07-09 12:07:59 +0000 | [diff] [blame] | 883 | __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, |
| 884 | wrapped_gl_readdir, wrapped_gl_opendir, |
| 885 | wrapped_gl_lstat, wrapped_gl_stat}; |
| 886 | if (flags & glob_altdirfunc) { |
| 887 | Swap(pglob->gl_closedir, glob_copy.gl_closedir); |
| 888 | Swap(pglob->gl_readdir, glob_copy.gl_readdir); |
| 889 | Swap(pglob->gl_opendir, glob_copy.gl_opendir); |
| 890 | Swap(pglob->gl_lstat, glob_copy.gl_lstat); |
| 891 | Swap(pglob->gl_stat, glob_copy.gl_stat); |
| 892 | pglob_copy = &glob_copy; |
| 893 | glob_ctx = ctx; |
| 894 | } |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 895 | int res = REAL(glob)(pattern, flags, errfunc, pglob); |
Evgeniy Stepanov | 3fa122e | 2013-07-09 12:07:59 +0000 | [diff] [blame] | 896 | if (flags & glob_altdirfunc) { |
| 897 | Swap(pglob->gl_closedir, glob_copy.gl_closedir); |
| 898 | Swap(pglob->gl_readdir, glob_copy.gl_readdir); |
| 899 | Swap(pglob->gl_opendir, glob_copy.gl_opendir); |
| 900 | Swap(pglob->gl_lstat, glob_copy.gl_lstat); |
| 901 | Swap(pglob->gl_stat, glob_copy.gl_stat); |
| 902 | } |
| 903 | pglob_copy = 0; |
| 904 | glob_ctx = 0; |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 905 | if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 906 | return res; |
| 907 | } |
| 908 | |
| 909 | INTERCEPTOR(int, glob64, const char *pattern, int flags, |
| 910 | int (*errfunc)(const char *epath, int eerrno), |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 911 | __sanitizer_glob_t *pglob) { |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 912 | void *ctx; |
| 913 | COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); |
Evgeniy Stepanov | 57876cf | 2013-07-09 12:34:25 +0000 | [diff] [blame] | 914 | __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, |
| 915 | wrapped_gl_readdir, wrapped_gl_opendir, |
| 916 | wrapped_gl_lstat, wrapped_gl_stat}; |
| 917 | if (flags & glob_altdirfunc) { |
| 918 | Swap(pglob->gl_closedir, glob_copy.gl_closedir); |
| 919 | Swap(pglob->gl_readdir, glob_copy.gl_readdir); |
| 920 | Swap(pglob->gl_opendir, glob_copy.gl_opendir); |
| 921 | Swap(pglob->gl_lstat, glob_copy.gl_lstat); |
| 922 | Swap(pglob->gl_stat, glob_copy.gl_stat); |
| 923 | pglob_copy = &glob_copy; |
| 924 | glob_ctx = ctx; |
| 925 | } |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 926 | int res = REAL(glob64)(pattern, flags, errfunc, pglob); |
Evgeniy Stepanov | 57876cf | 2013-07-09 12:34:25 +0000 | [diff] [blame] | 927 | if (flags & glob_altdirfunc) { |
| 928 | Swap(pglob->gl_closedir, glob_copy.gl_closedir); |
| 929 | Swap(pglob->gl_readdir, glob_copy.gl_readdir); |
| 930 | Swap(pglob->gl_opendir, glob_copy.gl_opendir); |
| 931 | Swap(pglob->gl_lstat, glob_copy.gl_lstat); |
| 932 | Swap(pglob->gl_stat, glob_copy.gl_stat); |
| 933 | } |
| 934 | pglob_copy = 0; |
| 935 | glob_ctx = 0; |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 936 | if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 937 | return res; |
| 938 | } |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 939 | #define INIT_GLOB \ |
| 940 | INTERCEPT_FUNCTION(glob); \ |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 941 | INTERCEPT_FUNCTION(glob64); |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 942 | #else // SANITIZER_INTERCEPT_GLOB |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 943 | #define INIT_GLOB |
Evgeniy Stepanov | 906f2c1 | 2013-07-02 14:08:52 +0000 | [diff] [blame] | 944 | #endif // SANITIZER_INTERCEPT_GLOB |
Evgeniy Stepanov | a1c2a55 | 2013-04-09 11:35:13 +0000 | [diff] [blame] | 945 | |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 946 | #if SANITIZER_INTERCEPT_WAIT |
Alexander Potapenko | 6a659df | 2013-05-20 13:32:35 +0000 | [diff] [blame] | 947 | // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version |
| 948 | // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for |
| 949 | // details. |
| 950 | INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 951 | void *ctx; |
| 952 | COMMON_INTERCEPTOR_ENTER(ctx, wait, status); |
| 953 | int res = REAL(wait)(status); |
Dmitry Vyukov | f82eb24 | 2013-04-29 09:04:24 +0000 | [diff] [blame] | 954 | if (res != -1 && status) |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 955 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); |
| 956 | return res; |
| 957 | } |
Kostya Serebryany | 30e970f | 2013-05-22 08:54:30 +0000 | [diff] [blame] | 958 | INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, |
| 959 | int options) { |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 960 | void *ctx; |
| 961 | COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); |
| 962 | int res = REAL(waitid)(idtype, id, infop, options); |
Dmitry Vyukov | f82eb24 | 2013-04-29 09:04:24 +0000 | [diff] [blame] | 963 | if (res != -1 && infop) |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 964 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); |
| 965 | return res; |
| 966 | } |
Alexander Potapenko | 6a659df | 2013-05-20 13:32:35 +0000 | [diff] [blame] | 967 | INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 968 | void *ctx; |
| 969 | COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); |
| 970 | int res = REAL(waitpid)(pid, status, options); |
Dmitry Vyukov | f82eb24 | 2013-04-29 09:04:24 +0000 | [diff] [blame] | 971 | if (res != -1 && status) |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 972 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); |
| 973 | return res; |
| 974 | } |
| 975 | INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { |
| 976 | void *ctx; |
| 977 | COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); |
| 978 | int res = REAL(wait3)(status, options, rusage); |
| 979 | if (res != -1) { |
Dmitry Vyukov | f82eb24 | 2013-04-29 09:04:24 +0000 | [diff] [blame] | 980 | if (status) |
| 981 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 982 | if (rusage) |
| 983 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); |
| 984 | } |
| 985 | return res; |
| 986 | } |
| 987 | INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { |
| 988 | void *ctx; |
| 989 | COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); |
| 990 | int res = REAL(wait4)(pid, status, options, rusage); |
| 991 | if (res != -1) { |
Dmitry Vyukov | f82eb24 | 2013-04-29 09:04:24 +0000 | [diff] [blame] | 992 | if (status) |
| 993 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 994 | if (rusage) |
| 995 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); |
| 996 | } |
| 997 | return res; |
| 998 | } |
| 999 | #define INIT_WAIT \ |
| 1000 | INTERCEPT_FUNCTION(wait); \ |
| 1001 | INTERCEPT_FUNCTION(waitid); \ |
| 1002 | INTERCEPT_FUNCTION(waitpid); \ |
| 1003 | INTERCEPT_FUNCTION(wait3); \ |
| 1004 | INTERCEPT_FUNCTION(wait4); |
| 1005 | #else |
| 1006 | #define INIT_WAIT |
| 1007 | #endif |
| 1008 | |
Evgeniy Stepanov | 9530eb7 | 2013-04-23 14:05:15 +0000 | [diff] [blame] | 1009 | #if SANITIZER_INTERCEPT_INET |
| 1010 | INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { |
| 1011 | void *ctx; |
| 1012 | COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); |
| 1013 | uptr sz = __sanitizer_in_addr_sz(af); |
| 1014 | if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); |
| 1015 | // FIXME: figure out read size based on the address family. |
| 1016 | char *res = REAL(inet_ntop)(af, src, dst, size); |
| 1017 | if (res) |
| 1018 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1019 | return res; |
| 1020 | } |
| 1021 | INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { |
| 1022 | void *ctx; |
| 1023 | COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); |
| 1024 | // FIXME: figure out read size based on the address family. |
| 1025 | int res = REAL(inet_pton)(af, src, dst); |
| 1026 | if (res == 1) { |
| 1027 | uptr sz = __sanitizer_in_addr_sz(af); |
| 1028 | if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); |
| 1029 | } |
| 1030 | return res; |
| 1031 | } |
| 1032 | #define INIT_INET \ |
| 1033 | INTERCEPT_FUNCTION(inet_ntop); \ |
| 1034 | INTERCEPT_FUNCTION(inet_pton); |
| 1035 | #else |
| 1036 | #define INIT_INET |
| 1037 | #endif |
| 1038 | |
Evgeniy Stepanov | 9d60087 | 2013-06-24 13:56:14 +0000 | [diff] [blame] | 1039 | #if SANITIZER_INTERCEPT_INET |
| 1040 | INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { |
| 1041 | void *ctx; |
| 1042 | COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); |
| 1043 | if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); |
| 1044 | int res = REAL(inet_aton)(cp, dst); |
| 1045 | if (res != 0) { |
| 1046 | uptr sz = __sanitizer_in_addr_sz(af_inet); |
| 1047 | if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); |
| 1048 | } |
| 1049 | return res; |
| 1050 | } |
| 1051 | #define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); |
| 1052 | #else |
| 1053 | #define INIT_INET_ATON |
| 1054 | #endif |
| 1055 | |
Evgeniy Stepanov | 56d3472 | 2013-05-21 08:12:08 +0000 | [diff] [blame] | 1056 | #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM |
| 1057 | INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { |
| 1058 | void *ctx; |
| 1059 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); |
| 1060 | int res = REAL(pthread_getschedparam)(thread, policy, param); |
| 1061 | if (res == 0) { |
| 1062 | if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); |
| 1063 | if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); |
| 1064 | } |
| 1065 | return res; |
| 1066 | } |
| 1067 | #define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); |
| 1068 | #else |
| 1069 | #define INIT_PTHREAD_GETSCHEDPARAM |
| 1070 | #endif |
Evgeniy Stepanov | 897a4ae | 2013-04-09 14:34:59 +0000 | [diff] [blame] | 1071 | |
Evgeniy Stepanov | 447ef19 | 2013-05-22 12:50:26 +0000 | [diff] [blame] | 1072 | #if SANITIZER_INTERCEPT_GETADDRINFO |
| 1073 | INTERCEPTOR(int, getaddrinfo, char *node, char *service, |
| 1074 | struct __sanitizer_addrinfo *hints, |
| 1075 | struct __sanitizer_addrinfo **out) { |
| 1076 | void *ctx; |
| 1077 | COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); |
| 1078 | if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); |
| 1079 | if (service) |
| 1080 | COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); |
| 1081 | if (hints) |
| 1082 | COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); |
| 1083 | int res = REAL(getaddrinfo)(node, service, hints, out); |
Evgeniy Stepanov | 3538eb8 | 2013-05-28 14:34:37 +0000 | [diff] [blame] | 1084 | if (res == 0 && out) { |
| 1085 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); |
Evgeniy Stepanov | 447ef19 | 2013-05-22 12:50:26 +0000 | [diff] [blame] | 1086 | struct __sanitizer_addrinfo *p = *out; |
| 1087 | while (p) { |
Evgeniy Stepanov | 3538eb8 | 2013-05-28 14:34:37 +0000 | [diff] [blame] | 1088 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); |
Evgeniy Stepanov | 447ef19 | 2013-05-22 12:50:26 +0000 | [diff] [blame] | 1089 | if (p->ai_addr) |
Evgeniy Stepanov | 512c616 | 2013-05-29 12:33:31 +0000 | [diff] [blame] | 1090 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); |
Evgeniy Stepanov | 447ef19 | 2013-05-22 12:50:26 +0000 | [diff] [blame] | 1091 | if (p->ai_canonname) |
| 1092 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, |
| 1093 | REAL(strlen)(p->ai_canonname) + 1); |
| 1094 | p = p->ai_next; |
| 1095 | } |
| 1096 | } |
| 1097 | return res; |
| 1098 | } |
| 1099 | #define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); |
| 1100 | #else |
| 1101 | #define INIT_GETADDRINFO |
| 1102 | #endif |
| 1103 | |
Evgeniy Stepanov | 9eedf48 | 2013-07-01 13:51:31 +0000 | [diff] [blame] | 1104 | #if SANITIZER_INTERCEPT_GETNAMEINFO |
| 1105 | INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, |
| 1106 | unsigned hostlen, char *serv, unsigned servlen, int flags) { |
| 1107 | void *ctx; |
| 1108 | COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, |
| 1109 | serv, servlen, flags); |
| 1110 | // FIXME: consider adding READ_RANGE(sockaddr, salen) |
| 1111 | // There is padding in in_addr that may make this too noisy |
| 1112 | int res = |
| 1113 | REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); |
| 1114 | if (res == 0) { |
| 1115 | if (host && hostlen) |
| 1116 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); |
| 1117 | if (serv && servlen) |
| 1118 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); |
| 1119 | } |
| 1120 | return res; |
| 1121 | } |
| 1122 | #define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); |
| 1123 | #else |
| 1124 | #define INIT_GETNAMEINFO |
| 1125 | #endif |
| 1126 | |
Evgeniy Stepanov | 9f58c5c | 2013-05-22 13:46:22 +0000 | [diff] [blame] | 1127 | #if SANITIZER_INTERCEPT_GETSOCKNAME |
| 1128 | INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { |
| 1129 | void *ctx; |
| 1130 | COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); |
| 1131 | COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); |
| 1132 | int addrlen_in = *addrlen; |
| 1133 | int res = REAL(getsockname)(sock_fd, addr, addrlen); |
| 1134 | if (res == 0) { |
| 1135 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); |
| 1136 | } |
| 1137 | return res; |
| 1138 | } |
| 1139 | #define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); |
| 1140 | #else |
| 1141 | #define INIT_GETSOCKNAME |
| 1142 | #endif |
Evgeniy Stepanov | 447ef19 | 2013-05-22 12:50:26 +0000 | [diff] [blame] | 1143 | |
Evgeniy Stepanov | 33b1485 | 2013-05-23 11:41:58 +0000 | [diff] [blame] | 1144 | #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R |
Evgeniy Stepanov | 0a2cc37 | 2013-05-23 11:10:23 +0000 | [diff] [blame] | 1145 | static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { |
| 1146 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); |
| 1147 | if (h->h_name) |
| 1148 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); |
| 1149 | char **p = h->h_aliases; |
| 1150 | while (*p) { |
| 1151 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); |
| 1152 | ++p; |
| 1153 | } |
| 1154 | COMMON_INTERCEPTOR_WRITE_RANGE( |
| 1155 | ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); |
| 1156 | p = h->h_addr_list; |
| 1157 | while (*p) { |
| 1158 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); |
| 1159 | ++p; |
| 1160 | } |
| 1161 | COMMON_INTERCEPTOR_WRITE_RANGE( |
| 1162 | ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); |
| 1163 | } |
Evgeniy Stepanov | 33b1485 | 2013-05-23 11:41:58 +0000 | [diff] [blame] | 1164 | #endif |
Evgeniy Stepanov | 0a2cc37 | 2013-05-23 11:10:23 +0000 | [diff] [blame] | 1165 | |
| 1166 | #if SANITIZER_INTERCEPT_GETHOSTBYNAME |
| 1167 | INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { |
| 1168 | void *ctx; |
| 1169 | COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); |
| 1170 | struct __sanitizer_hostent *res = REAL(gethostbyname)(name); |
| 1171 | if (res) write_hostent(ctx, res); |
| 1172 | return res; |
| 1173 | } |
| 1174 | |
| 1175 | INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, |
| 1176 | int type) { |
| 1177 | void *ctx; |
| 1178 | COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); |
| 1179 | COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); |
| 1180 | struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); |
| 1181 | if (res) write_hostent(ctx, res); |
| 1182 | return res; |
| 1183 | } |
| 1184 | |
Dmitry Vyukov | 1d02bea | 2013-10-02 14:04:23 +0000 | [diff] [blame] | 1185 | INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { |
Evgeniy Stepanov | 0a2cc37 | 2013-05-23 11:10:23 +0000 | [diff] [blame] | 1186 | void *ctx; |
Dmitry Vyukov | 1d02bea | 2013-10-02 14:04:23 +0000 | [diff] [blame] | 1187 | COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); |
| 1188 | struct __sanitizer_hostent *res = REAL(gethostent)(fake); |
Evgeniy Stepanov | 0a2cc37 | 2013-05-23 11:10:23 +0000 | [diff] [blame] | 1189 | if (res) write_hostent(ctx, res); |
| 1190 | return res; |
| 1191 | } |
| 1192 | |
| 1193 | INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { |
| 1194 | void *ctx; |
| 1195 | COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); |
| 1196 | struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); |
| 1197 | if (res) write_hostent(ctx, res); |
| 1198 | return res; |
| 1199 | } |
| 1200 | #define INIT_GETHOSTBYNAME \ |
| 1201 | INTERCEPT_FUNCTION(gethostent); \ |
| 1202 | INTERCEPT_FUNCTION(gethostbyaddr); \ |
| 1203 | INTERCEPT_FUNCTION(gethostbyname); \ |
| 1204 | INTERCEPT_FUNCTION(gethostbyname2); |
| 1205 | #else |
| 1206 | #define INIT_GETHOSTBYNAME |
| 1207 | #endif |
| 1208 | |
| 1209 | #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R |
| 1210 | INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, |
| 1211 | SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { |
| 1212 | void *ctx; |
| 1213 | COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, |
| 1214 | h_errnop); |
| 1215 | int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); |
| 1216 | if (res == 0) { |
| 1217 | if (result) { |
| 1218 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 1219 | if (*result) write_hostent(ctx, *result); |
| 1220 | } |
| 1221 | if (h_errnop) |
| 1222 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); |
| 1223 | } |
| 1224 | return res; |
| 1225 | } |
| 1226 | |
| 1227 | INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, |
| 1228 | struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, |
| 1229 | __sanitizer_hostent **result, int *h_errnop) { |
| 1230 | void *ctx; |
| 1231 | COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, |
| 1232 | buflen, result, h_errnop); |
| 1233 | COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); |
| 1234 | int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, |
| 1235 | h_errnop); |
| 1236 | if (res == 0) { |
| 1237 | if (result) { |
| 1238 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 1239 | if (*result) write_hostent(ctx, *result); |
| 1240 | } |
| 1241 | if (h_errnop) |
| 1242 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); |
| 1243 | } |
| 1244 | return res; |
| 1245 | } |
| 1246 | |
| 1247 | INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, |
| 1248 | char *buf, SIZE_T buflen, __sanitizer_hostent **result, |
| 1249 | int *h_errnop) { |
| 1250 | void *ctx; |
| 1251 | COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, |
| 1252 | h_errnop); |
| 1253 | int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); |
| 1254 | if (res == 0) { |
| 1255 | if (result) { |
| 1256 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 1257 | if (*result) write_hostent(ctx, *result); |
| 1258 | } |
| 1259 | if (h_errnop) |
| 1260 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); |
| 1261 | } |
| 1262 | return res; |
| 1263 | } |
| 1264 | |
| 1265 | INTERCEPTOR(int, gethostbyname2_r, char *name, int af, |
| 1266 | struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, |
| 1267 | __sanitizer_hostent **result, int *h_errnop) { |
| 1268 | void *ctx; |
| 1269 | COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, |
| 1270 | result, h_errnop); |
| 1271 | int res = |
| 1272 | REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); |
| 1273 | if (res == 0) { |
| 1274 | if (result) { |
| 1275 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 1276 | if (*result) write_hostent(ctx, *result); |
| 1277 | } |
| 1278 | if (h_errnop) |
| 1279 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); |
| 1280 | } |
| 1281 | return res; |
| 1282 | } |
| 1283 | #define INIT_GETHOSTBYNAME_R \ |
| 1284 | INTERCEPT_FUNCTION(gethostent_r); \ |
| 1285 | INTERCEPT_FUNCTION(gethostbyaddr_r); \ |
| 1286 | INTERCEPT_FUNCTION(gethostbyname_r); \ |
| 1287 | INTERCEPT_FUNCTION(gethostbyname2_r); |
| 1288 | #else |
| 1289 | #define INIT_GETHOSTBYNAME_R |
| 1290 | #endif |
| 1291 | |
Evgeniy Stepanov | f32be42 | 2013-05-23 11:38:08 +0000 | [diff] [blame] | 1292 | #if SANITIZER_INTERCEPT_GETSOCKOPT |
| 1293 | INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, |
| 1294 | int *optlen) { |
| 1295 | void *ctx; |
| 1296 | COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, |
| 1297 | optlen); |
| 1298 | if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); |
| 1299 | int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); |
| 1300 | if (res == 0) |
| 1301 | if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); |
| 1302 | return res; |
| 1303 | } |
| 1304 | #define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); |
| 1305 | #else |
| 1306 | #define INIT_GETSOCKOPT |
| 1307 | #endif |
| 1308 | |
Evgeniy Stepanov | 9d1525e | 2013-05-29 09:09:58 +0000 | [diff] [blame] | 1309 | #if SANITIZER_INTERCEPT_ACCEPT |
| 1310 | INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { |
| 1311 | void *ctx; |
| 1312 | COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); |
| 1313 | unsigned addrlen0; |
| 1314 | if (addrlen) { |
| 1315 | COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); |
| 1316 | addrlen0 = *addrlen; |
| 1317 | } |
| 1318 | int fd2 = REAL(accept)(fd, addr, addrlen); |
| 1319 | if (fd2 >= 0) { |
| 1320 | if (fd >= 0) |
| 1321 | COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); |
| 1322 | if (addr && addrlen) |
| 1323 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); |
| 1324 | } |
| 1325 | return fd2; |
| 1326 | } |
| 1327 | #define INIT_ACCEPT INTERCEPT_FUNCTION(accept); |
| 1328 | #else |
| 1329 | #define INIT_ACCEPT |
| 1330 | #endif |
| 1331 | |
| 1332 | #if SANITIZER_INTERCEPT_ACCEPT4 |
| 1333 | INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { |
| 1334 | void *ctx; |
| 1335 | COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); |
| 1336 | unsigned addrlen0; |
| 1337 | if (addrlen) { |
| 1338 | COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); |
| 1339 | addrlen0 = *addrlen; |
| 1340 | } |
| 1341 | int fd2 = REAL(accept4)(fd, addr, addrlen, f); |
| 1342 | if (fd2 >= 0) { |
| 1343 | if (fd >= 0) |
| 1344 | COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); |
| 1345 | if (addr && addrlen) |
| 1346 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); |
| 1347 | } |
| 1348 | return fd2; |
| 1349 | } |
| 1350 | #define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); |
| 1351 | #else |
| 1352 | #define INIT_ACCEPT4 |
| 1353 | #endif |
| 1354 | |
Evgeniy Stepanov | c87088b | 2013-05-29 10:03:11 +0000 | [diff] [blame] | 1355 | #if SANITIZER_INTERCEPT_MODF |
| 1356 | INTERCEPTOR(double, modf, double x, double *iptr) { |
| 1357 | void *ctx; |
| 1358 | COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); |
| 1359 | double res = REAL(modf)(x, iptr); |
| 1360 | if (iptr) { |
| 1361 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); |
| 1362 | } |
| 1363 | return res; |
| 1364 | } |
| 1365 | INTERCEPTOR(float, modff, float x, float *iptr) { |
| 1366 | void *ctx; |
| 1367 | COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); |
| 1368 | float res = REAL(modff)(x, iptr); |
| 1369 | if (iptr) { |
| 1370 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); |
| 1371 | } |
| 1372 | return res; |
| 1373 | } |
| 1374 | INTERCEPTOR(long double, modfl, long double x, long double *iptr) { |
| 1375 | void *ctx; |
| 1376 | COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); |
| 1377 | long double res = REAL(modfl)(x, iptr); |
| 1378 | if (iptr) { |
| 1379 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); |
| 1380 | } |
| 1381 | return res; |
| 1382 | } |
| 1383 | #define INIT_MODF \ |
| 1384 | INTERCEPT_FUNCTION(modf); \ |
| 1385 | INTERCEPT_FUNCTION(modff); \ |
| 1386 | INTERCEPT_FUNCTION(modfl); |
| 1387 | #else |
| 1388 | #define INIT_MODF |
| 1389 | #endif |
| 1390 | |
Evgeniy Stepanov | 9666d89 | 2013-05-29 11:30:00 +0000 | [diff] [blame] | 1391 | #if SANITIZER_INTERCEPT_RECVMSG |
Evgeniy Stepanov | eb7c24b | 2013-06-26 09:16:45 +0000 | [diff] [blame] | 1392 | static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, |
| 1393 | SSIZE_T maxlen) { |
Evgeniy Stepanov | 9666d89 | 2013-05-29 11:30:00 +0000 | [diff] [blame] | 1394 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); |
Evgeniy Stepanov | ab8bf09 | 2013-10-17 11:32:30 +0000 | [diff] [blame] | 1395 | if (msg->msg_name && msg->msg_namelen) |
| 1396 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); |
| 1397 | if (msg->msg_iov && msg->msg_iovlen) |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 1398 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, |
| 1399 | sizeof(*msg->msg_iov) * msg->msg_iovlen); |
| 1400 | write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); |
Evgeniy Stepanov | ab8bf09 | 2013-10-17 11:32:30 +0000 | [diff] [blame] | 1401 | if (msg->msg_control && msg->msg_controllen) |
Evgeniy Stepanov | 9666d89 | 2013-05-29 11:30:00 +0000 | [diff] [blame] | 1402 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); |
| 1403 | } |
| 1404 | |
| 1405 | INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, |
| 1406 | int flags) { |
| 1407 | void *ctx; |
| 1408 | COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); |
| 1409 | SSIZE_T res = REAL(recvmsg)(fd, msg, flags); |
| 1410 | if (res >= 0) { |
| 1411 | if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 1412 | if (msg) write_msghdr(ctx, msg, res); |
Evgeniy Stepanov | 9666d89 | 2013-05-29 11:30:00 +0000 | [diff] [blame] | 1413 | } |
| 1414 | return res; |
| 1415 | } |
| 1416 | #define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); |
| 1417 | #else |
| 1418 | #define INIT_RECVMSG |
| 1419 | #endif |
| 1420 | |
Evgeniy Stepanov | bc33e13 | 2013-05-29 11:49:25 +0000 | [diff] [blame] | 1421 | #if SANITIZER_INTERCEPT_GETPEERNAME |
| 1422 | INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { |
| 1423 | void *ctx; |
| 1424 | COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); |
| 1425 | unsigned addr_sz; |
| 1426 | if (addrlen) addr_sz = *addrlen; |
| 1427 | int res = REAL(getpeername)(sockfd, addr, addrlen); |
| 1428 | if (!res && addr && addrlen) |
| 1429 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); |
| 1430 | return res; |
| 1431 | } |
| 1432 | #define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); |
| 1433 | #else |
| 1434 | #define INIT_GETPEERNAME |
| 1435 | #endif |
| 1436 | |
Evgeniy Stepanov | 359d7fc | 2013-06-24 14:25:33 +0000 | [diff] [blame] | 1437 | #if SANITIZER_INTERCEPT_SYSINFO |
| 1438 | INTERCEPTOR(int, sysinfo, void *info) { |
| 1439 | void *ctx; |
| 1440 | COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); |
| 1441 | int res = REAL(sysinfo)(info); |
| 1442 | if (!res && info) |
| 1443 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); |
| 1444 | return res; |
| 1445 | } |
| 1446 | #define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); |
| 1447 | #else |
| 1448 | #define INIT_SYSINFO |
| 1449 | #endif |
| 1450 | |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1451 | #if SANITIZER_INTERCEPT_READDIR |
Evgeniy Stepanov | a0379b5 | 2013-06-27 09:37:27 +0000 | [diff] [blame] | 1452 | INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1453 | void *ctx; |
| 1454 | COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); |
Evgeniy Stepanov | a0379b5 | 2013-06-27 09:37:27 +0000 | [diff] [blame] | 1455 | __sanitizer_dirent *res = REAL(readdir)(dirp); |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1456 | if (res) |
Evgeniy Stepanov | a0379b5 | 2013-06-27 09:37:27 +0000 | [diff] [blame] | 1457 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1458 | return res; |
| 1459 | } |
| 1460 | |
Alexey Samsonov | 52d08d8 | 2013-06-28 12:13:31 +0000 | [diff] [blame] | 1461 | INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, |
| 1462 | __sanitizer_dirent **result) { |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1463 | void *ctx; |
| 1464 | COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); |
| 1465 | int res = REAL(readdir_r)(dirp, entry, result); |
| 1466 | if (!res) { |
Chandler Carruth | 5a482cd | 2013-07-11 18:51:40 +0000 | [diff] [blame] | 1467 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 1468 | if (*result) |
| 1469 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1470 | } |
| 1471 | return res; |
| 1472 | } |
| 1473 | |
| 1474 | #define INIT_READDIR \ |
| 1475 | INTERCEPT_FUNCTION(readdir); \ |
| 1476 | INTERCEPT_FUNCTION(readdir_r); |
| 1477 | #else |
| 1478 | #define INIT_READDIR |
| 1479 | #endif |
| 1480 | |
| 1481 | #if SANITIZER_INTERCEPT_READDIR64 |
Evgeniy Stepanov | a0379b5 | 2013-06-27 09:37:27 +0000 | [diff] [blame] | 1482 | INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1483 | void *ctx; |
| 1484 | COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); |
Evgeniy Stepanov | a0379b5 | 2013-06-27 09:37:27 +0000 | [diff] [blame] | 1485 | __sanitizer_dirent64 *res = REAL(readdir64)(dirp); |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1486 | if (res) |
Evgeniy Stepanov | a0379b5 | 2013-06-27 09:37:27 +0000 | [diff] [blame] | 1487 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1488 | return res; |
| 1489 | } |
| 1490 | |
Alexey Samsonov | 52d08d8 | 2013-06-28 12:13:31 +0000 | [diff] [blame] | 1491 | INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, |
| 1492 | __sanitizer_dirent64 **result) { |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1493 | void *ctx; |
| 1494 | COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); |
| 1495 | int res = REAL(readdir64_r)(dirp, entry, result); |
| 1496 | if (!res) { |
Chandler Carruth | 5a482cd | 2013-07-11 18:51:40 +0000 | [diff] [blame] | 1497 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 1498 | if (*result) |
| 1499 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1500 | } |
| 1501 | return res; |
| 1502 | } |
| 1503 | #define INIT_READDIR64 \ |
| 1504 | INTERCEPT_FUNCTION(readdir64); \ |
| 1505 | INTERCEPT_FUNCTION(readdir64_r); |
| 1506 | #else |
| 1507 | #define INIT_READDIR64 |
| 1508 | #endif |
| 1509 | |
Evgeniy Stepanov | 341b9e6 | 2013-06-28 11:02:43 +0000 | [diff] [blame] | 1510 | #if SANITIZER_INTERCEPT_PTRACE |
| 1511 | INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { |
| 1512 | void *ctx; |
| 1513 | COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); |
| 1514 | |
| 1515 | if (data) { |
| 1516 | if (request == ptrace_setregs) |
| 1517 | COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); |
| 1518 | else if (request == ptrace_setfpregs) |
| 1519 | COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); |
| 1520 | else if (request == ptrace_setfpxregs) |
| 1521 | COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); |
| 1522 | else if (request == ptrace_setsiginfo) |
| 1523 | COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); |
| 1524 | else if (request == ptrace_setregset) { |
| 1525 | __sanitizer_iovec *iov = (__sanitizer_iovec *)data; |
| 1526 | COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); |
| 1527 | } |
| 1528 | } |
| 1529 | |
| 1530 | uptr res = REAL(ptrace)(request, pid, addr, data); |
| 1531 | |
| 1532 | if (!res && data) { |
| 1533 | // Note that PEEK* requests assing different meaning to the return value. |
| 1534 | // This function does not handle them (nor does it need to). |
| 1535 | if (request == ptrace_getregs) |
| 1536 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); |
| 1537 | else if (request == ptrace_getfpregs) |
| 1538 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); |
| 1539 | else if (request == ptrace_getfpxregs) |
| 1540 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); |
| 1541 | else if (request == ptrace_getsiginfo) |
| 1542 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); |
| 1543 | else if (request == ptrace_getregset) { |
| 1544 | __sanitizer_iovec *iov = (__sanitizer_iovec *)data; |
| 1545 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); |
| 1546 | } |
| 1547 | } |
| 1548 | return res; |
| 1549 | } |
| 1550 | |
| 1551 | #define INIT_PTRACE \ |
| 1552 | INTERCEPT_FUNCTION(ptrace); |
| 1553 | #else |
| 1554 | #define INIT_PTRACE |
| 1555 | #endif |
| 1556 | |
Evgeniy Stepanov | 3cae604 | 2013-07-02 09:23:45 +0000 | [diff] [blame] | 1557 | #if SANITIZER_INTERCEPT_SETLOCALE |
| 1558 | INTERCEPTOR(char *, setlocale, int category, char *locale) { |
| 1559 | void *ctx; |
| 1560 | COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); |
| 1561 | if (locale) |
| 1562 | COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); |
Evgeniy Stepanov | 8014489 | 2013-07-02 13:34:44 +0000 | [diff] [blame] | 1563 | char *res = REAL(setlocale)(category, locale); |
Evgeniy Stepanov | 3cae604 | 2013-07-02 09:23:45 +0000 | [diff] [blame] | 1564 | if (res) |
| 1565 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1566 | return res; |
| 1567 | } |
| 1568 | |
| 1569 | #define INIT_SETLOCALE \ |
| 1570 | INTERCEPT_FUNCTION(setlocale); |
| 1571 | #else |
| 1572 | #define INIT_SETLOCALE |
| 1573 | #endif |
| 1574 | |
Evgeniy Stepanov | 8014489 | 2013-07-02 13:34:44 +0000 | [diff] [blame] | 1575 | #if SANITIZER_INTERCEPT_GETCWD |
| 1576 | INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { |
| 1577 | void *ctx; |
| 1578 | COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); |
| 1579 | char *res = REAL(getcwd)(buf, size); |
| 1580 | if (res) |
| 1581 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1582 | return res; |
| 1583 | } |
| 1584 | #define INIT_GETCWD \ |
| 1585 | INTERCEPT_FUNCTION(getcwd); |
| 1586 | #else |
| 1587 | #define INIT_GETCWD |
| 1588 | #endif |
| 1589 | |
| 1590 | #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME |
Dmitry Vyukov | 1d02bea | 2013-10-02 14:04:23 +0000 | [diff] [blame] | 1591 | INTERCEPTOR(char *, get_current_dir_name, int fake) { |
Evgeniy Stepanov | 8014489 | 2013-07-02 13:34:44 +0000 | [diff] [blame] | 1592 | void *ctx; |
Dmitry Vyukov | 1d02bea | 2013-10-02 14:04:23 +0000 | [diff] [blame] | 1593 | COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); |
| 1594 | char *res = REAL(get_current_dir_name)(fake); |
Evgeniy Stepanov | 8014489 | 2013-07-02 13:34:44 +0000 | [diff] [blame] | 1595 | if (res) |
| 1596 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1597 | return res; |
| 1598 | } |
| 1599 | |
| 1600 | #define INIT_GET_CURRENT_DIR_NAME \ |
| 1601 | INTERCEPT_FUNCTION(get_current_dir_name); |
| 1602 | #else |
| 1603 | #define INIT_GET_CURRENT_DIR_NAME |
| 1604 | #endif |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 1605 | |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1606 | #if SANITIZER_INTERCEPT_STRTOIMAX |
| 1607 | INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { |
| 1608 | void *ctx; |
| 1609 | COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); |
| 1610 | INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); |
| 1611 | if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); |
| 1612 | return res; |
| 1613 | } |
| 1614 | |
| 1615 | INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { |
| 1616 | void *ctx; |
| 1617 | COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); |
| 1618 | INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); |
| 1619 | if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); |
| 1620 | return res; |
| 1621 | } |
| 1622 | |
| 1623 | #define INIT_STRTOIMAX \ |
| 1624 | INTERCEPT_FUNCTION(strtoimax); \ |
| 1625 | INTERCEPT_FUNCTION(strtoumax); |
| 1626 | #else |
| 1627 | #define INIT_STRTOIMAX |
| 1628 | #endif |
| 1629 | |
| 1630 | #if SANITIZER_INTERCEPT_MBSTOWCS |
| 1631 | INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { |
| 1632 | void *ctx; |
| 1633 | COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); |
| 1634 | SIZE_T res = REAL(mbstowcs)(dest, src, len); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1635 | if (res != (SIZE_T) - 1 && dest) { |
Alexey Samsonov | e43d210 | 2013-07-12 11:59:58 +0000 | [diff] [blame] | 1636 | SIZE_T write_cnt = res + (res < len); |
| 1637 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); |
| 1638 | } |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1639 | return res; |
| 1640 | } |
| 1641 | |
| 1642 | INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, |
| 1643 | void *ps) { |
| 1644 | void *ctx; |
| 1645 | COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1646 | if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); |
| 1647 | if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); |
Chandler Carruth | 5a482cd | 2013-07-11 18:51:40 +0000 | [diff] [blame] | 1648 | SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1649 | if (res != (SIZE_T)(-1) && dest && src) { |
| 1650 | // This function, and several others, may or may not write the terminating |
| 1651 | // \0 character. They write it iff they clear *src. |
| 1652 | SIZE_T write_cnt = res + !*src; |
Alexey Samsonov | e43d210 | 2013-07-12 11:59:58 +0000 | [diff] [blame] | 1653 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); |
| 1654 | } |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1655 | return res; |
| 1656 | } |
| 1657 | |
| 1658 | #define INIT_MBSTOWCS \ |
| 1659 | INTERCEPT_FUNCTION(mbstowcs); \ |
| 1660 | INTERCEPT_FUNCTION(mbsrtowcs); |
| 1661 | #else |
| 1662 | #define INIT_MBSTOWCS |
| 1663 | #endif |
| 1664 | |
| 1665 | #if SANITIZER_INTERCEPT_MBSNRTOWCS |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1666 | INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, |
| 1667 | SIZE_T len, void *ps) { |
| 1668 | void *ctx; |
| 1669 | COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1670 | if (src) { |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1671 | COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1672 | if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1673 | } |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1674 | if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1675 | SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1676 | if (res != (SIZE_T)(-1) && dest && src) { |
| 1677 | SIZE_T write_cnt = res + !*src; |
Alexey Samsonov | e43d210 | 2013-07-12 11:59:58 +0000 | [diff] [blame] | 1678 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); |
| 1679 | } |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1680 | return res; |
| 1681 | } |
| 1682 | |
| 1683 | #define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); |
| 1684 | #else |
| 1685 | #define INIT_MBSNRTOWCS |
| 1686 | #endif |
| 1687 | |
| 1688 | #if SANITIZER_INTERCEPT_WCSTOMBS |
| 1689 | INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { |
| 1690 | void *ctx; |
| 1691 | COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); |
| 1692 | SIZE_T res = REAL(wcstombs)(dest, src, len); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1693 | if (res != (SIZE_T) - 1 && dest) { |
Alexey Samsonov | e43d210 | 2013-07-12 11:59:58 +0000 | [diff] [blame] | 1694 | SIZE_T write_cnt = res + (res < len); |
| 1695 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); |
| 1696 | } |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1697 | return res; |
| 1698 | } |
| 1699 | |
| 1700 | INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, |
| 1701 | void *ps) { |
| 1702 | void *ctx; |
| 1703 | COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1704 | if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); |
| 1705 | if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); |
Chandler Carruth | 5a482cd | 2013-07-11 18:51:40 +0000 | [diff] [blame] | 1706 | SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1707 | if (res != (SIZE_T) - 1 && dest && src) { |
| 1708 | SIZE_T write_cnt = res + !*src; |
Alexey Samsonov | e43d210 | 2013-07-12 11:59:58 +0000 | [diff] [blame] | 1709 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); |
| 1710 | } |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1711 | return res; |
| 1712 | } |
| 1713 | |
| 1714 | #define INIT_WCSTOMBS \ |
| 1715 | INTERCEPT_FUNCTION(wcstombs); \ |
| 1716 | INTERCEPT_FUNCTION(wcsrtombs); |
| 1717 | #else |
| 1718 | #define INIT_WCSTOMBS |
| 1719 | #endif |
| 1720 | |
| 1721 | #if SANITIZER_INTERCEPT_WCSNRTOMBS |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1722 | INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, |
| 1723 | SIZE_T len, void *ps) { |
| 1724 | void *ctx; |
| 1725 | COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1726 | if (src) { |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1727 | COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1728 | if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1729 | } |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1730 | if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1731 | SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); |
Alexey Samsonov | 098c58f | 2013-07-12 12:33:23 +0000 | [diff] [blame] | 1732 | if (res != (SIZE_T) - 1 && dest && src) { |
| 1733 | SIZE_T write_cnt = res + !*src; |
Alexey Samsonov | e43d210 | 2013-07-12 11:59:58 +0000 | [diff] [blame] | 1734 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); |
| 1735 | } |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 1736 | return res; |
| 1737 | } |
| 1738 | |
| 1739 | #define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); |
| 1740 | #else |
| 1741 | #define INIT_WCSNRTOMBS |
| 1742 | #endif |
| 1743 | |
Evgeniy Stepanov | ea72768 | 2013-07-04 14:03:31 +0000 | [diff] [blame] | 1744 | |
| 1745 | #if SANITIZER_INTERCEPT_TCGETATTR |
| 1746 | INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { |
| 1747 | void *ctx; |
| 1748 | COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); |
| 1749 | int res = REAL(tcgetattr)(fd, termios_p); |
| 1750 | if (!res && termios_p) |
| 1751 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); |
| 1752 | return res; |
| 1753 | } |
| 1754 | |
| 1755 | #define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); |
| 1756 | #else |
| 1757 | #define INIT_TCGETATTR |
| 1758 | #endif |
| 1759 | |
Evgeniy Stepanov | 12eb79d | 2013-07-09 09:53:37 +0000 | [diff] [blame] | 1760 | |
| 1761 | #if SANITIZER_INTERCEPT_REALPATH |
| 1762 | INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { |
| 1763 | void *ctx; |
| 1764 | COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); |
| 1765 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); |
| 1766 | |
| 1767 | // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest |
| 1768 | // version of a versioned symbol. For realpath(), this gives us something |
| 1769 | // (called __old_realpath) that does not handle NULL in the second argument. |
| 1770 | // Handle it as part of the interceptor. |
| 1771 | char *allocated_path = 0; |
| 1772 | if (!resolved_path) |
| 1773 | allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); |
| 1774 | |
| 1775 | char *res = REAL(realpath)(path, resolved_path); |
| 1776 | if (allocated_path && !res) |
| 1777 | WRAP(free)(allocated_path); |
| 1778 | if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1779 | return res; |
| 1780 | } |
| 1781 | #define INIT_REALPATH INTERCEPT_FUNCTION(realpath); |
| 1782 | #else |
| 1783 | #define INIT_REALPATH |
| 1784 | #endif |
| 1785 | |
| 1786 | #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME |
| 1787 | INTERCEPTOR(char *, canonicalize_file_name, const char *path) { |
| 1788 | void *ctx; |
| 1789 | COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); |
| 1790 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); |
| 1791 | char *res = REAL(canonicalize_file_name)(path); |
| 1792 | if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1793 | return res; |
| 1794 | } |
| 1795 | #define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); |
| 1796 | #else |
| 1797 | #define INIT_CANONICALIZE_FILE_NAME |
| 1798 | #endif |
| 1799 | |
Evgeniy Stepanov | 5ec19bc | 2013-07-30 12:46:59 +0000 | [diff] [blame] | 1800 | #if SANITIZER_INTERCEPT_CONFSTR |
| 1801 | INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { |
| 1802 | void *ctx; |
| 1803 | COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); |
| 1804 | SIZE_T res = REAL(confstr)(name, buf, len); |
| 1805 | if (buf && res) |
| 1806 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); |
| 1807 | return res; |
| 1808 | } |
| 1809 | #define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); |
| 1810 | #else |
| 1811 | #define INIT_CONFSTR |
| 1812 | #endif |
| 1813 | |
Evgeniy Stepanov | 84ba74c | 2013-08-07 09:10:16 +0000 | [diff] [blame] | 1814 | #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY |
| 1815 | INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { |
| 1816 | void *ctx; |
| 1817 | COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); |
| 1818 | int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); |
| 1819 | if (mask && !res) |
| 1820 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); |
| 1821 | return res; |
| 1822 | } |
| 1823 | #define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); |
| 1824 | #else |
| 1825 | #define INIT_SCHED_GETAFFINITY |
| 1826 | #endif |
| 1827 | |
Evgeniy Stepanov | 1204979 | 2013-08-08 11:44:05 +0000 | [diff] [blame] | 1828 | #if SANITIZER_INTERCEPT_STRERROR |
| 1829 | INTERCEPTOR(char *, strerror, int errnum) { |
| 1830 | void *ctx; |
| 1831 | COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); |
| 1832 | char *res = REAL(strerror)(errnum); |
| 1833 | if (res) |
Dmitry Vyukov | 3e5c47d | 2013-10-21 07:40:19 +0000 | [diff] [blame] | 1834 | COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
Evgeniy Stepanov | 1204979 | 2013-08-08 11:44:05 +0000 | [diff] [blame] | 1835 | return res; |
| 1836 | } |
| 1837 | #define INIT_STRERROR INTERCEPT_FUNCTION(strerror); |
| 1838 | #else |
| 1839 | #define INIT_STRERROR |
| 1840 | #endif |
| 1841 | |
| 1842 | #if SANITIZER_INTERCEPT_STRERROR_R |
| 1843 | INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { |
| 1844 | void *ctx; |
| 1845 | COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); |
| 1846 | char *res = REAL(strerror_r)(errnum, buf, buflen); |
| 1847 | // There are 2 versions of strerror_r: |
| 1848 | // * POSIX version returns 0 on success, negative error code on failure, |
| 1849 | // writes message to buf. |
| 1850 | // * GNU version returns message pointer, which points to either buf or some |
| 1851 | // static storage. |
Evgeniy Stepanov | d9a5e24 | 2013-09-09 08:58:54 +0000 | [diff] [blame] | 1852 | SIZE_T posix_res = (SIZE_T)res; |
| 1853 | if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { |
Evgeniy Stepanov | 1204979 | 2013-08-08 11:44:05 +0000 | [diff] [blame] | 1854 | // POSIX version. Spec is not clear on whether buf is NULL-terminated. |
Evgeniy Stepanov | d9a5e24 | 2013-09-09 08:58:54 +0000 | [diff] [blame] | 1855 | // At least on OSX, buf contents are valid even when the call fails. |
Evgeniy Stepanov | 1204979 | 2013-08-08 11:44:05 +0000 | [diff] [blame] | 1856 | SIZE_T sz = internal_strnlen(buf, buflen); |
| 1857 | if (sz < buflen) ++sz; |
| 1858 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); |
Evgeniy Stepanov | d9a5e24 | 2013-09-09 08:58:54 +0000 | [diff] [blame] | 1859 | } else { |
Evgeniy Stepanov | 1204979 | 2013-08-08 11:44:05 +0000 | [diff] [blame] | 1860 | // GNU version. |
| 1861 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 1862 | } |
| 1863 | return res; |
| 1864 | } |
| 1865 | #define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r); |
| 1866 | #else |
| 1867 | #define INIT_STRERROR_R |
| 1868 | #endif |
| 1869 | |
Evgeniy Stepanov | 224226c | 2013-08-08 13:57:15 +0000 | [diff] [blame] | 1870 | #if SANITIZER_INTERCEPT_SCANDIR |
| 1871 | typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); |
| 1872 | typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, |
| 1873 | const struct __sanitizer_dirent **); |
| 1874 | |
| 1875 | static THREADLOCAL void *scandir_ctx; |
| 1876 | static THREADLOCAL scandir_filter_f scandir_filter; |
| 1877 | static THREADLOCAL scandir_compar_f scandir_compar; |
| 1878 | |
| 1879 | static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { |
| 1880 | COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); |
| 1881 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); |
| 1882 | return scandir_filter(dir); |
| 1883 | } |
| 1884 | |
| 1885 | static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, |
| 1886 | const struct __sanitizer_dirent **b) { |
| 1887 | COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); |
| 1888 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); |
| 1889 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); |
| 1890 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); |
| 1891 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); |
| 1892 | return scandir_compar(a, b); |
| 1893 | } |
| 1894 | |
| 1895 | INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, |
| 1896 | scandir_filter_f filter, scandir_compar_f compar) { |
| 1897 | void *ctx; |
| 1898 | COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); |
| 1899 | if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); |
Alexey Samsonov | 5bd2174 | 2013-08-23 07:43:56 +0000 | [diff] [blame] | 1900 | CHECK_EQ(0, scandir_ctx); |
Evgeniy Stepanov | 224226c | 2013-08-08 13:57:15 +0000 | [diff] [blame] | 1901 | scandir_ctx = ctx; |
| 1902 | scandir_filter = filter; |
| 1903 | scandir_compar = compar; |
| 1904 | int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, |
| 1905 | compar ? wrapped_scandir_compar : 0); |
| 1906 | scandir_ctx = 0; |
| 1907 | scandir_filter = 0; |
| 1908 | scandir_compar = 0; |
| 1909 | if (namelist && res > 0) { |
| 1910 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); |
| 1911 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); |
| 1912 | for (int i = 0; i < res; ++i) |
| 1913 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], |
| 1914 | (*namelist)[i]->d_reclen); |
| 1915 | } |
| 1916 | return res; |
| 1917 | } |
| 1918 | #define INIT_SCANDIR INTERCEPT_FUNCTION(scandir); |
| 1919 | #else |
| 1920 | #define INIT_SCANDIR |
| 1921 | #endif |
| 1922 | |
| 1923 | #if SANITIZER_INTERCEPT_SCANDIR64 |
| 1924 | typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); |
| 1925 | typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, |
| 1926 | const struct __sanitizer_dirent64 **); |
| 1927 | |
| 1928 | static THREADLOCAL void *scandir64_ctx; |
| 1929 | static THREADLOCAL scandir64_filter_f scandir64_filter; |
| 1930 | static THREADLOCAL scandir64_compar_f scandir64_compar; |
| 1931 | |
| 1932 | static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { |
| 1933 | COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); |
| 1934 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); |
| 1935 | return scandir64_filter(dir); |
| 1936 | } |
| 1937 | |
| 1938 | static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, |
| 1939 | const struct __sanitizer_dirent64 **b) { |
| 1940 | COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); |
| 1941 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); |
| 1942 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); |
| 1943 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); |
| 1944 | COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); |
| 1945 | return scandir64_compar(a, b); |
| 1946 | } |
| 1947 | |
| 1948 | INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, |
| 1949 | scandir64_filter_f filter, scandir64_compar_f compar) { |
| 1950 | void *ctx; |
| 1951 | COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); |
| 1952 | if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); |
Alexey Samsonov | 5bd2174 | 2013-08-23 07:43:56 +0000 | [diff] [blame] | 1953 | CHECK_EQ(0, scandir64_ctx); |
Evgeniy Stepanov | 224226c | 2013-08-08 13:57:15 +0000 | [diff] [blame] | 1954 | scandir64_ctx = ctx; |
| 1955 | scandir64_filter = filter; |
| 1956 | scandir64_compar = compar; |
| 1957 | int res = |
| 1958 | REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, |
| 1959 | compar ? wrapped_scandir64_compar : 0); |
| 1960 | scandir64_ctx = 0; |
| 1961 | scandir64_filter = 0; |
| 1962 | scandir64_compar = 0; |
| 1963 | if (namelist && res > 0) { |
| 1964 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); |
| 1965 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); |
| 1966 | for (int i = 0; i < res; ++i) |
| 1967 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], |
| 1968 | (*namelist)[i]->d_reclen); |
| 1969 | } |
| 1970 | return res; |
| 1971 | } |
| 1972 | #define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64); |
| 1973 | #else |
| 1974 | #define INIT_SCANDIR64 |
| 1975 | #endif |
| 1976 | |
Evgeniy Stepanov | edff34b | 2013-08-12 11:01:40 +0000 | [diff] [blame] | 1977 | #if SANITIZER_INTERCEPT_GETGROUPS |
| 1978 | INTERCEPTOR(int, getgroups, int size, u32 *lst) { |
| 1979 | void *ctx; |
| 1980 | COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); |
| 1981 | int res = REAL(getgroups)(size, lst); |
| 1982 | if (res && lst) |
| 1983 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); |
| 1984 | return res; |
| 1985 | } |
| 1986 | #define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups); |
| 1987 | #else |
| 1988 | #define INIT_GETGROUPS |
| 1989 | #endif |
| 1990 | |
Evgeniy Stepanov | e18e3f0 | 2013-08-12 13:19:53 +0000 | [diff] [blame] | 1991 | #if SANITIZER_INTERCEPT_POLL |
| 1992 | static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, |
| 1993 | __sanitizer_nfds_t nfds) { |
| 1994 | for (unsigned i = 0; i < nfds; ++i) { |
| 1995 | COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); |
| 1996 | COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); |
| 1997 | } |
| 1998 | } |
| 1999 | |
| 2000 | static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, |
| 2001 | __sanitizer_nfds_t nfds) { |
| 2002 | for (unsigned i = 0; i < nfds; ++i) |
Alexey Samsonov | 5bd2174 | 2013-08-23 07:43:56 +0000 | [diff] [blame] | 2003 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, |
| 2004 | sizeof(fds[i].revents)); |
Evgeniy Stepanov | e18e3f0 | 2013-08-12 13:19:53 +0000 | [diff] [blame] | 2005 | } |
| 2006 | |
| 2007 | INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, |
| 2008 | int timeout) { |
| 2009 | void *ctx; |
| 2010 | COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); |
| 2011 | if (fds && nfds) read_pollfd(ctx, fds, nfds); |
| 2012 | int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); |
| 2013 | if (fds && nfds) write_pollfd(ctx, fds, nfds); |
| 2014 | return res; |
| 2015 | } |
| 2016 | #define INIT_POLL INTERCEPT_FUNCTION(poll); |
| 2017 | #else |
| 2018 | #define INIT_POLL |
| 2019 | #endif |
| 2020 | |
| 2021 | #if SANITIZER_INTERCEPT_PPOLL |
| 2022 | INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, |
Evgeniy Stepanov | b32d1bf | 2013-08-27 11:10:04 +0000 | [diff] [blame] | 2023 | void *timeout_ts, __sanitizer_sigset_t *sigmask) { |
Evgeniy Stepanov | e18e3f0 | 2013-08-12 13:19:53 +0000 | [diff] [blame] | 2024 | void *ctx; |
| 2025 | COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); |
| 2026 | if (fds && nfds) read_pollfd(ctx, fds, nfds); |
| 2027 | if (timeout_ts) |
| 2028 | COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); |
Evgeniy Stepanov | b32d1bf | 2013-08-27 11:10:04 +0000 | [diff] [blame] | 2029 | // FIXME: read sigmask when all of sigemptyset, etc are intercepted. |
Evgeniy Stepanov | e18e3f0 | 2013-08-12 13:19:53 +0000 | [diff] [blame] | 2030 | int res = |
| 2031 | COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); |
| 2032 | if (fds && nfds) write_pollfd(ctx, fds, nfds); |
| 2033 | return res; |
| 2034 | } |
| 2035 | #define INIT_PPOLL INTERCEPT_FUNCTION(ppoll); |
| 2036 | #else |
| 2037 | #define INIT_PPOLL |
| 2038 | #endif |
| 2039 | |
Evgeniy Stepanov | c5a3855 | 2013-09-24 14:38:22 +0000 | [diff] [blame] | 2040 | #if SANITIZER_INTERCEPT_WORDEXP |
| 2041 | INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { |
| 2042 | void *ctx; |
| 2043 | COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); |
| 2044 | if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); |
| 2045 | int res = REAL(wordexp)(s, p, flags); |
| 2046 | if (!res && p) { |
| 2047 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); |
| 2048 | if (p->we_wordc) |
| 2049 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, |
| 2050 | sizeof(*p->we_wordv) * p->we_wordc); |
| 2051 | for (uptr i = 0; i < p->we_wordc; ++i) { |
| 2052 | char *w = p->we_wordv[i]; |
| 2053 | if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); |
| 2054 | } |
| 2055 | } |
| 2056 | return res; |
| 2057 | } |
| 2058 | #define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp); |
| 2059 | #else |
| 2060 | #define INIT_WORDEXP |
| 2061 | #endif |
| 2062 | |
Evgeniy Stepanov | 9a949a8 | 2013-09-25 14:47:43 +0000 | [diff] [blame] | 2063 | #if SANITIZER_INTERCEPT_SIGWAIT |
| 2064 | INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { |
| 2065 | void *ctx; |
| 2066 | COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); |
| 2067 | // FIXME: read sigset_t when all of sigemptyset, etc are intercepted |
| 2068 | int res = REAL(sigwait)(set, sig); |
| 2069 | if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); |
| 2070 | return res; |
| 2071 | } |
| 2072 | #define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait); |
| 2073 | #else |
| 2074 | #define INIT_SIGWAIT |
| 2075 | #endif |
| 2076 | |
| 2077 | #if SANITIZER_INTERCEPT_SIGWAITINFO |
| 2078 | INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { |
| 2079 | void *ctx; |
| 2080 | COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); |
| 2081 | // FIXME: read sigset_t when all of sigemptyset, etc are intercepted |
| 2082 | int res = REAL(sigwaitinfo)(set, info); |
| 2083 | if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); |
| 2084 | return res; |
| 2085 | } |
| 2086 | #define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo); |
| 2087 | #else |
| 2088 | #define INIT_SIGWAITINFO |
| 2089 | #endif |
| 2090 | |
| 2091 | #if SANITIZER_INTERCEPT_SIGTIMEDWAIT |
| 2092 | INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, |
| 2093 | void *timeout) { |
| 2094 | void *ctx; |
| 2095 | COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); |
| 2096 | if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); |
| 2097 | // FIXME: read sigset_t when all of sigemptyset, etc are intercepted |
| 2098 | int res = REAL(sigtimedwait)(set, info, timeout); |
| 2099 | if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); |
| 2100 | return res; |
| 2101 | } |
| 2102 | #define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait); |
| 2103 | #else |
| 2104 | #define INIT_SIGTIMEDWAIT |
| 2105 | #endif |
| 2106 | |
| 2107 | #if SANITIZER_INTERCEPT_SIGSETOPS |
| 2108 | INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { |
| 2109 | void *ctx; |
| 2110 | COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); |
| 2111 | int res = REAL(sigemptyset)(set); |
| 2112 | if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); |
| 2113 | return res; |
| 2114 | } |
| 2115 | |
| 2116 | INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { |
| 2117 | void *ctx; |
| 2118 | COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); |
| 2119 | int res = REAL(sigfillset)(set); |
| 2120 | if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); |
| 2121 | return res; |
| 2122 | } |
| 2123 | #define INIT_SIGSETOPS \ |
| 2124 | INTERCEPT_FUNCTION(sigemptyset); \ |
| 2125 | INTERCEPT_FUNCTION(sigfillset); |
| 2126 | #else |
| 2127 | #define INIT_SIGSETOPS |
| 2128 | #endif |
| 2129 | |
| 2130 | #if SANITIZER_INTERCEPT_SIGPENDING |
| 2131 | INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { |
| 2132 | void *ctx; |
| 2133 | COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); |
| 2134 | int res = REAL(sigpending)(set); |
| 2135 | if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); |
| 2136 | return res; |
| 2137 | } |
| 2138 | #define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending); |
| 2139 | #else |
| 2140 | #define INIT_SIGPENDING |
| 2141 | #endif |
| 2142 | |
| 2143 | #if SANITIZER_INTERCEPT_SIGPROCMASK |
| 2144 | INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, |
| 2145 | __sanitizer_sigset_t *oldset) { |
| 2146 | void *ctx; |
| 2147 | COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); |
| 2148 | // FIXME: read sigset_t when all of sigemptyset, etc are intercepted |
| 2149 | int res = REAL(sigprocmask)(how, set, oldset); |
| 2150 | if (!res && oldset) |
| 2151 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); |
| 2152 | return res; |
| 2153 | } |
| 2154 | #define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask); |
| 2155 | #else |
| 2156 | #define INIT_SIGPROCMASK |
| 2157 | #endif |
| 2158 | |
Evgeniy Stepanov | 1394be1 | 2013-09-27 12:40:23 +0000 | [diff] [blame] | 2159 | #if SANITIZER_INTERCEPT_BACKTRACE |
| 2160 | INTERCEPTOR(int, backtrace, void **buffer, int size) { |
| 2161 | void *ctx; |
| 2162 | COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); |
| 2163 | int res = REAL(backtrace)(buffer, size); |
| 2164 | if (res && buffer) |
| 2165 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); |
| 2166 | return res; |
| 2167 | } |
| 2168 | |
| 2169 | INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { |
| 2170 | void *ctx; |
| 2171 | COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); |
| 2172 | if (buffer && size) |
| 2173 | COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); |
| 2174 | char ** res = REAL(backtrace_symbols)(buffer, size); |
| 2175 | if (res && size) { |
| 2176 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); |
| 2177 | for (int i = 0; i < size; ++i) |
| 2178 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); |
| 2179 | } |
| 2180 | return res; |
| 2181 | } |
| 2182 | #define INIT_BACKTRACE \ |
| 2183 | INTERCEPT_FUNCTION(backtrace); \ |
| 2184 | INTERCEPT_FUNCTION(backtrace_symbols); |
| 2185 | #else |
| 2186 | #define INIT_BACKTRACE |
| 2187 | #endif |
| 2188 | |
Dmitry Vyukov | 14dd980 | 2013-10-03 15:22:29 +0000 | [diff] [blame] | 2189 | #if SANITIZER_INTERCEPT__EXIT |
| 2190 | INTERCEPTOR(void, _exit, int status) { |
| 2191 | void *ctx; |
| 2192 | COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); |
| 2193 | int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); |
| 2194 | if (status == 0) |
| 2195 | status = status1; |
| 2196 | REAL(_exit)(status); |
| 2197 | } |
| 2198 | #define INIT__EXIT INTERCEPT_FUNCTION(_exit); |
| 2199 | #else |
| 2200 | #define INIT__EXIT |
| 2201 | #endif |
| 2202 | |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 2203 | #if SANITIZER_INTERCEPT_PHTREAD_MUTEX |
| 2204 | INTERCEPTOR(int, pthread_mutex_lock, void *m) { |
| 2205 | void *ctx; |
| 2206 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); |
| 2207 | int res = REAL(pthread_mutex_lock)(m); |
| 2208 | if (res == 0) |
| 2209 | COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); |
| 2210 | return res; |
| 2211 | } |
| 2212 | |
| 2213 | INTERCEPTOR(int, pthread_mutex_unlock, void *m) { |
| 2214 | void *ctx; |
| 2215 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); |
| 2216 | COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); |
| 2217 | return REAL(pthread_mutex_unlock)(m); |
| 2218 | } |
| 2219 | |
| 2220 | #define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock) |
| 2221 | #define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock) |
| 2222 | #else |
| 2223 | #define INIT_PTHREAD_MUTEX_LOCK |
| 2224 | #define INIT_PTHREAD_MUTEX_UNLOCK |
| 2225 | #endif |
| 2226 | |
| 2227 | #if SANITIZER_INTERCEPT_PTHREAD_COND |
| 2228 | INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { |
| 2229 | void *ctx; |
| 2230 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m); |
| 2231 | COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); |
| 2232 | COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); |
| 2233 | int res = REAL(pthread_cond_wait)(c, m); |
| 2234 | COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); |
| 2235 | return res; |
| 2236 | } |
| 2237 | |
| 2238 | INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { |
| 2239 | void *ctx; |
| 2240 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a); |
| 2241 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz); |
| 2242 | return REAL(pthread_cond_init)(c, a); |
| 2243 | } |
| 2244 | |
Alexey Samsonov | fc81346 | 2013-10-17 09:24:03 +0000 | [diff] [blame] | 2245 | INTERCEPTOR(int, pthread_cond_signal, void *c) { |
| 2246 | void *ctx; |
| 2247 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c); |
| 2248 | COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); |
| 2249 | return REAL(pthread_cond_signal)(c); |
| 2250 | } |
| 2251 | |
| 2252 | INTERCEPTOR(int, pthread_cond_broadcast, void *c) { |
| 2253 | void *ctx; |
| 2254 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c); |
| 2255 | COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); |
| 2256 | return REAL(pthread_cond_broadcast)(c); |
| 2257 | } |
| 2258 | |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 2259 | #define INIT_PTHREAD_COND_WAIT \ |
| 2260 | INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2) |
| 2261 | #define INIT_PTHREAD_COND_INIT \ |
| 2262 | INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2) |
Alexey Samsonov | fc81346 | 2013-10-17 09:24:03 +0000 | [diff] [blame] | 2263 | #define INIT_PTHREAD_COND_SIGNAL \ |
| 2264 | INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2) |
| 2265 | #define INIT_PTHREAD_COND_BROADCAST \ |
| 2266 | INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2) |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 2267 | #else |
| 2268 | #define INIT_PTHREAD_COND_WAIT |
| 2269 | #define INIT_PTHREAD_COND_INIT |
Alexey Samsonov | fc81346 | 2013-10-17 09:24:03 +0000 | [diff] [blame] | 2270 | #define INIT_PTHREAD_COND_SIGNAL |
| 2271 | #define INIT_PTHREAD_COND_BROADCAST |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 2272 | #endif |
| 2273 | |
Evgeniy Stepanov | 4d7297d | 2013-10-18 09:41:43 +0000 | [diff] [blame] | 2274 | #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R |
| 2275 | static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { |
| 2276 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); |
| 2277 | if (mnt->mnt_fsname) |
| 2278 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, |
| 2279 | REAL(strlen)(mnt->mnt_fsname) + 1); |
| 2280 | if (mnt->mnt_dir) |
| 2281 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, |
| 2282 | REAL(strlen)(mnt->mnt_dir) + 1); |
| 2283 | if (mnt->mnt_type) |
| 2284 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, |
| 2285 | REAL(strlen)(mnt->mnt_type) + 1); |
| 2286 | if (mnt->mnt_opts) |
| 2287 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, |
| 2288 | REAL(strlen)(mnt->mnt_opts) + 1); |
| 2289 | } |
| 2290 | #endif |
| 2291 | |
| 2292 | #if SANITIZER_INTERCEPT_GETMNTENT |
| 2293 | INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { |
| 2294 | void *ctx; |
| 2295 | COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); |
| 2296 | __sanitizer_mntent *res = REAL(getmntent)(fp); |
| 2297 | if (res) write_mntent(ctx, res); |
| 2298 | return res; |
| 2299 | } |
| 2300 | #define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent); |
| 2301 | #else |
| 2302 | #define INIT_GETMNTENT |
| 2303 | #endif |
| 2304 | |
| 2305 | #if SANITIZER_INTERCEPT_GETMNTENT_R |
| 2306 | INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, |
| 2307 | __sanitizer_mntent *mntbuf, char *buf, int buflen) { |
| 2308 | void *ctx; |
| 2309 | COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); |
| 2310 | __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); |
| 2311 | if (res) write_mntent(ctx, res); |
| 2312 | return res; |
| 2313 | } |
| 2314 | #define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r); |
| 2315 | #else |
| 2316 | #define INIT_GETMNTENT_R |
| 2317 | #endif |
| 2318 | |
Evgeniy Stepanov | 5cee73e | 2013-10-18 11:14:16 +0000 | [diff] [blame] | 2319 | #if SANITIZER_INTERCEPT_STATFS |
| 2320 | INTERCEPTOR(int, statfs, char *path, void *buf) { |
| 2321 | void *ctx; |
| 2322 | COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); |
| 2323 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); |
| 2324 | int res = REAL(statfs)(path, buf); |
| 2325 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); |
| 2326 | return res; |
| 2327 | } |
| 2328 | INTERCEPTOR(int, fstatfs, int fd, void *buf) { |
| 2329 | void *ctx; |
| 2330 | COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); |
| 2331 | int res = REAL(fstatfs)(fd, buf); |
| 2332 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); |
| 2333 | return res; |
| 2334 | } |
| 2335 | #define INIT_STATFS \ |
| 2336 | INTERCEPT_FUNCTION(statfs); \ |
| 2337 | INTERCEPT_FUNCTION(fstatfs); |
| 2338 | #else |
| 2339 | #define INIT_STATFS |
| 2340 | #endif |
| 2341 | |
| 2342 | #if SANITIZER_INTERCEPT_STATFS64 |
| 2343 | INTERCEPTOR(int, statfs64, char *path, void *buf) { |
| 2344 | void *ctx; |
| 2345 | COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); |
| 2346 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); |
| 2347 | int res = REAL(statfs64)(path, buf); |
| 2348 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); |
| 2349 | return res; |
| 2350 | } |
| 2351 | INTERCEPTOR(int, fstatfs64, int fd, void *buf) { |
| 2352 | void *ctx; |
| 2353 | COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); |
| 2354 | int res = REAL(fstatfs64)(fd, buf); |
| 2355 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); |
| 2356 | return res; |
| 2357 | } |
| 2358 | #define INIT_STATFS64 \ |
| 2359 | INTERCEPT_FUNCTION(statfs64); \ |
| 2360 | INTERCEPT_FUNCTION(fstatfs64); |
| 2361 | #else |
| 2362 | #define INIT_STATFS64 |
| 2363 | #endif |
| 2364 | |
| 2365 | #if SANITIZER_INTERCEPT_STATVFS |
| 2366 | INTERCEPTOR(int, statvfs, char *path, void *buf) { |
| 2367 | void *ctx; |
| 2368 | COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); |
| 2369 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); |
| 2370 | int res = REAL(statvfs)(path, buf); |
| 2371 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); |
| 2372 | return res; |
| 2373 | } |
| 2374 | INTERCEPTOR(int, fstatvfs, int fd, void *buf) { |
| 2375 | void *ctx; |
| 2376 | COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); |
| 2377 | int res = REAL(fstatvfs)(fd, buf); |
| 2378 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); |
| 2379 | return res; |
| 2380 | } |
| 2381 | #define INIT_STATVFS \ |
| 2382 | INTERCEPT_FUNCTION(statvfs); \ |
| 2383 | INTERCEPT_FUNCTION(fstatvfs); |
| 2384 | #else |
| 2385 | #define INIT_STATVFS |
| 2386 | #endif |
| 2387 | |
| 2388 | #if SANITIZER_INTERCEPT_STATVFS64 |
| 2389 | INTERCEPTOR(int, statvfs64, char *path, void *buf) { |
| 2390 | void *ctx; |
| 2391 | COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); |
| 2392 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); |
| 2393 | int res = REAL(statvfs64)(path, buf); |
| 2394 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); |
| 2395 | return res; |
| 2396 | } |
| 2397 | INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { |
| 2398 | void *ctx; |
| 2399 | COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); |
| 2400 | int res = REAL(fstatvfs64)(fd, buf); |
| 2401 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); |
| 2402 | return res; |
| 2403 | } |
| 2404 | #define INIT_STATVFS64 \ |
| 2405 | INTERCEPT_FUNCTION(statvfs64); \ |
| 2406 | INTERCEPT_FUNCTION(fstatvfs64); |
| 2407 | #else |
| 2408 | #define INIT_STATVFS64 |
| 2409 | #endif |
Evgeniy Stepanov | 4d7297d | 2013-10-18 09:41:43 +0000 | [diff] [blame] | 2410 | |
Evgeniy Stepanov | 285d458 | 2013-10-22 12:24:48 +0000 | [diff] [blame] | 2411 | #if SANITIZER_INTERCEPT_INITGROUPS |
| 2412 | INTERCEPTOR(int, initgroups, char *user, u32 group) { |
| 2413 | void *ctx; |
| 2414 | COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); |
| 2415 | if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); |
| 2416 | int res = REAL(initgroups)(user, group); |
| 2417 | return res; |
| 2418 | } |
| 2419 | #define INIT_INITGROUPS INTERCEPT_FUNCTION(initgroups); |
| 2420 | #else |
| 2421 | #define INIT_INITGROUPS |
| 2422 | #endif |
| 2423 | |
Evgeniy Stepanov | 369a9a6 | 2013-10-23 13:57:47 +0000 | [diff] [blame] | 2424 | #if SANITIZER_INTERCEPT_ETHER |
| 2425 | INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { |
| 2426 | void *ctx; |
| 2427 | COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); |
| 2428 | if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); |
| 2429 | char *res = REAL(ether_ntoa)(addr); |
| 2430 | if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 2431 | return res; |
| 2432 | } |
Evgeniy Stepanov | 369a9a6 | 2013-10-23 13:57:47 +0000 | [diff] [blame] | 2433 | INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { |
| 2434 | void *ctx; |
| 2435 | COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); |
| 2436 | if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); |
| 2437 | __sanitizer_ether_addr *res = REAL(ether_aton)(buf); |
| 2438 | if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res)); |
| 2439 | return res; |
| 2440 | } |
Evgeniy Stepanov | 369a9a6 | 2013-10-23 13:57:47 +0000 | [diff] [blame] | 2441 | INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { |
| 2442 | void *ctx; |
| 2443 | COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); |
| 2444 | if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); |
| 2445 | int res = REAL(ether_ntohost)(hostname, addr); |
| 2446 | if (!res && hostname) |
| 2447 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); |
| 2448 | return res; |
| 2449 | } |
| 2450 | INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { |
| 2451 | void *ctx; |
| 2452 | COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); |
| 2453 | if (hostname) |
| 2454 | COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); |
| 2455 | int res = REAL(ether_hostton)(hostname, addr); |
| 2456 | if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); |
| 2457 | return res; |
| 2458 | } |
| 2459 | INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, |
| 2460 | char *hostname) { |
| 2461 | void *ctx; |
| 2462 | COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); |
| 2463 | if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); |
| 2464 | int res = REAL(ether_line)(line, addr, hostname); |
| 2465 | if (!res) { |
| 2466 | if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); |
| 2467 | if (hostname) |
| 2468 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); |
| 2469 | } |
| 2470 | return res; |
| 2471 | } |
| 2472 | #define INIT_ETHER \ |
Evgeniy Stepanov | 369a9a6 | 2013-10-23 13:57:47 +0000 | [diff] [blame] | 2473 | INTERCEPT_FUNCTION(ether_ntoa); \ |
| 2474 | INTERCEPT_FUNCTION(ether_aton); \ |
| 2475 | INTERCEPT_FUNCTION(ether_ntohost); \ |
| 2476 | INTERCEPT_FUNCTION(ether_hostton); \ |
| 2477 | INTERCEPT_FUNCTION(ether_line); |
| 2478 | #else |
| 2479 | #define INIT_ETHER |
| 2480 | #endif |
| 2481 | |
Evgeniy Stepanov | 220d1f7 | 2013-10-23 15:21:10 +0000 | [diff] [blame] | 2482 | #if SANITIZER_INTERCEPT_ETHER_R |
| 2483 | INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { |
| 2484 | void *ctx; |
| 2485 | COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); |
| 2486 | if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); |
| 2487 | char *res = REAL(ether_ntoa_r)(addr, buf); |
| 2488 | if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); |
| 2489 | return res; |
| 2490 | } |
| 2491 | INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, |
| 2492 | __sanitizer_ether_addr *addr) { |
| 2493 | void *ctx; |
| 2494 | COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); |
| 2495 | if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); |
| 2496 | __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); |
| 2497 | if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); |
| 2498 | return res; |
| 2499 | } |
| 2500 | #define INIT_ETHER_R \ |
| 2501 | INTERCEPT_FUNCTION(ether_ntoa_r); \ |
| 2502 | INTERCEPT_FUNCTION(ether_aton_r); |
| 2503 | #else |
| 2504 | #define INIT_ETHER_R |
| 2505 | #endif |
| 2506 | |
Evgeniy Stepanov | 10362d6 | 2013-10-24 14:47:34 +0000 | [diff] [blame] | 2507 | #if SANITIZER_INTERCEPT_SHMCTL |
| 2508 | INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { |
| 2509 | void *ctx; |
| 2510 | COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); |
| 2511 | int res = REAL(shmctl)(shmid, cmd, buf); |
| 2512 | if (res >= 0) { |
| 2513 | unsigned sz = 0; |
| 2514 | if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) |
| 2515 | sz = struct_shmid_ds_sz; |
| 2516 | else if (cmd == shmctl_ipc_info) |
| 2517 | sz = struct_shminfo_sz; |
| 2518 | else if (cmd == shmctl_shm_info) |
| 2519 | sz = struct_shm_info_sz; |
| 2520 | if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); |
| 2521 | } |
| 2522 | return res; |
| 2523 | } |
| 2524 | #define INIT_SHMCTL INTERCEPT_FUNCTION(shmctl); |
| 2525 | #else |
| 2526 | #define INIT_SHMCTL |
| 2527 | #endif |
| 2528 | |
Evgeniy Stepanov | aff25aa | 2013-10-25 08:58:13 +0000 | [diff] [blame] | 2529 | #if SANITIZER_INTERCEPT_RANDOM_R |
| 2530 | INTERCEPTOR(int, random_r, void *buf, u32 *result) { |
| 2531 | void *ctx; |
| 2532 | COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); |
| 2533 | int res = REAL(random_r)(buf, result); |
| 2534 | if (!res && result) |
| 2535 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); |
| 2536 | return res; |
| 2537 | } |
| 2538 | #define INIT_RANDOM_R INTERCEPT_FUNCTION(random_r); |
| 2539 | #else |
| 2540 | #define INIT_RANDOM_R |
| 2541 | #endif |
| 2542 | |
Evgeniy Stepanov | e236dbb | 2013-10-25 13:01:31 +0000 | [diff] [blame] | 2543 | #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ |
| 2544 | SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED |
| 2545 | #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ |
| 2546 | INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) { \ |
| 2547 | void *ctx; \ |
| 2548 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \ |
| 2549 | int res = REAL(pthread_attr_get##what)(attr, r); \ |
| 2550 | if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ |
| 2551 | return res; \ |
| 2552 | } |
| 2553 | #endif |
| 2554 | |
| 2555 | #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET |
| 2556 | INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) |
| 2557 | INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) |
| 2558 | INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) |
| 2559 | INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) |
| 2560 | INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) |
| 2561 | INTERCEPTOR_PTHREAD_ATTR_GET(stackaddr, sizeof(void *)) |
| 2562 | INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) |
| 2563 | INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { |
| 2564 | void *ctx; |
| 2565 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); |
| 2566 | int res = REAL(pthread_attr_getstack)(attr, addr, size); |
| 2567 | if (!res) { |
| 2568 | if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); |
| 2569 | if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); |
| 2570 | } |
| 2571 | return res; |
| 2572 | } |
| 2573 | |
| 2574 | #define INIT_PTHREAD_ATTR_GET \ |
| 2575 | INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ |
| 2576 | INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ |
| 2577 | INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ |
| 2578 | INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ |
Evgeniy Stepanov | e236dbb | 2013-10-25 13:01:31 +0000 | [diff] [blame] | 2579 | INTERCEPT_FUNCTION(pthread_attr_getscope); \ |
| 2580 | INTERCEPT_FUNCTION(pthread_attr_getstackaddr); \ |
| 2581 | INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ |
Evgeniy Stepanov | ec208e0 | 2013-10-25 14:24:31 +0000 | [diff] [blame^] | 2582 | INTERCEPT_FUNCTION(pthread_attr_getstack); |
Evgeniy Stepanov | e236dbb | 2013-10-25 13:01:31 +0000 | [diff] [blame] | 2583 | #else |
| 2584 | #define INIT_PTHREAD_ATTR_GET |
| 2585 | #endif |
| 2586 | |
| 2587 | #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED |
| 2588 | INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) |
| 2589 | |
| 2590 | #define INIT_PTHREAD_ATTR_GETINHERITSCHED \ |
| 2591 | INTERCEPT_FUNCTION(pthread_attr_getinheritsched); |
| 2592 | #else |
| 2593 | #define INIT_PTHREAD_ATTR_GETINHERITSCHED |
| 2594 | #endif |
| 2595 | |
| 2596 | #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP |
| 2597 | INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, |
| 2598 | void *cpuset) { |
| 2599 | void *ctx; |
| 2600 | COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, |
| 2601 | cpuset); |
| 2602 | int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); |
| 2603 | if (!res && cpusetsize && cpuset) |
| 2604 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); |
| 2605 | return res; |
| 2606 | } |
| 2607 | |
| 2608 | #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ |
| 2609 | INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); |
| 2610 | #else |
| 2611 | #define INIT_PTHREAD_ATTR_GETAFFINITY_NP |
| 2612 | #endif |
| 2613 | |
Evgeniy Stepanov | 56d3472 | 2013-05-21 08:12:08 +0000 | [diff] [blame] | 2614 | #define SANITIZER_COMMON_INTERCEPTORS_INIT \ |
Alexey Samsonov | 67505a8 | 2013-07-16 12:51:53 +0000 | [diff] [blame] | 2615 | INIT_STRCMP; \ |
| 2616 | INIT_STRNCMP; \ |
Evgeniy Stepanov | 56d3472 | 2013-05-21 08:12:08 +0000 | [diff] [blame] | 2617 | INIT_STRCASECMP; \ |
| 2618 | INIT_STRNCASECMP; \ |
| 2619 | INIT_READ; \ |
| 2620 | INIT_PREAD; \ |
| 2621 | INIT_PREAD64; \ |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 2622 | INIT_READV; \ |
| 2623 | INIT_PREADV; \ |
| 2624 | INIT_PREADV64; \ |
Evgeniy Stepanov | 56d3472 | 2013-05-21 08:12:08 +0000 | [diff] [blame] | 2625 | INIT_WRITE; \ |
| 2626 | INIT_PWRITE; \ |
| 2627 | INIT_PWRITE64; \ |
Evgeniy Stepanov | b916e6a | 2013-06-24 10:43:23 +0000 | [diff] [blame] | 2628 | INIT_WRITEV; \ |
| 2629 | INIT_PWRITEV; \ |
| 2630 | INIT_PWRITEV64; \ |
| 2631 | INIT_PRCTL; \ |
Evgeniy Stepanov | 56d3472 | 2013-05-21 08:12:08 +0000 | [diff] [blame] | 2632 | INIT_LOCALTIME_AND_FRIENDS; \ |
| 2633 | INIT_SCANF; \ |
Evgeniy Stepanov | ba15077 | 2013-08-22 13:59:15 +0000 | [diff] [blame] | 2634 | INIT_ISOC99_SCANF; \ |
Evgeniy Stepanov | 56d3472 | 2013-05-21 08:12:08 +0000 | [diff] [blame] | 2635 | INIT_FREXP; \ |
| 2636 | INIT_FREXPF_FREXPL; \ |
| 2637 | INIT_GETPWNAM_AND_FRIENDS; \ |
| 2638 | INIT_GETPWNAM_R_AND_FRIENDS; \ |
| 2639 | INIT_CLOCK_GETTIME; \ |
| 2640 | INIT_GETITIMER; \ |
| 2641 | INIT_TIME; \ |
| 2642 | INIT_GLOB; \ |
| 2643 | INIT_WAIT; \ |
| 2644 | INIT_INET; \ |
Evgeniy Stepanov | 447ef19 | 2013-05-22 12:50:26 +0000 | [diff] [blame] | 2645 | INIT_PTHREAD_GETSCHEDPARAM; \ |
Evgeniy Stepanov | 9f58c5c | 2013-05-22 13:46:22 +0000 | [diff] [blame] | 2646 | INIT_GETADDRINFO; \ |
Evgeniy Stepanov | 9eedf48 | 2013-07-01 13:51:31 +0000 | [diff] [blame] | 2647 | INIT_GETNAMEINFO; \ |
Evgeniy Stepanov | 0a2cc37 | 2013-05-23 11:10:23 +0000 | [diff] [blame] | 2648 | INIT_GETSOCKNAME; \ |
| 2649 | INIT_GETHOSTBYNAME; \ |
Evgeniy Stepanov | f32be42 | 2013-05-23 11:38:08 +0000 | [diff] [blame] | 2650 | INIT_GETHOSTBYNAME_R; \ |
Evgeniy Stepanov | 9d1525e | 2013-05-29 09:09:58 +0000 | [diff] [blame] | 2651 | INIT_GETSOCKOPT; \ |
| 2652 | INIT_ACCEPT; \ |
Evgeniy Stepanov | c87088b | 2013-05-29 10:03:11 +0000 | [diff] [blame] | 2653 | INIT_ACCEPT4; \ |
Evgeniy Stepanov | 9666d89 | 2013-05-29 11:30:00 +0000 | [diff] [blame] | 2654 | INIT_MODF; \ |
Evgeniy Stepanov | bc33e13 | 2013-05-29 11:49:25 +0000 | [diff] [blame] | 2655 | INIT_RECVMSG; \ |
Evgeniy Stepanov | 745dd0d | 2013-06-07 13:00:47 +0000 | [diff] [blame] | 2656 | INIT_GETPEERNAME; \ |
Evgeniy Stepanov | 9d60087 | 2013-06-24 13:56:14 +0000 | [diff] [blame] | 2657 | INIT_IOCTL; \ |
Evgeniy Stepanov | 359d7fc | 2013-06-24 14:25:33 +0000 | [diff] [blame] | 2658 | INIT_INET_ATON; \ |
Evgeniy Stepanov | b5cf98f | 2013-06-26 15:00:53 +0000 | [diff] [blame] | 2659 | INIT_SYSINFO; \ |
| 2660 | INIT_READDIR; \ |
Evgeniy Stepanov | 341b9e6 | 2013-06-28 11:02:43 +0000 | [diff] [blame] | 2661 | INIT_READDIR64; \ |
Evgeniy Stepanov | 3cae604 | 2013-07-02 09:23:45 +0000 | [diff] [blame] | 2662 | INIT_PTRACE; \ |
Evgeniy Stepanov | 8014489 | 2013-07-02 13:34:44 +0000 | [diff] [blame] | 2663 | INIT_SETLOCALE; \ |
| 2664 | INIT_GETCWD; \ |
Evgeniy Stepanov | ff6c9fb | 2013-07-04 13:19:41 +0000 | [diff] [blame] | 2665 | INIT_GET_CURRENT_DIR_NAME; \ |
| 2666 | INIT_STRTOIMAX; \ |
| 2667 | INIT_MBSTOWCS; \ |
| 2668 | INIT_MBSNRTOWCS; \ |
| 2669 | INIT_WCSTOMBS; \ |
Evgeniy Stepanov | ea72768 | 2013-07-04 14:03:31 +0000 | [diff] [blame] | 2670 | INIT_WCSNRTOMBS; \ |
Evgeniy Stepanov | 12eb79d | 2013-07-09 09:53:37 +0000 | [diff] [blame] | 2671 | INIT_TCGETATTR; \ |
| 2672 | INIT_REALPATH; \ |
Evgeniy Stepanov | 5ec19bc | 2013-07-30 12:46:59 +0000 | [diff] [blame] | 2673 | INIT_CANONICALIZE_FILE_NAME; \ |
Evgeniy Stepanov | 84ba74c | 2013-08-07 09:10:16 +0000 | [diff] [blame] | 2674 | INIT_CONFSTR; \ |
Evgeniy Stepanov | 1204979 | 2013-08-08 11:44:05 +0000 | [diff] [blame] | 2675 | INIT_SCHED_GETAFFINITY; \ |
| 2676 | INIT_STRERROR; \ |
Evgeniy Stepanov | 224226c | 2013-08-08 13:57:15 +0000 | [diff] [blame] | 2677 | INIT_STRERROR_R; \ |
| 2678 | INIT_SCANDIR; \ |
Evgeniy Stepanov | edff34b | 2013-08-12 11:01:40 +0000 | [diff] [blame] | 2679 | INIT_SCANDIR64; \ |
Evgeniy Stepanov | e18e3f0 | 2013-08-12 13:19:53 +0000 | [diff] [blame] | 2680 | INIT_GETGROUPS; \ |
| 2681 | INIT_POLL; \ |
Evgeniy Stepanov | c5a3855 | 2013-09-24 14:38:22 +0000 | [diff] [blame] | 2682 | INIT_PPOLL; \ |
Evgeniy Stepanov | 9a949a8 | 2013-09-25 14:47:43 +0000 | [diff] [blame] | 2683 | INIT_WORDEXP; \ |
| 2684 | INIT_SIGWAIT; \ |
| 2685 | INIT_SIGWAITINFO; \ |
| 2686 | INIT_SIGTIMEDWAIT; \ |
| 2687 | INIT_SIGSETOPS; \ |
| 2688 | INIT_SIGPENDING; \ |
Evgeniy Stepanov | 1394be1 | 2013-09-27 12:40:23 +0000 | [diff] [blame] | 2689 | INIT_SIGPROCMASK; \ |
Dmitry Vyukov | 14dd980 | 2013-10-03 15:22:29 +0000 | [diff] [blame] | 2690 | INIT_BACKTRACE; \ |
| 2691 | INIT__EXIT; \ |
Alexey Samsonov | 5e2d377 | 2013-10-16 08:20:31 +0000 | [diff] [blame] | 2692 | INIT_PTHREAD_MUTEX_LOCK; \ |
| 2693 | INIT_PTHREAD_MUTEX_UNLOCK; \ |
| 2694 | INIT_PTHREAD_COND_WAIT; \ |
| 2695 | INIT_PTHREAD_COND_INIT; \ |
Alexey Samsonov | fc81346 | 2013-10-17 09:24:03 +0000 | [diff] [blame] | 2696 | INIT_PTHREAD_COND_SIGNAL; \ |
| 2697 | INIT_PTHREAD_COND_BROADCAST; \ |
Evgeniy Stepanov | 4d7297d | 2013-10-18 09:41:43 +0000 | [diff] [blame] | 2698 | INIT_GETMNTENT; \ |
| 2699 | INIT_GETMNTENT_R; \ |
Evgeniy Stepanov | 5cee73e | 2013-10-18 11:14:16 +0000 | [diff] [blame] | 2700 | INIT_STATFS; \ |
| 2701 | INIT_STATFS64; \ |
| 2702 | INIT_STATVFS; \ |
| 2703 | INIT_STATVFS64; \ |
Evgeniy Stepanov | 285d458 | 2013-10-22 12:24:48 +0000 | [diff] [blame] | 2704 | INIT_INITGROUPS; \ |
Evgeniy Stepanov | 369a9a6 | 2013-10-23 13:57:47 +0000 | [diff] [blame] | 2705 | INIT_ETHER; \ |
Evgeniy Stepanov | 220d1f7 | 2013-10-23 15:21:10 +0000 | [diff] [blame] | 2706 | INIT_ETHER_R; \ |
Evgeniy Stepanov | 10362d6 | 2013-10-24 14:47:34 +0000 | [diff] [blame] | 2707 | INIT_SHMCTL; \ |
Evgeniy Stepanov | aff25aa | 2013-10-25 08:58:13 +0000 | [diff] [blame] | 2708 | INIT_RANDOM_R; \ |
Evgeniy Stepanov | e236dbb | 2013-10-25 13:01:31 +0000 | [diff] [blame] | 2709 | INIT_PTHREAD_ATTR_GET; \ |
| 2710 | INIT_PTHREAD_ATTR_GETINHERITSCHED; \ |
| 2711 | INIT_PTHREAD_ATTR_GETAFFINITY_NP; \ |
Dmitry Vyukov | 14dd980 | 2013-10-03 15:22:29 +0000 | [diff] [blame] | 2712 | /**/ |