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