1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * crash02.c - Test OS robustness by executing syscalls with random args.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * Copyright (C) 2001 Stephane Fillod <f4cfe@free.fr>
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * This test program was inspired from crashme, by GEORGE J. CARRETT.
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or
9f08c3bdfSopenharmony_ci * modify it under the terms of the GNU General Public License
10f08c3bdfSopenharmony_ci * as published by the Free Software Foundation; either version 2
11f08c3bdfSopenharmony_ci * of the License, or (at your option) any later version.
12f08c3bdfSopenharmony_ci *
13f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful,
14f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
16f08c3bdfSopenharmony_ci * GNU General Public License for more details.
17f08c3bdfSopenharmony_ci *
18f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License
19f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software
20f08c3bdfSopenharmony_ci * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA	02111-1307, USA.
21f08c3bdfSopenharmony_ci */
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci/*
24f08c3bdfSopenharmony_ciA signal handler is set up so that in most cases the machine exception
25f08c3bdfSopenharmony_cigenerated by the illegal syscall, bad operands, etc in the procedure
26f08c3bdfSopenharmony_cimade up of random data are caught; and another round of randomness may
27f08c3bdfSopenharmony_cibe tried. Eventually a random syscall may corrupt the program or
28f08c3bdfSopenharmony_cithe machine state in such a way that the program must halt. This is
29f08c3bdfSopenharmony_cia test of the robustness of the hardware/software for instruction
30f08c3bdfSopenharmony_cifault handling.
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ciNote: Running this program just a few times, using total CPU time of
33f08c3bdfSopenharmony_ciless than a few seconds SHOULD NOT GIVE YOU ANY CONFIDENCE in system
34f08c3bdfSopenharmony_cirobustness. Having it run for hours, with tens of thousands of cases
35f08c3bdfSopenharmony_ciwould be a different thing. It would also make sense to run this
36f08c3bdfSopenharmony_cistress test at the same time you run other tests, like a multi-user
37f08c3bdfSopenharmony_cibenchmark.
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ciCAUTION: running this program may crash your system, your disk and all
40f08c3bdfSopenharmony_ci	your data along! DO NOT RUN IT ON PRODUCTION SYSTEMS!
41f08c3bdfSopenharmony_ci	CONSIDER YOUR DISK FRIED.
42f08c3bdfSopenharmony_ci	REMEMBER THE DISCLAIMER PART OF THE LICENSE.
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	Running as user nobody and with all your filesystems
45f08c3bdfSopenharmony_ci	remounted to readonly may be wise..
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_ciTODO:
48f08c3bdfSopenharmony_ci	* in rand_long(), stuff in some real pointers to random data
49f08c3bdfSopenharmony_ci	* Does a syscall is supposed to send SIGSEGV?
50f08c3bdfSopenharmony_ci*/
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci#define _GNU_SOURCE
53f08c3bdfSopenharmony_ci#include <sys/syscall.h>
54f08c3bdfSopenharmony_ci#include <stdio.h>
55f08c3bdfSopenharmony_ci#include <stdlib.h>
56f08c3bdfSopenharmony_ci#include <string.h>
57f08c3bdfSopenharmony_ci#include <signal.h>
58f08c3bdfSopenharmony_ci#include <setjmp.h>
59f08c3bdfSopenharmony_ci#include <time.h>
60f08c3bdfSopenharmony_ci#include <unistd.h>
61f08c3bdfSopenharmony_ci#include <errno.h>
62f08c3bdfSopenharmony_ci#include <sys/types.h>
63f08c3bdfSopenharmony_ci#include <sys/wait.h>
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci#include "test.h"
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_cichar *TCID = "crash02";
68f08c3bdfSopenharmony_ciint TST_TOTAL = 1;
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_cistatic int x_opt = 0;
71f08c3bdfSopenharmony_cistatic int v_opt = 0;
72f08c3bdfSopenharmony_cistatic char *v_copt;
73f08c3bdfSopenharmony_cistatic int s_opt = 0;
74f08c3bdfSopenharmony_cistatic char *s_copt;
75f08c3bdfSopenharmony_cistatic int l_opt = 0;
76f08c3bdfSopenharmony_cistatic char *l_copt;
77f08c3bdfSopenharmony_cistatic int n_opt = 0;
78f08c3bdfSopenharmony_cistatic char *n_copt;
79f08c3bdfSopenharmony_ci
80f08c3bdfSopenharmony_ciint verbose_level = 2;
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci/* depends on architecture.. */
83f08c3bdfSopenharmony_ciunsigned int sysno_max = 127;
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ciint nseed;
86f08c3bdfSopenharmony_ciint ntries = 100;
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ci/* max time allowed per try, in seconds */
89f08c3bdfSopenharmony_ci#define MAX_TRY_TIME 5
90f08c3bdfSopenharmony_ci
91f08c3bdfSopenharmony_civoid cleanup(void)
92f08c3bdfSopenharmony_ci{
93f08c3bdfSopenharmony_ci
94f08c3bdfSopenharmony_ci	tst_rmdir();
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_ci}
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_civoid setup(void)
99f08c3bdfSopenharmony_ci{
100f08c3bdfSopenharmony_ci	/*
101f08c3bdfSopenharmony_ci	 * setup a default signal hander and a
102f08c3bdfSopenharmony_ci	 * temporary working directory.
103f08c3bdfSopenharmony_ci	 */
104f08c3bdfSopenharmony_ci	tst_sig(FORK, DEF_HANDLER, cleanup);
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_ci	TEST_PAUSE;
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_ci	tst_tmpdir();
109f08c3bdfSopenharmony_ci}
110f08c3bdfSopenharmony_ci
111f08c3bdfSopenharmony_civoid help(void)
112f08c3bdfSopenharmony_ci{
113f08c3bdfSopenharmony_ci	printf
114f08c3bdfSopenharmony_ci	    ("	-x		dry run, hexdump random code instead\n");
115f08c3bdfSopenharmony_ci	printf("	-l x		max syscall no\n");
116f08c3bdfSopenharmony_ci	printf("	-v x		verbose level\n");
117f08c3bdfSopenharmony_ci	printf("	-s x		random seed\n");
118f08c3bdfSopenharmony_ci	printf("	-n x		ntries\n");
119f08c3bdfSopenharmony_ci}
120f08c3bdfSopenharmony_ci
121f08c3bdfSopenharmony_ci/*
122f08c3bdfSopenharmony_ci */
123f08c3bdfSopenharmony_cioption_t options[] = {
124f08c3bdfSopenharmony_ci	{"v:", &v_opt, &v_copt},
125f08c3bdfSopenharmony_ci	{"l:", &l_opt, &l_copt},
126f08c3bdfSopenharmony_ci	{"s:", &s_opt, &s_copt},
127f08c3bdfSopenharmony_ci	{"n:", &n_opt, &n_copt},
128f08c3bdfSopenharmony_ci	{"x", &x_opt, NULL},
129f08c3bdfSopenharmony_ci
130f08c3bdfSopenharmony_ci	{NULL, NULL, NULL}
131f08c3bdfSopenharmony_ci};
132f08c3bdfSopenharmony_ci
133f08c3bdfSopenharmony_civoid badboy_fork();
134f08c3bdfSopenharmony_civoid badboy_loop();
135f08c3bdfSopenharmony_ci
136f08c3bdfSopenharmony_civoid summarize_errno();
137f08c3bdfSopenharmony_civoid record_errno(unsigned int n);
138f08c3bdfSopenharmony_ci
139f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
140f08c3bdfSopenharmony_ci{
141f08c3bdfSopenharmony_ci	int lc;
142f08c3bdfSopenharmony_ci
143f08c3bdfSopenharmony_ci	tst_parse_opts(argc, argv, options, help);
144f08c3bdfSopenharmony_ci
145f08c3bdfSopenharmony_ci	if (v_opt)
146f08c3bdfSopenharmony_ci		verbose_level = atoi(v_copt);
147f08c3bdfSopenharmony_ci
148f08c3bdfSopenharmony_ci	if (n_opt)
149f08c3bdfSopenharmony_ci		ntries = atoi(n_copt);
150f08c3bdfSopenharmony_ci
151f08c3bdfSopenharmony_ci	if (l_opt)
152f08c3bdfSopenharmony_ci		sysno_max = atoi(l_copt);
153f08c3bdfSopenharmony_ci
154f08c3bdfSopenharmony_ci	if (s_opt)
155f08c3bdfSopenharmony_ci		nseed = atoi(s_copt);
156f08c3bdfSopenharmony_ci	else
157f08c3bdfSopenharmony_ci		nseed = time(NULL);
158f08c3bdfSopenharmony_ci
159f08c3bdfSopenharmony_ci	setup();
160f08c3bdfSopenharmony_ci
161f08c3bdfSopenharmony_ci	for (lc = 0; TEST_LOOPING(lc); lc++) {
162f08c3bdfSopenharmony_ci		tst_count = 0;
163f08c3bdfSopenharmony_ci
164f08c3bdfSopenharmony_ci		tst_resm(TINFO, "crashme02 %d %d %d", sysno_max, nseed, ntries);
165f08c3bdfSopenharmony_ci
166f08c3bdfSopenharmony_ci		srand(nseed);
167f08c3bdfSopenharmony_ci		badboy_fork();
168f08c3bdfSopenharmony_ci
169f08c3bdfSopenharmony_ci		/* still there? */
170f08c3bdfSopenharmony_ci		tst_resm(TPASS, "we're still here, OS seems to be robust");
171f08c3bdfSopenharmony_ci
172f08c3bdfSopenharmony_ci		nseed++;
173f08c3bdfSopenharmony_ci	}
174f08c3bdfSopenharmony_ci	cleanup();
175f08c3bdfSopenharmony_ci	tst_exit();
176f08c3bdfSopenharmony_ci}
177f08c3bdfSopenharmony_ci
178f08c3bdfSopenharmony_ci/* ************************* */
179f08c3bdfSopenharmony_ciint badboy_pid;
180f08c3bdfSopenharmony_ci
181f08c3bdfSopenharmony_civoid my_signal(int sig, void (*func) ());
182f08c3bdfSopenharmony_ci
183f08c3bdfSopenharmony_civoid monitor_fcn(int sig)
184f08c3bdfSopenharmony_ci{
185f08c3bdfSopenharmony_ci	int status;
186f08c3bdfSopenharmony_ci
187f08c3bdfSopenharmony_ci	if (verbose_level >= 3)
188f08c3bdfSopenharmony_ci		printf("time limit reached on pid. using kill.\n");
189f08c3bdfSopenharmony_ci
190f08c3bdfSopenharmony_ci	status = kill(badboy_pid, SIGKILL);
191f08c3bdfSopenharmony_ci	if (status < 0) {
192f08c3bdfSopenharmony_ci		if (verbose_level >= 3)
193f08c3bdfSopenharmony_ci			printf("failed to kill process\n");
194f08c3bdfSopenharmony_ci	}
195f08c3bdfSopenharmony_ci}
196f08c3bdfSopenharmony_ci
197f08c3bdfSopenharmony_civoid badboy_fork(void)
198f08c3bdfSopenharmony_ci{
199f08c3bdfSopenharmony_ci	int status, pid;
200f08c3bdfSopenharmony_ci	pid_t child = fork();
201f08c3bdfSopenharmony_ci
202f08c3bdfSopenharmony_ci	switch (child) {
203f08c3bdfSopenharmony_ci	case -1:
204f08c3bdfSopenharmony_ci		perror("fork");
205f08c3bdfSopenharmony_ci	case 0:
206f08c3bdfSopenharmony_ci#ifdef DEBUG_LATE_BADBOY
207f08c3bdfSopenharmony_ci		sleep(ntries * MAX_TRY_TIME + 10);
208f08c3bdfSopenharmony_ci#else
209f08c3bdfSopenharmony_ci		badboy_loop();
210f08c3bdfSopenharmony_ci#endif
211f08c3bdfSopenharmony_ci		exit(0);
212f08c3bdfSopenharmony_ci	default:
213f08c3bdfSopenharmony_ci		badboy_pid = child;
214f08c3bdfSopenharmony_ci		if (verbose_level > 3)
215f08c3bdfSopenharmony_ci			printf("badboy pid = %d\n", badboy_pid);
216f08c3bdfSopenharmony_ci
217f08c3bdfSopenharmony_ci		/* don't trust the child to return at night */
218f08c3bdfSopenharmony_ci		my_signal(SIGALRM, monitor_fcn);
219f08c3bdfSopenharmony_ci		alarm(ntries * MAX_TRY_TIME);
220f08c3bdfSopenharmony_ci
221f08c3bdfSopenharmony_ci		pid = waitpid(-1, &status, WUNTRACED);
222f08c3bdfSopenharmony_ci		if (pid <= 0)
223f08c3bdfSopenharmony_ci			perror("wait");
224f08c3bdfSopenharmony_ci		else {
225f08c3bdfSopenharmony_ci			if (verbose_level > 3)
226f08c3bdfSopenharmony_ci				printf("pid %d exited with status %d\n",
227f08c3bdfSopenharmony_ci				       pid, status);
228f08c3bdfSopenharmony_ci#if 0
229f08c3bdfSopenharmony_ci			record_status(status);
230f08c3bdfSopenharmony_ci#endif
231f08c3bdfSopenharmony_ci		}
232f08c3bdfSopenharmony_ci	}
233f08c3bdfSopenharmony_ci	alarm(0);
234f08c3bdfSopenharmony_ci}
235f08c3bdfSopenharmony_ci
236f08c3bdfSopenharmony_ci/* *************** status recording ************************* */
237f08c3bdfSopenharmony_ci
238f08c3bdfSopenharmony_ci/* errno status table (max is actually around 127) */
239f08c3bdfSopenharmony_ci#define STATUS_MAX 256
240f08c3bdfSopenharmony_cistatic int errno_table[STATUS_MAX];
241f08c3bdfSopenharmony_ci
242f08c3bdfSopenharmony_civoid record_errno(unsigned int n)
243f08c3bdfSopenharmony_ci{
244f08c3bdfSopenharmony_ci	if (n >= STATUS_MAX)
245f08c3bdfSopenharmony_ci		return;
246f08c3bdfSopenharmony_ci
247f08c3bdfSopenharmony_ci	errno_table[n]++;
248f08c3bdfSopenharmony_ci}
249f08c3bdfSopenharmony_ci
250f08c3bdfSopenharmony_ci/* may not work with -c option */
251f08c3bdfSopenharmony_civoid summarize_errno(void)
252f08c3bdfSopenharmony_ci{
253f08c3bdfSopenharmony_ci	int i;
254f08c3bdfSopenharmony_ci
255f08c3bdfSopenharmony_ci	if (x_opt || verbose_level < 2)
256f08c3bdfSopenharmony_ci		return;
257f08c3bdfSopenharmony_ci
258f08c3bdfSopenharmony_ci	printf("errno status ... number of cases\n");
259f08c3bdfSopenharmony_ci	for (i = 0; i < STATUS_MAX; i++) {
260f08c3bdfSopenharmony_ci		if (errno_table[i])
261f08c3bdfSopenharmony_ci			printf("%12d ... %5d\n", i, errno_table[i]);
262f08c3bdfSopenharmony_ci	}
263f08c3bdfSopenharmony_ci}
264f08c3bdfSopenharmony_ci
265f08c3bdfSopenharmony_ci/* ************* badboy ******************************************* */
266f08c3bdfSopenharmony_ci
267f08c3bdfSopenharmony_cijmp_buf again_buff;
268f08c3bdfSopenharmony_ci
269f08c3bdfSopenharmony_ciunsigned char *bad_malloc(int n);
270f08c3bdfSopenharmony_civoid my_signal(int sig, void (*func) ());
271f08c3bdfSopenharmony_civoid again_handler(int sig);
272f08c3bdfSopenharmony_civoid try_one_crash(int try_num);
273f08c3bdfSopenharmony_civoid set_up_signals();
274f08c3bdfSopenharmony_ciint in_blacklist(int sysno);
275f08c3bdfSopenharmony_ci
276f08c3bdfSopenharmony_ci/* badboy "entry" point */
277f08c3bdfSopenharmony_ci
278f08c3bdfSopenharmony_ci/*
279f08c3bdfSopenharmony_ci * Unlike crashme, faulty syscalls are not supposed to barf
280f08c3bdfSopenharmony_ci */
281f08c3bdfSopenharmony_civoid badboy_loop(void)
282f08c3bdfSopenharmony_ci{
283f08c3bdfSopenharmony_ci	int i;
284f08c3bdfSopenharmony_ci
285f08c3bdfSopenharmony_ci	for (i = 0; i < ntries; ++i) {
286f08c3bdfSopenharmony_ci		/* level 5 */
287f08c3bdfSopenharmony_ci
288f08c3bdfSopenharmony_ci		if (!x_opt && verbose_level >= 5) {
289f08c3bdfSopenharmony_ci			printf("try %d\n", i);
290f08c3bdfSopenharmony_ci		}
291f08c3bdfSopenharmony_ci
292f08c3bdfSopenharmony_ci		if (setjmp(again_buff) == 3) {
293f08c3bdfSopenharmony_ci			if (verbose_level >= 5)
294f08c3bdfSopenharmony_ci				printf("Barfed\n");
295f08c3bdfSopenharmony_ci		} else {
296f08c3bdfSopenharmony_ci			set_up_signals();
297f08c3bdfSopenharmony_ci			alarm(MAX_TRY_TIME);
298f08c3bdfSopenharmony_ci			try_one_crash(i);
299f08c3bdfSopenharmony_ci		}
300f08c3bdfSopenharmony_ci	}
301f08c3bdfSopenharmony_ci	summarize_errno();
302f08c3bdfSopenharmony_ci}
303f08c3bdfSopenharmony_ci
304f08c3bdfSopenharmony_civoid again_handler(int sig)
305f08c3bdfSopenharmony_ci{
306f08c3bdfSopenharmony_ci	char *ss;
307f08c3bdfSopenharmony_ci
308f08c3bdfSopenharmony_ci	switch (sig) {
309f08c3bdfSopenharmony_ci	case SIGILL:
310f08c3bdfSopenharmony_ci		ss = " illegal instruction";
311f08c3bdfSopenharmony_ci		break;
312f08c3bdfSopenharmony_ci#ifdef SIGTRAP
313f08c3bdfSopenharmony_ci	case SIGTRAP:
314f08c3bdfSopenharmony_ci		ss = " trace trap";
315f08c3bdfSopenharmony_ci		break;
316f08c3bdfSopenharmony_ci#endif
317f08c3bdfSopenharmony_ci	case SIGFPE:
318f08c3bdfSopenharmony_ci		ss = " arithmetic exception";
319f08c3bdfSopenharmony_ci		break;
320f08c3bdfSopenharmony_ci#ifdef SIGBUS
321f08c3bdfSopenharmony_ci	case SIGBUS:
322f08c3bdfSopenharmony_ci		ss = " bus error";
323f08c3bdfSopenharmony_ci		break;
324f08c3bdfSopenharmony_ci#endif
325f08c3bdfSopenharmony_ci	case SIGSEGV:
326f08c3bdfSopenharmony_ci		ss = " segmentation violation";
327f08c3bdfSopenharmony_ci		break;
328f08c3bdfSopenharmony_ci#ifdef SIGIOT
329f08c3bdfSopenharmony_ci	case SIGIOT:
330f08c3bdfSopenharmony_ci		ss = " IOT instruction";
331f08c3bdfSopenharmony_ci		break;
332f08c3bdfSopenharmony_ci#endif
333f08c3bdfSopenharmony_ci#ifdef SIGEMT
334f08c3bdfSopenharmony_ci	case SIGEMT:
335f08c3bdfSopenharmony_ci		ss = " EMT instruction";
336f08c3bdfSopenharmony_ci		break;
337f08c3bdfSopenharmony_ci#endif
338f08c3bdfSopenharmony_ci#ifdef SIGALRM
339f08c3bdfSopenharmony_ci	case SIGALRM:
340f08c3bdfSopenharmony_ci		ss = " alarm clock";
341f08c3bdfSopenharmony_ci		break;
342f08c3bdfSopenharmony_ci#endif
343f08c3bdfSopenharmony_ci	case SIGINT:
344f08c3bdfSopenharmony_ci		ss = " interrupt";
345f08c3bdfSopenharmony_ci		break;
346f08c3bdfSopenharmony_ci	default:
347f08c3bdfSopenharmony_ci		ss = "";
348f08c3bdfSopenharmony_ci	}
349f08c3bdfSopenharmony_ci	if (verbose_level >= 5)
350f08c3bdfSopenharmony_ci		printf("Got signal %d%s\n", sig, ss);
351f08c3bdfSopenharmony_ci
352f08c3bdfSopenharmony_ci	longjmp(again_buff, 3);
353f08c3bdfSopenharmony_ci}
354f08c3bdfSopenharmony_ci
355f08c3bdfSopenharmony_civoid my_signal(int sig, void (*func) ())
356f08c3bdfSopenharmony_ci{
357f08c3bdfSopenharmony_ci	struct sigaction act;
358f08c3bdfSopenharmony_ci
359f08c3bdfSopenharmony_ci	act.sa_handler = func;
360f08c3bdfSopenharmony_ci	memset(&act.sa_mask, 0x00, sizeof(sigset_t));
361f08c3bdfSopenharmony_ci	act.sa_flags = SA_NOMASK | SA_RESTART;
362f08c3bdfSopenharmony_ci	sigaction(sig, &act, 0);
363f08c3bdfSopenharmony_ci}
364f08c3bdfSopenharmony_ci
365f08c3bdfSopenharmony_civoid set_up_signals(void)
366f08c3bdfSopenharmony_ci{
367f08c3bdfSopenharmony_ci	my_signal(SIGILL, again_handler);
368f08c3bdfSopenharmony_ci#ifdef SIGTRAP
369f08c3bdfSopenharmony_ci	my_signal(SIGTRAP, again_handler);
370f08c3bdfSopenharmony_ci#endif
371f08c3bdfSopenharmony_ci	my_signal(SIGFPE, again_handler);
372f08c3bdfSopenharmony_ci#ifdef SIGBUS
373f08c3bdfSopenharmony_ci	my_signal(SIGBUS, again_handler);
374f08c3bdfSopenharmony_ci#endif
375f08c3bdfSopenharmony_ci	my_signal(SIGSEGV, again_handler);
376f08c3bdfSopenharmony_ci#ifdef SIGIOT
377f08c3bdfSopenharmony_ci	my_signal(SIGIOT, again_handler);
378f08c3bdfSopenharmony_ci#endif
379f08c3bdfSopenharmony_ci#ifdef SIGEMT
380f08c3bdfSopenharmony_ci	my_signal(SIGEMT, again_handler);
381f08c3bdfSopenharmony_ci#endif
382f08c3bdfSopenharmony_ci#ifdef SIGALRM
383f08c3bdfSopenharmony_ci	my_signal(SIGALRM, again_handler);
384f08c3bdfSopenharmony_ci#endif
385f08c3bdfSopenharmony_ci	my_signal(SIGINT, again_handler);
386f08c3bdfSopenharmony_ci}
387f08c3bdfSopenharmony_ci
388f08c3bdfSopenharmony_ci/*
389f08c3bdfSopenharmony_ci * NB: rand() (ie. RAND_MAX) might be on 31bits only!
390f08c3bdfSopenharmony_ci *
391f08c3bdfSopenharmony_ci * FIXME: 64-bit systems
392f08c3bdfSopenharmony_ci *
393f08c3bdfSopenharmony_ci * TODO: improve arg mixing (16bits and 8bits values, NULLs, etc.).
394f08c3bdfSopenharmony_ci *	big values as returned by rand() are no so interresting
395f08c3bdfSopenharmony_ci *	(except when used as pointers) because they may fall too
396f08c3bdfSopenharmony_ci *	quickly in the invalid parameter sieve. Smaller values,
397f08c3bdfSopenharmony_ci *	will be more insidious because they may refer to existing
398f08c3bdfSopenharmony_ci *	objects (pids, fd, etc.).
399f08c3bdfSopenharmony_ci */
400f08c3bdfSopenharmony_cilong int rand_long(void)
401f08c3bdfSopenharmony_ci{
402f08c3bdfSopenharmony_ci	int r1, r2;
403f08c3bdfSopenharmony_ci
404f08c3bdfSopenharmony_ci	r1 = rand();
405f08c3bdfSopenharmony_ci	r2 = rand();
406f08c3bdfSopenharmony_ci
407f08c3bdfSopenharmony_ci	if (r1 & 0x10000L)
408f08c3bdfSopenharmony_ci		r1 = 0;
409f08c3bdfSopenharmony_ci	if (!r1 && (r2 & 0x50000L))
410f08c3bdfSopenharmony_ci		r2 = 0;
411f08c3bdfSopenharmony_ci	else if (!r1 && (r2 & 0x20000L))
412f08c3bdfSopenharmony_ci		r2 &= 0x00ffL;
413f08c3bdfSopenharmony_ci
414f08c3bdfSopenharmony_ci	return (long int)((r1 & 0xffffL) << 16) | (r2 & 0xffffL);
415f08c3bdfSopenharmony_ci}
416f08c3bdfSopenharmony_ci
417f08c3bdfSopenharmony_civoid try_one_crash(int try_num)
418f08c3bdfSopenharmony_ci{
419f08c3bdfSopenharmony_ci	long int sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
420f08c3bdfSopenharmony_ci
421f08c3bdfSopenharmony_ci	do {
422f08c3bdfSopenharmony_ci		sysno = rand() % sysno_max;
423f08c3bdfSopenharmony_ci	} while (in_blacklist(sysno));
424f08c3bdfSopenharmony_ci
425f08c3bdfSopenharmony_ci	arg1 = rand_long();
426f08c3bdfSopenharmony_ci	arg2 = rand_long();
427f08c3bdfSopenharmony_ci	arg3 = rand_long();
428f08c3bdfSopenharmony_ci	arg4 = rand_long();
429f08c3bdfSopenharmony_ci	arg5 = rand_long();
430f08c3bdfSopenharmony_ci	arg6 = rand_long();
431f08c3bdfSopenharmony_ci	arg7 = rand_long();
432f08c3bdfSopenharmony_ci
433f08c3bdfSopenharmony_ci	if (x_opt || verbose_level >= 1)
434f08c3bdfSopenharmony_ci		printf("%04d: syscall(%ld, %#lx, %#lx, %#lx, %#lx, %#lx, "
435f08c3bdfSopenharmony_ci		       "%#lx, %#lx)\n", try_num, sysno, arg1, arg2, arg3,
436f08c3bdfSopenharmony_ci		       arg4, arg5, arg6, arg7);
437f08c3bdfSopenharmony_ci
438f08c3bdfSopenharmony_ci	if (!x_opt) {
439f08c3bdfSopenharmony_ci		syscall(sysno, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
440f08c3bdfSopenharmony_ci		record_errno(errno);
441f08c3bdfSopenharmony_ci	}
442f08c3bdfSopenharmony_ci}
443f08c3bdfSopenharmony_ci
444f08c3bdfSopenharmony_ci/* The following syscalls create new processes which may cause the test
445f08c3bdfSopenharmony_ci	 unable to finish. */
446f08c3bdfSopenharmony_ciint in_blacklist(int sysno)
447f08c3bdfSopenharmony_ci{
448f08c3bdfSopenharmony_ci	int i;
449f08c3bdfSopenharmony_ci	const int list[] = {
450f08c3bdfSopenharmony_ci#if defined(__ia64__)
451f08c3bdfSopenharmony_ci		SYS_clone2,
452f08c3bdfSopenharmony_ci#else
453f08c3bdfSopenharmony_ci		/*
454f08c3bdfSopenharmony_ci		 * No SYS_fork(vfork) on IA-64. Instead, it uses,
455f08c3bdfSopenharmony_ci		 * clone(child_stack=0, flags=CLONE_VM|CLONE_VFORK|SIGCHLD)
456f08c3bdfSopenharmony_ci		 * clone2()
457f08c3bdfSopenharmony_ci		 */
458f08c3bdfSopenharmony_ci
459f08c3bdfSopenharmony_ci		/*
460f08c3bdfSopenharmony_ci		 * NOTE (garrcoop):
461f08c3bdfSopenharmony_ci		 * Could not find reference to SYS_fork(vfork) on mips32
462f08c3bdfSopenharmony_ci		 * with the Montavista / Octeon toolchain. Need to develop an
463f08c3bdfSopenharmony_ci		 * autoconf check for this item.
464f08c3bdfSopenharmony_ci		 */
465f08c3bdfSopenharmony_ci#if defined(__NR_vfork) && __NR_vfork
466f08c3bdfSopenharmony_ci		SYS_vfork,
467f08c3bdfSopenharmony_ci#endif
468f08c3bdfSopenharmony_ci#if defined(__NR_fork) && __NR_fork
469f08c3bdfSopenharmony_ci		SYS_fork,
470f08c3bdfSopenharmony_ci#endif
471f08c3bdfSopenharmony_ci#endif /* __ia64__ */
472f08c3bdfSopenharmony_ci#if defined(__NR_clone) && __NR_clone
473f08c3bdfSopenharmony_ci		SYS_clone,
474f08c3bdfSopenharmony_ci#endif
475f08c3bdfSopenharmony_ci#if defined(__NR_vhangup) && __NR_vhangup
476f08c3bdfSopenharmony_ci		__NR_vhangup,	/* int vhangup(void); - terminal logout */
477f08c3bdfSopenharmony_ci#endif
478f08c3bdfSopenharmony_ci#if defined(__NR_pause) && __NR_pause
479f08c3bdfSopenharmony_ci		__NR_pause,	/* int pause(void); - sleep indefinitely */
480f08c3bdfSopenharmony_ci#endif
481f08c3bdfSopenharmony_ci#if defined(__NR_read) && __NR_read
482f08c3bdfSopenharmony_ci		/*
483f08c3bdfSopenharmony_ci		 * ssize_t read(int fd, void *buf, size_t count); - will sleep
484f08c3bdfSopenharmony_ci		 * indefinitely if the first argument is 0
485f08c3bdfSopenharmony_ci		 */
486f08c3bdfSopenharmony_ci		__NR_read,
487f08c3bdfSopenharmony_ci#endif
488f08c3bdfSopenharmony_ci		-1
489f08c3bdfSopenharmony_ci	};
490f08c3bdfSopenharmony_ci
491f08c3bdfSopenharmony_ci	for (i = 0; list[i] != -1; i++) {
492f08c3bdfSopenharmony_ci		if (sysno == list[i])
493f08c3bdfSopenharmony_ci			return 1;
494f08c3bdfSopenharmony_ci	}
495f08c3bdfSopenharmony_ci
496f08c3bdfSopenharmony_ci	return 0;
497f08c3bdfSopenharmony_ci}
498