xref: /aosp_15_r20/external/ltp/testcases/misc/crash/crash01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * crash01.c - Test OS robustness by creating a string of random bytes and then jump to it.
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * New version Copyright (C) 2001 Stephane Fillod <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker  *
6*49cdfc7eSAndroid Build Coastguard Worker  * Original idea (c) 1990-1994 by GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.
7*49cdfc7eSAndroid Build Coastguard Worker  *	from crashme version: "2.4 20-MAY-1994" <[email protected]>
8*49cdfc7eSAndroid Build Coastguard Worker  */
9*49cdfc7eSAndroid Build Coastguard Worker /* TODO: trapme: forge syscall with random args, and run it!! --SF */
10*49cdfc7eSAndroid Build Coastguard Worker 
11*49cdfc7eSAndroid Build Coastguard Worker /*
12*49cdfc7eSAndroid Build Coastguard Worker  *             COPYRIGHT (c) 1990-1994 BY        *
13*49cdfc7eSAndroid Build Coastguard Worker  *  GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.  *
14*49cdfc7eSAndroid Build Coastguard Worker  *             ALL RIGHTS RESERVED               *
15*49cdfc7eSAndroid Build Coastguard Worker 
16*49cdfc7eSAndroid Build Coastguard Worker Permission to use, copy, modify, distribute and sell this software
17*49cdfc7eSAndroid Build Coastguard Worker and its documentation for any purpose and without fee is hereby
18*49cdfc7eSAndroid Build Coastguard Worker granted, provided that the above copyright notice appear in all copies
19*49cdfc7eSAndroid Build Coastguard Worker and that both that copyright notice and this permission notice appear
20*49cdfc7eSAndroid Build Coastguard Worker in supporting documentation, and that the name of the author
21*49cdfc7eSAndroid Build Coastguard Worker not be used in advertising or publicity pertaining to distribution
22*49cdfc7eSAndroid Build Coastguard Worker of the software without specific, written prior permission.
23*49cdfc7eSAndroid Build Coastguard Worker 
24*49cdfc7eSAndroid Build Coastguard Worker THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25*49cdfc7eSAndroid Build Coastguard Worker ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
26*49cdfc7eSAndroid Build Coastguard Worker HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
27*49cdfc7eSAndroid Build Coastguard Worker ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
28*49cdfc7eSAndroid Build Coastguard Worker WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
29*49cdfc7eSAndroid Build Coastguard Worker ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
30*49cdfc7eSAndroid Build Coastguard Worker SOFTWARE.
31*49cdfc7eSAndroid Build Coastguard Worker 
32*49cdfc7eSAndroid Build Coastguard Worker */
33*49cdfc7eSAndroid Build Coastguard Worker 
34*49cdfc7eSAndroid Build Coastguard Worker /*
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker A signal handler is set up so that in most cases the machine exception
37*49cdfc7eSAndroid Build Coastguard Worker generated by the illegal instructions, bad operands, etc in the procedure
38*49cdfc7eSAndroid Build Coastguard Worker made up of random data are caught; and another round of randomness may
39*49cdfc7eSAndroid Build Coastguard Worker be tried. Eventually a random instruction may corrupt the program or
40*49cdfc7eSAndroid Build Coastguard Worker the machine state in such a way that the program must halt. This is
41*49cdfc7eSAndroid Build Coastguard Worker a test of the robustness of the hardware/software for instruction
42*49cdfc7eSAndroid Build Coastguard Worker fault handling.
43*49cdfc7eSAndroid Build Coastguard Worker 
44*49cdfc7eSAndroid Build Coastguard Worker Note: Running this program just a few times, using total CPU time of
45*49cdfc7eSAndroid Build Coastguard Worker less than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
46*49cdfc7eSAndroid Build Coastguard Worker robustness. Having it run for hours, with tens of thousands of cases
47*49cdfc7eSAndroid Build Coastguard Worker would be a different thing. It would also make sense to run this
48*49cdfc7eSAndroid Build Coastguard Worker stress test at the same time you run other tests, like a multi-user
49*49cdfc7eSAndroid Build Coastguard Worker benchmark.
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker */
52*49cdfc7eSAndroid Build Coastguard Worker 
53*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
54*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
55*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
56*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
57*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
58*49cdfc7eSAndroid Build Coastguard Worker #include <setjmp.h>
59*49cdfc7eSAndroid Build Coastguard Worker #include <time.h>
60*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
61*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
62*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
63*49cdfc7eSAndroid Build Coastguard Worker 
64*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
65*49cdfc7eSAndroid Build Coastguard Worker 
66*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "crash01";
67*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;
68*49cdfc7eSAndroid Build Coastguard Worker 
69*49cdfc7eSAndroid Build Coastguard Worker static int x_opt = 0;
70*49cdfc7eSAndroid Build Coastguard Worker static int v_opt = 0;
71*49cdfc7eSAndroid Build Coastguard Worker static char *v_copt;
72*49cdfc7eSAndroid Build Coastguard Worker static int s_opt = 0;
73*49cdfc7eSAndroid Build Coastguard Worker static char *s_copt;
74*49cdfc7eSAndroid Build Coastguard Worker static int b_opt = 0;
75*49cdfc7eSAndroid Build Coastguard Worker static char *b_copt;
76*49cdfc7eSAndroid Build Coastguard Worker static int n_opt = 0;
77*49cdfc7eSAndroid Build Coastguard Worker static char *n_copt;
78*49cdfc7eSAndroid Build Coastguard Worker 
79*49cdfc7eSAndroid Build Coastguard Worker int verbose_level = 2;
80*49cdfc7eSAndroid Build Coastguard Worker 
81*49cdfc7eSAndroid Build Coastguard Worker /* Also, it may spend more time trapping and less time computing random bytes
82*49cdfc7eSAndroid Build Coastguard Worker  * by using the smallest incptr (while not executing already tested bits).
83*49cdfc7eSAndroid Build Coastguard Worker  */
84*49cdfc7eSAndroid Build Coastguard Worker int incptr = 80;
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker int nseed;
87*49cdfc7eSAndroid Build Coastguard Worker int ntries = 100;
88*49cdfc7eSAndroid Build Coastguard Worker 
89*49cdfc7eSAndroid Build Coastguard Worker /* compute block of nbytes at a time */
90*49cdfc7eSAndroid Build Coastguard Worker const int nbytes = 2000;
91*49cdfc7eSAndroid Build Coastguard Worker 
92*49cdfc7eSAndroid Build Coastguard Worker /* max time allowed per try, in seconds */
93*49cdfc7eSAndroid Build Coastguard Worker #define MAX_TRY_TIME 5
94*49cdfc7eSAndroid Build Coastguard Worker 
95*49cdfc7eSAndroid Build Coastguard Worker /* in % */
96*49cdfc7eSAndroid Build Coastguard Worker #define BLOCK_TRIGGER 80
97*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)98*49cdfc7eSAndroid Build Coastguard Worker void cleanup(void)
99*49cdfc7eSAndroid Build Coastguard Worker {
100*49cdfc7eSAndroid Build Coastguard Worker 
101*49cdfc7eSAndroid Build Coastguard Worker 	tst_rmdir();
102*49cdfc7eSAndroid Build Coastguard Worker 
103*49cdfc7eSAndroid Build Coastguard Worker }
104*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)105*49cdfc7eSAndroid Build Coastguard Worker void setup(void)
106*49cdfc7eSAndroid Build Coastguard Worker {
107*49cdfc7eSAndroid Build Coastguard Worker 	/*
108*49cdfc7eSAndroid Build Coastguard Worker 	 * setup a default signal hander and a
109*49cdfc7eSAndroid Build Coastguard Worker 	 * temporary working directory.
110*49cdfc7eSAndroid Build Coastguard Worker 	 */
111*49cdfc7eSAndroid Build Coastguard Worker 	tst_sig(FORK, DEF_HANDLER, cleanup);
112*49cdfc7eSAndroid Build Coastguard Worker 
113*49cdfc7eSAndroid Build Coastguard Worker 	tst_tmpdir();
114*49cdfc7eSAndroid Build Coastguard Worker 
115*49cdfc7eSAndroid Build Coastguard Worker 	TEST_PAUSE;
116*49cdfc7eSAndroid Build Coastguard Worker }
117*49cdfc7eSAndroid Build Coastguard Worker 
help(void)118*49cdfc7eSAndroid Build Coastguard Worker void help(void)
119*49cdfc7eSAndroid Build Coastguard Worker {
120*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -x      dry run, hexdump random code instead\n");
121*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -v x    verbose level\n");
122*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -s x    random seed\n");
123*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -n x    ntries\n");
124*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -b x    inc\n");
125*49cdfc7eSAndroid Build Coastguard Worker }
126*49cdfc7eSAndroid Build Coastguard Worker 
127*49cdfc7eSAndroid Build Coastguard Worker /*
128*49cdfc7eSAndroid Build Coastguard Worker  * crashme [+]<nbytes>[.inc] <srand> <ntries> [nsub] [verbose]"
129*49cdfc7eSAndroid Build Coastguard Worker  *
130*49cdfc7eSAndroid Build Coastguard Worker  * crashme <-b [+]<nbytes>[.inc]> <-s srand> <-n ntries> [-v verbose]"
131*49cdfc7eSAndroid Build Coastguard Worker  *  crashme +2000.80 666 100 1:10:30 2
132*49cdfc7eSAndroid Build Coastguard Worker  *	nsub  -> -c ?
133*49cdfc7eSAndroid Build Coastguard Worker  */
134*49cdfc7eSAndroid Build Coastguard Worker option_t options[] = {
135*49cdfc7eSAndroid Build Coastguard Worker 	{"v:", &v_opt, &v_copt},
136*49cdfc7eSAndroid Build Coastguard Worker 	{"s:", &s_opt, &s_copt},
137*49cdfc7eSAndroid Build Coastguard Worker 	{"n:", &n_opt, &n_copt},
138*49cdfc7eSAndroid Build Coastguard Worker 	{"b:", &b_opt, &b_copt},
139*49cdfc7eSAndroid Build Coastguard Worker 	{"x", &x_opt, NULL},
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker 	{NULL, NULL, NULL}
142*49cdfc7eSAndroid Build Coastguard Worker };
143*49cdfc7eSAndroid Build Coastguard Worker 
144*49cdfc7eSAndroid Build Coastguard Worker int malloc_flag = 1;		/* to be phased out */
145*49cdfc7eSAndroid Build Coastguard Worker 
146*49cdfc7eSAndroid Build Coastguard Worker void badboy_fork();
147*49cdfc7eSAndroid Build Coastguard Worker void badboy_loop();
148*49cdfc7eSAndroid Build Coastguard Worker void summarize_status();
149*49cdfc7eSAndroid Build Coastguard Worker void record_status(unsigned int n);
150*49cdfc7eSAndroid Build Coastguard Worker 
main(int argc,char * argv[])151*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char *argv[])
152*49cdfc7eSAndroid Build Coastguard Worker {
153*49cdfc7eSAndroid Build Coastguard Worker 	int lc;
154*49cdfc7eSAndroid Build Coastguard Worker 
155*49cdfc7eSAndroid Build Coastguard Worker 	tst_parse_opts(argc, argv, options, help);
156*49cdfc7eSAndroid Build Coastguard Worker 
157*49cdfc7eSAndroid Build Coastguard Worker 	if (v_opt)
158*49cdfc7eSAndroid Build Coastguard Worker 		verbose_level = atoi(v_copt);
159*49cdfc7eSAndroid Build Coastguard Worker 
160*49cdfc7eSAndroid Build Coastguard Worker 	if (n_opt)
161*49cdfc7eSAndroid Build Coastguard Worker 		ntries = atoi(n_copt);
162*49cdfc7eSAndroid Build Coastguard Worker 
163*49cdfc7eSAndroid Build Coastguard Worker 	if (s_opt)
164*49cdfc7eSAndroid Build Coastguard Worker 		nseed = atoi(s_copt);
165*49cdfc7eSAndroid Build Coastguard Worker 	else
166*49cdfc7eSAndroid Build Coastguard Worker 		nseed = time(NULL);
167*49cdfc7eSAndroid Build Coastguard Worker 
168*49cdfc7eSAndroid Build Coastguard Worker 	if (b_opt) {
169*49cdfc7eSAndroid Build Coastguard Worker 		int inc;
170*49cdfc7eSAndroid Build Coastguard Worker 
171*49cdfc7eSAndroid Build Coastguard Worker 		inc = atoi(b_copt);
172*49cdfc7eSAndroid Build Coastguard Worker 		if (inc <= nbytes / 2)
173*49cdfc7eSAndroid Build Coastguard Worker 			incptr = inc;
174*49cdfc7eSAndroid Build Coastguard Worker 		else
175*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TBROK, cleanup,
176*49cdfc7eSAndroid Build Coastguard Worker 				 "Invalid arg for -b (max: %u): %s", nbytes / 2,
177*49cdfc7eSAndroid Build Coastguard Worker 				 b_copt);
178*49cdfc7eSAndroid Build Coastguard Worker 	}
179*49cdfc7eSAndroid Build Coastguard Worker 
180*49cdfc7eSAndroid Build Coastguard Worker 	setup();
181*49cdfc7eSAndroid Build Coastguard Worker 
182*49cdfc7eSAndroid Build Coastguard Worker 	for (lc = 0; TEST_LOOPING(lc); lc++) {
183*49cdfc7eSAndroid Build Coastguard Worker 		tst_count = 0;
184*49cdfc7eSAndroid Build Coastguard Worker 
185*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "crashme %s%d.%d %d %d",
186*49cdfc7eSAndroid Build Coastguard Worker 			 (malloc_flag == 0) ? "" : "+", nbytes, incptr, nseed,
187*49cdfc7eSAndroid Build Coastguard Worker 			 ntries);
188*49cdfc7eSAndroid Build Coastguard Worker 
189*49cdfc7eSAndroid Build Coastguard Worker 		srand(nseed);
190*49cdfc7eSAndroid Build Coastguard Worker 		badboy_fork();
191*49cdfc7eSAndroid Build Coastguard Worker 
192*49cdfc7eSAndroid Build Coastguard Worker 		/* still there? */
193*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TPASS, "we're still here, OS seems to be robust");
194*49cdfc7eSAndroid Build Coastguard Worker 
195*49cdfc7eSAndroid Build Coastguard Worker 		nseed++;
196*49cdfc7eSAndroid Build Coastguard Worker 	}
197*49cdfc7eSAndroid Build Coastguard Worker 	summarize_status();
198*49cdfc7eSAndroid Build Coastguard Worker 	cleanup();
199*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
200*49cdfc7eSAndroid Build Coastguard Worker }
201*49cdfc7eSAndroid Build Coastguard Worker 
202*49cdfc7eSAndroid Build Coastguard Worker /* ************************* */
203*49cdfc7eSAndroid Build Coastguard Worker int badboy_pid;
204*49cdfc7eSAndroid Build Coastguard Worker 
205*49cdfc7eSAndroid Build Coastguard Worker void my_signal(int sig, void (*func) ());
206*49cdfc7eSAndroid Build Coastguard Worker 
monitor_fcn(int sig)207*49cdfc7eSAndroid Build Coastguard Worker void monitor_fcn(int sig)
208*49cdfc7eSAndroid Build Coastguard Worker {
209*49cdfc7eSAndroid Build Coastguard Worker 	int status;
210*49cdfc7eSAndroid Build Coastguard Worker 
211*49cdfc7eSAndroid Build Coastguard Worker 	if (verbose_level >= 3)
212*49cdfc7eSAndroid Build Coastguard Worker 		printf("time limit reached on pid. using kill.\n");
213*49cdfc7eSAndroid Build Coastguard Worker 
214*49cdfc7eSAndroid Build Coastguard Worker 	status = kill(badboy_pid, SIGKILL);
215*49cdfc7eSAndroid Build Coastguard Worker 	if (status < 0) {
216*49cdfc7eSAndroid Build Coastguard Worker 		if (verbose_level >= 3)
217*49cdfc7eSAndroid Build Coastguard Worker 			printf("failed to kill process\n");
218*49cdfc7eSAndroid Build Coastguard Worker 	}
219*49cdfc7eSAndroid Build Coastguard Worker }
220*49cdfc7eSAndroid Build Coastguard Worker 
badboy_fork(void)221*49cdfc7eSAndroid Build Coastguard Worker void badboy_fork(void)
222*49cdfc7eSAndroid Build Coastguard Worker {
223*49cdfc7eSAndroid Build Coastguard Worker 	int status, pid;
224*49cdfc7eSAndroid Build Coastguard Worker 
225*49cdfc7eSAndroid Build Coastguard Worker 	status = fork();
226*49cdfc7eSAndroid Build Coastguard Worker 	badboy_pid = status;
227*49cdfc7eSAndroid Build Coastguard Worker 	if (status == 0) {	/* badboy */
228*49cdfc7eSAndroid Build Coastguard Worker #ifdef DEBUG_LATE_BADBOY
229*49cdfc7eSAndroid Build Coastguard Worker 		sleep(ntries * MAX_TRY_TIME + 10);
230*49cdfc7eSAndroid Build Coastguard Worker #else
231*49cdfc7eSAndroid Build Coastguard Worker 		badboy_loop();
232*49cdfc7eSAndroid Build Coastguard Worker #endif
233*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);	/* good goy, he survived! */
234*49cdfc7eSAndroid Build Coastguard Worker 	} else if (status < 0)
235*49cdfc7eSAndroid Build Coastguard Worker 		perror("fork");
236*49cdfc7eSAndroid Build Coastguard Worker 	else {			/* parent watching over badboy */
237*49cdfc7eSAndroid Build Coastguard Worker 
238*49cdfc7eSAndroid Build Coastguard Worker 		if (verbose_level > 3)
239*49cdfc7eSAndroid Build Coastguard Worker 			printf("badboy pid = %d\n", badboy_pid);
240*49cdfc7eSAndroid Build Coastguard Worker 
241*49cdfc7eSAndroid Build Coastguard Worker /* don't trust the child to return at night */
242*49cdfc7eSAndroid Build Coastguard Worker 		my_signal(SIGALRM, monitor_fcn);
243*49cdfc7eSAndroid Build Coastguard Worker 		alarm(ntries * MAX_TRY_TIME);
244*49cdfc7eSAndroid Build Coastguard Worker 
245*49cdfc7eSAndroid Build Coastguard Worker 		pid = wait(&status);
246*49cdfc7eSAndroid Build Coastguard Worker 		if (pid <= 0) {
247*49cdfc7eSAndroid Build Coastguard Worker 			perror("wait");
248*49cdfc7eSAndroid Build Coastguard Worker 		} else {
249*49cdfc7eSAndroid Build Coastguard Worker 			if (verbose_level > 3)
250*49cdfc7eSAndroid Build Coastguard Worker 				printf("pid %d exited with status %d\n", pid,
251*49cdfc7eSAndroid Build Coastguard Worker 				       status);
252*49cdfc7eSAndroid Build Coastguard Worker 			record_status(status);
253*49cdfc7eSAndroid Build Coastguard Worker 		}
254*49cdfc7eSAndroid Build Coastguard Worker 	}			/* parent */
255*49cdfc7eSAndroid Build Coastguard Worker 	alarm(0);
256*49cdfc7eSAndroid Build Coastguard Worker }
257*49cdfc7eSAndroid Build Coastguard Worker 
258*49cdfc7eSAndroid Build Coastguard Worker /* *************** status recording ************************* */
259*49cdfc7eSAndroid Build Coastguard Worker 
260*49cdfc7eSAndroid Build Coastguard Worker #define STATUS_MAX 256
261*49cdfc7eSAndroid Build Coastguard Worker static int status_table[STATUS_MAX];
262*49cdfc7eSAndroid Build Coastguard Worker 
record_status(unsigned int n)263*49cdfc7eSAndroid Build Coastguard Worker void record_status(unsigned int n)
264*49cdfc7eSAndroid Build Coastguard Worker {
265*49cdfc7eSAndroid Build Coastguard Worker 	if (n >= STATUS_MAX)
266*49cdfc7eSAndroid Build Coastguard Worker 		return;
267*49cdfc7eSAndroid Build Coastguard Worker 
268*49cdfc7eSAndroid Build Coastguard Worker 	status_table[n]++;
269*49cdfc7eSAndroid Build Coastguard Worker }
270*49cdfc7eSAndroid Build Coastguard Worker 
271*49cdfc7eSAndroid Build Coastguard Worker /* may not work with -c option */
summarize_status(void)272*49cdfc7eSAndroid Build Coastguard Worker void summarize_status(void)
273*49cdfc7eSAndroid Build Coastguard Worker {
274*49cdfc7eSAndroid Build Coastguard Worker 	int i;
275*49cdfc7eSAndroid Build Coastguard Worker 
276*49cdfc7eSAndroid Build Coastguard Worker 	if (verbose_level < 2)
277*49cdfc7eSAndroid Build Coastguard Worker 		return;
278*49cdfc7eSAndroid Build Coastguard Worker 
279*49cdfc7eSAndroid Build Coastguard Worker 	printf("exit status ... number of cases\n");
280*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < STATUS_MAX; i++) {
281*49cdfc7eSAndroid Build Coastguard Worker 		if (status_table[i])
282*49cdfc7eSAndroid Build Coastguard Worker 			printf("%11d ... %5d\n", i, status_table[i]);
283*49cdfc7eSAndroid Build Coastguard Worker 	}
284*49cdfc7eSAndroid Build Coastguard Worker }
285*49cdfc7eSAndroid Build Coastguard Worker 
286*49cdfc7eSAndroid Build Coastguard Worker /* ************* badboy ******************************************* */
287*49cdfc7eSAndroid Build Coastguard Worker 
288*49cdfc7eSAndroid Build Coastguard Worker jmp_buf again_buff;
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker typedef void (*BADBOY) ();
291*49cdfc7eSAndroid Build Coastguard Worker 
292*49cdfc7eSAndroid Build Coastguard Worker BADBOY badboy;
293*49cdfc7eSAndroid Build Coastguard Worker char *the_data;
294*49cdfc7eSAndroid Build Coastguard Worker 
295*49cdfc7eSAndroid Build Coastguard Worker int offset = 0;
296*49cdfc7eSAndroid Build Coastguard Worker int next_offset = 0;
297*49cdfc7eSAndroid Build Coastguard Worker 
298*49cdfc7eSAndroid Build Coastguard Worker char *bad_malloc(int n);
299*49cdfc7eSAndroid Build Coastguard Worker void my_signal(int sig, void (*func) ());
300*49cdfc7eSAndroid Build Coastguard Worker void again_handler(int sig);
301*49cdfc7eSAndroid Build Coastguard Worker void compute_block_badboy(int n);
302*49cdfc7eSAndroid Build Coastguard Worker void compute_badboy();
303*49cdfc7eSAndroid Build Coastguard Worker BADBOY castaway(char *dat);
304*49cdfc7eSAndroid Build Coastguard Worker void try_one_crash();
305*49cdfc7eSAndroid Build Coastguard Worker void set_up_signals();
306*49cdfc7eSAndroid Build Coastguard Worker 
307*49cdfc7eSAndroid Build Coastguard Worker /* badboy "entry" point */
badboy_loop(void)308*49cdfc7eSAndroid Build Coastguard Worker void badboy_loop(void)
309*49cdfc7eSAndroid Build Coastguard Worker {
310*49cdfc7eSAndroid Build Coastguard Worker 	int i;
311*49cdfc7eSAndroid Build Coastguard Worker 
312*49cdfc7eSAndroid Build Coastguard Worker 	if (malloc_flag == 0) {
313*49cdfc7eSAndroid Build Coastguard Worker 		the_data = bad_malloc((nbytes < 0) ? -nbytes : nbytes);
314*49cdfc7eSAndroid Build Coastguard Worker 		badboy = castaway(the_data);
315*49cdfc7eSAndroid Build Coastguard Worker 		printf("Badboy at %p\n", badboy);
316*49cdfc7eSAndroid Build Coastguard Worker 	}
317*49cdfc7eSAndroid Build Coastguard Worker 
318*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ntries; ++i) {
319*49cdfc7eSAndroid Build Coastguard Worker 		compute_badboy();
320*49cdfc7eSAndroid Build Coastguard Worker 		/* level 5 */
321*49cdfc7eSAndroid Build Coastguard Worker 
322*49cdfc7eSAndroid Build Coastguard Worker 		if (!x_opt && verbose_level >= 5) {
323*49cdfc7eSAndroid Build Coastguard Worker 			if (offset)
324*49cdfc7eSAndroid Build Coastguard Worker 				printf("try %d, offset %d\n", i, offset);
325*49cdfc7eSAndroid Build Coastguard Worker 			else if (malloc_flag == 1)
326*49cdfc7eSAndroid Build Coastguard Worker 				printf("try %d, Badboy at %p\n", i, badboy);
327*49cdfc7eSAndroid Build Coastguard Worker 			else
328*49cdfc7eSAndroid Build Coastguard Worker 				printf("try %d\n", i);
329*49cdfc7eSAndroid Build Coastguard Worker 		}
330*49cdfc7eSAndroid Build Coastguard Worker 
331*49cdfc7eSAndroid Build Coastguard Worker 		if (setjmp(again_buff) == 3) {
332*49cdfc7eSAndroid Build Coastguard Worker 			if (verbose_level >= 5)
333*49cdfc7eSAndroid Build Coastguard Worker 				printf("Barfed\n");
334*49cdfc7eSAndroid Build Coastguard Worker 		} else {
335*49cdfc7eSAndroid Build Coastguard Worker 			set_up_signals();
336*49cdfc7eSAndroid Build Coastguard Worker 			alarm(MAX_TRY_TIME);
337*49cdfc7eSAndroid Build Coastguard Worker 			try_one_crash();
338*49cdfc7eSAndroid Build Coastguard Worker 			if (!x_opt && verbose_level >= 5)
339*49cdfc7eSAndroid Build Coastguard Worker 				printf("didn't barf!\n");
340*49cdfc7eSAndroid Build Coastguard Worker 		}
341*49cdfc7eSAndroid Build Coastguard Worker 	}
342*49cdfc7eSAndroid Build Coastguard Worker }
343*49cdfc7eSAndroid Build Coastguard Worker 
bad_malloc(int n)344*49cdfc7eSAndroid Build Coastguard Worker char *bad_malloc(int n)
345*49cdfc7eSAndroid Build Coastguard Worker {
346*49cdfc7eSAndroid Build Coastguard Worker 	char *data;
347*49cdfc7eSAndroid Build Coastguard Worker 	data = malloc(n);
348*49cdfc7eSAndroid Build Coastguard Worker #ifdef pyr
349*49cdfc7eSAndroid Build Coastguard Worker 	if (mprotect(((int)data / PAGSIZ) * PAGSIZ, (n / PAGSIZ + 1) * PAGSIZ,
350*49cdfc7eSAndroid Build Coastguard Worker 		     PROT_READ | PROT_WRITE | PROT_EXEC))
351*49cdfc7eSAndroid Build Coastguard Worker 		perror("mprotect");
352*49cdfc7eSAndroid Build Coastguard Worker #endif
353*49cdfc7eSAndroid Build Coastguard Worker 	return (data);
354*49cdfc7eSAndroid Build Coastguard Worker }
355*49cdfc7eSAndroid Build Coastguard Worker 
again_handler(int sig)356*49cdfc7eSAndroid Build Coastguard Worker void again_handler(int sig)
357*49cdfc7eSAndroid Build Coastguard Worker {
358*49cdfc7eSAndroid Build Coastguard Worker 	char *ss;
359*49cdfc7eSAndroid Build Coastguard Worker 
360*49cdfc7eSAndroid Build Coastguard Worker 	switch (sig) {
361*49cdfc7eSAndroid Build Coastguard Worker 	case SIGILL:
362*49cdfc7eSAndroid Build Coastguard Worker 		ss = " illegal instruction";
363*49cdfc7eSAndroid Build Coastguard Worker 		break;
364*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGTRAP
365*49cdfc7eSAndroid Build Coastguard Worker 	case SIGTRAP:
366*49cdfc7eSAndroid Build Coastguard Worker 		ss = " trace trap";
367*49cdfc7eSAndroid Build Coastguard Worker 		break;
368*49cdfc7eSAndroid Build Coastguard Worker #endif
369*49cdfc7eSAndroid Build Coastguard Worker 	case SIGFPE:
370*49cdfc7eSAndroid Build Coastguard Worker 		ss = " arithmetic exception";
371*49cdfc7eSAndroid Build Coastguard Worker 		break;
372*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGBUS
373*49cdfc7eSAndroid Build Coastguard Worker 	case SIGBUS:
374*49cdfc7eSAndroid Build Coastguard Worker 		ss = " bus error";
375*49cdfc7eSAndroid Build Coastguard Worker 		break;
376*49cdfc7eSAndroid Build Coastguard Worker #endif
377*49cdfc7eSAndroid Build Coastguard Worker 	case SIGSEGV:
378*49cdfc7eSAndroid Build Coastguard Worker 		ss = " segmentation violation";
379*49cdfc7eSAndroid Build Coastguard Worker 		break;
380*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGIOT
381*49cdfc7eSAndroid Build Coastguard Worker 	case SIGIOT:
382*49cdfc7eSAndroid Build Coastguard Worker 		ss = " IOT instruction";
383*49cdfc7eSAndroid Build Coastguard Worker 		break;
384*49cdfc7eSAndroid Build Coastguard Worker #endif
385*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGEMT
386*49cdfc7eSAndroid Build Coastguard Worker 	case SIGEMT:
387*49cdfc7eSAndroid Build Coastguard Worker 		ss = " EMT instruction";
388*49cdfc7eSAndroid Build Coastguard Worker 		break;
389*49cdfc7eSAndroid Build Coastguard Worker #endif
390*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGALRM
391*49cdfc7eSAndroid Build Coastguard Worker 	case SIGALRM:
392*49cdfc7eSAndroid Build Coastguard Worker 		ss = " alarm clock";
393*49cdfc7eSAndroid Build Coastguard Worker 		break;
394*49cdfc7eSAndroid Build Coastguard Worker #endif
395*49cdfc7eSAndroid Build Coastguard Worker 	case SIGINT:
396*49cdfc7eSAndroid Build Coastguard Worker 		ss = " interrupt";
397*49cdfc7eSAndroid Build Coastguard Worker 		break;
398*49cdfc7eSAndroid Build Coastguard Worker 	default:
399*49cdfc7eSAndroid Build Coastguard Worker 		ss = "";
400*49cdfc7eSAndroid Build Coastguard Worker 	}
401*49cdfc7eSAndroid Build Coastguard Worker 	if (verbose_level >= 5)
402*49cdfc7eSAndroid Build Coastguard Worker 		printf("Got signal %d%s\n", sig, ss);
403*49cdfc7eSAndroid Build Coastguard Worker 
404*49cdfc7eSAndroid Build Coastguard Worker 	longjmp(again_buff, 3);
405*49cdfc7eSAndroid Build Coastguard Worker }
406*49cdfc7eSAndroid Build Coastguard Worker 
my_signal(int sig,void (* func)())407*49cdfc7eSAndroid Build Coastguard Worker void my_signal(int sig, void (*func) ())
408*49cdfc7eSAndroid Build Coastguard Worker {
409*49cdfc7eSAndroid Build Coastguard Worker 	struct sigaction act;
410*49cdfc7eSAndroid Build Coastguard Worker 
411*49cdfc7eSAndroid Build Coastguard Worker 	act.sa_handler = func;
412*49cdfc7eSAndroid Build Coastguard Worker 	memset(&act.sa_mask, 0x00, sizeof(sigset_t));
413*49cdfc7eSAndroid Build Coastguard Worker 	act.sa_flags = SA_NOMASK | SA_RESTART;
414*49cdfc7eSAndroid Build Coastguard Worker 	sigaction(sig, &act, 0);
415*49cdfc7eSAndroid Build Coastguard Worker }
416*49cdfc7eSAndroid Build Coastguard Worker 
set_up_signals(void)417*49cdfc7eSAndroid Build Coastguard Worker void set_up_signals(void)
418*49cdfc7eSAndroid Build Coastguard Worker {
419*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGILL, again_handler);
420*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGTRAP
421*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGTRAP, again_handler);
422*49cdfc7eSAndroid Build Coastguard Worker #endif
423*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGFPE, again_handler);
424*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGBUS
425*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGBUS, again_handler);
426*49cdfc7eSAndroid Build Coastguard Worker #endif
427*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGSEGV, again_handler);
428*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGIOT
429*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGIOT, again_handler);
430*49cdfc7eSAndroid Build Coastguard Worker #endif
431*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGEMT
432*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGEMT, again_handler);
433*49cdfc7eSAndroid Build Coastguard Worker #endif
434*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGALRM
435*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGALRM, again_handler);
436*49cdfc7eSAndroid Build Coastguard Worker #endif
437*49cdfc7eSAndroid Build Coastguard Worker 	my_signal(SIGINT, again_handler);
438*49cdfc7eSAndroid Build Coastguard Worker }
439*49cdfc7eSAndroid Build Coastguard Worker 
compute_block_badboy(int n)440*49cdfc7eSAndroid Build Coastguard Worker void compute_block_badboy(int n)
441*49cdfc7eSAndroid Build Coastguard Worker {
442*49cdfc7eSAndroid Build Coastguard Worker 	int j;
443*49cdfc7eSAndroid Build Coastguard Worker 
444*49cdfc7eSAndroid Build Coastguard Worker 	if (malloc_flag == 1) {
445*49cdfc7eSAndroid Build Coastguard Worker 		free(the_data);
446*49cdfc7eSAndroid Build Coastguard Worker 		the_data = bad_malloc(n);
447*49cdfc7eSAndroid Build Coastguard Worker 	}
448*49cdfc7eSAndroid Build Coastguard Worker 
449*49cdfc7eSAndroid Build Coastguard Worker 	for (j = 0; j < n; ++j) {
450*49cdfc7eSAndroid Build Coastguard Worker #ifdef WANT_SLOW_RAND
451*49cdfc7eSAndroid Build Coastguard Worker 		the_data[j] = 0xFF & (int)(256.0 * rand() / (RAND_MAX + 1.0));
452*49cdfc7eSAndroid Build Coastguard Worker #else
453*49cdfc7eSAndroid Build Coastguard Worker 		the_data[j] = (rand() >> 7) & 0xFF;
454*49cdfc7eSAndroid Build Coastguard Worker #endif
455*49cdfc7eSAndroid Build Coastguard Worker #ifdef __powerpc__
456*49cdfc7eSAndroid Build Coastguard Worker 		__asm__
457*49cdfc7eSAndroid Build Coastguard Worker 		    __volatile__("dcbst 0,%0 ; icbi 0,%0 ; isync"::"r"
458*49cdfc7eSAndroid Build Coastguard Worker 				 (&the_data[j]));
459*49cdfc7eSAndroid Build Coastguard Worker #endif
460*49cdfc7eSAndroid Build Coastguard Worker 
461*49cdfc7eSAndroid Build Coastguard Worker 	}
462*49cdfc7eSAndroid Build Coastguard Worker 
463*49cdfc7eSAndroid Build Coastguard Worker 	/* was (nbytes < 0) */
464*49cdfc7eSAndroid Build Coastguard Worker 	if (x_opt) {
465*49cdfc7eSAndroid Build Coastguard Worker 		if (verbose_level >= 1)
466*49cdfc7eSAndroid Build Coastguard Worker 			printf("Dump of %d bytes of data\n", n);
467*49cdfc7eSAndroid Build Coastguard Worker 		for (j = 0; j < n; ++j) {
468*49cdfc7eSAndroid Build Coastguard Worker 			if ((j % 16) == 0)
469*49cdfc7eSAndroid Build Coastguard Worker 				printf("\n%04d: ", j);
470*49cdfc7eSAndroid Build Coastguard Worker 
471*49cdfc7eSAndroid Build Coastguard Worker 			printf("%02x ", the_data[j]);
472*49cdfc7eSAndroid Build Coastguard Worker 		}
473*49cdfc7eSAndroid Build Coastguard Worker 		putc('\n', stdout);
474*49cdfc7eSAndroid Build Coastguard Worker 	}
475*49cdfc7eSAndroid Build Coastguard Worker }
476*49cdfc7eSAndroid Build Coastguard Worker 
castaway(char * dat)477*49cdfc7eSAndroid Build Coastguard Worker BADBOY castaway(char *dat)
478*49cdfc7eSAndroid Build Coastguard Worker {
479*49cdfc7eSAndroid Build Coastguard Worker 	return ((BADBOY) dat);
480*49cdfc7eSAndroid Build Coastguard Worker }
481*49cdfc7eSAndroid Build Coastguard Worker 
compute_badboy(void)482*49cdfc7eSAndroid Build Coastguard Worker void compute_badboy(void)
483*49cdfc7eSAndroid Build Coastguard Worker {
484*49cdfc7eSAndroid Build Coastguard Worker 	if (incptr == 0) {
485*49cdfc7eSAndroid Build Coastguard Worker 		compute_block_badboy(nbytes);
486*49cdfc7eSAndroid Build Coastguard Worker 		badboy = castaway(the_data);
487*49cdfc7eSAndroid Build Coastguard Worker 	}
488*49cdfc7eSAndroid Build Coastguard Worker 	/* trigger block generation at xx % of the current block */
489*49cdfc7eSAndroid Build Coastguard Worker 	else if ((next_offset == 0)
490*49cdfc7eSAndroid Build Coastguard Worker 		 || (next_offset > ((nbytes * BLOCK_TRIGGER) / 100))) {
491*49cdfc7eSAndroid Build Coastguard Worker 		compute_block_badboy(nbytes);
492*49cdfc7eSAndroid Build Coastguard Worker 		offset = 0;
493*49cdfc7eSAndroid Build Coastguard Worker 		next_offset = offset + incptr;
494*49cdfc7eSAndroid Build Coastguard Worker 		badboy = castaway(the_data);
495*49cdfc7eSAndroid Build Coastguard Worker 	} else {
496*49cdfc7eSAndroid Build Coastguard Worker 		offset = next_offset;
497*49cdfc7eSAndroid Build Coastguard Worker 		next_offset = offset + incptr;
498*49cdfc7eSAndroid Build Coastguard Worker 		badboy = castaway(&the_data[offset]);
499*49cdfc7eSAndroid Build Coastguard Worker 	}
500*49cdfc7eSAndroid Build Coastguard Worker }
501*49cdfc7eSAndroid Build Coastguard Worker 
try_one_crash(void)502*49cdfc7eSAndroid Build Coastguard Worker void try_one_crash(void)
503*49cdfc7eSAndroid Build Coastguard Worker {
504*49cdfc7eSAndroid Build Coastguard Worker 	/* was (nbytes < 0) */
505*49cdfc7eSAndroid Build Coastguard Worker 	if (!x_opt)
506*49cdfc7eSAndroid Build Coastguard Worker 		(*badboy) ();
507*49cdfc7eSAndroid Build Coastguard Worker 	else if (nbytes == 0)
508*49cdfc7eSAndroid Build Coastguard Worker 		while (1) ;
509*49cdfc7eSAndroid Build Coastguard Worker }
510