OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libmudflap/] [mf-hooks2.c] - Blame information for rev 818

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 738 jeremybenn
/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2
   Copyright (C) 2002, 2003, 2004, 2009, 2011 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
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
 
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
 
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
 
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
 
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
 
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
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
 
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
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
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
 
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
 
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
 
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
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
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
 
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
 
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
 
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
 
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
 
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
 
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>
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
 
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
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
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
 
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
 
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
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
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
714
WRAPPER2(int, setlinebuf, FILE* stream)
715
{
716
  return __mfwrap_setvbuf(stream, NULL, _IOLBF, 0);
717
}
718
#endif
719
 
720
 
721
 
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
 
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
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
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
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
 
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
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
 
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
 
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
 
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
 
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
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
 
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
 
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
 
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
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
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
 
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
 
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
 
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.