00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <stdio.h>
00045 #include <stdint.h>
00046 #include <unistd.h>
00047 #include <err.h>
00048
00049 #if defined(__mips__)
00050 #define KERNEL_ADDR 0x80000000
00051 #define INVAL_ADDR 0x40000000
00052 #define INSN_TYPE uint32_t
00053 #define INVAL_INSN 0x0000003f
00054 #else
00055 #error "Please fix this"
00056 #endif
00057
00058 typedef void (*func)(void);
00059
00060 static
00061 void
00062 read_from_null(void)
00063 {
00064 int *null = NULL;
00065 volatile int x;
00066 x = *null;
00067 }
00068
00069 static
00070 void
00071 read_from_inval(void)
00072 {
00073 int *ptr = (int *) INVAL_ADDR;
00074 volatile int x;
00075 x = *ptr;
00076 }
00077
00078 static
00079 void
00080 read_from_kernel(void)
00081 {
00082 int *ptr = (int *) KERNEL_ADDR;
00083 volatile int x;
00084 x = *ptr;
00085 }
00086
00087 static
00088 void
00089 write_to_null(void)
00090 {
00091 int *null = NULL;
00092 *null = 6;
00093 }
00094
00095 static
00096 void
00097 write_to_inval(void)
00098 {
00099 int *ptr = (int *) INVAL_ADDR;
00100 *ptr = 8;
00101 }
00102
00103 static
00104 void
00105 write_to_code(void)
00106 {
00107 INSN_TYPE *x = (INSN_TYPE *)write_to_code;
00108 *x = INVAL_INSN;
00109 }
00110
00111 static
00112 void
00113 write_to_kernel(void)
00114 {
00115 int *ptr = (int *) KERNEL_ADDR;
00116 *ptr = 8;
00117 }
00118
00119 static
00120 void
00121 jump_to_null(void)
00122 {
00123 func f = NULL;
00124 f();
00125 }
00126
00127 static
00128 void
00129 jump_to_inval(void)
00130 {
00131 func f = (func) INVAL_ADDR;
00132 f();
00133 }
00134
00135 static
00136 void
00137 jump_to_kernel(void)
00138 {
00139 func f = (func) KERNEL_ADDR;
00140 f();
00141 }
00142
00143
00144 static
00145 void
00146 illegal_instruction(void)
00147 {
00148 #if defined(__mips__)
00149 asm(".long 0x0000003f");
00150 #else
00151 #error "Please fix this"
00152 #endif
00153 }
00154
00155 static
00156 void
00157 alignment_error(void)
00158 {
00159 int x;
00160 int *ptr = &x;
00161 int *badptr = (int *)(((char *)ptr)+1);
00162
00163 volatile int j;
00164 j = *badptr;
00165 }
00166
00167 static
00168 void
00169 divide_by_zero(void)
00170 {
00171 volatile int x = 6;
00172 volatile int z = 0;
00173 volatile int a;
00174
00175 a = x/z;
00176 }
00177
00178 static
00179 void
00180 mod_by_zero(void)
00181 {
00182 volatile int x = 6;
00183 volatile int z = 0;
00184 volatile int a;
00185
00186 a = x%z;
00187 }
00188
00189 static
00190 void
00191 recurse_inf(void)
00192 {
00193 volatile char buf[16];
00194 buf[0] = 0;
00195 recurse_inf();
00196 buf[0] = 1;
00197 }
00198
00199
00200 static
00201 struct {
00202 int ch;
00203 const char *name;
00204 func f;
00205 } ops[] = {
00206 { 'a', "read from NULL", read_from_null },
00207 { 'b', "read from invalid address", read_from_inval },
00208 { 'c', "read from kernel address", read_from_kernel },
00209 { 'd', "write to NULL", write_to_null },
00210 { 'e', "write to invalid address", write_to_inval },
00211 { 'f', "write to code segment", write_to_code },
00212 { 'g', "write to kernel address", write_to_kernel },
00213 { 'h', "jump to NULL", jump_to_null },
00214 { 'i', "jump to invalid address", jump_to_inval },
00215 { 'j', "jump to kernel address", jump_to_kernel },
00216 { 'k', "alignment error", alignment_error },
00217 { 'l', "illegal instruction", illegal_instruction },
00218 { 'm', "divide by zero", divide_by_zero },
00219 { 'n', "mod by zero", mod_by_zero },
00220 { 'o', "Recurse infinitely", recurse_inf },
00221 { 0, NULL, NULL }
00222 };
00223
00224 int
00225 main(int argc, char **argv)
00226 {
00227 int op, i, status;
00228 pid_t pid;
00229
00230 if (argc == 2) {
00231 op = argv[1][0];
00232 }
00233 else {
00234 for (i=0; ops[i].name; i++) {
00235 printf("[%c] %s\n", ops[i].ch, ops[i].name);
00236 }
00237 printf("[*] Run everything (in subprocesses)\n");
00238 printf("Note: [f] may not cause an exception on some "
00239 "platforms, in which\ncase it'll appear to fail.\n");
00240
00241 printf("Choose: ");
00242 op = getchar();
00243 }
00244
00245 if (op=='*') {
00246 for (i=0; ops[i].name; i++) {
00247 printf("Running: [%c] %s\n", ops[i].ch, ops[i].name);
00248 pid = fork();
00249 if (pid<0) {
00250
00251 warn("fork");
00252 }
00253 else if (pid==0) {
00254
00255 ops[i].f();
00256 printf("I wasn't killed - test fails!\n");
00257 _exit(1);
00258 }
00259 waitpid(pid, &status, 0);
00260 if (WIFSIGNALED(status)) {
00261 printf("Signal %d\n", WTERMSIG(status));
00262 }
00263 else {
00264 printf("Exit %d\n", WEXITSTATUS(status));
00265 }
00266 }
00267 }
00268 else {
00269
00270 ops[op-'a'].f();
00271
00272 printf("I wasn't killed - test fails!\n");
00273 }
00274
00275 return 0;
00276 }