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
seed_random(void)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
get_big_randnum(void * buf,unsigned int size)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
get_randnum(unsigned long min,unsigned long max)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
find_syscall(void)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
bogus_signal_handler(int signum)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
real_signal_handler(int signum)193 void real_signal_handler(int signum)
194 {
195 exit(0);
196 }
197
install_signal_handlers(void)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
main(int argc,char * argv[])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