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