• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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