1 /* $OpenBSD: malloc0test.c,v 1.3 2004/02/11 08:16:00 deraadt 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 rblob = malloc(1); 62 caddr_t zblob = malloc(0); 63 caddr_t *blobp, blob; 64 int size, rsize, tsize; 65 int prot; 66 int rval = 0, fuckup = 0; 67 long limit = 200000, count; 68 int ch, silent = 0; 69 char *ep; 70 extern char *__progname; 71 72 while ((ch = getopt(argc, argv, "sn:")) != -1) { 73 switch (ch) { 74 case 's': 75 silent = 1; 76 break; 77 case 'n': 78 errno = 0; 79 limit = strtol(optarg, &ep, 10); 80 if (optarg[0] == '\0' || *ep != '\0' || 81 (errno == ERANGE && 82 (limit == LONG_MAX || limit == LONG_MIN))) 83 goto usage; 84 break; 85 default: 86 usage: 87 fprintf(stderr, "Usage: %s [-s][-n <count>]\n", 88 __progname); 89 exit(1); 90 } 91 } 92 93 if (limit == 0) 94 limit = LONG_MAX; 95 96 for (count = 0; count < limit; count++) { 97 size = arc4random() % SIZE; 98 blob = malloc(size); 99 if (blob == NULL) { 100 fprintf(stderr, "success: out of memory\n"); 101 exit(rval); 102 } 103 104 if (size == 0) { 105 blobp = &zblob; 106 tsize = 16; 107 } else { 108 blobp = &rblob; 109 tsize = size; 110 } 111 112 rsize = blob - *blobp; 113 fuckup = SIZE < 16 && size >= rsize; 114 prot = test(blob, tsize); 115 116 if (size == 0 && rsize < 16) 117 fuckup = 1; 118 if (size == 0 && prot < 2) 119 fuckup = 1; 120 121 if (fuckup) { 122 printf("%8p %6d %6d %20s %10s\n", blob, size, rsize, 123 prot_table[prot], fuckup ? "fuckup" : ""); 124 rval = 1; 125 } 126 *blobp = blob; 127 128 if (!silent && count % 100000 == 0 && count != 0) 129 fprintf(stderr, "count = %d\n", count); 130 } 131 132 return rval; 133 } 134