Mercurial > hg > CbC > CbC_gcc
comparison libmudflap/mf-hooks2.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting. | |
2 Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc. | |
3 Contributed by Frank Ch. Eigler <fche@redhat.com> | |
4 and Graydon Hoare <graydon@redhat.com> | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 Under Section 7 of GPL version 3, you are granted additional | |
19 permissions described in the GCC Runtime Library Exception, version | |
20 3.1, as published by the Free Software Foundation. | |
21 | |
22 You should have received a copy of the GNU General Public License and | |
23 a copy of the GCC Runtime Library Exception along with this program; | |
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 <http://www.gnu.org/licenses/>. */ | |
26 | |
27 #include "config.h" | |
28 | |
29 #ifndef HAVE_SOCKLEN_T | |
30 #define socklen_t int | |
31 #endif | |
32 | |
33 /* These attempt to coax various unix flavours to declare all our | |
34 needed tidbits in the system headers. */ | |
35 #if !defined(__FreeBSD__) && !defined(__APPLE__) | |
36 #define _POSIX_SOURCE | |
37 #endif /* Some BSDs break <sys/socket.h> if this is defined. */ | |
38 #define _GNU_SOURCE | |
39 #define _XOPEN_SOURCE | |
40 #define _BSD_TYPES | |
41 #define __EXTENSIONS__ | |
42 #define _ALL_SOURCE | |
43 #define _LARGE_FILE_API | |
44 #define _LARGEFILE64_SOURCE | |
45 #define _XOPEN_SOURCE_EXTENDED 1 | |
46 | |
47 #include <string.h> | |
48 #include <stdarg.h> | |
49 #include <stdio.h> | |
50 #include <stdlib.h> | |
51 #include <sys/stat.h> | |
52 #include <sys/time.h> | |
53 #include <sys/types.h> | |
54 #include <unistd.h> | |
55 #include <assert.h> | |
56 #include <errno.h> | |
57 #include <limits.h> | |
58 #include <time.h> | |
59 #include <ctype.h> | |
60 #ifdef HAVE_DLFCN_H | |
61 #include <dlfcn.h> | |
62 #endif | |
63 #ifdef HAVE_DIRENT_H | |
64 #include <dirent.h> | |
65 #endif | |
66 #ifdef HAVE_SYS_SOCKET_H | |
67 #include <sys/socket.h> | |
68 #endif | |
69 #ifdef HAVE_NETDB_H | |
70 #include <netdb.h> | |
71 #endif | |
72 #ifdef HAVE_SYS_WAIT_H | |
73 #include <sys/wait.h> | |
74 #endif | |
75 #ifdef HAVE_SYS_IPC_H | |
76 #include <sys/ipc.h> | |
77 #endif | |
78 #ifdef HAVE_SYS_SEM_H | |
79 #include <sys/sem.h> | |
80 #endif | |
81 #ifdef HAVE_SYS_SHM_H | |
82 #include <sys/shm.h> | |
83 #endif | |
84 #ifdef HAVE_PWD_H | |
85 #include <pwd.h> | |
86 #endif | |
87 #ifdef HAVE_GRP_H | |
88 #include <grp.h> | |
89 #endif | |
90 #ifdef HAVE_MNTENT_H | |
91 #include <mntent.h> | |
92 #endif | |
93 #ifdef HAVE_SYS_SOCKET_H | |
94 #include <sys/socket.h> | |
95 #endif | |
96 #ifdef HAVE_NETINET_IN_H | |
97 #include <netinet/in.h> | |
98 #endif | |
99 #ifdef HAVE_ARPA_INET_H | |
100 #include <arpa/inet.h> | |
101 #endif | |
102 | |
103 #include "mf-runtime.h" | |
104 #include "mf-impl.h" | |
105 | |
106 #ifdef _MUDFLAP | |
107 #error "Do not compile this file with -fmudflap!" | |
108 #endif | |
109 | |
110 | |
111 /* A bunch of independent stdlib/unistd hook functions, all | |
112 intercepted by mf-runtime.h macros. */ | |
113 | |
114 #ifndef HAVE_STRNLEN | |
115 static inline size_t (strnlen) (const char* str, size_t n) | |
116 { | |
117 const char *s; | |
118 | |
119 for (s = str; n && *s; ++s, --n) | |
120 ; | |
121 return (s - str); | |
122 } | |
123 #endif | |
124 | |
125 | |
126 /* str*,mem*,b* */ | |
127 | |
128 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n) | |
129 { | |
130 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
131 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source"); | |
132 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest"); | |
133 return memcpy (dest, src, n); | |
134 } | |
135 | |
136 | |
137 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n) | |
138 { | |
139 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
140 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src"); | |
141 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest"); | |
142 return memmove (dest, src, n); | |
143 } | |
144 | |
145 | |
146 WRAPPER2(void *, memset, void *s, int c, size_t n) | |
147 { | |
148 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
149 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest"); | |
150 return memset (s, c, n); | |
151 } | |
152 | |
153 | |
154 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n) | |
155 { | |
156 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
157 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg"); | |
158 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg"); | |
159 return memcmp (s1, s2, n); | |
160 } | |
161 | |
162 | |
163 WRAPPER2(void *, memchr, const void *s, int c, size_t n) | |
164 { | |
165 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
166 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region"); | |
167 return memchr (s, c, n); | |
168 } | |
169 | |
170 | |
171 #ifdef HAVE_MEMRCHR | |
172 WRAPPER2(void *, memrchr, const void *s, int c, size_t n) | |
173 { | |
174 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
175 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region"); | |
176 return memrchr (s, c, n); | |
177 } | |
178 #endif | |
179 | |
180 | |
181 WRAPPER2(char *, strcpy, char *dest, const char *src) | |
182 { | |
183 /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n + | |
184 1) are valid pointers. the allocated object might have size < n. | |
185 check anyways. */ | |
186 | |
187 size_t n = strlen (src); | |
188 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
189 MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src"); | |
190 MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest"); | |
191 return strcpy (dest, src); | |
192 } | |
193 | |
194 | |
195 #ifdef HAVE_STRNCPY | |
196 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n) | |
197 { | |
198 size_t len = strnlen (src, n); | |
199 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
200 MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src"); | |
201 MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */ | |
202 return strncpy (dest, src, n); | |
203 } | |
204 #endif | |
205 | |
206 | |
207 WRAPPER2(char *, strcat, char *dest, const char *src) | |
208 { | |
209 size_t dest_sz; | |
210 size_t src_sz; | |
211 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
212 dest_sz = strlen (dest); | |
213 src_sz = strlen (src); | |
214 MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src"); | |
215 MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)), | |
216 __MF_CHECK_WRITE, "strcat dest"); | |
217 return strcat (dest, src); | |
218 } | |
219 | |
220 | |
221 WRAPPER2(char *, strncat, char *dest, const char *src, size_t n) | |
222 { | |
223 | |
224 /* nb: validating the extents (s,n) might be a mistake for two reasons. | |
225 | |
226 (1) the string s might be shorter than n chars, and n is just a | |
227 poor choice by the programmer. this is not a "true" error in the | |
228 sense that the call to strncat would still be ok. | |
229 | |
230 (2) we could try to compensate for case (1) by calling strlen(s) and | |
231 using that as a bound for the extent to verify, but strlen might fall off | |
232 the end of a non-terminated string, leading to a false positive. | |
233 | |
234 so we will call strnlen(s,n) and use that as a bound. | |
235 | |
236 if strnlen returns a length beyond the end of the registered extent | |
237 associated with s, there is an error: the programmer's estimate for n is | |
238 too large _AND_ the string s is unterminated, in which case they'd be | |
239 about to touch memory they don't own while calling strncat. | |
240 | |
241 this same logic applies to further uses of strnlen later down in this | |
242 file. */ | |
243 | |
244 size_t src_sz; | |
245 size_t dest_sz; | |
246 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
247 src_sz = strnlen (src, n); | |
248 dest_sz = strnlen (dest, n); | |
249 MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src"); | |
250 MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))), | |
251 __MF_CHECK_WRITE, "strncat dest"); | |
252 return strncat (dest, src, n); | |
253 } | |
254 | |
255 | |
256 WRAPPER2(int, strcmp, const char *s1, const char *s2) | |
257 { | |
258 size_t s1_sz; | |
259 size_t s2_sz; | |
260 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
261 s1_sz = strlen (s1); | |
262 s2_sz = strlen (s2); | |
263 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg"); | |
264 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg"); | |
265 return strcmp (s1, s2); | |
266 } | |
267 | |
268 | |
269 WRAPPER2(int, strcasecmp, const char *s1, const char *s2) | |
270 { | |
271 size_t s1_sz; | |
272 size_t s2_sz; | |
273 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
274 s1_sz = strlen (s1); | |
275 s2_sz = strlen (s2); | |
276 MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg"); | |
277 MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg"); | |
278 return strcasecmp (s1, s2); | |
279 } | |
280 | |
281 | |
282 WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n) | |
283 { | |
284 size_t s1_sz; | |
285 size_t s2_sz; | |
286 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
287 s1_sz = strnlen (s1, n); | |
288 s2_sz = strnlen (s2, n); | |
289 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg"); | |
290 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg"); | |
291 return strncmp (s1, s2, n); | |
292 } | |
293 | |
294 | |
295 WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n) | |
296 { | |
297 size_t s1_sz; | |
298 size_t s2_sz; | |
299 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
300 s1_sz = strnlen (s1, n); | |
301 s2_sz = strnlen (s2, n); | |
302 MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg"); | |
303 MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg"); | |
304 return strncasecmp (s1, s2, n); | |
305 } | |
306 | |
307 | |
308 WRAPPER2(char *, strdup, const char *s) | |
309 { | |
310 DECLARE(void *, malloc, size_t sz); | |
311 char *result; | |
312 size_t n = strlen (s); | |
313 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
314 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region"); | |
315 result = (char *)CALL_REAL(malloc, | |
316 CLAMPADD(CLAMPADD(n,1), | |
317 CLAMPADD(__mf_opts.crumple_zone, | |
318 __mf_opts.crumple_zone))); | |
319 | |
320 if (UNLIKELY(! result)) return result; | |
321 | |
322 result += __mf_opts.crumple_zone; | |
323 memcpy (result, s, n); | |
324 result[n] = '\0'; | |
325 | |
326 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region"); | |
327 return result; | |
328 } | |
329 | |
330 | |
331 WRAPPER2(char *, strndup, const char *s, size_t n) | |
332 { | |
333 DECLARE(void *, malloc, size_t sz); | |
334 char *result; | |
335 size_t sz = strnlen (s, n); | |
336 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
337 MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */ | |
338 | |
339 /* note: strndup still adds a \0, even with the N limit! */ | |
340 result = (char *)CALL_REAL(malloc, | |
341 CLAMPADD(CLAMPADD(n,1), | |
342 CLAMPADD(__mf_opts.crumple_zone, | |
343 __mf_opts.crumple_zone))); | |
344 | |
345 if (UNLIKELY(! result)) return result; | |
346 | |
347 result += __mf_opts.crumple_zone; | |
348 memcpy (result, s, n); | |
349 result[n] = '\0'; | |
350 | |
351 __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region"); | |
352 return result; | |
353 } | |
354 | |
355 | |
356 WRAPPER2(char *, strchr, const char *s, int c) | |
357 { | |
358 size_t n; | |
359 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
360 n = strlen (s); | |
361 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region"); | |
362 return strchr (s, c); | |
363 } | |
364 | |
365 | |
366 WRAPPER2(char *, strrchr, const char *s, int c) | |
367 { | |
368 size_t n; | |
369 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
370 n = strlen (s); | |
371 MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region"); | |
372 return strrchr (s, c); | |
373 } | |
374 | |
375 | |
376 WRAPPER2(char *, strstr, const char *haystack, const char *needle) | |
377 { | |
378 size_t haystack_sz; | |
379 size_t needle_sz; | |
380 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
381 haystack_sz = strlen (haystack); | |
382 needle_sz = strlen (needle); | |
383 MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack"); | |
384 MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle"); | |
385 return strstr (haystack, needle); | |
386 } | |
387 | |
388 | |
389 #ifdef HAVE_MEMMEM | |
390 WRAPPER2(void *, memmem, | |
391 const void *haystack, size_t haystacklen, | |
392 const void *needle, size_t needlelen) | |
393 { | |
394 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
395 MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack"); | |
396 MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle"); | |
397 return memmem (haystack, haystacklen, needle, needlelen); | |
398 } | |
399 #endif | |
400 | |
401 | |
402 WRAPPER2(size_t, strlen, const char *s) | |
403 { | |
404 size_t result = strlen (s); | |
405 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
406 MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region"); | |
407 return result; | |
408 } | |
409 | |
410 | |
411 WRAPPER2(size_t, strnlen, const char *s, size_t n) | |
412 { | |
413 size_t result = strnlen (s, n); | |
414 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
415 MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region"); | |
416 return result; | |
417 } | |
418 | |
419 | |
420 WRAPPER2(void, bzero, void *s, size_t n) | |
421 { | |
422 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
423 MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region"); | |
424 bzero (s, n); | |
425 } | |
426 | |
427 | |
428 #undef bcopy | |
429 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n) | |
430 { | |
431 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
432 MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src"); | |
433 MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest"); | |
434 bcopy (src, dest, n); | |
435 } | |
436 | |
437 | |
438 #undef bcmp | |
439 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n) | |
440 { | |
441 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
442 MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg"); | |
443 MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg"); | |
444 return bcmp (s1, s2, n); | |
445 } | |
446 | |
447 | |
448 WRAPPER2(char *, index, const char *s, int c) | |
449 { | |
450 size_t n = strlen (s); | |
451 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
452 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region"); | |
453 return index (s, c); | |
454 } | |
455 | |
456 | |
457 WRAPPER2(char *, rindex, const char *s, int c) | |
458 { | |
459 size_t n = strlen (s); | |
460 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
461 MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region"); | |
462 return rindex (s, c); | |
463 } | |
464 | |
465 /* XXX: stpcpy, memccpy */ | |
466 | |
467 /* XXX: *printf,*scanf */ | |
468 | |
469 /* XXX: setjmp, longjmp */ | |
470 | |
471 WRAPPER2(char *, asctime, struct tm *tm) | |
472 { | |
473 static char *reg_result = NULL; | |
474 char *result; | |
475 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
476 MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm"); | |
477 result = asctime (tm); | |
478 if (reg_result == NULL) | |
479 { | |
480 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string"); | |
481 reg_result = result; | |
482 } | |
483 return result; | |
484 } | |
485 | |
486 | |
487 WRAPPER2(char *, ctime, const time_t *timep) | |
488 { | |
489 static char *reg_result = NULL; | |
490 char *result; | |
491 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
492 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time"); | |
493 result = ctime (timep); | |
494 if (reg_result == NULL) | |
495 { | |
496 /* XXX: what if asctime and ctime return the same static ptr? */ | |
497 __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string"); | |
498 reg_result = result; | |
499 } | |
500 return result; | |
501 } | |
502 | |
503 | |
504 WRAPPER2(struct tm*, localtime, const time_t *timep) | |
505 { | |
506 static struct tm *reg_result = NULL; | |
507 struct tm *result; | |
508 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
509 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time"); | |
510 result = localtime (timep); | |
511 if (reg_result == NULL) | |
512 { | |
513 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm"); | |
514 reg_result = result; | |
515 } | |
516 return result; | |
517 } | |
518 | |
519 | |
520 WRAPPER2(struct tm*, gmtime, const time_t *timep) | |
521 { | |
522 static struct tm *reg_result = NULL; | |
523 struct tm *result; | |
524 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
525 MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time"); | |
526 result = gmtime (timep); | |
527 if (reg_result == NULL) | |
528 { | |
529 __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm"); | |
530 reg_result = result; | |
531 } | |
532 return result; | |
533 } | |
534 | |
535 | |
536 /* EL start */ | |
537 | |
538 /* The following indicate if the result of the corresponding function | |
539 * should be explicitly un/registered by the wrapper | |
540 */ | |
541 | |
542 #ifdef __FreeBSD__ | |
543 #define MF_REGISTER_fopen __MF_TYPE_STATIC | |
544 #else | |
545 #undef MF_REGISTER_fopen | |
546 #endif | |
547 #define MF_RESULT_SIZE_fopen (sizeof (FILE)) | |
548 | |
549 #undef MF_REGISTER_opendir | |
550 #define MF_RESULT_SIZE_opendir 0 /* (sizeof (DIR)) */ | |
551 #undef MF_REGISTER_readdir | |
552 #define MF_REGISTER_gethostbyname __MF_TYPE_STATIC | |
553 #undef MF_REGISTER_gethostbyname_items | |
554 #undef MF_REGISTER_dlopen | |
555 #undef MF_REGISTER_dlerror | |
556 #undef MF_REGISTER_dlsym | |
557 #define MF_REGISTER_shmat __MF_TYPE_GUESS | |
558 | |
559 | |
560 #include <time.h> | |
561 WRAPPER2(time_t, time, time_t *timep) | |
562 { | |
563 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
564 if (NULL != timep) | |
565 MF_VALIDATE_EXTENT (timep, sizeof (*timep), __MF_CHECK_WRITE, | |
566 "time timep"); | |
567 return time (timep); | |
568 } | |
569 | |
570 | |
571 WRAPPER2(char *, strerror, int errnum) | |
572 { | |
573 char *p; | |
574 static char * last_strerror = NULL; | |
575 | |
576 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
577 p = strerror (errnum); | |
578 if (last_strerror != NULL) | |
579 __mf_unregister (last_strerror, 0, __MF_TYPE_STATIC); | |
580 if (NULL != p) | |
581 __mf_register (p, strlen (p) + 1, __MF_TYPE_STATIC, "strerror result"); | |
582 last_strerror = p; | |
583 return p; | |
584 } | |
585 | |
586 | |
587 | |
588 /* An auxiliary data structure for tracking the hand-made stdio | |
589 buffers we generate during the fopen/fopen64 hooks. In a civilized | |
590 language, this would be a simple dynamically sized FILE*->char* | |
591 lookup table, but this is C and we get to do it by hand. */ | |
592 struct mf_filebuffer | |
593 { | |
594 FILE *file; | |
595 char *buffer; | |
596 struct mf_filebuffer *next; | |
597 }; | |
598 static struct mf_filebuffer *mf_filebuffers = NULL; | |
599 | |
600 static void | |
601 mkbuffer (FILE *f) | |
602 { | |
603 /* Reset any buffer automatically provided by libc, since this may | |
604 have been done via mechanisms that libmudflap couldn't | |
605 intercept. */ | |
606 int rc; | |
607 size_t bufsize = BUFSIZ; | |
608 int bufmode; | |
609 char *buffer = malloc (bufsize); | |
610 struct mf_filebuffer *b = malloc (sizeof (struct mf_filebuffer)); | |
611 assert ((buffer != NULL) && (b != NULL)); | |
612 | |
613 /* Link it into list. */ | |
614 b->file = f; | |
615 b->buffer = buffer; | |
616 b->next = mf_filebuffers; | |
617 mf_filebuffers = b; | |
618 | |
619 /* Determine how the file is supposed to be buffered at the moment. */ | |
620 bufmode = fileno (f) == 2 ? _IONBF : (isatty (fileno (f)) ? _IOLBF : _IOFBF); | |
621 | |
622 rc = setvbuf (f, buffer, bufmode, bufsize); | |
623 assert (rc == 0); | |
624 } | |
625 | |
626 static void | |
627 unmkbuffer (FILE *f) | |
628 { | |
629 struct mf_filebuffer *b = mf_filebuffers; | |
630 struct mf_filebuffer **pb = & mf_filebuffers; | |
631 while (b != NULL) | |
632 { | |
633 if (b->file == f) | |
634 { | |
635 *pb = b->next; | |
636 free (b->buffer); | |
637 free (b); | |
638 return; | |
639 } | |
640 pb = & b->next; | |
641 b = b->next; | |
642 } | |
643 } | |
644 | |
645 | |
646 | |
647 WRAPPER2(FILE *, fopen, const char *path, const char *mode) | |
648 { | |
649 size_t n; | |
650 FILE *p; | |
651 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
652 | |
653 n = strlen (path); | |
654 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path"); | |
655 | |
656 n = strlen (mode); | |
657 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode"); | |
658 | |
659 p = fopen (path, mode); | |
660 if (NULL != p) { | |
661 #ifdef MF_REGISTER_fopen | |
662 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result"); | |
663 #endif | |
664 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result"); | |
665 | |
666 mkbuffer (p); | |
667 } | |
668 | |
669 return p; | |
670 } | |
671 | |
672 | |
673 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode, size_t size) | |
674 { | |
675 int rc = 0; | |
676 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
677 | |
678 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, "setvbuf stream"); | |
679 | |
680 unmkbuffer (stream); | |
681 | |
682 if (buf != NULL) | |
683 MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_WRITE, "setvbuf buffer"); | |
684 | |
685 /* Override the user only if it's an auto-allocated buffer request. Otherwise | |
686 assume that the supplied buffer is already known to libmudflap. */ | |
687 if ((buf == NULL) && ((mode == _IOFBF) || (mode == _IOLBF))) | |
688 mkbuffer (stream); | |
689 else | |
690 rc = setvbuf (stream, buf, mode, size); | |
691 | |
692 return rc; | |
693 } | |
694 | |
695 | |
696 #ifdef HAVE_SETBUF | |
697 WRAPPER2(int, setbuf, FILE* stream, char *buf) | |
698 { | |
699 return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); | |
700 } | |
701 #endif | |
702 | |
703 #ifdef HAVE_SETBUFFER | |
704 WRAPPER2(int, setbuffer, FILE* stream, char *buf, size_t sz) | |
705 { | |
706 return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, sz); | |
707 } | |
708 #endif | |
709 | |
710 #ifdef HAVE_SETLINEBUF | |
711 WRAPPER2(int, setlinebuf, FILE* stream) | |
712 { | |
713 return __mfwrap_setvbuf(stream, NULL, _IOLBF, 0); | |
714 } | |
715 #endif | |
716 | |
717 | |
718 | |
719 WRAPPER2(FILE *, fdopen, int fd, const char *mode) | |
720 { | |
721 size_t n; | |
722 FILE *p; | |
723 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
724 | |
725 n = strlen (mode); | |
726 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fdopen mode"); | |
727 | |
728 p = fdopen (fd, mode); | |
729 if (NULL != p) { | |
730 #ifdef MF_REGISTER_fopen | |
731 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fdopen result"); | |
732 #endif | |
733 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fdopen result"); | |
734 | |
735 mkbuffer (p); | |
736 } | |
737 | |
738 return p; | |
739 } | |
740 | |
741 | |
742 WRAPPER2(FILE *, freopen, const char *path, const char *mode, FILE *s) | |
743 { | |
744 size_t n; | |
745 FILE *p; | |
746 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
747 | |
748 n = strlen (path); | |
749 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen path"); | |
750 | |
751 MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen stream"); | |
752 unmkbuffer (s); | |
753 | |
754 n = strlen (mode); | |
755 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen mode"); | |
756 | |
757 p = freopen (path, mode, s); | |
758 if (NULL != p) { | |
759 #ifdef MF_REGISTER_fopen | |
760 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen result"); | |
761 #endif | |
762 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen result"); | |
763 | |
764 mkbuffer (p); | |
765 } | |
766 | |
767 return p; | |
768 } | |
769 | |
770 | |
771 #ifdef HAVE_FOPEN64 | |
772 WRAPPER2(FILE *, fopen64, const char *path, const char *mode) | |
773 { | |
774 size_t n; | |
775 FILE *p; | |
776 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
777 | |
778 n = strlen (path); | |
779 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path"); | |
780 | |
781 n = strlen (mode); | |
782 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode"); | |
783 | |
784 p = fopen64 (path, mode); | |
785 if (NULL != p) { | |
786 #ifdef MF_REGISTER_fopen | |
787 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result"); | |
788 #endif | |
789 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result"); | |
790 | |
791 mkbuffer (p); | |
792 } | |
793 | |
794 return p; | |
795 } | |
796 #endif | |
797 | |
798 | |
799 #ifdef HAVE_FREOPEN64 | |
800 WRAPPER2(FILE *, freopen64, const char *path, const char *mode, FILE *s) | |
801 { | |
802 size_t n; | |
803 FILE *p; | |
804 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
805 | |
806 n = strlen (path); | |
807 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 path"); | |
808 | |
809 MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen64 stream"); | |
810 unmkbuffer (s); | |
811 | |
812 n = strlen (mode); | |
813 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 mode"); | |
814 | |
815 p = freopen (path, mode, s); | |
816 if (NULL != p) { | |
817 #ifdef MF_REGISTER_fopen | |
818 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen64 result"); | |
819 #endif | |
820 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen64 result"); | |
821 | |
822 mkbuffer (p); | |
823 } | |
824 | |
825 return p; | |
826 } | |
827 #endif | |
828 | |
829 | |
830 WRAPPER2(int, fclose, FILE *stream) | |
831 { | |
832 int resp; | |
833 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
834 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
835 "fclose stream"); | |
836 resp = fclose (stream); | |
837 #ifdef MF_REGISTER_fopen | |
838 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen); | |
839 #endif | |
840 unmkbuffer (stream); | |
841 | |
842 return resp; | |
843 } | |
844 | |
845 | |
846 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream) | |
847 { | |
848 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
849 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
850 "fread stream"); | |
851 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer"); | |
852 return fread (ptr, size, nmemb, stream); | |
853 } | |
854 | |
855 | |
856 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb, | |
857 FILE *stream) | |
858 { | |
859 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
860 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
861 "fwrite stream"); | |
862 MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer"); | |
863 return fwrite (ptr, size, nmemb, stream); | |
864 } | |
865 | |
866 | |
867 WRAPPER2(int, fgetc, FILE *stream) | |
868 { | |
869 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
870 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
871 "fgetc stream"); | |
872 return fgetc (stream); | |
873 } | |
874 | |
875 | |
876 WRAPPER2(char *, fgets, char *s, int size, FILE *stream) | |
877 { | |
878 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
879 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
880 "fgets stream"); | |
881 MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer"); | |
882 return fgets (s, size, stream); | |
883 } | |
884 | |
885 | |
886 WRAPPER2(int, getc, FILE *stream) | |
887 { | |
888 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
889 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
890 "getc stream"); | |
891 return getc (stream); | |
892 } | |
893 | |
894 | |
895 WRAPPER2(char *, gets, char *s) | |
896 { | |
897 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
898 MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer"); | |
899 /* Avoid link-time warning... */ | |
900 s = fgets (s, INT_MAX, stdin); | |
901 if (NULL != s) { /* better late than never */ | |
902 size_t n = strlen (s); | |
903 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer"); | |
904 } | |
905 return s; | |
906 } | |
907 | |
908 | |
909 WRAPPER2(int, ungetc, int c, FILE *stream) | |
910 { | |
911 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
912 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
913 "ungetc stream"); | |
914 return ungetc (c, stream); | |
915 } | |
916 | |
917 | |
918 WRAPPER2(int, fputc, int c, FILE *stream) | |
919 { | |
920 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
921 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
922 "fputc stream"); | |
923 return fputc (c, stream); | |
924 } | |
925 | |
926 | |
927 WRAPPER2(int, fputs, const char *s, FILE *stream) | |
928 { | |
929 size_t n; | |
930 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
931 n = strlen (s); | |
932 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer"); | |
933 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
934 "fputs stream"); | |
935 return fputs (s, stream); | |
936 } | |
937 | |
938 | |
939 WRAPPER2(int, putc, int c, FILE *stream) | |
940 { | |
941 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
942 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
943 "putc stream"); | |
944 return putc (c, stream); | |
945 } | |
946 | |
947 | |
948 WRAPPER2(int, puts, const char *s) | |
949 { | |
950 size_t n; | |
951 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
952 n = strlen (s); | |
953 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer"); | |
954 return puts (s); | |
955 } | |
956 | |
957 | |
958 WRAPPER2(void, clearerr, FILE *stream) | |
959 { | |
960 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
961 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
962 "clearerr stream"); | |
963 clearerr (stream); | |
964 } | |
965 | |
966 | |
967 WRAPPER2(int, feof, FILE *stream) | |
968 { | |
969 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
970 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
971 "feof stream"); | |
972 return feof (stream); | |
973 } | |
974 | |
975 | |
976 WRAPPER2(int, ferror, FILE *stream) | |
977 { | |
978 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
979 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
980 "ferror stream"); | |
981 return ferror (stream); | |
982 } | |
983 | |
984 | |
985 WRAPPER2(int, fileno, FILE *stream) | |
986 { | |
987 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
988 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
989 "fileno stream"); | |
990 return fileno (stream); | |
991 } | |
992 | |
993 | |
994 WRAPPER2(int, printf, const char *format, ...) | |
995 { | |
996 size_t n; | |
997 va_list ap; | |
998 int result; | |
999 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1000 n = strlen (format); | |
1001 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1002 "printf format"); | |
1003 va_start (ap, format); | |
1004 result = vprintf (format, ap); | |
1005 va_end (ap); | |
1006 return result; | |
1007 } | |
1008 | |
1009 | |
1010 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...) | |
1011 { | |
1012 size_t n; | |
1013 va_list ap; | |
1014 int result; | |
1015 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1016 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1017 "fprintf stream"); | |
1018 n = strlen (format); | |
1019 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1020 "fprintf format"); | |
1021 va_start (ap, format); | |
1022 result = vfprintf (stream, format, ap); | |
1023 va_end (ap); | |
1024 return result; | |
1025 } | |
1026 | |
1027 | |
1028 WRAPPER2(int, sprintf, char *str, const char *format, ...) | |
1029 { | |
1030 size_t n; | |
1031 va_list ap; | |
1032 int result; | |
1033 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1034 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str"); | |
1035 n = strlen (format); | |
1036 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1037 "sprintf format"); | |
1038 va_start (ap, format); | |
1039 result = vsprintf (str, format, ap); | |
1040 va_end (ap); | |
1041 n = strlen (str); | |
1042 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str"); | |
1043 return result; | |
1044 } | |
1045 | |
1046 | |
1047 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...) | |
1048 { | |
1049 size_t n; | |
1050 va_list ap; | |
1051 int result; | |
1052 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1053 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str"); | |
1054 n = strlen (format); | |
1055 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1056 "snprintf format"); | |
1057 va_start (ap, format); | |
1058 result = vsnprintf (str, size, format, ap); | |
1059 va_end (ap); | |
1060 return result; | |
1061 } | |
1062 | |
1063 | |
1064 WRAPPER2(int, vprintf, const char *format, va_list ap) | |
1065 { | |
1066 size_t n; | |
1067 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1068 n = strlen (format); | |
1069 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1070 "vprintf format"); | |
1071 return vprintf (format, ap); | |
1072 } | |
1073 | |
1074 | |
1075 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap) | |
1076 { | |
1077 size_t n; | |
1078 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1079 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1080 "vfprintf stream"); | |
1081 n = strlen (format); | |
1082 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1083 "vfprintf format"); | |
1084 return vfprintf (stream, format, ap); | |
1085 } | |
1086 | |
1087 | |
1088 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap) | |
1089 { | |
1090 size_t n; | |
1091 int result; | |
1092 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1093 MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str"); | |
1094 n = strlen (format); | |
1095 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1096 "vsprintf format"); | |
1097 result = vsprintf (str, format, ap); | |
1098 n = strlen (str); | |
1099 MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str"); | |
1100 return result; | |
1101 } | |
1102 | |
1103 | |
1104 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format, | |
1105 va_list ap) | |
1106 { | |
1107 size_t n; | |
1108 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1109 MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str"); | |
1110 n = strlen (format); | |
1111 MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1112 "vsnprintf format"); | |
1113 return vsnprintf (str, size, format, ap); | |
1114 } | |
1115 | |
1116 | |
1117 WRAPPER2(int , access, const char *path, int mode) | |
1118 { | |
1119 size_t n; | |
1120 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1121 n = strlen (path); | |
1122 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path"); | |
1123 return access (path, mode); | |
1124 } | |
1125 | |
1126 | |
1127 WRAPPER2(int , remove, const char *path) | |
1128 { | |
1129 size_t n; | |
1130 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1131 n = strlen (path); | |
1132 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path"); | |
1133 return remove (path); | |
1134 } | |
1135 | |
1136 | |
1137 WRAPPER2(int, fflush, FILE *stream) | |
1138 { | |
1139 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1140 if (stream != NULL) | |
1141 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1142 "fflush stream"); | |
1143 return fflush (stream); | |
1144 } | |
1145 | |
1146 | |
1147 WRAPPER2(int, fseek, FILE *stream, long offset, int whence) | |
1148 { | |
1149 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1150 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1151 "fseek stream"); | |
1152 return fseek (stream, offset, whence); | |
1153 } | |
1154 | |
1155 | |
1156 #ifdef HAVE_FSEEKO64 | |
1157 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence) | |
1158 { | |
1159 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1160 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1161 "fseeko64 stream"); | |
1162 return fseeko64 (stream, offset, whence); | |
1163 } | |
1164 #endif | |
1165 | |
1166 | |
1167 WRAPPER2(long, ftell, FILE *stream) | |
1168 { | |
1169 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1170 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1171 "ftell stream"); | |
1172 return ftell (stream); | |
1173 } | |
1174 | |
1175 | |
1176 #ifdef HAVE_FTELLO64 | |
1177 WRAPPER2(off64_t, ftello64, FILE *stream) | |
1178 { | |
1179 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1180 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1181 "ftello64 stream"); | |
1182 return ftello64 (stream); | |
1183 } | |
1184 #endif | |
1185 | |
1186 | |
1187 WRAPPER2(void, rewind, FILE *stream) | |
1188 { | |
1189 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1190 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1191 "rewind stream"); | |
1192 rewind (stream); | |
1193 } | |
1194 | |
1195 | |
1196 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos) | |
1197 { | |
1198 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1199 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1200 "fgetpos stream"); | |
1201 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos"); | |
1202 return fgetpos (stream, pos); | |
1203 } | |
1204 | |
1205 | |
1206 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos) | |
1207 { | |
1208 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1209 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1210 "fsetpos stream"); | |
1211 MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos"); | |
1212 return fsetpos (stream, pos); | |
1213 } | |
1214 | |
1215 | |
1216 WRAPPER2(int , stat, const char *path, struct stat *buf) | |
1217 { | |
1218 size_t n; | |
1219 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1220 n = strlen (path); | |
1221 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path"); | |
1222 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf"); | |
1223 return stat (path, buf); | |
1224 } | |
1225 | |
1226 | |
1227 #ifdef HAVE_STAT64 | |
1228 WRAPPER2(int , stat64, const char *path, struct stat64 *buf) | |
1229 { | |
1230 size_t n; | |
1231 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1232 n = strlen (path); | |
1233 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path"); | |
1234 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf"); | |
1235 return stat64 (path, buf); | |
1236 } | |
1237 #endif | |
1238 | |
1239 | |
1240 WRAPPER2(int , fstat, int filedes, struct stat *buf) | |
1241 { | |
1242 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1243 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf"); | |
1244 return fstat (filedes, buf); | |
1245 } | |
1246 | |
1247 | |
1248 WRAPPER2(int , lstat, const char *path, struct stat *buf) | |
1249 { | |
1250 size_t n; | |
1251 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1252 n = strlen (path); | |
1253 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path"); | |
1254 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf"); | |
1255 return lstat (path, buf); | |
1256 } | |
1257 | |
1258 | |
1259 WRAPPER2(int , mkfifo, const char *path, mode_t mode) | |
1260 { | |
1261 size_t n; | |
1262 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1263 n = strlen (path); | |
1264 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path"); | |
1265 return mkfifo (path, mode); | |
1266 } | |
1267 | |
1268 | |
1269 #ifdef HAVE_DIRENT_H | |
1270 WRAPPER2(DIR *, opendir, const char *path) | |
1271 { | |
1272 DIR *p; | |
1273 size_t n; | |
1274 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1275 n = strlen (path); | |
1276 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path"); | |
1277 | |
1278 p = opendir (path); | |
1279 if (NULL != p) { | |
1280 #ifdef MF_REGISTER_opendir | |
1281 __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir, | |
1282 "opendir result"); | |
1283 #endif | |
1284 MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE, | |
1285 "opendir result"); | |
1286 } | |
1287 return p; | |
1288 } | |
1289 | |
1290 | |
1291 WRAPPER2(int, closedir, DIR *dir) | |
1292 { | |
1293 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1294 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir"); | |
1295 #ifdef MF_REGISTER_opendir | |
1296 __mf_unregister (dir, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir); | |
1297 #endif | |
1298 return closedir (dir); | |
1299 } | |
1300 | |
1301 | |
1302 WRAPPER2(struct dirent *, readdir, DIR *dir) | |
1303 { | |
1304 struct dirent *p; | |
1305 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1306 MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir"); | |
1307 p = readdir (dir); | |
1308 if (NULL != p) { | |
1309 #ifdef MF_REGISTER_readdir | |
1310 __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result"); | |
1311 #endif | |
1312 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result"); | |
1313 } | |
1314 return p; | |
1315 } | |
1316 #endif | |
1317 | |
1318 | |
1319 #ifdef HAVE_SYS_SOCKET_H | |
1320 | |
1321 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags) | |
1322 { | |
1323 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1324 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf"); | |
1325 return recv (s, buf, len, flags); | |
1326 } | |
1327 | |
1328 | |
1329 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags, | |
1330 struct sockaddr *from, socklen_t *fromlen) | |
1331 { | |
1332 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1333 MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf"); | |
1334 MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE, | |
1335 "recvfrom from"); | |
1336 return recvfrom (s, buf, len, flags, from, fromlen); | |
1337 } | |
1338 | |
1339 | |
1340 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags) | |
1341 { | |
1342 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1343 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg"); | |
1344 return recvmsg (s, msg, flags); | |
1345 } | |
1346 | |
1347 | |
1348 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags) | |
1349 { | |
1350 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1351 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg"); | |
1352 return send (s, msg, len, flags); | |
1353 } | |
1354 | |
1355 | |
1356 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags, | |
1357 const struct sockaddr *to, socklen_t tolen) | |
1358 { | |
1359 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1360 MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg"); | |
1361 MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to"); | |
1362 return sendto (s, msg, len, flags, to, tolen); | |
1363 } | |
1364 | |
1365 | |
1366 WRAPPER2(int, sendmsg, int s, const void *msg, int flags) | |
1367 { | |
1368 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1369 MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg"); | |
1370 return sendmsg (s, msg, flags); | |
1371 } | |
1372 | |
1373 | |
1374 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval, | |
1375 socklen_t optlen) | |
1376 { | |
1377 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1378 MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ, | |
1379 "setsockopt optval"); | |
1380 return setsockopt (s, level, optname, optval, optlen); | |
1381 } | |
1382 | |
1383 | |
1384 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval, | |
1385 socklen_t *optlen) | |
1386 { | |
1387 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1388 MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE, | |
1389 "getsockopt optval"); | |
1390 return getsockopt (s, level, optname, optval, optlen); | |
1391 } | |
1392 | |
1393 | |
1394 WRAPPER2(int, accept, int s, struct sockaddr *addr, socklen_t *addrlen) | |
1395 { | |
1396 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1397 if (addr != NULL) | |
1398 MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr"); | |
1399 return accept (s, addr, addrlen); | |
1400 } | |
1401 | |
1402 | |
1403 WRAPPER2(int, bind, int sockfd, struct sockaddr *addr, socklen_t addrlen) | |
1404 { | |
1405 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1406 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr"); | |
1407 return bind (sockfd, addr, addrlen); | |
1408 } | |
1409 | |
1410 | |
1411 WRAPPER2(int, connect, int sockfd, const struct sockaddr *addr, | |
1412 socklen_t addrlen) | |
1413 { | |
1414 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1415 MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ, | |
1416 "connect addr"); | |
1417 return connect (sockfd, addr, addrlen); | |
1418 } | |
1419 | |
1420 #endif /* HAVE_SYS_SOCKET_H */ | |
1421 | |
1422 | |
1423 WRAPPER2(int, gethostname, char *name, size_t len) | |
1424 { | |
1425 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1426 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name"); | |
1427 return gethostname (name, len); | |
1428 } | |
1429 | |
1430 | |
1431 #ifdef HAVE_SETHOSTNAME | |
1432 WRAPPER2(int, sethostname, const char *name, size_t len) | |
1433 { | |
1434 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1435 MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name"); | |
1436 return sethostname (name, len); | |
1437 } | |
1438 #endif | |
1439 | |
1440 | |
1441 #ifdef HAVE_NETDB_H | |
1442 | |
1443 WRAPPER2(struct hostent *, gethostbyname, const char *name) | |
1444 { | |
1445 struct hostent *p; | |
1446 char **ss; | |
1447 char *s; | |
1448 size_t n; | |
1449 int nreg; | |
1450 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1451 n = strlen (name); | |
1452 MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1453 "gethostbyname name"); | |
1454 p = gethostbyname (name); | |
1455 if (NULL != p) { | |
1456 #ifdef MF_REGISTER_gethostbyname | |
1457 __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname, | |
1458 "gethostbyname result"); | |
1459 #endif | |
1460 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, | |
1461 "gethostbyname result"); | |
1462 if (NULL != (s = p->h_name)) { | |
1463 n = strlen (s); | |
1464 n = CLAMPADD(n, 1); | |
1465 #ifdef MF_REGISTER_gethostbyname_items | |
1466 __mf_register (s, n, MF_REGISTER_gethostbyname_items, | |
1467 "gethostbyname result->h_name"); | |
1468 #endif | |
1469 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE, | |
1470 "gethostbyname result->h_name"); | |
1471 } | |
1472 | |
1473 if (NULL != (ss = p->h_aliases)) { | |
1474 for (nreg = 1;; ++nreg) { | |
1475 s = *ss++; | |
1476 if (NULL == s) | |
1477 break; | |
1478 n = strlen (s); | |
1479 n = CLAMPADD(n, 1); | |
1480 #ifdef MF_REGISTER_gethostbyname_items | |
1481 __mf_register (s, n, MF_REGISTER_gethostbyname_items, | |
1482 "gethostbyname result->h_aliases[]"); | |
1483 #endif | |
1484 MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE, | |
1485 "gethostbyname result->h_aliases[]"); | |
1486 } | |
1487 nreg *= sizeof (*p->h_aliases); | |
1488 #ifdef MF_REGISTER_gethostbyname_items | |
1489 __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items, | |
1490 "gethostbyname result->h_aliases"); | |
1491 #endif | |
1492 MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE, | |
1493 "gethostbyname result->h_aliases"); | |
1494 } | |
1495 | |
1496 if (NULL != (ss = p->h_addr_list)) { | |
1497 for (nreg = 1;; ++nreg) { | |
1498 s = *ss++; | |
1499 if (NULL == s) | |
1500 break; | |
1501 #ifdef MF_REGISTER_gethostbyname_items | |
1502 __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items, | |
1503 "gethostbyname result->h_addr_list[]"); | |
1504 #endif | |
1505 MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE, | |
1506 "gethostbyname result->h_addr_list[]"); | |
1507 } | |
1508 nreg *= sizeof (*p->h_addr_list); | |
1509 #ifdef MF_REGISTER_gethostbyname_items | |
1510 __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items, | |
1511 "gethostbyname result->h_addr_list"); | |
1512 #endif | |
1513 MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE, | |
1514 "gethostbyname result->h_addr_list"); | |
1515 } | |
1516 } | |
1517 return p; | |
1518 } | |
1519 | |
1520 #endif /* HAVE_NETDB_H */ | |
1521 | |
1522 | |
1523 #ifdef HAVE_SYS_WAIT_H | |
1524 | |
1525 WRAPPER2(pid_t, wait, int *status) | |
1526 { | |
1527 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1528 if (NULL != status) | |
1529 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE, | |
1530 "wait status"); | |
1531 return wait (status); | |
1532 } | |
1533 | |
1534 | |
1535 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options) | |
1536 { | |
1537 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1538 if (NULL != status) | |
1539 MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE, | |
1540 "waitpid status"); | |
1541 return waitpid (pid, status, options); | |
1542 } | |
1543 | |
1544 #endif /* HAVE_SYS_WAIT_H */ | |
1545 | |
1546 | |
1547 WRAPPER2(FILE *, popen, const char *command, const char *mode) | |
1548 { | |
1549 size_t n; | |
1550 FILE *p; | |
1551 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1552 | |
1553 n = strlen (command); | |
1554 MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path"); | |
1555 | |
1556 n = strlen (mode); | |
1557 MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode"); | |
1558 | |
1559 p = popen (command, mode); | |
1560 if (NULL != p) { | |
1561 #ifdef MF_REGISTER_fopen | |
1562 __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result"); | |
1563 #endif | |
1564 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result"); | |
1565 } | |
1566 return p; | |
1567 } | |
1568 | |
1569 | |
1570 WRAPPER2(int, pclose, FILE *stream) | |
1571 { | |
1572 int resp; | |
1573 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1574 MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, | |
1575 "pclose stream"); | |
1576 resp = pclose (stream); | |
1577 #ifdef MF_REGISTER_fopen | |
1578 __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen); | |
1579 #endif | |
1580 return resp; | |
1581 } | |
1582 | |
1583 | |
1584 WRAPPER2(int, execve, const char *path, char *const argv [], | |
1585 char *const envp[]) | |
1586 { | |
1587 size_t n; | |
1588 char *const *p; | |
1589 const char *s; | |
1590 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1591 | |
1592 n = strlen (path); | |
1593 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path"); | |
1594 | |
1595 for (p = argv;;) { | |
1596 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv"); | |
1597 s = *p++; | |
1598 if (NULL == s) | |
1599 break; | |
1600 n = strlen (s); | |
1601 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv"); | |
1602 } | |
1603 | |
1604 for (p = envp;;) { | |
1605 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp"); | |
1606 s = *p++; | |
1607 if (NULL == s) | |
1608 break; | |
1609 n = strlen (s); | |
1610 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp"); | |
1611 } | |
1612 return execve (path, argv, envp); | |
1613 } | |
1614 | |
1615 | |
1616 WRAPPER2(int, execv, const char *path, char *const argv []) | |
1617 { | |
1618 size_t n; | |
1619 char *const *p; | |
1620 const char *s; | |
1621 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1622 | |
1623 n = strlen (path); | |
1624 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path"); | |
1625 | |
1626 for (p = argv;;) { | |
1627 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv"); | |
1628 s = *p++; | |
1629 if (NULL == s) | |
1630 break; | |
1631 n = strlen (s); | |
1632 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv"); | |
1633 } | |
1634 return execv (path, argv); | |
1635 } | |
1636 | |
1637 | |
1638 WRAPPER2(int, execvp, const char *path, char *const argv []) | |
1639 { | |
1640 size_t n; | |
1641 char *const *p; | |
1642 const char *s; | |
1643 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1644 | |
1645 n = strlen (path); | |
1646 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path"); | |
1647 | |
1648 for (p = argv;;) { | |
1649 MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv"); | |
1650 s = *p++; | |
1651 if (NULL == s) | |
1652 break; | |
1653 n = strlen (s); | |
1654 MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv"); | |
1655 } | |
1656 return execvp (path, argv); | |
1657 } | |
1658 | |
1659 | |
1660 WRAPPER2(int, system, const char *string) | |
1661 { | |
1662 size_t n; | |
1663 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1664 n = strlen (string); | |
1665 MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ, | |
1666 "system string"); | |
1667 return system (string); | |
1668 } | |
1669 | |
1670 | |
1671 WRAPPER2(void *, dlopen, const char *path, int flags) | |
1672 { | |
1673 void *p; | |
1674 size_t n; | |
1675 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1676 n = strlen (path); | |
1677 MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path"); | |
1678 p = dlopen (path, flags); | |
1679 if (NULL != p) { | |
1680 #ifdef MF_REGISTER_dlopen | |
1681 __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result"); | |
1682 #endif | |
1683 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result"); | |
1684 } | |
1685 return p; | |
1686 } | |
1687 | |
1688 | |
1689 WRAPPER2(int, dlclose, void *handle) | |
1690 { | |
1691 int resp; | |
1692 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1693 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle"); | |
1694 resp = dlclose (handle); | |
1695 #ifdef MF_REGISTER_dlopen | |
1696 __mf_unregister (handle, 0, MF_REGISTER_dlopen); | |
1697 #endif | |
1698 return resp; | |
1699 } | |
1700 | |
1701 | |
1702 WRAPPER2(char *, dlerror) | |
1703 { | |
1704 char *p; | |
1705 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1706 p = dlerror (); | |
1707 if (NULL != p) { | |
1708 size_t n; | |
1709 n = strlen (p); | |
1710 n = CLAMPADD(n, 1); | |
1711 #ifdef MF_REGISTER_dlerror | |
1712 __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result"); | |
1713 #endif | |
1714 MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result"); | |
1715 } | |
1716 return p; | |
1717 } | |
1718 | |
1719 | |
1720 WRAPPER2(void *, dlsym, void *handle, char *symbol) | |
1721 { | |
1722 size_t n; | |
1723 void *p; | |
1724 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1725 MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle"); | |
1726 n = strlen (symbol); | |
1727 MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol"); | |
1728 p = dlsym (handle, symbol); | |
1729 if (NULL != p) { | |
1730 #ifdef MF_REGISTER_dlsym | |
1731 __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result"); | |
1732 #endif | |
1733 MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result"); | |
1734 } | |
1735 return p; | |
1736 } | |
1737 | |
1738 | |
1739 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H) | |
1740 | |
1741 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops) | |
1742 { | |
1743 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1744 MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ, | |
1745 "semop sops"); | |
1746 return semop (semid, sops, nsops); | |
1747 } | |
1748 | |
1749 | |
1750 #ifndef HAVE_UNION_SEMUN | |
1751 union semun { | |
1752 int val; /* value for SETVAL */ | |
1753 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ | |
1754 unsigned short int *array; /* array for GETALL, SETALL */ | |
1755 struct seminfo *__buf; /* buffer for IPC_INFO */ | |
1756 }; | |
1757 #endif | |
1758 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg) | |
1759 { | |
1760 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1761 switch (cmd) { | |
1762 case IPC_STAT: | |
1763 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE, | |
1764 "semctl buf"); | |
1765 break; | |
1766 case IPC_SET: | |
1767 MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ, | |
1768 "semctl buf"); | |
1769 break; | |
1770 case GETALL: | |
1771 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE, | |
1772 "semctl array"); | |
1773 case SETALL: | |
1774 MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ, | |
1775 "semctl array"); | |
1776 break; | |
1777 #ifdef IPC_INFO | |
1778 /* FreeBSD 5.1 And Cygwin headers include IPC_INFO but not the __buf field. */ | |
1779 #if !defined(__FreeBSD__) && !defined(__CYGWIN__) | |
1780 case IPC_INFO: | |
1781 MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE, | |
1782 "semctl __buf"); | |
1783 break; | |
1784 #endif | |
1785 #endif | |
1786 default: | |
1787 break; | |
1788 } | |
1789 return semctl (semid, semnum, cmd, arg); | |
1790 } | |
1791 | |
1792 | |
1793 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf) | |
1794 { | |
1795 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1796 switch (cmd) { | |
1797 case IPC_STAT: | |
1798 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE, | |
1799 "shmctl buf"); | |
1800 break; | |
1801 case IPC_SET: | |
1802 MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, | |
1803 "shmctl buf"); | |
1804 break; | |
1805 default: | |
1806 break; | |
1807 } | |
1808 return shmctl (shmid, cmd, buf); | |
1809 } | |
1810 | |
1811 | |
1812 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg) | |
1813 { | |
1814 void *p; | |
1815 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1816 p = shmat (shmid, shmaddr, shmflg); | |
1817 #ifdef MF_REGISTER_shmat | |
1818 if (NULL != p) { | |
1819 struct shmid_ds buf; | |
1820 __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz, | |
1821 MF_REGISTER_shmat, "shmat result"); | |
1822 } | |
1823 #endif | |
1824 return p; | |
1825 } | |
1826 | |
1827 | |
1828 WRAPPER2(int, shmdt, const void *shmaddr) | |
1829 { | |
1830 int resp; | |
1831 TRACE ("%s\n", __PRETTY_FUNCTION__); | |
1832 resp = shmdt (shmaddr); | |
1833 #ifdef MF_REGISTER_shmat | |
1834 __mf_unregister ((void *)shmaddr, 0, MF_REGISTER_shmat); | |
1835 #endif | |
1836 return resp; | |
1837 } | |
1838 | |
1839 | |
1840 #endif /* HAVE_SYS_IPC/SEM/SHM_H */ | |
1841 | |
1842 | |
1843 | |
1844 /* ctype stuff. This is host-specific by necessity, as the arrays | |
1845 that is used by most is*()/to*() macros are implementation-defined. */ | |
1846 | |
1847 /* GLIBC 2.3 */ | |
1848 #ifdef HAVE___CTYPE_B_LOC | |
1849 WRAPPER2(unsigned short **, __ctype_b_loc, void) | |
1850 { | |
1851 static unsigned short * last_buf = (void *) 0; | |
1852 static unsigned short ** last_ptr = (void *) 0; | |
1853 unsigned short ** ptr = (unsigned short **) __ctype_b_loc (); | |
1854 unsigned short * buf = * ptr; | |
1855 if (ptr != last_ptr) | |
1856 { | |
1857 /* XXX: unregister last_ptr? */ | |
1858 last_ptr = ptr; | |
1859 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **"); | |
1860 } | |
1861 if (buf != last_buf) | |
1862 { | |
1863 last_buf = buf; | |
1864 __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC, | |
1865 "ctype_b_loc []"); | |
1866 } | |
1867 return ptr; | |
1868 } | |
1869 #endif | |
1870 | |
1871 #ifdef HAVE___CTYPE_TOUPPER_LOC | |
1872 WRAPPER2(int **, __ctype_toupper_loc, void) | |
1873 { | |
1874 static int * last_buf = (void *) 0; | |
1875 static int ** last_ptr = (void *) 0; | |
1876 int ** ptr = (int **) __ctype_toupper_loc (); | |
1877 int * buf = * ptr; | |
1878 if (ptr != last_ptr) | |
1879 { | |
1880 /* XXX: unregister last_ptr? */ | |
1881 last_ptr = ptr; | |
1882 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **"); | |
1883 } | |
1884 if (buf != last_buf) | |
1885 { | |
1886 last_buf = buf; | |
1887 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC, | |
1888 "ctype_toupper_loc []"); | |
1889 } | |
1890 return ptr; | |
1891 } | |
1892 #endif | |
1893 | |
1894 #ifdef HAVE___CTYPE_TOLOWER_LOC | |
1895 WRAPPER2(int **, __ctype_tolower_loc, void) | |
1896 { | |
1897 static int * last_buf = (void *) 0; | |
1898 static int ** last_ptr = (void *) 0; | |
1899 int ** ptr = (int **) __ctype_tolower_loc (); | |
1900 int * buf = * ptr; | |
1901 if (ptr != last_ptr) | |
1902 { | |
1903 /* XXX: unregister last_ptr? */ | |
1904 last_ptr = ptr; | |
1905 __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **"); | |
1906 } | |
1907 if (buf != last_buf) | |
1908 { | |
1909 last_buf = buf; | |
1910 __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC, | |
1911 "ctype_tolower_loc []"); | |
1912 } | |
1913 return ptr; | |
1914 } | |
1915 #endif | |
1916 | |
1917 | |
1918 /* passwd/group related functions. These register every (static) pointer value returned, | |
1919 and rely on libmudflap's quiet toleration of duplicate static registrations. */ | |
1920 | |
1921 #ifdef HAVE_GETLOGIN | |
1922 WRAPPER2(char *, getlogin, void) | |
1923 { | |
1924 char *buf = getlogin (); | |
1925 if (buf != NULL) | |
1926 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
1927 "getlogin() return"); | |
1928 return buf; | |
1929 } | |
1930 #endif | |
1931 | |
1932 | |
1933 #ifdef HAVE_CUSERID | |
1934 WRAPPER2(char *, cuserid, char * buf) | |
1935 { | |
1936 if (buf != NULL) | |
1937 { | |
1938 MF_VALIDATE_EXTENT(buf, L_cuserid, __MF_CHECK_WRITE, | |
1939 "cuserid destination"); | |
1940 return cuserid (buf); | |
1941 } | |
1942 buf = cuserid (NULL); | |
1943 if (buf != NULL) | |
1944 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
1945 "getcuserid() return"); | |
1946 return buf; | |
1947 } | |
1948 #endif | |
1949 | |
1950 | |
1951 #ifdef HAVE_GETPWNAM | |
1952 WRAPPER2(struct passwd *, getpwnam, const char *name) | |
1953 { | |
1954 struct passwd *buf; | |
1955 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, | |
1956 "getpwnam name"); | |
1957 buf = getpwnam (name); | |
1958 if (buf != NULL) | |
1959 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
1960 "getpw*() return"); | |
1961 return buf; | |
1962 } | |
1963 #endif | |
1964 | |
1965 | |
1966 #ifdef HAVE_GETPWUID | |
1967 WRAPPER2(struct passwd *, getpwuid, uid_t uid) | |
1968 { | |
1969 struct passwd *buf; | |
1970 buf = getpwuid (uid); | |
1971 if (buf != NULL) | |
1972 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
1973 "getpw*() return"); | |
1974 return buf; | |
1975 } | |
1976 #endif | |
1977 | |
1978 | |
1979 #ifdef HAVE_GETGRNAM | |
1980 WRAPPER2(struct group *, getgrnam, const char *name) | |
1981 { | |
1982 struct group *buf; | |
1983 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, | |
1984 "getgrnam name"); | |
1985 buf = getgrnam (name); | |
1986 if (buf != NULL) | |
1987 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
1988 "getgr*() return"); | |
1989 return buf; | |
1990 } | |
1991 #endif | |
1992 | |
1993 | |
1994 #ifdef HAVE_GETGRGID | |
1995 WRAPPER2(struct group *, getgrgid, uid_t uid) | |
1996 { | |
1997 struct group *buf; | |
1998 buf = getgrgid (uid); | |
1999 if (buf != NULL) | |
2000 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
2001 "getgr*() return"); | |
2002 return buf; | |
2003 } | |
2004 #endif | |
2005 | |
2006 | |
2007 #ifdef HAVE_GETSERVENT | |
2008 WRAPPER2(struct servent *, getservent, void) | |
2009 { | |
2010 struct servent *buf; | |
2011 buf = getservent (); | |
2012 if (buf != NULL) | |
2013 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
2014 "getserv*() return"); | |
2015 return buf; | |
2016 } | |
2017 #endif | |
2018 | |
2019 | |
2020 #ifdef HAVE_GETSERVBYNAME | |
2021 WRAPPER2(struct servent *, getservbyname, const char *name, const char *proto) | |
2022 { | |
2023 struct servent *buf; | |
2024 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, | |
2025 "getservbyname name"); | |
2026 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ, | |
2027 "getservbyname proto"); | |
2028 buf = getservbyname (name, proto); | |
2029 if (buf != NULL) | |
2030 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
2031 "getserv*() return"); | |
2032 return buf; | |
2033 } | |
2034 #endif | |
2035 | |
2036 | |
2037 #ifdef HAVE_GETSERVBYPORT | |
2038 WRAPPER2(struct servent *, getservbyport, int port, const char *proto) | |
2039 { | |
2040 struct servent *buf; | |
2041 MF_VALIDATE_EXTENT(proto, strlen(proto)+1, __MF_CHECK_READ, | |
2042 "getservbyport proto"); | |
2043 buf = getservbyport (port, proto); | |
2044 if (buf != NULL) | |
2045 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
2046 "getserv*() return"); | |
2047 return buf; | |
2048 } | |
2049 #endif | |
2050 | |
2051 | |
2052 #ifdef HAVE_GAI_STRERROR | |
2053 WRAPPER2(const char *, gai_strerror, int errcode) | |
2054 { | |
2055 const char *buf; | |
2056 buf = gai_strerror (errcode); | |
2057 if (buf != NULL) | |
2058 __mf_register ((void *) buf, strlen(buf)+1, __MF_TYPE_STATIC, | |
2059 "gai_strerror() return"); | |
2060 return buf; | |
2061 } | |
2062 #endif | |
2063 | |
2064 | |
2065 #ifdef HAVE_GETMNTENT | |
2066 WRAPPER2(struct mntent *, getmntent, FILE *filep) | |
2067 { | |
2068 struct mntent *m; | |
2069 static struct mntent *last = NULL; | |
2070 | |
2071 MF_VALIDATE_EXTENT (filep, sizeof (*filep), __MF_CHECK_WRITE, | |
2072 "getmntent stream"); | |
2073 #define UR(field) __mf_unregister(last->field, strlen (last->field)+1, __MF_TYPE_STATIC) | |
2074 if (last) | |
2075 { | |
2076 UR (mnt_fsname); | |
2077 UR (mnt_dir); | |
2078 UR (mnt_type); | |
2079 UR (mnt_opts); | |
2080 __mf_unregister (last, sizeof (*last), __MF_TYPE_STATIC); | |
2081 } | |
2082 #undef UR | |
2083 | |
2084 m = getmntent (filep); | |
2085 last = m; | |
2086 | |
2087 #define R(field) __mf_register(last->field, strlen (last->field)+1, __MF_TYPE_STATIC, "mntent " #field) | |
2088 if (m) | |
2089 { | |
2090 R (mnt_fsname); | |
2091 R (mnt_dir); | |
2092 R (mnt_type); | |
2093 R (mnt_opts); | |
2094 __mf_register (last, sizeof (*last), __MF_TYPE_STATIC, "getmntent result"); | |
2095 } | |
2096 #undef R | |
2097 | |
2098 return m; | |
2099 } | |
2100 #endif | |
2101 | |
2102 | |
2103 #ifdef HAVE_INET_NTOA | |
2104 WRAPPER2(char *, inet_ntoa, struct in_addr in) | |
2105 { | |
2106 static char *last_buf = NULL; | |
2107 char *buf; | |
2108 if (last_buf) | |
2109 __mf_unregister (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC); | |
2110 buf = inet_ntoa (in); | |
2111 last_buf = buf; | |
2112 if (buf) | |
2113 __mf_register (last_buf, strlen (last_buf)+1, __MF_TYPE_STATIC, "inet_ntoa result"); | |
2114 return buf; | |
2115 } | |
2116 #endif | |
2117 | |
2118 | |
2119 #ifdef HAVE_GETPROTOENT | |
2120 WRAPPER2(struct protoent *, getprotoent, void) | |
2121 { | |
2122 struct protoent *buf; | |
2123 buf = getprotoent (); | |
2124 if (buf != NULL) | |
2125 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, "getproto*() return"); | |
2126 return buf; | |
2127 } | |
2128 #endif | |
2129 | |
2130 | |
2131 #ifdef HAVE_GETPROTOBYNAME | |
2132 WRAPPER2(struct protoent *, getprotobyname, const char *name) | |
2133 { | |
2134 struct protoent *buf; | |
2135 MF_VALIDATE_EXTENT(name, strlen(name)+1, __MF_CHECK_READ, | |
2136 "getprotobyname name"); | |
2137 buf = getprotobyname (name); | |
2138 if (buf != NULL) | |
2139 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
2140 "getproto*() return"); | |
2141 return buf; | |
2142 } | |
2143 #endif | |
2144 | |
2145 | |
2146 #ifdef HAVE_GETPROTOBYNUMBER | |
2147 WRAPPER2(struct protoent *, getprotobynumber, int port) | |
2148 { | |
2149 struct protoent *buf; | |
2150 buf = getprotobynumber (port); | |
2151 if (buf != NULL) | |
2152 __mf_register (buf, sizeof(*buf), __MF_TYPE_STATIC, | |
2153 "getproto*() return"); | |
2154 return buf; | |
2155 } | |
2156 #endif |