Home | History | Annotate | Download | only in randasyscall
      1 /*
      2  * Program that makes random system calls with random arguments.
      3  */
      4 
      5 /*
      6  * Copyright (C) 2003-2006 IBM
      7  *
      8  * This program is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU General Public License as
     10  * published by the Free Software Foundation; either version 2 of the
     11  * License, or (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful, but
     14  * WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
     21  * 02111-1307, USA.
     22  */
     23 
     24 #include <signal.h>
     25 #include <limits.h>
     26 #include <strings.h>
     27 #include <unistd.h>
     28 #include <fcntl.h>
     29 #include <errno.h>
     30 #include <string.h>
     31 #include <stdio.h>
     32 #include <sys/syscall.h>
     33 #include <stdint.h>
     34 #include <stdlib.h>
     35 
     36 unsigned long callnum, args[6];
     37 
     38 int seed_random(void)
     39 {
     40 	int fp;
     41 	long seed;
     42 
     43 	fp = open("/dev/urandom", O_RDONLY);
     44 	if (fp < 0) {
     45 		perror("/dev/urandom");
     46 		return 0;
     47 	}
     48 
     49 	if (read(fp, &seed, sizeof(seed)) != sizeof(seed)) {
     50 		perror("read random seed");
     51 		return 0;
     52 	}
     53 
     54 	close(fp);
     55 	srand(seed);
     56 
     57 	return 1;
     58 }
     59 
     60 void get_big_randnum(void *buf, unsigned int size)
     61 {
     62 	uint32_t *x = buf;
     63 	int i;
     64 
     65 	for (i = 0; i < size; i += 4, x++) {
     66 		*x = (unsigned long)((float)UINT_MAX *
     67 				     (rand() / (RAND_MAX + 1.0)));
     68 	}
     69 }
     70 
     71 unsigned long get_randnum(unsigned long min, unsigned long max)
     72 {
     73 	return min + (unsigned long)((float)max * (rand() / (RAND_MAX + 1.0)));
     74 }
     75 
     76 int find_syscall(void)
     77 {
     78 	int x;
     79 
     80 badcall:
     81 	x = get_randnum(0, 384);
     82 
     83 	/* poorly implemented blacklist */
     84 	switch (x) {
     85 		/* don't screw with signal handling */
     86 #ifdef SYS_signal
     87 	case SYS_signal:
     88 #endif
     89 #ifdef SYS_sigaction
     90 	case SYS_sigaction:
     91 #endif
     92 #ifdef SYS_sigsuspend
     93 	case SYS_sigsuspend:
     94 #endif
     95 #ifdef SYS_sigpending
     96 	case SYS_sigpending:
     97 #endif
     98 #ifdef SYS_sigreturn
     99 	case SYS_sigreturn:
    100 #endif
    101 #ifdef SYS_sigprocmask
    102 	case SYS_sigprocmask:
    103 #endif
    104 #ifdef SYS_rt_sigreturn
    105 	case SYS_rt_sigreturn:
    106 #endif
    107 #ifdef SYS_rt_sigaction
    108 	case SYS_rt_sigaction:
    109 #endif
    110 #ifdef SYS_rt_sigprocmask
    111 	case SYS_rt_sigprocmask:
    112 #endif
    113 #ifdef SYS_rt_sigpending
    114 	case SYS_rt_sigpending:
    115 #endif
    116 #ifdef SYS_rt_sigtimedwait
    117 	case SYS_rt_sigtimedwait:
    118 #endif
    119 #ifdef SYS_rt_sigqueueinfo
    120 	case SYS_rt_sigqueueinfo:
    121 #endif
    122 #ifdef SYS_rt_sigsuspend
    123 	case SYS_rt_sigsuspend:
    124 #endif
    125 #ifdef SYS_sigaltstack
    126 	case SYS_sigaltstack:
    127 #endif
    128 #ifdef SYS_settimeofday
    129 	case SYS_settimeofday:
    130 #endif
    131 
    132 		/* don't exit the program :P */
    133 #ifdef SYS_exit
    134 	case SYS_exit:
    135 #endif
    136 #ifdef SYS_exit_group
    137 	case SYS_exit_group:
    138 #endif
    139 
    140 		/* don't put it to sleep either */
    141 #ifdef SYS_pause
    142 	case SYS_pause:
    143 #endif
    144 #ifdef SYS_select
    145 	case SYS_select:
    146 #endif
    147 #ifdef SYS_read
    148 	case SYS_read:
    149 #endif
    150 #ifdef SYS_write
    151 	case SYS_write:
    152 #endif
    153 
    154 		/* these can fill the process table */
    155 #ifdef SYS_fork
    156 	case SYS_fork:
    157 #endif
    158 #ifdef SYS_vfork
    159 	case SYS_vfork:
    160 #endif
    161 #ifdef SYS_clone
    162 	case SYS_clone:
    163 #endif
    164 
    165 		/* This causes OOM conditions */
    166 #if 1
    167 #ifdef SYS_brk
    168 	case SYS_brk:
    169 #endif
    170 #endif
    171 
    172 		/* these get our program killed */
    173 #ifdef SYS_vm86
    174 	case SYS_vm86:
    175 #endif
    176 #ifdef SYS_vm86old
    177 	case SYS_vm86old:
    178 #endif
    179 		goto badcall;
    180 	}
    181 
    182 	return x;
    183 }
    184 
    185 void bogus_signal_handler(int signum)
    186 {
    187 	fprintf(stderr,
    188 		"                                    Signal %d on syscall(%lu, 0x%lX, 0x%lX, 0x%lX, 0x%lX, 0x%lX, 0x%lX).\n",
    189 		signum, callnum, args[0], args[1], args[2], args[3], args[4],
    190 		args[5]);
    191 }
    192 
    193 void real_signal_handler(int signum)
    194 {
    195 	exit(0);
    196 }
    197 
    198 void install_signal_handlers(void)
    199 {
    200 	int x;
    201 	struct sigaction zig;
    202 
    203 	memset(&zig, 0x00, sizeof(zig));
    204 	zig.sa_handler = bogus_signal_handler;
    205 	for (x = 0; x < 64; x++) {
    206 		sigaction(x, &zig, NULL);
    207 	}
    208 
    209 	zig.sa_handler = real_signal_handler;
    210 	sigaction(SIGINT, &zig, NULL);
    211 	sigaction(SIGTERM, &zig, NULL);
    212 }
    213 
    214 int main(int argc, char *argv[])
    215 {
    216 	int i;
    217 	int debug = 0, zero_mode = 0;
    218 
    219 	if (!seed_random()) {
    220 		return 1;
    221 	}
    222 
    223 	for (i = 1; i < argc; i++) {
    224 		if (!strcmp(argv[i], "-d"))
    225 			debug = 1;
    226 		else if (!strcmp(argv[i], "-z"))
    227 			zero_mode = 1;
    228 	}
    229 
    230 	memset(args, 0, sizeof(unsigned long) * 6);
    231 
    232 	install_signal_handlers();
    233 
    234 	while (1) {
    235 		callnum = find_syscall();
    236 		if (!zero_mode)
    237 			get_big_randnum(&args[0], sizeof(unsigned long) * 6);
    238 
    239 		if (debug) {
    240 			printf("syscall(%lu, 0x%lX, 0x%lX, 0x%lX, 0x%lX, "
    241 			       "0x%lX, 0x%lX);       \n",
    242 			       callnum, args[0], args[1], args[2], args[3],
    243 			       args[4], args[5]);
    244 			fflush(stdout);
    245 		}
    246 
    247 		syscall(callnum, args[0], args[1], args[2],
    248 			args[3], args[4], args[5]);
    249 	}
    250 
    251 	return 0;
    252 }
    253