OSDN Git Service

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