0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <stdio.h>
0033 #include <limits.h>
0034 #include <sys/wait.h>
0035 #include <unistd.h>
0036 #include <stdlib.h>
0037 #include <signal.h>
0038 #include <string.h>
0039 #include <ucontext.h>
0040 #include <sys/mman.h>
0041 #include <pthread.h>
0042 #include "utils.h"
0043
0044
0045 #define COUNT_MAX 600
0046 #define THREADS 16
0047
0048
0049 #define ARG_MESS_WITH_TM_AT 0x1
0050 #define ARG_MESS_WITH_TM_BEFORE 0x2
0051 #define ARG_MESS_WITH_MSR_AT 0x4
0052 #define ARG_FOREVER 0x10
0053 #define ARG_COMPLETE (ARG_MESS_WITH_TM_AT | \
0054 ARG_MESS_WITH_TM_BEFORE | \
0055 ARG_MESS_WITH_MSR_AT)
0056
0057 static int args;
0058 static int nthread = THREADS;
0059 static int count_max = COUNT_MAX;
0060
0061
0062 static ucontext_t *tmp_uc;
0063
0064
0065 static int one_in_chance(int x)
0066 {
0067 return rand() % x == 0;
0068 }
0069
0070
0071 static void mess_with_tm(void)
0072 {
0073
0074 if (one_in_chance(3)) {
0075 asm ("tbegin. ;"
0076 "beq 8 ;");
0077
0078
0079 if (one_in_chance(2))
0080 asm("tsuspend. ;");
0081 }
0082
0083
0084 if (one_in_chance(20))
0085 asm("tend. ;");
0086 }
0087
0088
0089 static void trap_signal_handler(int signo, siginfo_t *si, void *uc)
0090 {
0091 ucontext_t *ucp = uc;
0092
0093 ucp->uc_link = tmp_uc;
0094
0095
0096
0097
0098
0099
0100
0101 if (one_in_chance(3)) {
0102 memset(ucp->uc_link, rand(), sizeof(ucontext_t));
0103 } else if (one_in_chance(2)) {
0104 memcpy(ucp->uc_link, uc, sizeof(ucontext_t));
0105 } else if (one_in_chance(2)) {
0106 if (tmp_uc) {
0107 free(tmp_uc);
0108 tmp_uc = NULL;
0109 }
0110 tmp_uc = malloc(sizeof(ucontext_t));
0111 ucp->uc_link = tmp_uc;
0112
0113 madvise(ucp->uc_link, sizeof(ucontext_t), MADV_DONTNEED);
0114 }
0115
0116 if (args & ARG_MESS_WITH_MSR_AT) {
0117
0118 if (one_in_chance(4)) {
0119 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |= MSR_TS_S;
0120 } else {
0121 if (one_in_chance(2)) {
0122 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |=
0123 MSR_TS_T;
0124 } else if (one_in_chance(2)) {
0125 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |=
0126 MSR_TS_T | MSR_TS_S;
0127 }
0128 }
0129
0130
0131 if (one_in_chance(2)) {
0132 ucp->uc_mcontext.gp_regs[PT_MSR] |= MSR_TS_S;
0133 } else if (one_in_chance(2)) {
0134 if (one_in_chance(2))
0135 ucp->uc_mcontext.gp_regs[PT_MSR] |=
0136 MSR_TS_T;
0137 else if (one_in_chance(2))
0138 ucp->uc_mcontext.gp_regs[PT_MSR] |=
0139 MSR_TS_T | MSR_TS_S;
0140 }
0141 }
0142
0143 if (one_in_chance(20)) {
0144
0145 if (one_in_chance(5))
0146 mess_with_tm();
0147
0148
0149 return;
0150 }
0151
0152 if (one_in_chance(10))
0153 ucp->uc_mcontext.gp_regs[PT_MSR] = random();
0154 if (one_in_chance(10))
0155 ucp->uc_mcontext.gp_regs[PT_NIP] = random();
0156 if (one_in_chance(10))
0157 ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] = random();
0158 if (one_in_chance(10))
0159 ucp->uc_link->uc_mcontext.gp_regs[PT_NIP] = random();
0160
0161 ucp->uc_mcontext.gp_regs[PT_TRAP] = random();
0162 ucp->uc_mcontext.gp_regs[PT_DSISR] = random();
0163 ucp->uc_mcontext.gp_regs[PT_DAR] = random();
0164 ucp->uc_mcontext.gp_regs[PT_ORIG_R3] = random();
0165 ucp->uc_mcontext.gp_regs[PT_XER] = random();
0166 ucp->uc_mcontext.gp_regs[PT_RESULT] = random();
0167 ucp->uc_mcontext.gp_regs[PT_SOFTE] = random();
0168 ucp->uc_mcontext.gp_regs[PT_DSCR] = random();
0169 ucp->uc_mcontext.gp_regs[PT_CTR] = random();
0170 ucp->uc_mcontext.gp_regs[PT_LNK] = random();
0171 ucp->uc_mcontext.gp_regs[PT_CCR] = random();
0172 ucp->uc_mcontext.gp_regs[PT_REGS_COUNT] = random();
0173
0174 ucp->uc_link->uc_mcontext.gp_regs[PT_TRAP] = random();
0175 ucp->uc_link->uc_mcontext.gp_regs[PT_DSISR] = random();
0176 ucp->uc_link->uc_mcontext.gp_regs[PT_DAR] = random();
0177 ucp->uc_link->uc_mcontext.gp_regs[PT_ORIG_R3] = random();
0178 ucp->uc_link->uc_mcontext.gp_regs[PT_XER] = random();
0179 ucp->uc_link->uc_mcontext.gp_regs[PT_RESULT] = random();
0180 ucp->uc_link->uc_mcontext.gp_regs[PT_SOFTE] = random();
0181 ucp->uc_link->uc_mcontext.gp_regs[PT_DSCR] = random();
0182 ucp->uc_link->uc_mcontext.gp_regs[PT_CTR] = random();
0183 ucp->uc_link->uc_mcontext.gp_regs[PT_LNK] = random();
0184 ucp->uc_link->uc_mcontext.gp_regs[PT_CCR] = random();
0185 ucp->uc_link->uc_mcontext.gp_regs[PT_REGS_COUNT] = random();
0186
0187 if (args & ARG_MESS_WITH_TM_BEFORE) {
0188 if (one_in_chance(2))
0189 mess_with_tm();
0190 }
0191 }
0192
0193 static void seg_signal_handler(int signo, siginfo_t *si, void *uc)
0194 {
0195
0196 exit(0);
0197 }
0198
0199 static void *sigfuz_test(void *thrid)
0200 {
0201 struct sigaction trap_sa, seg_sa;
0202 int ret, i = 0;
0203 pid_t t;
0204
0205 tmp_uc = malloc(sizeof(ucontext_t));
0206
0207
0208 trap_sa.sa_flags = SA_SIGINFO;
0209 trap_sa.sa_sigaction = trap_signal_handler;
0210
0211
0212 seg_sa.sa_flags = SA_SIGINFO;
0213 seg_sa.sa_sigaction = seg_signal_handler;
0214
0215
0216 sigaction(SIGUSR1, &trap_sa, NULL);
0217
0218
0219 sigaction(SIGSEGV, &seg_sa, NULL);
0220
0221 while (i < count_max) {
0222 t = fork();
0223
0224 if (t == 0) {
0225
0226 srand(time(NULL) + getpid());
0227 if (args & ARG_MESS_WITH_TM_AT) {
0228 if (one_in_chance(2))
0229 mess_with_tm();
0230 }
0231 raise(SIGUSR1);
0232 exit(0);
0233 } else {
0234 waitpid(t, &ret, 0);
0235 }
0236 if (!(args & ARG_FOREVER))
0237 i++;
0238 }
0239
0240
0241 if (tmp_uc) {
0242 free(tmp_uc);
0243 tmp_uc = NULL;
0244 }
0245
0246 return NULL;
0247 }
0248
0249 static int signal_fuzzer(void)
0250 {
0251 int t, rc;
0252 pthread_t *threads;
0253
0254 threads = malloc(nthread * sizeof(pthread_t));
0255
0256 for (t = 0; t < nthread; t++) {
0257 rc = pthread_create(&threads[t], NULL, sigfuz_test,
0258 (void *)&t);
0259 if (rc)
0260 perror("Thread creation error\n");
0261 }
0262
0263 for (t = 0; t < nthread; t++) {
0264 rc = pthread_join(threads[t], NULL);
0265 if (rc)
0266 perror("Thread join error\n");
0267 }
0268
0269 free(threads);
0270
0271 return EXIT_SUCCESS;
0272 }
0273
0274 static void show_help(char *name)
0275 {
0276 printf("%s: Sigfuzzer for powerpc\n", name);
0277 printf("Usage:\n");
0278 printf("\t-b\t Mess with TM before raising a SIGUSR1 signal\n");
0279 printf("\t-a\t Mess with TM after raising a SIGUSR1 signal\n");
0280 printf("\t-m\t Mess with MSR[TS] bits at mcontext\n");
0281 printf("\t-x\t Mess with everything above\n");
0282 printf("\t-f\t Run forever (Press ^C to Quit)\n");
0283 printf("\t-i\t Amount of interactions. (Default = %d)\n", COUNT_MAX);
0284 printf("\t-t\t Amount of threads. (Default = %d)\n", THREADS);
0285 exit(-1);
0286 }
0287
0288 int main(int argc, char **argv)
0289 {
0290 int opt;
0291
0292 while ((opt = getopt(argc, argv, "bamxt:fi:h")) != -1) {
0293 if (opt == 'b') {
0294 printf("Mess with TM before signal\n");
0295 args |= ARG_MESS_WITH_TM_BEFORE;
0296 } else if (opt == 'a') {
0297 printf("Mess with TM at signal handler\n");
0298 args |= ARG_MESS_WITH_TM_AT;
0299 } else if (opt == 'm') {
0300 printf("Mess with MSR[TS] bits in mcontext\n");
0301 args |= ARG_MESS_WITH_MSR_AT;
0302 } else if (opt == 'x') {
0303 printf("Running with all options enabled\n");
0304 args |= ARG_COMPLETE;
0305 } else if (opt == 't') {
0306 nthread = atoi(optarg);
0307 printf("Threads = %d\n", nthread);
0308 } else if (opt == 'f') {
0309 args |= ARG_FOREVER;
0310 printf("Press ^C to stop\n");
0311 test_harness_set_timeout(-1);
0312 } else if (opt == 'i') {
0313 count_max = atoi(optarg);
0314 printf("Running for %d interactions\n", count_max);
0315 } else if (opt == 'h') {
0316 show_help(argv[0]);
0317 }
0318 }
0319
0320
0321 if (!args)
0322 args = ARG_COMPLETE;
0323
0324 test_harness(signal_fuzzer, "signal_fuzzer");
0325 }