This source file includes following definitions.
- one_in_chance
- mess_with_tm
- trap_signal_handler
- seg_signal_handler
- sigfuz_test
- signal_fuzzer
- show_help
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include <stdio.h>
33 #include <limits.h>
34 #include <sys/wait.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <ucontext.h>
40 #include <sys/mman.h>
41 #include <pthread.h>
42 #include "utils.h"
43
44
45 #define COUNT_MAX 4000
46 #define THREADS 16
47
48
49 #define ARG_MESS_WITH_TM_AT 0x1
50 #define ARG_MESS_WITH_TM_BEFORE 0x2
51 #define ARG_MESS_WITH_MSR_AT 0x4
52 #define ARG_FOREVER 0x10
53 #define ARG_COMPLETE (ARG_MESS_WITH_TM_AT | \
54 ARG_MESS_WITH_TM_BEFORE | \
55 ARG_MESS_WITH_MSR_AT)
56
57 static int args;
58 static int nthread = THREADS;
59 static int count_max = COUNT_MAX;
60
61
62 static ucontext_t *tmp_uc;
63
64
65 static int one_in_chance(int x)
66 {
67 return rand() % x == 0;
68 }
69
70
71 static void mess_with_tm(void)
72 {
73
74 if (one_in_chance(3)) {
75 asm ("tbegin. ;"
76 "beq 8 ;");
77
78
79 if (one_in_chance(2))
80 asm("tsuspend. ;");
81 }
82
83
84 if (one_in_chance(20))
85 asm("tend. ;");
86 }
87
88
89 static void trap_signal_handler(int signo, siginfo_t *si, void *uc)
90 {
91 ucontext_t *ucp = uc;
92
93 ucp->uc_link = tmp_uc;
94
95
96
97
98
99
100
101 if (one_in_chance(3)) {
102 memset(ucp->uc_link, rand(), sizeof(ucontext_t));
103 } else if (one_in_chance(2)) {
104 memcpy(ucp->uc_link, uc, sizeof(ucontext_t));
105 } else if (one_in_chance(2)) {
106 if (tmp_uc) {
107 free(tmp_uc);
108 tmp_uc = NULL;
109 }
110 tmp_uc = malloc(sizeof(ucontext_t));
111 ucp->uc_link = tmp_uc;
112
113 madvise(ucp->uc_link, sizeof(ucontext_t), MADV_DONTNEED);
114 }
115
116 if (args & ARG_MESS_WITH_MSR_AT) {
117
118 if (one_in_chance(4)) {
119 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |= MSR_TS_S;
120 } else {
121 if (one_in_chance(2)) {
122 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |=
123 MSR_TS_T;
124 } else if (one_in_chance(2)) {
125 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |=
126 MSR_TS_T | MSR_TS_S;
127 }
128 }
129
130
131 if (one_in_chance(2)) {
132 ucp->uc_mcontext.gp_regs[PT_MSR] |= MSR_TS_S;
133 } else if (one_in_chance(2)) {
134 if (one_in_chance(2))
135 ucp->uc_mcontext.gp_regs[PT_MSR] |=
136 MSR_TS_T;
137 else if (one_in_chance(2))
138 ucp->uc_mcontext.gp_regs[PT_MSR] |=
139 MSR_TS_T | MSR_TS_S;
140 }
141 }
142
143 if (one_in_chance(20)) {
144
145 if (one_in_chance(5))
146 mess_with_tm();
147
148
149 return;
150 }
151
152 if (one_in_chance(10))
153 ucp->uc_mcontext.gp_regs[PT_MSR] = random();
154 if (one_in_chance(10))
155 ucp->uc_mcontext.gp_regs[PT_NIP] = random();
156 if (one_in_chance(10))
157 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] = random();
158 if (one_in_chance(10))
159 ucp->uc_link->uc_mcontext.gp_regs[PT_NIP] = random();
160
161 ucp->uc_mcontext.gp_regs[PT_TRAP] = random();
162 ucp->uc_mcontext.gp_regs[PT_DSISR] = random();
163 ucp->uc_mcontext.gp_regs[PT_DAR] = random();
164 ucp->uc_mcontext.gp_regs[PT_ORIG_R3] = random();
165 ucp->uc_mcontext.gp_regs[PT_XER] = random();
166 ucp->uc_mcontext.gp_regs[PT_RESULT] = random();
167 ucp->uc_mcontext.gp_regs[PT_SOFTE] = random();
168 ucp->uc_mcontext.gp_regs[PT_DSCR] = random();
169 ucp->uc_mcontext.gp_regs[PT_CTR] = random();
170 ucp->uc_mcontext.gp_regs[PT_LNK] = random();
171 ucp->uc_mcontext.gp_regs[PT_CCR] = random();
172 ucp->uc_mcontext.gp_regs[PT_REGS_COUNT] = random();
173
174 ucp->uc_link->uc_mcontext.gp_regs[PT_TRAP] = random();
175 ucp->uc_link->uc_mcontext.gp_regs[PT_DSISR] = random();
176 ucp->uc_link->uc_mcontext.gp_regs[PT_DAR] = random();
177 ucp->uc_link->uc_mcontext.gp_regs[PT_ORIG_R3] = random();
178 ucp->uc_link->uc_mcontext.gp_regs[PT_XER] = random();
179 ucp->uc_link->uc_mcontext.gp_regs[PT_RESULT] = random();
180 ucp->uc_link->uc_mcontext.gp_regs[PT_SOFTE] = random();
181 ucp->uc_link->uc_mcontext.gp_regs[PT_DSCR] = random();
182 ucp->uc_link->uc_mcontext.gp_regs[PT_CTR] = random();
183 ucp->uc_link->uc_mcontext.gp_regs[PT_LNK] = random();
184 ucp->uc_link->uc_mcontext.gp_regs[PT_CCR] = random();
185 ucp->uc_link->uc_mcontext.gp_regs[PT_REGS_COUNT] = random();
186
187 if (args & ARG_MESS_WITH_TM_BEFORE) {
188 if (one_in_chance(2))
189 mess_with_tm();
190 }
191 }
192
193 static void seg_signal_handler(int signo, siginfo_t *si, void *uc)
194 {
195
196 exit(0);
197 }
198
199 static void *sigfuz_test(void *thrid)
200 {
201 struct sigaction trap_sa, seg_sa;
202 int ret, i = 0;
203 pid_t t;
204
205 tmp_uc = malloc(sizeof(ucontext_t));
206
207
208 trap_sa.sa_flags = SA_SIGINFO;
209 trap_sa.sa_sigaction = trap_signal_handler;
210
211
212 seg_sa.sa_flags = SA_SIGINFO;
213 seg_sa.sa_sigaction = seg_signal_handler;
214
215
216 sigaction(SIGUSR1, &trap_sa, NULL);
217
218
219 sigaction(SIGSEGV, &seg_sa, NULL);
220
221 while (i < count_max) {
222 t = fork();
223
224 if (t == 0) {
225
226 srand(time(NULL) + getpid());
227 if (args & ARG_MESS_WITH_TM_AT) {
228 if (one_in_chance(2))
229 mess_with_tm();
230 }
231 raise(SIGUSR1);
232 exit(0);
233 } else {
234 waitpid(t, &ret, 0);
235 }
236 if (!(args & ARG_FOREVER))
237 i++;
238 }
239
240
241 if (tmp_uc) {
242 free(tmp_uc);
243 tmp_uc = NULL;
244 }
245
246 return NULL;
247 }
248
249 static int signal_fuzzer(void)
250 {
251 int t, rc;
252 pthread_t *threads;
253
254 threads = malloc(nthread * sizeof(pthread_t));
255
256 for (t = 0; t < nthread; t++) {
257 rc = pthread_create(&threads[t], NULL, sigfuz_test,
258 (void *)&t);
259 if (rc)
260 perror("Thread creation error\n");
261 }
262
263 for (t = 0; t < nthread; t++) {
264 rc = pthread_join(threads[t], NULL);
265 if (rc)
266 perror("Thread join error\n");
267 }
268
269 free(threads);
270
271 return EXIT_SUCCESS;
272 }
273
274 static void show_help(char *name)
275 {
276 printf("%s: Sigfuzzer for powerpc\n", name);
277 printf("Usage:\n");
278 printf("\t-b\t Mess with TM before raising a SIGUSR1 signal\n");
279 printf("\t-a\t Mess with TM after raising a SIGUSR1 signal\n");
280 printf("\t-m\t Mess with MSR[TS] bits at mcontext\n");
281 printf("\t-x\t Mess with everything above\n");
282 printf("\t-f\t Run forever (Press ^C to Quit)\n");
283 printf("\t-i\t Amount of interactions. (Default = %d)\n", COUNT_MAX);
284 printf("\t-t\t Amount of threads. (Default = %d)\n", THREADS);
285 exit(-1);
286 }
287
288 int main(int argc, char **argv)
289 {
290 int opt;
291
292 while ((opt = getopt(argc, argv, "bamxt:fi:h")) != -1) {
293 if (opt == 'b') {
294 printf("Mess with TM before signal\n");
295 args |= ARG_MESS_WITH_TM_BEFORE;
296 } else if (opt == 'a') {
297 printf("Mess with TM at signal handler\n");
298 args |= ARG_MESS_WITH_TM_AT;
299 } else if (opt == 'm') {
300 printf("Mess with MSR[TS] bits in mcontext\n");
301 args |= ARG_MESS_WITH_MSR_AT;
302 } else if (opt == 'x') {
303 printf("Running with all options enabled\n");
304 args |= ARG_COMPLETE;
305 } else if (opt == 't') {
306 nthread = atoi(optarg);
307 printf("Threads = %d\n", nthread);
308 } else if (opt == 'f') {
309 args |= ARG_FOREVER;
310 printf("Press ^C to stop\n");
311 test_harness_set_timeout(-1);
312 } else if (opt == 'i') {
313 count_max = atoi(optarg);
314 printf("Running for %d interactions\n", count_max);
315 } else if (opt == 'h') {
316 show_help(argv[0]);
317 }
318 }
319
320
321 if (!args)
322 args = ARG_COMPLETE;
323
324 test_harness(signal_fuzzer, "signal_fuzzer");
325 }