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