OSDN Git Service

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