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