OSDN Git Service

ff08d42ef7610414bc1b899a1b8ae46e0c1b0c58
[pf3gnuchains/gcc-fork.git] / libmudflap / mf-hooks2.c
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2    Copyright (C) 2002, 2003, 2004 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 2, or (at your option) any later
11 version.
12
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file.  (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
21
22 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23 WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25 for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING.  If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 02111-1307, USA.  */
31
32
33 #include "config.h"
34
35 #ifndef HAVE_SOCKLEN_T
36 #define socklen_t int
37 #endif
38
39 /* These attempt to coax various unix flavours to declare all our
40    needed tidbits in the system headers.  */
41 #if !defined(__FreeBSD__) && !defined(__APPLE__)
42 #define _POSIX_SOURCE
43 #endif /* Some BSDs break <sys/socket.h> if this is defined. */
44 #define _GNU_SOURCE 
45 #define _XOPEN_SOURCE
46 #define _BSD_TYPES
47 #define __EXTENSIONS__
48 #define _ALL_SOURCE
49 #define _LARGE_FILE_API
50 #define _LARGEFILE64_SOURCE
51 #define _XOPEN_SOURCE_EXTENDED 1
52
53 #include <string.h>
54 #include <stdarg.h>
55 #include <strings.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <sys/stat.h>
59 #include <sys/time.h>
60 #include <sys/types.h>
61 #include <unistd.h>
62 #include <assert.h>
63 #include <errno.h>
64 #include <limits.h>
65 #include <time.h>
66 #include <ctype.h>
67 #include <dirent.h>
68 #ifdef HAVE_SYS_SOCKET_H
69 #include <sys/socket.h>
70 #endif
71 #ifdef HAVE_NETDB_H
72 #include <netdb.h>
73 #endif
74 #ifdef HAVE_SYS_WAIT_H
75 #include <sys/wait.h>
76 #endif
77 #ifdef HAVE_SYS_IPC_H
78 #include <sys/ipc.h>
79 #endif
80 #ifdef HAVE_SYS_SEM_H
81 #include <sys/sem.h>
82 #endif
83 #ifdef HAVE_SYS_SHM_H
84 #include <sys/shm.h>
85 #endif
86
87
88 #include "mf-runtime.h"
89 #include "mf-impl.h"
90
91 #ifdef _MUDFLAP
92 #error "Do not compile this file with -fmudflap!"
93 #endif
94
95
96 /* A bunch of independent stdlib/unistd hook functions, all
97    intercepted by mf-runtime.h macros.  */
98
99 #ifndef HAVE_STRNLEN
100 static inline size_t (strnlen) (const char* str, size_t n)
101 {
102   const char *s;
103
104   for (s = str; n && *s; ++s, --n)
105     ;
106   return (s - str);
107 }
108 #endif
109
110
111 /* str*,mem*,b* */
112
113 WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
114 {
115   TRACE ("%s\n", __PRETTY_FUNCTION__);
116   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
117   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
118   return memcpy (dest, src, n);
119 }
120
121
122 WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
123 {
124   TRACE ("%s\n", __PRETTY_FUNCTION__);
125   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
126   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
127   return memmove (dest, src, n);
128 }
129
130
131 WRAPPER2(void *, memset, void *s, int c, size_t n)
132 {
133   TRACE ("%s\n", __PRETTY_FUNCTION__);
134   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
135   return memset (s, c, n);
136 }
137
138
139 WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
140 {
141   TRACE ("%s\n", __PRETTY_FUNCTION__);
142   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
143   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
144   return memcmp (s1, s2, n);
145 }
146
147
148 WRAPPER2(void *, memchr, const void *s, int c, size_t n)
149 {
150   TRACE ("%s\n", __PRETTY_FUNCTION__);
151   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
152   return memchr (s, c, n);
153 }
154
155
156 #ifdef HAVE_MEMRCHR
157 WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
158 {
159   TRACE ("%s\n", __PRETTY_FUNCTION__);
160   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
161   return memrchr (s, c, n);
162 }
163 #endif
164
165
166 WRAPPER2(char *, strcpy, char *dest, const char *src)
167 {
168   /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
169      1) are valid pointers. the allocated object might have size < n.
170      check anyways. */
171
172   size_t n = strlen (src);
173   TRACE ("%s\n", __PRETTY_FUNCTION__);
174   MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src"); 
175   MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
176   return strcpy (dest, src);
177 }
178
179
180 #ifdef HAVE_STRNCPY
181 WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
182 {
183   size_t len = strnlen (src, n);
184   TRACE ("%s\n", __PRETTY_FUNCTION__);
185   MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
186   MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
187   return strncpy (dest, src, n);
188 }
189 #endif
190
191
192 WRAPPER2(char *, strcat, char *dest, const char *src)
193 {
194   size_t dest_sz;
195   size_t src_sz;
196   TRACE ("%s\n", __PRETTY_FUNCTION__);
197   dest_sz = strlen (dest);
198   src_sz = strlen (src);  
199   MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
200   MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)),
201                      __MF_CHECK_WRITE, "strcat dest");
202   return strcat (dest, src);
203 }
204
205
206 WRAPPER2(char *, strncat, char *dest, const char *src, size_t n)
207 {
208
209   /* nb: validating the extents (s,n) might be a mistake for two reasons.
210      
211   (1) the string s might be shorter than n chars, and n is just a 
212   poor choice by the programmer. this is not a "true" error in the
213   sense that the call to strncat would still be ok.
214   
215   (2) we could try to compensate for case (1) by calling strlen(s) and
216   using that as a bound for the extent to verify, but strlen might fall off
217   the end of a non-terminated string, leading to a false positive.
218   
219   so we will call strnlen(s,n) and use that as a bound.
220
221   if strnlen returns a length beyond the end of the registered extent
222   associated with s, there is an error: the programmer's estimate for n is
223   too large _AND_ the string s is unterminated, in which case they'd be
224   about to touch memory they don't own while calling strncat.
225
226   this same logic applies to further uses of strnlen later down in this
227   file. */
228
229   size_t src_sz;
230   size_t dest_sz;
231   TRACE ("%s\n", __PRETTY_FUNCTION__);
232   src_sz = strnlen (src, n);
233   dest_sz = strnlen (dest, n);
234   MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
235   MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))),
236                      __MF_CHECK_WRITE, "strncat dest");
237   return strncat (dest, src, n);
238 }
239
240
241 WRAPPER2(int, strcmp, const char *s1, const char *s2)
242 {
243   size_t s1_sz;
244   size_t s2_sz;
245   TRACE ("%s\n", __PRETTY_FUNCTION__);
246   s1_sz = strlen (s1);
247   s2_sz = strlen (s2);  
248   MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
249   MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg");
250   return strcmp (s1, s2);
251 }
252
253
254 WRAPPER2(int, strcasecmp, const char *s1, const char *s2)
255 {
256   size_t s1_sz;
257   size_t s2_sz;
258   TRACE ("%s\n", __PRETTY_FUNCTION__);
259   s1_sz = strlen (s1);
260   s2_sz = strlen (s2);  
261   MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
262   MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg");
263   return strcasecmp (s1, s2);
264 }
265
266
267 WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n)
268 {
269   size_t s1_sz;
270   size_t s2_sz;
271   TRACE ("%s\n", __PRETTY_FUNCTION__);
272   s1_sz = strnlen (s1, n);
273   s2_sz = strnlen (s2, n);
274   MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
275   MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg");
276   return strncmp (s1, s2, n);
277 }
278
279
280 WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n)
281 {
282   size_t s1_sz;
283   size_t s2_sz;
284   TRACE ("%s\n", __PRETTY_FUNCTION__);
285   s1_sz = strnlen (s1, n);
286   s2_sz = strnlen (s2, n);
287   MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
288   MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg");
289   return strncasecmp (s1, s2, n);
290 }
291
292
293 WRAPPER2(char *, strdup, const char *s)
294 {
295   DECLARE(void *, malloc, size_t sz);
296   char *result;
297   size_t n = strlen (s);
298   TRACE ("%s\n", __PRETTY_FUNCTION__);
299   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
300   result = (char *)CALL_REAL(malloc, 
301                              CLAMPADD(CLAMPADD(n,1),
302                                       CLAMPADD(__mf_opts.crumple_zone,
303                                                __mf_opts.crumple_zone)));
304
305   if (UNLIKELY(! result)) return result;
306
307   result += __mf_opts.crumple_zone;
308   memcpy (result, s, n);
309   result[n] = '\0';
310
311   __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region");
312   return result;
313 }
314
315
316 WRAPPER2(char *, strndup, const char *s, size_t n)
317 {
318   DECLARE(void *, malloc, size_t sz);
319   char *result;
320   size_t sz = strnlen (s, n);
321   TRACE ("%s\n", __PRETTY_FUNCTION__);
322   MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
323
324   /* note: strndup still adds a \0, even with the N limit! */
325   result = (char *)CALL_REAL(malloc, 
326                              CLAMPADD(CLAMPADD(n,1),
327                                       CLAMPADD(__mf_opts.crumple_zone,
328                                                __mf_opts.crumple_zone)));
329   
330   if (UNLIKELY(! result)) return result;
331
332   result += __mf_opts.crumple_zone;
333   memcpy (result, s, n);
334   result[n] = '\0';
335
336   __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region");
337   return result;
338 }
339
340
341 WRAPPER2(char *, strchr, const char *s, int c)
342 {
343   size_t n;
344   TRACE ("%s\n", __PRETTY_FUNCTION__);
345   n = strlen (s);
346   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
347   return strchr (s, c);
348 }
349
350
351 WRAPPER2(char *, strrchr, const char *s, int c)
352 {
353   size_t n;
354   TRACE ("%s\n", __PRETTY_FUNCTION__);
355   n = strlen (s);
356   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
357   return strrchr (s, c);
358 }
359
360
361 WRAPPER2(char *, strstr, const char *haystack, const char *needle)
362 {
363   size_t haystack_sz;
364   size_t needle_sz;
365   TRACE ("%s\n", __PRETTY_FUNCTION__);
366   haystack_sz = strlen (haystack);
367   needle_sz = strlen (needle);
368   MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
369   MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle");
370   return strstr (haystack, needle);
371 }
372
373
374 #ifdef HAVE_MEMMEM
375 WRAPPER2(void *, memmem, 
376         const void *haystack, size_t haystacklen,
377         const void *needle, size_t needlelen)
378 {
379   TRACE ("%s\n", __PRETTY_FUNCTION__);
380   MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
381   MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
382   return memmem (haystack, haystacklen, needle, needlelen);
383 }
384 #endif
385
386
387 WRAPPER2(size_t, strlen, const char *s)
388 {
389   size_t result = strlen (s);
390   TRACE ("%s\n", __PRETTY_FUNCTION__);
391   MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
392   return result;
393 }
394
395
396 WRAPPER2(size_t, strnlen, const char *s, size_t n)
397 {
398   size_t result = strnlen (s, n);
399   TRACE ("%s\n", __PRETTY_FUNCTION__);
400   MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
401   return result;
402 }
403
404
405 WRAPPER2(void, bzero, void *s, size_t n)
406 {
407   TRACE ("%s\n", __PRETTY_FUNCTION__);
408   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
409   bzero (s, n);
410 }
411
412
413 #undef bcopy
414 WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
415 {
416   TRACE ("%s\n", __PRETTY_FUNCTION__);
417   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
418   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
419   bcopy (src, dest, n);
420 }
421
422
423 #undef bcmp
424 WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
425 {
426   TRACE ("%s\n", __PRETTY_FUNCTION__);
427   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
428   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
429   return bcmp (s1, s2, n);
430 }
431
432
433 WRAPPER2(char *, index, const char *s, int c)
434 {
435   size_t n = strlen (s);
436   TRACE ("%s\n", __PRETTY_FUNCTION__);
437   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
438   return index (s, c);
439 }
440
441
442 WRAPPER2(char *, rindex, const char *s, int c)
443 {
444   size_t n = strlen (s);
445   TRACE ("%s\n", __PRETTY_FUNCTION__);
446   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
447   return rindex (s, c);
448 }
449
450 /* XXX:  stpcpy, memccpy */
451
452 /* XXX: *printf,*scanf */
453
454 /* XXX: setjmp, longjmp */
455
456 WRAPPER2(char *, asctime, struct tm *tm)
457 {
458   static char *reg_result = NULL;
459   char *result;
460   TRACE ("%s\n", __PRETTY_FUNCTION__);
461   MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
462   result = asctime (tm);
463   if (reg_result == NULL)
464     {
465       __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
466       reg_result = result;
467     }
468   return result;
469 }
470
471
472 WRAPPER2(char *, ctime, const time_t *timep)
473 {
474   static char *reg_result = NULL;
475   char *result;
476   TRACE ("%s\n", __PRETTY_FUNCTION__);
477   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
478   result = ctime (timep);
479   if (reg_result == NULL)
480     {
481       /* XXX: what if asctime and ctime return the same static ptr? */
482       __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
483       reg_result = result;
484     }
485   return result;
486 }
487
488
489 WRAPPER2(struct tm*, localtime, const time_t *timep)
490 {
491   static struct tm *reg_result = NULL;
492   struct tm *result;
493   TRACE ("%s\n", __PRETTY_FUNCTION__);
494   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
495   result = localtime (timep);
496   if (reg_result == NULL)
497     {
498       __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
499       reg_result = result;
500     }
501   return result;
502 }
503
504
505 WRAPPER2(struct tm*, gmtime, const time_t *timep)
506 {
507   static struct tm *reg_result = NULL;
508   struct tm *result;
509   TRACE ("%s\n", __PRETTY_FUNCTION__);
510   MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
511   result = gmtime (timep);
512   if (reg_result == NULL)
513     {
514       __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
515       reg_result = result;
516     }
517   return result;
518 }
519
520
521 /* EL start */
522
523 /* The following indicate if the result of the corresponding function
524  * should be explicitly un/registered by the wrapper
525 */
526 #define MF_REGISTER_strerror            __MF_TYPE_STATIC
527 #undef  MF_REGISTER_fopen
528 #define MF_RESULT_SIZE_fopen            (sizeof (FILE))
529 #undef  MF_REGISTER_opendir
530 #define MF_RESULT_SIZE_opendir          0       /* (sizeof (DIR)) */
531 #undef  MF_REGISTER_readdir
532 #define MF_REGISTER_gethostbyname       __MF_TYPE_STATIC
533 #undef  MF_REGISTER_gethostbyname_items
534 #undef  MF_REGISTER_dlopen
535 #undef  MF_REGISTER_dlerror
536 #undef  MF_REGISTER_dlsym
537 #define MF_REGISTER_shmat               __MF_TYPE_GUESS
538
539
540 #include <time.h>
541 WRAPPER2(time_t, time, time_t *timep)
542 {
543   TRACE ("%s\n", __PRETTY_FUNCTION__);
544   if (NULL != timep)
545     MF_VALIDATE_EXTENT (timep, sizeof (*timep), __MF_CHECK_WRITE,
546       "time timep");
547   return time (timep);
548 }
549
550
551 WRAPPER2(char *, strerror, int errnum)
552 {
553   char *p;
554   size_t n;
555   TRACE ("%s\n", __PRETTY_FUNCTION__);
556   p = strerror (errnum);
557   if (NULL != p) {
558     n = strlen (p);
559     n = CLAMPADD(n, 1);
560 #ifdef MF_REGISTER_strerror
561     __mf_register (p, n, MF_REGISTER_strerror, "strerror result");
562 #endif
563     MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "strerror result");
564   }
565   return p;
566 }
567
568
569 WRAPPER2(FILE *, fopen, const char *path, const char *mode)
570 {
571   size_t n;
572   FILE *p;
573   TRACE ("%s\n", __PRETTY_FUNCTION__);
574
575   n = strlen (path);
576   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
577
578   n = strlen (mode);
579   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
580
581   p = fopen (path, mode);
582   if (NULL != p) {
583 #ifdef MF_REGISTER_fopen
584     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
585 #endif
586     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
587   }
588
589   return p;
590 }
591
592
593 #ifdef HAVE_FOPEN64
594 WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
595 {
596   size_t n;
597   FILE *p;
598   TRACE ("%s\n", __PRETTY_FUNCTION__);
599
600   n = strlen (path);
601   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
602
603   n = strlen (mode);
604   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
605
606   p = fopen64 (path, mode);
607   if (NULL != p) {
608 #ifdef MF_REGISTER_fopen
609     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
610 #endif
611     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
612   }
613
614   return p;
615 }
616 #endif
617
618
619 WRAPPER2(int, fclose, FILE *stream)
620 {
621   int resp;
622   TRACE ("%s\n", __PRETTY_FUNCTION__);
623   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
624     "fclose stream");
625   resp = fclose (stream);
626 #ifdef MF_REGISTER_fopen
627   __mf_unregister (stream, sizeof (*stream));
628 #endif
629
630   return resp;
631 }
632
633
634 WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
635 {
636   TRACE ("%s\n", __PRETTY_FUNCTION__);
637   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
638     "fread stream");
639   MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
640   return fread (ptr, size, nmemb, stream);
641 }
642
643
644 WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
645         FILE *stream)
646 {
647   TRACE ("%s\n", __PRETTY_FUNCTION__);
648   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
649     "fwrite stream");
650   MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
651   return fwrite (ptr, size, nmemb, stream);
652 }
653
654
655 WRAPPER2(int, fgetc, FILE *stream)
656 {
657   TRACE ("%s\n", __PRETTY_FUNCTION__);
658   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
659     "fgetc stream");
660   return fgetc (stream);
661 }
662
663
664 WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
665 {
666   TRACE ("%s\n", __PRETTY_FUNCTION__);
667   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
668     "fgets stream");
669   MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
670   return fgets (s, size, stream);
671 }
672
673
674 WRAPPER2(int, getc, FILE *stream)
675 {
676   TRACE ("%s\n", __PRETTY_FUNCTION__);
677   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
678     "getc stream");
679   return getc (stream);
680 }
681
682
683 WRAPPER2(char *, gets, char *s)
684 {
685   TRACE ("%s\n", __PRETTY_FUNCTION__);
686   MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
687   /* Avoid link-time warning... */
688   s = fgets (s, INT_MAX, stdin);
689   if (NULL != s) {      /* better late than never */
690     size_t n = strlen (s);
691     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
692   }
693   return s;
694 }
695
696
697 WRAPPER2(int, ungetc, int c, FILE *stream)
698 {
699   TRACE ("%s\n", __PRETTY_FUNCTION__);
700   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
701      "ungetc stream");
702   return ungetc (c, stream);
703 }
704
705
706 WRAPPER2(int, fputc, int c, FILE *stream)
707 {
708   TRACE ("%s\n", __PRETTY_FUNCTION__);
709   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
710     "fputc stream");
711   return fputc (c, stream);
712 }
713
714
715 WRAPPER2(int, fputs, const char *s, FILE *stream)
716 {
717   size_t n;
718   TRACE ("%s\n", __PRETTY_FUNCTION__);
719   n = strlen (s);
720   MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
721   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
722     "fputs stream");
723   return fputs (s, stream);
724 }
725
726
727 WRAPPER2(int, putc, int c, FILE *stream)
728 {
729   TRACE ("%s\n", __PRETTY_FUNCTION__);
730   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
731     "putc stream");
732   return putc (c, stream);
733 }
734
735
736 WRAPPER2(int, puts, const char *s)
737 {
738   size_t n;
739   TRACE ("%s\n", __PRETTY_FUNCTION__);
740   n = strlen (s);
741   MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
742   return puts (s);
743 }
744
745
746 WRAPPER2(void, clearerr, FILE *stream)
747 {
748   TRACE ("%s\n", __PRETTY_FUNCTION__);
749   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
750     "clearerr stream");
751   clearerr (stream);
752 }
753
754
755 WRAPPER2(int, feof, FILE *stream)
756 {
757   TRACE ("%s\n", __PRETTY_FUNCTION__);
758   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
759     "feof stream");
760   return feof (stream);
761 }
762
763
764 WRAPPER2(int, ferror, FILE *stream)
765 {
766   TRACE ("%s\n", __PRETTY_FUNCTION__);
767   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
768     "ferror stream");
769   return ferror (stream);
770 }
771
772
773 WRAPPER2(int, fileno, FILE *stream)
774 {
775   TRACE ("%s\n", __PRETTY_FUNCTION__);
776   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
777     "fileno stream");
778   return fileno (stream);
779 }
780
781
782 WRAPPER2(int, printf, const char *format, ...)
783 {
784   size_t n;
785   va_list ap;
786   int result;
787   TRACE ("%s\n", __PRETTY_FUNCTION__);
788   n = strlen (format);
789   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
790     "printf format");
791   va_start (ap, format);
792   result = vprintf (format, ap);
793   va_end (ap);
794   return result;
795 }
796
797
798 WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
799 {
800   size_t n;
801   va_list ap;
802   int result;
803   TRACE ("%s\n", __PRETTY_FUNCTION__);
804   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
805     "fprintf stream");
806   n = strlen (format);
807   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
808     "fprintf format");
809   va_start (ap, format);
810   result = vfprintf (stream, format, ap);
811   va_end (ap);
812   return result;
813 }
814
815
816 WRAPPER2(int, sprintf, char *str, const char *format, ...)
817 {
818   size_t n;
819   va_list ap;
820   int result;
821   TRACE ("%s\n", __PRETTY_FUNCTION__);
822   MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
823   n = strlen (format);
824   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
825     "sprintf format");
826   va_start (ap, format);
827   result = vsprintf (str, format, ap);
828   va_end (ap);
829   n = strlen (str);
830   MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
831   return result;
832 }
833
834
835 WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
836 {
837   size_t n;
838   va_list ap;
839   int result;
840   TRACE ("%s\n", __PRETTY_FUNCTION__);
841   MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
842   n = strlen (format);
843   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
844     "snprintf format");
845   va_start (ap, format);
846   result = vsnprintf (str, size, format, ap);
847   va_end (ap);
848   return result;
849 }
850
851
852 WRAPPER2(int, vprintf,  const char *format, va_list ap)
853 {
854   size_t n;
855   TRACE ("%s\n", __PRETTY_FUNCTION__);
856   n = strlen (format);
857   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
858     "vprintf format");
859   return vprintf (format, ap);
860 }
861
862
863 WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
864 {
865   size_t n;
866   TRACE ("%s\n", __PRETTY_FUNCTION__);
867   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
868     "vfprintf stream");
869   n = strlen (format);
870   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
871     "vfprintf format");
872   return vfprintf (stream, format, ap);
873 }
874
875
876 WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
877 {
878   size_t n;
879   int result;
880   TRACE ("%s\n", __PRETTY_FUNCTION__);
881   MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
882   n = strlen (format);
883   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
884     "vsprintf format");
885   result = vsprintf (str, format, ap);
886   n = strlen (str);
887   MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
888   return result;
889 }
890
891
892 WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
893         va_list ap)
894 {
895   size_t n;
896   TRACE ("%s\n", __PRETTY_FUNCTION__);
897   MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
898   n = strlen (format);
899   MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
900     "vsnprintf format");
901   return vsnprintf (str, size, format, ap);
902 }
903
904
905 WRAPPER2(int , access, const char *path, int mode)
906 {
907   size_t n;
908   TRACE ("%s\n", __PRETTY_FUNCTION__);
909   n = strlen (path);
910   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
911   return access (path, mode);
912 }
913
914
915 WRAPPER2(int , remove, const char *path)
916 {
917   size_t n;
918   TRACE ("%s\n", __PRETTY_FUNCTION__);
919   n = strlen (path);
920   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
921   return remove (path);
922 }
923
924
925 WRAPPER2(int, fflush, FILE *stream)
926 {
927   TRACE ("%s\n", __PRETTY_FUNCTION__);
928   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
929     "fflush stream");
930   return fflush (stream);
931 }
932
933
934 WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
935 {
936   TRACE ("%s\n", __PRETTY_FUNCTION__);
937   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
938     "fseek stream");
939   return fseek (stream, offset, whence);
940 }
941
942
943 #ifdef HAVE_FSEEKO64
944 WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
945 {
946   TRACE ("%s\n", __PRETTY_FUNCTION__);
947   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
948     "fseeko64 stream");
949   return fseeko64 (stream, offset, whence);
950 }
951 #endif
952
953
954 WRAPPER2(long, ftell, FILE *stream)
955 {
956   TRACE ("%s\n", __PRETTY_FUNCTION__);
957   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
958     "ftell stream");
959   return ftell (stream);
960 }
961
962
963 #ifdef HAVE_FTELLO64
964 WRAPPER2(off64_t, ftello64, FILE *stream)
965 {
966   TRACE ("%s\n", __PRETTY_FUNCTION__);
967   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
968     "ftello64 stream");
969   return ftello64 (stream);
970 }
971 #endif
972
973
974 WRAPPER2(void, rewind, FILE *stream)
975 {
976   TRACE ("%s\n", __PRETTY_FUNCTION__);
977   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
978     "rewind stream");
979   rewind (stream);
980 }
981
982
983 WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
984 {
985   TRACE ("%s\n", __PRETTY_FUNCTION__);
986   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
987     "fgetpos stream");
988   MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
989   return fgetpos (stream, pos);
990 }
991
992
993 WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
994 {
995   TRACE ("%s\n", __PRETTY_FUNCTION__);
996   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
997     "fsetpos stream");
998   MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
999   return fsetpos (stream, pos);
1000 }
1001
1002
1003 WRAPPER2(int , stat, const char *path, struct stat *buf)
1004 {
1005   size_t n;
1006   TRACE ("%s\n", __PRETTY_FUNCTION__);
1007   n = strlen (path);
1008   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
1009   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
1010   return stat (path, buf);
1011 }
1012
1013
1014 #ifdef HAVE_STAT64
1015 WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
1016 {
1017   size_t n;
1018   TRACE ("%s\n", __PRETTY_FUNCTION__);
1019   n = strlen (path);
1020   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
1021   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
1022   return stat64 (path, buf);
1023 }
1024 #endif
1025
1026
1027 WRAPPER2(int , fstat, int filedes, struct stat *buf)
1028 {
1029   TRACE ("%s\n", __PRETTY_FUNCTION__);
1030   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
1031   return fstat (filedes, buf);
1032 }
1033
1034
1035 WRAPPER2(int , lstat, const char *path, struct stat *buf)
1036 {
1037   size_t n;
1038   TRACE ("%s\n", __PRETTY_FUNCTION__);
1039   n = strlen (path);
1040   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
1041   MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
1042   return lstat (path, buf);
1043 }
1044
1045
1046 WRAPPER2(int , mkfifo, const char *path, mode_t mode)
1047 {
1048   size_t n;
1049   TRACE ("%s\n", __PRETTY_FUNCTION__);
1050   n = strlen (path);
1051   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
1052   return mkfifo (path, mode);
1053 }
1054
1055
1056 WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size)
1057 {
1058   TRACE ("%s\n", __PRETTY_FUNCTION__);
1059   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1060     "setvbuf stream");
1061   if (NULL != buf)
1062     MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf");
1063   return setvbuf (stream, buf, mode, size);
1064 }
1065
1066
1067 WRAPPER2(void, setbuf, FILE *stream, char *buf)
1068 {
1069   TRACE ("%s\n", __PRETTY_FUNCTION__);
1070   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1071     "setbuf stream");
1072   if (NULL != buf)
1073     MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf");
1074   setbuf (stream, buf);
1075 }
1076
1077
1078 WRAPPER2(DIR *, opendir, const char *path)
1079 {
1080   DIR *p;
1081   size_t n;
1082   TRACE ("%s\n", __PRETTY_FUNCTION__);
1083   n = strlen (path);
1084   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
1085
1086   p = opendir (path);
1087   if (NULL != p) {
1088 #ifdef MF_REGISTER_opendir
1089     __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
1090       "opendir result");
1091 #endif
1092     MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
1093       "opendir result");
1094   }
1095   return p;
1096 }
1097
1098
1099 WRAPPER2(int, closedir, DIR *dir)
1100 {
1101   TRACE ("%s\n", __PRETTY_FUNCTION__);
1102   MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
1103 #ifdef MF_REGISTER_opendir
1104   __mf_unregister (dir, MF_RESULT_SIZE_opendir);
1105 #endif
1106   return closedir (dir);
1107 }
1108
1109
1110 WRAPPER2(struct dirent *, readdir, DIR *dir)
1111 {
1112   struct dirent *p;
1113   TRACE ("%s\n", __PRETTY_FUNCTION__);
1114   MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
1115   p = readdir (dir);
1116   if (NULL != p) {
1117 #ifdef MF_REGISTER_readdir
1118     __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
1119 #endif
1120     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
1121   }
1122   return p;
1123 }
1124
1125
1126 #ifdef HAVE_SYS_SOCKET_H
1127
1128 WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
1129 {
1130   TRACE ("%s\n", __PRETTY_FUNCTION__);
1131   MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
1132   return recv (s, buf, len, flags);
1133 }
1134
1135
1136 WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
1137                 struct sockaddr *from, socklen_t *fromlen)
1138 {
1139   TRACE ("%s\n", __PRETTY_FUNCTION__);
1140   MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
1141   MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
1142     "recvfrom from");
1143   return recvfrom (s, buf, len, flags, from, fromlen);
1144 }
1145
1146
1147 WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
1148 {
1149   TRACE ("%s\n", __PRETTY_FUNCTION__);
1150   MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
1151   return recvmsg (s, msg, flags);
1152 }
1153
1154
1155 WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
1156 {
1157   TRACE ("%s\n", __PRETTY_FUNCTION__);
1158   MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
1159   return send (s, msg, len, flags);
1160 }
1161
1162
1163 WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
1164                 const struct sockaddr *to, socklen_t tolen)
1165 {
1166   TRACE ("%s\n", __PRETTY_FUNCTION__);
1167   MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
1168   MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
1169   return sendto (s, msg, len, flags, to, tolen);
1170 }
1171
1172
1173 WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
1174 {
1175   TRACE ("%s\n", __PRETTY_FUNCTION__);
1176   MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
1177   return sendmsg (s, msg, flags);
1178 }
1179
1180
1181 WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
1182         socklen_t optlen)
1183 {
1184   TRACE ("%s\n", __PRETTY_FUNCTION__);
1185   MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
1186     "setsockopt optval");
1187   return setsockopt (s, level, optname, optval, optlen);
1188 }
1189
1190
1191 WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
1192                 socklen_t *optlen)
1193 {
1194   TRACE ("%s\n", __PRETTY_FUNCTION__);
1195   MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
1196     "getsockopt optval");
1197   return getsockopt (s, level, optname, optval, optlen);
1198 }
1199
1200
1201 WRAPPER2(int, accept, int s, struct  sockaddr *addr, socklen_t *addrlen)
1202 {
1203   TRACE ("%s\n", __PRETTY_FUNCTION__);
1204   MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
1205   return accept (s, addr, addrlen);
1206 }
1207
1208
1209 WRAPPER2(int, bind, int sockfd, struct  sockaddr *addr, socklen_t addrlen)
1210 {
1211   TRACE ("%s\n", __PRETTY_FUNCTION__);
1212   MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
1213   return bind (sockfd, addr, addrlen);
1214 }
1215
1216
1217 WRAPPER2(int, connect, int sockfd, const struct sockaddr  *addr,
1218         socklen_t addrlen)
1219 {
1220   TRACE ("%s\n", __PRETTY_FUNCTION__);
1221   MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
1222     "connect addr");
1223   return connect (sockfd, addr, addrlen);
1224 }
1225
1226 #endif /* HAVE_SYS_SOCKET_H */
1227
1228
1229 WRAPPER2(int, gethostname, char *name, size_t len)
1230 {
1231   TRACE ("%s\n", __PRETTY_FUNCTION__);
1232   MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
1233   return gethostname (name, len);
1234 }
1235
1236
1237 #ifdef HAVE_SETHOSTNAME
1238 WRAPPER2(int, sethostname, const char *name, size_t len)
1239 {
1240   TRACE ("%s\n", __PRETTY_FUNCTION__);
1241   MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
1242   return sethostname (name, len);
1243 }
1244 #endif
1245
1246
1247 #ifdef HAVE_NETDB_H
1248
1249 WRAPPER2(struct hostent *, gethostbyname, const char *name)
1250 {
1251   struct hostent *p;
1252   char **ss;
1253   char *s;
1254   size_t n;
1255   int nreg;
1256   TRACE ("%s\n", __PRETTY_FUNCTION__);
1257   n = strlen (name);
1258   MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
1259     "gethostbyname name");
1260   p = gethostbyname (name);
1261   if (NULL != p) {
1262 #ifdef MF_REGISTER_gethostbyname
1263     __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
1264       "gethostbyname result");
1265 #endif
1266     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
1267       "gethostbyname result");
1268     if (NULL != (s = p->h_name)) {
1269       n = strlen (s);
1270       n = CLAMPADD(n, 1);
1271 #ifdef MF_REGISTER_gethostbyname_items
1272       __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1273         "gethostbyname result->h_name");
1274 #endif
1275       MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1276         "gethostbyname result->h_name");
1277     }
1278
1279     if (NULL != (ss = p->h_aliases)) {
1280       for (nreg = 1;; ++nreg) {
1281         s = *ss++;
1282         if (NULL == s)
1283           break;
1284         n = strlen (s);
1285         n = CLAMPADD(n, 1);
1286 #ifdef MF_REGISTER_gethostbyname_items
1287         __mf_register (s, n, MF_REGISTER_gethostbyname_items,
1288           "gethostbyname result->h_aliases[]");
1289 #endif
1290         MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
1291           "gethostbyname result->h_aliases[]");
1292       }
1293       nreg *= sizeof (*p->h_aliases);
1294 #ifdef MF_REGISTER_gethostbyname_items
1295       __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
1296         "gethostbyname result->h_aliases");
1297 #endif
1298       MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
1299         "gethostbyname result->h_aliases");
1300     }
1301
1302     if (NULL != (ss = p->h_addr_list)) {
1303       for (nreg = 1;; ++nreg) {
1304         s = *ss++;
1305         if (NULL == s)
1306           break;
1307 #ifdef MF_REGISTER_gethostbyname_items
1308         __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
1309           "gethostbyname result->h_addr_list[]");
1310 #endif
1311         MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
1312           "gethostbyname result->h_addr_list[]");
1313       }
1314       nreg *= sizeof (*p->h_addr_list);
1315 #ifdef MF_REGISTER_gethostbyname_items
1316       __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
1317         "gethostbyname result->h_addr_list");
1318 #endif
1319       MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
1320         "gethostbyname result->h_addr_list");
1321     }
1322   }
1323   return p;
1324 }
1325
1326 #endif /* HAVE_NETDB_H */
1327
1328
1329 #ifdef HAVE_SYS_WAIT_H
1330
1331 WRAPPER2(pid_t, wait, int *status)
1332 {
1333   TRACE ("%s\n", __PRETTY_FUNCTION__);
1334   if (NULL != status)
1335     MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1336       "wait status");
1337   return wait (status);
1338 }
1339
1340
1341 WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
1342 {
1343   TRACE ("%s\n", __PRETTY_FUNCTION__);
1344   if (NULL != status)
1345     MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
1346       "waitpid status");
1347   return waitpid (pid, status, options);
1348 }
1349
1350 #endif /* HAVE_SYS_WAIT_H */
1351
1352
1353 WRAPPER2(FILE *, popen, const char *command, const char *mode)
1354 {
1355   size_t n;
1356   FILE *p;
1357   TRACE ("%s\n", __PRETTY_FUNCTION__);
1358
1359   n = strlen (command);
1360   MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
1361
1362   n = strlen (mode);
1363   MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
1364
1365   p = popen (command, mode);
1366   if (NULL != p) {
1367 #ifdef MF_REGISTER_fopen
1368     __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
1369 #endif
1370     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
1371   }
1372   return p;
1373 }
1374
1375
1376 WRAPPER2(int, pclose, FILE *stream)
1377 {
1378   int resp;
1379   TRACE ("%s\n", __PRETTY_FUNCTION__);
1380   MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
1381     "pclose stream");
1382   resp = pclose (stream);
1383 #ifdef MF_REGISTER_fopen
1384   __mf_unregister (stream, sizeof (*stream));
1385 #endif
1386   return resp;
1387 }
1388
1389
1390 WRAPPER2(int, execve, const char *path, char *const argv [],
1391         char *const envp[])
1392 {
1393   size_t n;
1394   char *const *p;
1395   const char *s;
1396   TRACE ("%s\n", __PRETTY_FUNCTION__);
1397
1398   n = strlen (path);
1399   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
1400
1401   for (p = argv;;) {
1402     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
1403     s = *p++;
1404     if (NULL == s)
1405       break;
1406     n = strlen (s);
1407     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
1408   }
1409
1410   for (p = envp;;) {
1411     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
1412     s = *p++;
1413     if (NULL == s)
1414       break;
1415     n = strlen (s);
1416     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
1417   }
1418   return execve (path, argv, envp);
1419 }
1420
1421
1422 WRAPPER2(int, execv, const char *path, char *const argv [])
1423 {
1424   size_t n;
1425   char *const *p;
1426   const char *s;
1427   TRACE ("%s\n", __PRETTY_FUNCTION__);
1428
1429   n = strlen (path);
1430   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
1431
1432   for (p = argv;;) {
1433     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
1434     s = *p++;
1435     if (NULL == s)
1436       break;
1437     n = strlen (s);
1438     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
1439   }
1440   return execv (path, argv);
1441 }
1442
1443
1444 WRAPPER2(int, execvp, const char *path, char *const argv [])
1445 {
1446   size_t n;
1447   char *const *p;
1448   const char *s;
1449   TRACE ("%s\n", __PRETTY_FUNCTION__);
1450
1451   n = strlen (path);
1452   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
1453
1454   for (p = argv;;) {
1455     MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
1456     s = *p++;
1457     if (NULL == s)
1458       break;
1459     n = strlen (s);
1460     MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
1461   }
1462   return execvp (path, argv);
1463 }
1464
1465
1466 WRAPPER2(int, system, const char *string)
1467 {
1468   size_t n;
1469   TRACE ("%s\n", __PRETTY_FUNCTION__);
1470   n = strlen (string);
1471   MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
1472     "system string");
1473   return system (string);
1474 }
1475
1476
1477 WRAPPER2(void *, dlopen, const char *path, int flags)
1478 {
1479   void *p;
1480   size_t n;
1481   TRACE ("%s\n", __PRETTY_FUNCTION__);
1482   n = strlen (path);
1483   MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
1484   p = dlopen (path, flags);
1485   if (NULL != p) {
1486 #ifdef MF_REGISTER_dlopen
1487     __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
1488 #endif
1489     MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
1490   }
1491   return p;
1492 }
1493
1494
1495 WRAPPER2(int, dlclose, void *handle)
1496 {
1497   int resp;
1498   TRACE ("%s\n", __PRETTY_FUNCTION__);
1499   MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
1500   resp = dlclose (handle);
1501 #ifdef MF_REGISTER_dlopen
1502   __mf_unregister (handle, 0);
1503 #endif
1504   return resp;
1505 }
1506
1507
1508 WRAPPER2(char *, dlerror)
1509 {
1510   char *p;
1511   TRACE ("%s\n", __PRETTY_FUNCTION__);
1512   p = dlerror ();
1513   if (NULL != p) {
1514     size_t n;
1515     n = strlen (p);
1516     n = CLAMPADD(n, 1);
1517 #ifdef MF_REGISTER_dlerror
1518     __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
1519 #endif
1520     MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
1521   }
1522   return p;
1523 }
1524
1525
1526 WRAPPER2(void *, dlsym, void *handle, char *symbol)
1527 {
1528   size_t n;
1529   void *p;
1530   TRACE ("%s\n", __PRETTY_FUNCTION__);
1531   MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
1532   n = strlen (symbol);
1533   MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
1534   p = dlsym (handle, symbol);
1535   if (NULL != p) {
1536 #ifdef MF_REGISTER_dlsym
1537     __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
1538 #endif
1539     MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
1540   }
1541   return p;
1542 }
1543
1544
1545 #if defined (HAVE_SYS_IPC_H) && defined (HAVE_SYS_SEM_H) && defined (HAVE_SYS_SHM_H)
1546
1547 WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
1548 {
1549   TRACE ("%s\n", __PRETTY_FUNCTION__);
1550   MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
1551     "semop sops");
1552   return semop (semid, sops, nsops);
1553 }
1554
1555
1556 #ifndef HAVE_UNION_SEMUN
1557 union semun {
1558         int val;                        /* value for SETVAL */
1559         struct semid_ds *buf;           /* buffer for IPC_STAT, IPC_SET */
1560         unsigned short int *array;      /* array for GETALL, SETALL */
1561         struct seminfo *__buf;          /* buffer for IPC_INFO */
1562 };
1563 #endif
1564 WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
1565 {
1566   TRACE ("%s\n", __PRETTY_FUNCTION__);
1567   switch (cmd) {
1568   case IPC_STAT:
1569     MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
1570       "semctl buf");
1571     break;
1572   case IPC_SET:
1573     MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
1574       "semctl buf");
1575     break;
1576   case GETALL:
1577     MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
1578       "semctl array");
1579   case SETALL:
1580     MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
1581       "semctl array");
1582     break;
1583 #ifdef IPC_INFO
1584   /* FreeBSD 5.1 headers include IPC_INFO but not the __buf field.  */
1585 #if !defined(__FreeBSD__)
1586   case IPC_INFO:
1587     MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
1588       "semctl __buf");
1589     break;
1590 #endif
1591 #endif
1592   default:
1593     break;
1594   }
1595   return semctl (semid, semnum, cmd, arg);
1596 }
1597
1598
1599 WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
1600 {
1601   TRACE ("%s\n", __PRETTY_FUNCTION__);
1602   switch (cmd) {
1603   case IPC_STAT:
1604     MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
1605       "shmctl buf");
1606     break;
1607   case IPC_SET:
1608     MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
1609       "shmctl buf");
1610     break;
1611   default:
1612     break;
1613   }
1614   return shmctl (shmid, cmd, buf);
1615 }
1616
1617
1618 WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
1619 {
1620   void *p;
1621   TRACE ("%s\n", __PRETTY_FUNCTION__);
1622   p = shmat (shmid, shmaddr, shmflg);
1623 #ifdef MF_REGISTER_shmat
1624   if (NULL != p) {
1625     struct shmid_ds buf;
1626     __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
1627       MF_REGISTER_shmat, "shmat result");
1628   }
1629 #endif
1630   return p;
1631 }
1632
1633
1634 WRAPPER2(int, shmdt, const void *shmaddr)
1635 {
1636   int resp;
1637   TRACE ("%s\n", __PRETTY_FUNCTION__);
1638   resp = shmdt (shmaddr);
1639 #ifdef MF_REGISTER_shmat
1640   __mf_unregister ((void *)shmaddr, 0);
1641 #endif
1642   return resp;
1643 }
1644
1645
1646 #endif /* HAVE_SYS_IPC/SEM/SHM_H */
1647
1648
1649
1650 /* ctype stuff.  This is host-specific by necessity, as the arrays
1651    that is used by most is*()/to*() macros are implementation-defined.  */
1652
1653 /* GLIBC 2.3 */
1654 #ifdef HAVE___CTYPE_B_LOC
1655 WRAPPER2(unsigned short **, __ctype_b_loc, void)
1656 {
1657   static unsigned short * last_buf = (void *) 0;
1658   static unsigned short ** last_ptr = (void *) 0;
1659   unsigned short ** ptr = (unsigned short **) __ctype_b_loc ();
1660   unsigned short * buf = * ptr;
1661   if (ptr != last_ptr)
1662     {
1663       /* XXX: unregister last_ptr? */
1664       last_ptr = ptr;
1665       __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_b_loc **");
1666     }
1667   if (buf != last_buf)
1668     {
1669       last_buf = buf;
1670       __mf_register ((void *) (last_buf - 128), 384 * sizeof(unsigned short), __MF_TYPE_STATIC,
1671                      "ctype_b_loc []");
1672     }
1673   return ptr;
1674 }
1675 #endif
1676
1677 #ifdef HAVE___CTYPE_TOUPPER_LOC
1678 WRAPPER2(int **, __ctype_toupper_loc, void)
1679 {
1680   static int * last_buf = (void *) 0;
1681   static int ** last_ptr = (void *) 0;
1682   int ** ptr = (int **) __ctype_toupper_loc ();
1683   int * buf = * ptr;
1684   if (ptr != last_ptr)
1685     {
1686       /* XXX: unregister last_ptr? */
1687       last_ptr = ptr;
1688       __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_toupper_loc **");
1689     }
1690   if (buf != last_buf)
1691     {
1692       last_buf = buf;
1693       __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1694                      "ctype_toupper_loc []");
1695     }
1696   return ptr;
1697 }
1698 #endif
1699
1700 #ifdef HAVE___CTYPE_TOLOWER_LOC
1701 WRAPPER2(int **, __ctype_tolower_loc, void)
1702 {
1703   static int * last_buf = (void *) 0;
1704   static int ** last_ptr = (void *) 0;
1705   int ** ptr = (int **) __ctype_tolower_loc ();
1706   int * buf = * ptr;
1707   if (ptr != last_ptr)
1708     {
1709       /* XXX: unregister last_ptr? */
1710       last_ptr = ptr;
1711       __mf_register (last_ptr, sizeof(last_ptr), __MF_TYPE_STATIC, "ctype_tolower_loc **");
1712     }
1713   if (buf != last_buf)
1714     {
1715       last_buf = buf;
1716       __mf_register ((void *) (last_buf - 128), 384 * sizeof(int), __MF_TYPE_STATIC,
1717                      "ctype_tolower_loc []");
1718     }
1719   return ptr;
1720 }
1721 #endif