xref: /openbsd-src/regress/lib/libc/malloc/malloc0test/malloc0test.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
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