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