1 //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // Common function interceptors for tools like AddressSanitizer,
9 // ThreadSanitizer, MemorySanitizer, etc.
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"
26 #define va_copy(dst, src) ((dst) = (src))
29 #if SANITIZER_INTERCEPT_READ
30 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
32 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
33 SSIZE_T res = REAL(read)(fd, ptr, count);
35 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
36 if (res >= 0 && fd >= 0)
37 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
40 #define INIT_READ INTERCEPT_FUNCTION(read)
45 #if SANITIZER_INTERCEPT_PREAD
46 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
48 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
49 SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
51 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
52 if (res >= 0 && fd >= 0)
53 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
56 #define INIT_PREAD INTERCEPT_FUNCTION(pread)
61 #if SANITIZER_INTERCEPT_PREAD64
62 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
64 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
65 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
67 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
68 if (res >= 0 && fd >= 0)
69 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
72 #define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
77 #if SANITIZER_INTERCEPT_WRITE
78 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
80 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
82 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
83 SSIZE_T res = REAL(write)(fd, ptr, count);
85 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
88 #define INIT_WRITE INTERCEPT_FUNCTION(write)
93 #if SANITIZER_INTERCEPT_PWRITE
94 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
96 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
98 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
99 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
101 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
104 #define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
109 #if SANITIZER_INTERCEPT_PWRITE64
110 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
113 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
115 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
116 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
118 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
121 #define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
123 #define INIT_PWRITE64
126 #if SANITIZER_INTERCEPT_PRCTL
127 INTERCEPTOR(int, prctl, int option,
128 unsigned long arg2, unsigned long arg3, // NOLINT
129 unsigned long arg4, unsigned long arg5) { // NOLINT
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) {
136 internal_strncpy(buff, (char *)arg2, 15);
138 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
142 #define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
145 #endif // SANITIZER_INTERCEPT_PRCTL
147 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
148 INTERCEPTOR(void *, localtime, unsigned long *timep) {
150 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
151 void *res = REAL(localtime)(timep);
153 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
154 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
158 INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
160 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
161 void *res = REAL(localtime_r)(timep, result);
163 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
164 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
168 INTERCEPTOR(void *, gmtime, unsigned long *timep) {
170 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
171 void *res = REAL(gmtime)(timep);
173 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
174 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
178 INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
180 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
181 void *res = REAL(gmtime_r)(timep, result);
183 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
184 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
188 INTERCEPTOR(char *, ctime, unsigned long *timep) {
190 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
191 char *res = REAL(ctime)(timep);
193 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
194 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
198 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
200 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
201 char *res = REAL(ctime_r)(timep, result);
203 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
204 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
208 INTERCEPTOR(char *, asctime, void *tm) {
210 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
211 char *res = REAL(asctime)(tm);
213 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
218 INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
220 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
221 char *res = REAL(asctime_r)(tm, result);
223 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
224 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
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);
238 #define INIT_LOCALTIME_AND_FRIENDS
239 #endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
241 #if SANITIZER_INTERCEPT_SCANF
243 #include "sanitizer_common_interceptors_scanf.inc"
245 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \
248 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
251 int res = REAL(vname)(__VA_ARGS__); \
253 scanf_common(ctx, res, allowGnuMalloc, format, aq); \
258 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
259 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
261 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
262 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
264 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
265 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
267 #if SANITIZER_INTERCEPT_ISOC99_SCANF
268 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
269 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
271 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
273 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
275 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
276 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
277 #endif // SANITIZER_INTERCEPT_ISOC99_SCANF
279 #define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \
282 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \
284 va_start(ap, format); \
285 int res = vname(__VA_ARGS__, ap); \
290 INTERCEPTOR(int, scanf, const char *format, ...)
291 SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
293 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
294 SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
296 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
297 SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
299 #if SANITIZER_INTERCEPT_ISOC99_SCANF
300 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
301 SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
303 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
304 SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
306 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
307 SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
311 INTERCEPT_FUNCTION(scanf); \
312 INTERCEPT_FUNCTION(sscanf); \
313 INTERCEPT_FUNCTION(fscanf); \
314 INTERCEPT_FUNCTION(vscanf); \
315 INTERCEPT_FUNCTION(vsscanf); \
316 INTERCEPT_FUNCTION(vfscanf); \
317 INTERCEPT_FUNCTION(__isoc99_scanf); \
318 INTERCEPT_FUNCTION(__isoc99_sscanf); \
319 INTERCEPT_FUNCTION(__isoc99_fscanf); \
320 INTERCEPT_FUNCTION(__isoc99_vscanf); \
321 INTERCEPT_FUNCTION(__isoc99_vsscanf); \
322 INTERCEPT_FUNCTION(__isoc99_vfscanf);
328 #define SANITIZER_COMMON_INTERCEPTORS_INIT \
336 INIT_LOCALTIME_AND_FRIENDS; \