sanitizer_common_interceptors.inc revision 1.2
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// Common function interceptors for tools like AddressSanitizer, 9// ThreadSanitizer, MemorySanitizer, etc. 10// 11// This file should be included into the tool's interceptor file, 12// which has to define it's own macros: 13// COMMON_INTERCEPTOR_ENTER 14// COMMON_INTERCEPTOR_READ_RANGE 15// COMMON_INTERCEPTOR_WRITE_RANGE 16// COMMON_INTERCEPTOR_FD_ACQUIRE 17// COMMON_INTERCEPTOR_FD_RELEASE 18// COMMON_INTERCEPTOR_SET_THREAD_NAME 19//===----------------------------------------------------------------------===// 20#include "interception/interception.h" 21#include "sanitizer_platform_interceptors.h" 22 23#include <stdarg.h> 24 25#ifdef _WIN32 26#define va_copy(dst, src) ((dst) = (src)) 27#endif // _WIN32 28 29#if SANITIZER_INTERCEPT_READ 30INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 31 void *ctx; 32 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 33 SSIZE_T res = REAL(read)(fd, ptr, count); 34 if (res > 0) 35 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 36 if (res >= 0 && fd >= 0) 37 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 38 return res; 39} 40#define INIT_READ INTERCEPT_FUNCTION(read) 41#else 42#define INIT_READ 43#endif 44 45#if SANITIZER_INTERCEPT_PREAD 46INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 47 void *ctx; 48 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 49 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 50 if (res > 0) 51 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 52 if (res >= 0 && fd >= 0) 53 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 54 return res; 55} 56#define INIT_PREAD INTERCEPT_FUNCTION(pread) 57#else 58#define INIT_PREAD 59#endif 60 61#if SANITIZER_INTERCEPT_PREAD64 62INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 63 void *ctx; 64 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 65 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 66 if (res > 0) 67 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 68 if (res >= 0 && fd >= 0) 69 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 70 return res; 71} 72#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 73#else 74#define INIT_PREAD64 75#endif 76 77#if SANITIZER_INTERCEPT_WRITE 78INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 79 void *ctx; 80 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 81 if (fd >= 0) 82 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 83 SSIZE_T res = REAL(write)(fd, ptr, count); 84 if (res > 0) 85 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 86 return res; 87} 88#define INIT_WRITE INTERCEPT_FUNCTION(write) 89#else 90#define INIT_WRITE 91#endif 92 93#if SANITIZER_INTERCEPT_PWRITE 94INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 95 void *ctx; 96 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 97 if (fd >= 0) 98 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 99 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 100 if (res > 0) 101 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 102 return res; 103} 104#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 105#else 106#define INIT_PWRITE 107#endif 108 109#if SANITIZER_INTERCEPT_PWRITE64 110INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 111 OFF64_T offset) { 112 void *ctx; 113 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 114 if (fd >= 0) 115 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 116 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 117 if (res > 0) 118 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 119 return res; 120} 121#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 122#else 123#define INIT_PWRITE64 124#endif 125 126#if SANITIZER_INTERCEPT_PRCTL 127INTERCEPTOR(int, prctl, int option, 128 unsigned long arg2, unsigned long arg3, // NOLINT 129 unsigned long arg4, unsigned long arg5) { // NOLINT 130 void *ctx; 131 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 132 static const int PR_SET_NAME = 15; 133 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 134 if (option == PR_SET_NAME) { 135 char buff[16]; 136 internal_strncpy(buff, (char *)arg2, 15); 137 buff[15] = 0; 138 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 139 } 140 return res; 141} 142#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 143#else 144#define INIT_PRCTL 145#endif // SANITIZER_INTERCEPT_PRCTL 146 147#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 148INTERCEPTOR(void *, localtime, unsigned long *timep) { 149 void *ctx; 150 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 151 void *res = REAL(localtime)(timep); 152 if (res) { 153 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 154 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 155 } 156 return res; 157} 158INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { 159 void *ctx; 160 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 161 void *res = REAL(localtime_r)(timep, result); 162 if (res) { 163 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 164 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 165 } 166 return res; 167} 168INTERCEPTOR(void *, gmtime, unsigned long *timep) { 169 void *ctx; 170 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 171 void *res = REAL(gmtime)(timep); 172 if (res) { 173 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 174 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 175 } 176 return res; 177} 178INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { 179 void *ctx; 180 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 181 void *res = REAL(gmtime_r)(timep, result); 182 if (res) { 183 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 184 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 185 } 186 return res; 187} 188INTERCEPTOR(char *, ctime, unsigned long *timep) { 189 void *ctx; 190 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 191 char *res = REAL(ctime)(timep); 192 if (res) { 193 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 194 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 195 } 196 return res; 197} 198INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 199 void *ctx; 200 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 201 char *res = REAL(ctime_r)(timep, result); 202 if (res) { 203 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 204 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 205 } 206 return res; 207} 208INTERCEPTOR(char *, asctime, void *tm) { 209 void *ctx; 210 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 211 char *res = REAL(asctime)(tm); 212 if (res) { 213 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 215 } 216 return res; 217} 218INTERCEPTOR(char *, asctime_r, void *tm, char *result) { 219 void *ctx; 220 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 221 char *res = REAL(asctime_r)(tm, result); 222 if (res) { 223 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 224 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 225 } 226 return res; 227} 228#define INIT_LOCALTIME_AND_FRIENDS \ 229 INTERCEPT_FUNCTION(localtime); \ 230 INTERCEPT_FUNCTION(localtime_r); \ 231 INTERCEPT_FUNCTION(gmtime); \ 232 INTERCEPT_FUNCTION(gmtime_r); \ 233 INTERCEPT_FUNCTION(ctime); \ 234 INTERCEPT_FUNCTION(ctime_r); \ 235 INTERCEPT_FUNCTION(asctime); \ 236 INTERCEPT_FUNCTION(asctime_r); 237#else 238#define INIT_LOCALTIME_AND_FRIENDS 239#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 240 241#if SANITIZER_INTERCEPT_SCANF 242 243#include "sanitizer_common_interceptors_scanf.inc" 244 245#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 246 { \ 247 void *ctx; \ 248 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 249 va_list aq; \ 250 va_copy(aq, ap); \ 251 int res = REAL(vname)(__VA_ARGS__); \ 252 if (res > 0) \ 253 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 254 va_end(aq); \ 255 return res; \ 256 } 257 258INTERCEPTOR(int, vscanf, const char *format, va_list ap) 259VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 260 261INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 262VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 263 264INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 265VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 266 267#if SANITIZER_INTERCEPT_ISOC99_SCANF 268INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 269VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 270 271INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 272 va_list ap) 273VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 274 275INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 276VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 277#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 278 279#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 280 { \ 281 void *ctx; \ 282 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \ 283 va_list ap; \ 284 va_start(ap, format); \ 285 int res = vname(__VA_ARGS__, ap); \ 286 va_end(ap); \ 287 return res; \ 288 } 289 290INTERCEPTOR(int, scanf, const char *format, ...) 291SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 292 293INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 294SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 295 296INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 297SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 298 299#define INIT_SCANF_NORMAL \ 300 INTERCEPT_FUNCTION(scanf); \ 301 INTERCEPT_FUNCTION(sscanf); \ 302 INTERCEPT_FUNCTION(fscanf); \ 303 INTERCEPT_FUNCTION(vscanf); \ 304 INTERCEPT_FUNCTION(vsscanf); \ 305 INTERCEPT_FUNCTION(vfscanf); \ 306 307#if SANITIZER_INTERCEPT_ISOC99_SCANF 308INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 309SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 310 311INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 312SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 313 314INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 315SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 316 317 318#define INIT_SCANF_ISOC99 \ 319 INTERCEPT_FUNCTION(__isoc99_scanf); \ 320 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 321 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 322 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 323 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 324 INTERCEPT_FUNCTION(__isoc99_vfscanf); 325#else 326#define INIT_SCANF_ISOC99 327#endif 328 329#define INIT_SCANF \ 330 INIT_SCANF_NORMAL \ 331 INIT_SCANF_ISOC99 332 333#else 334#define INIT_SCANF 335#endif 336 337#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 338 INIT_READ; \ 339 INIT_PREAD; \ 340 INIT_PREAD64; \ 341 INIT_PRCTL; \ 342 INIT_WRITE; \ 343 INIT_PWRITE; \ 344 INIT_PWRITE64; \ 345 INIT_LOCALTIME_AND_FRIENDS; \ 346 INIT_SCANF; 347