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