1 /* $OpenBSD: malloc0test.c,v 1.5 2008/04/13 00:22:17 djm Exp $ */ 2 /* 3 * Public domain. 2001, Theo de Raadt 4 */ 5 #include <sys/types.h> 6 #include <sys/signal.h> 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <stdlib.h> 10 #include <setjmp.h> 11 #include <limits.h> 12 #include <errno.h> 13 14 volatile sig_atomic_t got; 15 jmp_buf jmp; 16 17 static void 18 catch(int signo) 19 { 20 got++; 21 longjmp(jmp, 1); 22 } 23 24 static int 25 test(char *p, int size) 26 { 27 signal(SIGSEGV, catch); 28 got = 0; 29 if (setjmp(jmp) == 0) 30 *p = 0; 31 if (setjmp(jmp) == 0) 32 *(p+size-1) = 0; 33 return (got); 34 } 35 36 char *prot_table[] = { 37 "unprotected", 38 "fuckup", 39 "protected" 40 }; 41 42 #define SIZE 10 43 44 /* 45 * Do random memory allocations. 46 * 47 * For each one, ensure that it is at least 16 bytes in size (that 48 * being what our current malloc returns for the minsize of an 49 * object, alignment wise); 50 * 51 * For zero-byte allocations, check that they are still aligned. 52 * 53 * For each object, ensure that they are correctly protected or not 54 * protected. 55 * 56 * Does not regress test malloc + free combinations ... it should. 57 */ 58 int 59 main(int argc, char *argv[]) 60 { 61 caddr_t blob; 62 int size, tsize; 63 int prot; 64 int rval = 0, fuckup = 0; 65 long limit = 200000, count; 66 int ch, silent = 0; 67 char *ep; 68 extern char *__progname; 69 70 while ((ch = getopt(argc, argv, "sn:")) != -1) { 71 switch (ch) { 72 case 's': 73 silent = 1; 74 break; 75 case 'n': 76 errno = 0; 77 limit = strtol(optarg, &ep, 10); 78 if (optarg[0] == '\0' || *ep != '\0' || 79 (errno == ERANGE && 80 (limit == LONG_MAX || limit == LONG_MIN))) 81 goto usage; 82 break; 83 default: 84 usage: 85 fprintf(stderr, "Usage: %s [-s][-n <count>]\n", 86 __progname); 87 exit(1); 88 } 89 } 90 91 if (limit == 0) 92 limit = LONG_MAX; 93 94 for (count = 0; count < limit; count++) { 95 size = arc4random_uniform(SIZE); 96 blob = malloc(size); 97 if (blob == NULL) { 98 fprintf(stderr, "success: out of memory\n"); 99 exit(rval); 100 } 101 102 tsize = size == 0 ? 16 : size; 103 fuckup = 0; 104 prot = test(blob, tsize); 105 106 if (size == 0 && prot < 2) 107 fuckup = 1; 108 109 if (fuckup) { 110 printf("%8p %6d %20s %10s\n", blob, size, 111 prot_table[prot], fuckup ? "fuckup" : ""); 112 rval = 1; 113 } 114 115 if (!silent && count % 100000 == 0 && count != 0) 116 fprintf(stderr, "count = %ld\n", count); 117 } 118 119 return rval; 120 } 121