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
catch(int signo)18 catch(int signo)
19 {
20 got++;
21 longjmp(jmp, 1);
22 }
23
24 static int
test(char * p,int size)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
main(int argc,char * argv[])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