blob: a7c7de5b22fc84f290f4220a25acaa706cd6a931 [file] [log] [blame]
Evgeniy Stepanov4f32c0b2013-01-18 13:01:18 +00001//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
Kostya Serebryany8530e2b2012-12-12 09:54:35 +00002//
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
Kostya Serebryanyc8033192013-01-17 13:09:00 +000018// COMMON_INTERCEPTOR_FD_ACQUIRE
19// COMMON_INTERCEPTOR_FD_RELEASE
Kostya Serebryanyc20b3212013-01-18 06:43:13 +000020// COMMON_INTERCEPTOR_SET_THREAD_NAME
Kostya Serebryany8530e2b2012-12-12 09:54:35 +000021//===----------------------------------------------------------------------===//
Kostya Serebryany6afa1b02012-12-13 06:31:40 +000022#include "interception/interception.h"
Alexey Samsonov74737d52012-12-13 08:50:16 +000023#include "sanitizer_platform_interceptors.h"
Kostya Serebryanyb1cc4e42012-12-13 05:27:08 +000024
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +000025#include <stdarg.h>
26
Evgeniy Stepanov30e110e2013-03-19 14:54:17 +000027#if SANITIZER_WINDOWS
Evgeniy Stepanov348bd122013-02-11 14:08:12 +000028#define va_copy(dst, src) ((dst) = (src))
29#endif // _WIN32
30
Dmitry Vyukovbe523662013-03-26 12:40:23 +000031#if SANITIZER_INTERCEPT_STRCASECMP
32static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
33 int c1_low = ToLower(c1);
34 int c2_low = ToLower(c2);
35 return c1_low - c2_low;
36}
37
38INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
39 void *ctx;
40 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
41 unsigned char c1 = 0, c2 = 0;
42 uptr i;
43 for (i = 0; ; i++) {
44 c1 = (unsigned char)s1[i];
45 c2 = (unsigned char)s2[i];
46 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
47 break;
48 }
49 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
50 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
51 return CharCaseCmp(c1, c2);
52}
53
54INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
55 void *ctx;
56 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
57 unsigned char c1 = 0, c2 = 0;
58 uptr i;
59 for (i = 0; i < n; i++) {
60 c1 = (unsigned char)s1[i];
61 c2 = (unsigned char)s2[i];
62 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
63 break;
64 }
65 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
66 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
67 return CharCaseCmp(c1, c2);
68}
69
70#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
71#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
72#else
73#define INIT_STRCASECMP
74#define INIT_STRNCASECMP
75#endif
76
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +000077#if SANITIZER_INTERCEPT_FREXP
78INTERCEPTOR(double, frexp, double x, int *exp) {
79 void *ctx;
80 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
81 double res = REAL(frexp)(x, exp);
82 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
83 return res;
84}
85
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +000086#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
87#else
88#define INIT_FREXP
89#endif // SANITIZER_INTERCEPT_FREXP
90
91#if SANITIZER_INTERCEPT_FREXPF_FREXPL
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +000092INTERCEPTOR(float, frexpf, float x, int *exp) {
93 void *ctx;
94 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
95 float res = REAL(frexpf)(x, exp);
96 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
97 return res;
98}
99
100INTERCEPTOR(long double, frexpl, long double x, int *exp) {
101 void *ctx;
102 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
103 long double res = REAL(frexpl)(x, exp);
104 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
105 return res;
106}
107
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +0000108#define INIT_FREXPF_FREXPL \
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000109 INTERCEPT_FUNCTION(frexpf); \
110 INTERCEPT_FUNCTION(frexpl)
111#else
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +0000112#define INIT_FREXPF_FREXPL
113#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000114
Alexey Samsonov8ffd8772012-12-13 08:36:13 +0000115#if SANITIZER_INTERCEPT_READ
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000116INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000117 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000118 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000119 SSIZE_T res = REAL(read)(fd, ptr, count);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000120 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000121 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
Kostya Serebryanyc8033192013-01-17 13:09:00 +0000122 if (res >= 0 && fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000123 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000124 return res;
125}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000126#define INIT_READ INTERCEPT_FUNCTION(read)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000127#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000128#define INIT_READ
Alexey Samsonov8ffd8772012-12-13 08:36:13 +0000129#endif
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000130
Alexey Samsonovc333dff2012-12-13 08:10:23 +0000131#if SANITIZER_INTERCEPT_PREAD
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000132INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000133 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000134 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000135 SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000136 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000137 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
Kostya Serebryanyc8033192013-01-17 13:09:00 +0000138 if (res >= 0 && fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000139 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000140 return res;
141}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000142#define INIT_PREAD INTERCEPT_FUNCTION(pread)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000143#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000144#define INIT_PREAD
Alexey Samsonovc333dff2012-12-13 08:10:23 +0000145#endif
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000146
Kostya Serebryanyb1cc4e42012-12-13 05:27:08 +0000147#if SANITIZER_INTERCEPT_PREAD64
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000148INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000149 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000150 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
Kostya Serebryany6afa1b02012-12-13 06:31:40 +0000151 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000152 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000153 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
Kostya Serebryanyc8033192013-01-17 13:09:00 +0000154 if (res >= 0 && fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000155 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000156 return res;
157}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000158#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
Alexey Samsonovc333dff2012-12-13 08:10:23 +0000159#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000160#define INIT_PREAD64
Alexander Potapenko1f5e23e2012-12-12 11:52:26 +0000161#endif
Kostya Serebryany8530e2b2012-12-12 09:54:35 +0000162
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000163#if SANITIZER_INTERCEPT_WRITE
164INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000165 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000166 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000167 if (fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000168 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000169 SSIZE_T res = REAL(write)(fd, ptr, count);
170 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000171 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000172 return res;
173}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000174#define INIT_WRITE INTERCEPT_FUNCTION(write)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000175#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000176#define INIT_WRITE
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000177#endif
178
179#if SANITIZER_INTERCEPT_PWRITE
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000180INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000181 void *ctx;
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000182 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000183 if (fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000184 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000185 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000186 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000187 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000188 return res;
189}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000190#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000191#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000192#define INIT_PWRITE
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000193#endif
194
195#if SANITIZER_INTERCEPT_PWRITE64
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000196INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
197 OFF64_T offset) {
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000198 void *ctx;
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000199 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000200 if (fd >= 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000201 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
Dmitry Vyukovf0c846b2013-01-24 07:44:21 +0000202 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000203 if (res > 0)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000204 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000205 return res;
206}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000207#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000208#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000209#define INIT_PWRITE64
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000210#endif
211
212#if SANITIZER_INTERCEPT_PRCTL
Evgeniy Stepanov69b109a2013-02-20 11:06:07 +0000213INTERCEPTOR(int, prctl, int option,
214 unsigned long arg2, unsigned long arg3, // NOLINT
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000215 unsigned long arg4, unsigned long arg5) { // NOLINT
216 void *ctx;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000217 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000218 static const int PR_SET_NAME = 15;
219 int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
220 if (option == PR_SET_NAME) {
221 char buff[16];
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000222 internal_strncpy(buff, (char *)arg2, 15);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000223 buff[15] = 0;
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000224 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000225 }
226 return res;
227}
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000228#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
Kostya Serebryanyc20b3212013-01-18 06:43:13 +0000229#else
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000230#define INIT_PRCTL
231#endif // SANITIZER_INTERCEPT_PRCTL
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000232
Evgeniy Stepanovfef66052013-04-08 08:25:22 +0000233
234#if SANITIZER_INTERCEPT_TIME
235INTERCEPTOR(unsigned long, time, unsigned long *t) {
236 void *ctx;
237 COMMON_INTERCEPTOR_ENTER(ctx, time, t);
238 unsigned long res = REAL(time)(t);
Alexander Potapenko15832c22013-04-10 15:13:00 +0000239 if (t && res != (unsigned long)-1) {
Evgeniy Stepanovfef66052013-04-08 08:25:22 +0000240 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
241 }
242 return res;
243}
244#define INIT_TIME \
245 INTERCEPT_FUNCTION(time);
246#else
247#define INIT_TIME
248#endif // SANITIZER_INTERCEPT_TIME
249
250
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000251#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
252INTERCEPTOR(void *, localtime, unsigned long *timep) {
253 void *ctx;
254 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
255 void *res = REAL(localtime)(timep);
256 if (res) {
257 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
258 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
259 }
260 return res;
261}
262INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
263 void *ctx;
264 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
265 void *res = REAL(localtime_r)(timep, result);
266 if (res) {
267 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
268 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
269 }
270 return res;
271}
272INTERCEPTOR(void *, gmtime, unsigned long *timep) {
273 void *ctx;
274 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
275 void *res = REAL(gmtime)(timep);
276 if (res) {
277 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
279 }
280 return res;
281}
282INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
283 void *ctx;
284 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
285 void *res = REAL(gmtime_r)(timep, result);
286 if (res) {
287 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
288 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
289 }
290 return res;
291}
292INTERCEPTOR(char *, ctime, unsigned long *timep) {
293 void *ctx;
294 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
295 char *res = REAL(ctime)(timep);
296 if (res) {
297 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
298 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
299 }
300 return res;
301}
302INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
303 void *ctx;
304 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
305 char *res = REAL(ctime_r)(timep, result);
306 if (res) {
307 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
308 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
309 }
310 return res;
311}
312INTERCEPTOR(char *, asctime, void *tm) {
313 void *ctx;
314 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
315 char *res = REAL(asctime)(tm);
316 if (res) {
317 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
318 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
319 }
320 return res;
321}
322INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
323 void *ctx;
324 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
325 char *res = REAL(asctime_r)(tm, result);
326 if (res) {
327 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
328 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
329 }
330 return res;
331}
332#define INIT_LOCALTIME_AND_FRIENDS \
333 INTERCEPT_FUNCTION(localtime); \
334 INTERCEPT_FUNCTION(localtime_r); \
335 INTERCEPT_FUNCTION(gmtime); \
336 INTERCEPT_FUNCTION(gmtime_r); \
337 INTERCEPT_FUNCTION(ctime); \
338 INTERCEPT_FUNCTION(ctime_r); \
339 INTERCEPT_FUNCTION(asctime); \
340 INTERCEPT_FUNCTION(asctime_r);
341#else
342#define INIT_LOCALTIME_AND_FRIENDS
343#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
344
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000345#if SANITIZER_INTERCEPT_SCANF
346
Evgeniy Stepanov4f32c0b2013-01-18 13:01:18 +0000347#include "sanitizer_common_interceptors_scanf.inc"
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000348
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000349#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000350 { \
351 void *ctx; \
352 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
353 va_list aq; \
354 va_copy(aq, ap); \
355 int res = REAL(vname)(__VA_ARGS__); \
356 if (res > 0) \
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000357 scanf_common(ctx, res, allowGnuMalloc, format, aq); \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000358 va_end(aq); \
359 return res; \
360 }
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000361
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000362INTERCEPTOR(int, vscanf, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000363VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000364
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000365INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000366VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000367
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000368INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000369VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000370
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000371#if SANITIZER_INTERCEPT_ISOC99_SCANF
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000372INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000373VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000374
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000375INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
376 va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000377VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000378
379INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
Evgeniy Stepanovc5b4e862013-02-12 14:29:34 +0000380VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000381#endif // SANITIZER_INTERCEPT_ISOC99_SCANF
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000382
383#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \
384 { \
385 void *ctx; \
386 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \
387 va_list ap; \
388 va_start(ap, format); \
389 int res = vname(__VA_ARGS__, ap); \
390 va_end(ap); \
391 return res; \
392 }
393
394INTERCEPTOR(int, scanf, const char *format, ...)
395SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
396
397INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
398SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
399
400INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
401SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
402
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000403#if SANITIZER_INTERCEPT_ISOC99_SCANF
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000404INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
405SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
406
407INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
408SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
409
410INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
411SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
Alexander Potapenko9eab8582013-02-20 15:27:58 +0000412#endif
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000413
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000414#define INIT_SCANF \
415 INTERCEPT_FUNCTION(scanf); \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000416 INTERCEPT_FUNCTION(sscanf); \
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000417 INTERCEPT_FUNCTION(fscanf); \
418 INTERCEPT_FUNCTION(vscanf); \
419 INTERCEPT_FUNCTION(vsscanf); \
Evgeniy Stepanov4ae1adb2013-02-12 11:34:52 +0000420 INTERCEPT_FUNCTION(vfscanf); \
421 INTERCEPT_FUNCTION(__isoc99_scanf); \
422 INTERCEPT_FUNCTION(__isoc99_sscanf); \
423 INTERCEPT_FUNCTION(__isoc99_fscanf); \
424 INTERCEPT_FUNCTION(__isoc99_vscanf); \
425 INTERCEPT_FUNCTION(__isoc99_vsscanf); \
426 INTERCEPT_FUNCTION(__isoc99_vfscanf);
Evgeniy Stepanov996c4f22013-01-18 11:17:23 +0000427
428#else
429#define INIT_SCANF
430#endif
431
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000432#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000433INTERCEPTOR(void *, getpwnam, const char *name) {
434 void *ctx;
435 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
436 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
437 void *res = REAL(getpwnam)(name);
438 if (res != 0)
439 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
440 return res;
441}
442INTERCEPTOR(void *, getpwuid, u32 uid) {
443 void *ctx;
444 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
445 void *res = REAL(getpwuid)(uid);
446 if (res != 0)
447 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
448 return res;
449}
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000450INTERCEPTOR(void *, getgrnam, const char *name) {
451 void *ctx;
452 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
453 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
454 void *res = REAL(getgrnam)(name);
455 if (res != 0)
456 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
457 return res;
458}
459INTERCEPTOR(void *, getgrgid, u32 gid) {
460 void *ctx;
461 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
462 void *res = REAL(getgrgid)(gid);
463 if (res != 0)
464 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
465 return res;
466}
467#define INIT_GETPWNAM_AND_FRIENDS \
468 INTERCEPT_FUNCTION(getpwnam); \
469 INTERCEPT_FUNCTION(getpwuid); \
470 INTERCEPT_FUNCTION(getgrnam); \
471 INTERCEPT_FUNCTION(getgrgid);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000472#else
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000473#define INIT_GETPWNAM_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000474#endif
475
476
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000477#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000478INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
479 char *buf, SIZE_T buflen, void **result) {
480 void *ctx;
481 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
482 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
483 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
484 if (!res) {
485 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
487 }
488 return res;
489}
490INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
491 char *buf, SIZE_T buflen, void **result) {
492 void *ctx;
493 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
494 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
495 if (!res) {
496 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
497 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
498 }
499 return res;
500}
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000501INTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
502 char *buf, SIZE_T buflen, void **result) {
503 void *ctx;
504 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
505 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
506 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
507 if (!res) {
508 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
509 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
510 }
511 return res;
512}
513INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
514 char *buf, SIZE_T buflen, void **result) {
515 void *ctx;
516 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
517 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
518 if (!res) {
519 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
520 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
521 }
522 return res;
523}
524#define INIT_GETPWNAM_R_AND_FRIENDS \
525 INTERCEPT_FUNCTION(getpwnam_r); \
526 INTERCEPT_FUNCTION(getpwuid_r); \
527 INTERCEPT_FUNCTION(getgrnam_r); \
528 INTERCEPT_FUNCTION(getgrgid_r);
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000529#else
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000530#define INIT_GETPWNAM_R_AND_FRIENDS
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000531#endif
532
533
534#if SANITIZER_INTERCEPT_CLOCK_GETTIME
535INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
536 void *ctx;
537 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
538 int res = REAL(clock_getres)(clk_id, tp);
Evgeniy Stepanov7cdae162013-04-23 11:48:31 +0000539 if (!res && tp) {
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
541 }
542 return res;
543}
544INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
545 void *ctx;
546 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
547 int res = REAL(clock_gettime)(clk_id, tp);
548 if (!res) {
549 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
550 }
551 return res;
552}
553INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
554 void *ctx;
555 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
556 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
557 return REAL(clock_settime)(clk_id, tp);
558}
559#define INIT_CLOCK_GETTIME \
560 INTERCEPT_FUNCTION(clock_getres); \
561 INTERCEPT_FUNCTION(clock_gettime); \
562 INTERCEPT_FUNCTION(clock_settime);
563#else
564#define INIT_CLOCK_GETTIME
565#endif
566
567
568#if SANITIZER_INTERCEPT_GETITIMER
569INTERCEPTOR(int, getitimer, int which, void *curr_value) {
570 void *ctx;
571 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
572 int res = REAL(getitimer)(which, curr_value);
573 if (!res) {
574 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
575 }
576 return res;
577}
578INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
579 void *ctx;
580 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
581 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
582 int res = REAL(setitimer)(which, new_value, old_value);
583 if (!res && old_value) {
584 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
585 }
586 return res;
587}
588#define INIT_GETITIMER \
589 INTERCEPT_FUNCTION(getitimer); \
590 INTERCEPT_FUNCTION(setitimer);
591#else
592#define INIT_GETITIMER
593#endif
594
595
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000596#if SANITIZER_INTERCEPT_GLOB
597struct sanitizer_glob_t {
598 SIZE_T gl_pathc;
599 char **gl_pathv;
600};
601
602static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) {
603 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
604 // +1 for NULL pointer at the end.
605 COMMON_INTERCEPTOR_WRITE_RANGE(
606 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
607 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
608 char *p = pglob->gl_pathv[i];
609 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
610 }
611}
612
613INTERCEPTOR(int, glob, const char *pattern, int flags,
614 int (*errfunc)(const char *epath, int eerrno),
615 sanitizer_glob_t *pglob) {
616 void *ctx;
617 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
618 int res = REAL(glob)(pattern, flags, errfunc, pglob);
619 if (res == 0)
620 unpoison_glob_t(ctx, pglob);
621 return res;
622}
623
624INTERCEPTOR(int, glob64, const char *pattern, int flags,
625 int (*errfunc)(const char *epath, int eerrno),
626 sanitizer_glob_t *pglob) {
627 void *ctx;
628 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
629 int res = REAL(glob64)(pattern, flags, errfunc, pglob);
630 if (res == 0)
631 unpoison_glob_t(ctx, pglob);
632 return res;
633}
634#define INIT_GLOB \
635 INTERCEPT_FUNCTION(glob); \
636 INTERCEPT_FUNCTION(glob64);
637#else // SANITIZER_INTERCEPT_GLOB
638#define INIT_GLOB
639#endif // SANITIZER_INTERCEPT_GLOB
640
641
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000642#if SANITIZER_INTERCEPT_WAIT
643INTERCEPTOR(int, wait, int *status) {
644 void *ctx;
645 COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
646 int res = REAL(wait)(status);
647 if (res != -1)
648 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
649 return res;
650}
651INTERCEPTOR(int, waitid, int idtype, int id, void *infop, int options) {
652 void *ctx;
653 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
654 int res = REAL(waitid)(idtype, id, infop, options);
655 if (res != -1)
656 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
657 return res;
658}
659INTERCEPTOR(int, waitpid, int pid, int *status, int options) {
660 void *ctx;
661 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
662 int res = REAL(waitpid)(pid, status, options);
663 if (res != -1)
664 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
665 return res;
666}
667INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
668 void *ctx;
669 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
670 int res = REAL(wait3)(status, options, rusage);
671 if (res != -1) {
672 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
673 if (rusage)
674 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
675 }
676 return res;
677}
678INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
679 void *ctx;
680 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
681 int res = REAL(wait4)(pid, status, options, rusage);
682 if (res != -1) {
683 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
684 if (rusage)
685 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
686 }
687 return res;
688}
689#define INIT_WAIT \
690 INTERCEPT_FUNCTION(wait); \
691 INTERCEPT_FUNCTION(waitid); \
692 INTERCEPT_FUNCTION(waitpid); \
693 INTERCEPT_FUNCTION(wait3); \
694 INTERCEPT_FUNCTION(wait4);
695#else
696#define INIT_WAIT
697#endif
698
Evgeniy Stepanov9530eb72013-04-23 14:05:15 +0000699#if SANITIZER_INTERCEPT_INET
700INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
701 void *ctx;
702 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
703 uptr sz = __sanitizer_in_addr_sz(af);
704 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
705 // FIXME: figure out read size based on the address family.
706 char *res = REAL(inet_ntop)(af, src, dst, size);
707 if (res)
708 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
709 return res;
710}
711INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
712 void *ctx;
713 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
714 // FIXME: figure out read size based on the address family.
715 int res = REAL(inet_pton)(af, src, dst);
716 if (res == 1) {
717 uptr sz = __sanitizer_in_addr_sz(af);
718 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
719 }
720 return res;
721}
722#define INIT_INET \
723 INTERCEPT_FUNCTION(inet_ntop); \
724 INTERCEPT_FUNCTION(inet_pton);
725#else
726#define INIT_INET
727#endif
728
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000729
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000730#define SANITIZER_COMMON_INTERCEPTORS_INIT \
Dmitry Vyukovbe523662013-03-26 12:40:23 +0000731 INIT_STRCASECMP; \
732 INIT_STRNCASECMP; \
Evgeniy Stepanov44be70b2013-02-11 15:22:34 +0000733 INIT_READ; \
734 INIT_PREAD; \
735 INIT_PREAD64; \
736 INIT_PRCTL; \
737 INIT_WRITE; \
738 INIT_PWRITE; \
739 INIT_PWRITE64; \
Evgeniy Stepanov9358c582013-02-19 09:19:16 +0000740 INIT_LOCALTIME_AND_FRIENDS; \
Evgeniy Stepanov7cbbb292013-03-14 11:34:39 +0000741 INIT_SCANF; \
Alexey Samsonovff5d1fc2013-03-15 14:02:21 +0000742 INIT_FREXP; \
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000743 INIT_FREXPF_FREXPL; \
Evgeniy Stepanov103a63e2013-04-23 12:01:20 +0000744 INIT_GETPWNAM_AND_FRIENDS; \
745 INIT_GETPWNAM_R_AND_FRIENDS; \
Evgeniy Stepanove4bdda52013-04-01 14:47:21 +0000746 INIT_CLOCK_GETTIME; \
Evgeniy Stepanovfef66052013-04-08 08:25:22 +0000747 INIT_GETITIMER; \
Evgeniy Stepanova1c2a552013-04-09 11:35:13 +0000748 INIT_TIME; \
Evgeniy Stepanov897a4ae2013-04-09 14:34:59 +0000749 INIT_GLOB; \
Evgeniy Stepanov9530eb72013-04-23 14:05:15 +0000750 INIT_WAIT; \
751 INIT_INET;