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