/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- read_from_null
- read_from_inval
- read_from_kernel
- write_to_null
- write_to_inval
- write_to_code
- write_to_kernel
- jump_to_null
- jump_to_inval
- jump_to_kernel
- illegal_instruction
- alignment_error
- divide_by_zero
- mod_by_zero
- recurse_inf
- main
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * crash.c
32 *
33 * Commit a variety of exceptions, primarily address faults.
34 *
35 * Once the basic system calls assignment is complete, none of these
36 * should crash the kernel.
37 *
38 * They should all, however, terminate this program, except for the
39 * one that writes to the code segment. (That one won't cause program
40 * termination until/unless you implement read-only segments in your
41 * VM system.)
42 */
43
44 #include <stdio.h>
45 #include <stdint.h>
46 #include <unistd.h>
47 #include <err.h>
48
49 #if defined(__mips__)
50 #define KERNEL_ADDR 0x80000000
51 #define INVAL_ADDR 0x40000000
52 #define INSN_TYPE uint32_t
53 #define INVAL_INSN 0x0000003f
54 #else
55 #error "Please fix this"
56 #endif
57
58 typedef void (*func)(void);
59
60 static
61 void
62 read_from_null(void)
63 {
64 int *null = NULL;
65 volatile int x;
66 x = *null;
67 }
68
69 static
70 void
71 read_from_inval(void)
72 {
73 int *ptr = (int *) INVAL_ADDR;
74 volatile int x;
75 x = *ptr;
76 }
77
78 static
79 void
80 read_from_kernel(void)
81 {
82 int *ptr = (int *) KERNEL_ADDR;
83 volatile int x;
84 x = *ptr;
85 }
86
87 static
88 void
89 write_to_null(void)
90 {
91 int *null = NULL;
92 *null = 6;
93 }
94
95 static
96 void
97 write_to_inval(void)
98 {
99 int *ptr = (int *) INVAL_ADDR;
100 *ptr = 8;
101 }
102
103 static
104 void
105 write_to_code(void)
106 {
107 INSN_TYPE *x = (INSN_TYPE *)write_to_code;
108 *x = INVAL_INSN;
109 }
110
111 static
112 void
113 write_to_kernel(void)
114 {
115 int *ptr = (int *) KERNEL_ADDR;
116 *ptr = 8;
117 }
118
119 static
120 void
121 jump_to_null(void)
122 {
123 func f = NULL;
124 f();
125 }
126
127 static
128 void
129 jump_to_inval(void)
130 {
131 func f = (func) INVAL_ADDR;
132 f();
133 }
134
135 static
136 void
137 jump_to_kernel(void)
138 {
139 func f = (func) KERNEL_ADDR;
140 f();
141 }
142
143
144 static
145 void
146 illegal_instruction(void)
147 {
148 #if defined(__mips__)
149 asm(".long 0x0000003f");
150 #else
151 #error "Please fix this"
152 #endif
153 }
154
155 static
156 void
157 alignment_error(void)
158 {
159 int x;
160 int *ptr = &x;
161 int *badptr = (int *)(((char *)ptr)+1);
162
163 volatile int j;
164 j = *badptr;
165 }
166
167 static
168 void
169 divide_by_zero(void)
170 {
171 volatile int x = 6;
172 volatile int z = 0;
173 volatile int a;
174
175 a = x/z;
176 }
177
178 static
179 void
180 mod_by_zero(void)
181 {
182 volatile int x = 6;
183 volatile int z = 0;
184 volatile int a;
185
186 a = x%z;
187 }
188
189 static
190 void
191 recurse_inf(void)
192 {
193 volatile char buf[16];
194 buf[0] = 0;
195 recurse_inf();
196 buf[0] = 1;
197 }
198
199
200 static
201 struct {
202 int ch;
203 const char *name;
204 func f;
205 } ops[] = {
206 { 'a', "read from NULL", read_from_null },
207 { 'b', "read from invalid address", read_from_inval },
208 { 'c', "read from kernel address", read_from_kernel },
209 { 'd', "write to NULL", write_to_null },
210 { 'e', "write to invalid address", write_to_inval },
211 { 'f', "write to code segment", write_to_code },
212 { 'g', "write to kernel address", write_to_kernel },
213 { 'h', "jump to NULL", jump_to_null },
214 { 'i', "jump to invalid address", jump_to_inval },
215 { 'j', "jump to kernel address", jump_to_kernel },
216 { 'k', "alignment error", alignment_error },
217 { 'l', "illegal instruction", illegal_instruction },
218 { 'm', "divide by zero", divide_by_zero },
219 { 'n', "mod by zero", mod_by_zero },
220 { 'o', "Recurse infinitely", recurse_inf },
221 { 0, NULL, NULL }
222 };
223
224 int
225 main(int argc, char **argv)
226 {
227 int op, i, status;
228 pid_t pid;
229
230 if (argc == 2) {
231 op = argv[1][0];
232 }
233 else {
234 for (i=0; ops[i].name; i++) {
235 printf("[%c] %s\n", ops[i].ch, ops[i].name);
236 }
237 printf("[*] Run everything (in subprocesses)\n");
238 printf("Note: [f] may not cause an exception on some "
239 "platforms, in which\ncase it'll appear to fail.\n");
240
241 printf("Choose: ");
242 op = getchar();
243 }
244
245 if (op=='*') {
246 for (i=0; ops[i].name; i++) {
247 printf("Running: [%c] %s\n", ops[i].ch, ops[i].name);
248 pid = fork();
249 if (pid<0) {
250 /* error */
251 warn("fork");
252 }
253 else if (pid==0) {
254 /* child */
255 ops[i].f();
256 printf("I wasn't killed - test fails!\n");
257 _exit(1);
258 }
259 waitpid(pid, &status, 0);
260 if (WIFSIGNALED(status)) {
261 printf("Signal %d\n", WTERMSIG(status));
262 }
263 else {
264 printf("Exit %d\n", WEXITSTATUS(status));
265 }
266 }
267 }
268 else {
269 /* intentionally don't check if op is in bounds :) */
270 ops[op-'a'].f();
271
272 printf("I wasn't killed - test fails!\n");
273 }
274
275 return 0;
276 }