1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2018 Joyent, Inc.
14 */
15
16 #include <stdlib.h>
17 #include <ucontext.h>
18 #include <sys/wait.h>
19 #include <unistd.h>
20 #include <sys/regset.h>
21
22 /*
23 * Load a bunch of bad selectors into the seg regs: this will typically cause
24 * the child process to core dump, but it shouldn't panic the kernel...
25 *
26 * It's especially interesting to run this on CPU0.
27 */
28
29 unsigned short selector;
30
31 static void badds(void)
32 {
33 __asm__ volatile("movw %0, %%ds" : : "r" (selector));
34 }
35
36 static void bades(void)
37 {
38 __asm__ volatile("movw %0, %%es" : : "r" (selector));
39 }
40
41 static void badfs(void)
42 {
43 __asm__ volatile("movw %0, %%fs" : : "r" (selector));
44 }
45
46 static void badgs(void)
47 {
48 __asm__ volatile("movw %0, %%gs" : : "r" (selector));
49 }
50
51 static void badss(void)
52 {
53 __asm__ volatile("movw %0, %%ss" : : "r" (selector));
54 }
55
56 static void
57 resetseg(uint_t seg)
58 {
59 ucontext_t ucp;
60 int done = 0;
61
62 int rc = getcontext(&ucp);
63 if (done) {
64 rc = getcontext(&ucp);
65 return;
66 }
67
68 done = 1;
69 ucp.uc_mcontext.gregs[seg] = selector;
70 setcontext(&ucp);
71 abort();
72 }
73
74 static void
75 resetcs(void)
76 {
77 return (resetseg(CS));
78 }
79
80 static void
81 resetds(void)
82 {
83 return (resetseg(DS));
84 }
85
86 static void
87 resetes(void)
88 {
89 return (resetseg(ES));
90 }
91
92 static void
93 resetfs(void)
94 {
95 return (resetseg(FS));
96 }
97
98 static void
99 resetgs(void)
100 {
101 return (resetseg(GS));
102 }
103
104 static void
105 resetss(void)
106 {
107 return (resetseg(SS));
108 }
109
110 static void
111 inchild(void (*func)())
112 {
113 pid_t pid;
114
115 switch ((pid = fork())) {
116 case 0:
117 func();
118 exit(0);
119 case -1:
120 exit(1);
121 default:
122 (void) waitpid(pid, NULL, 0);
123 return;
124 }
125
126 }
127
128 int
129 main(int argc, char *argv[])
130 {
131 for (selector = 0; selector < 8194; selector++) {
132 inchild(resetcs);
133 inchild(resetds);
134 inchild(resetes);
135 inchild(resetfs);
136 inchild(resetgs);
137 inchild(resetss);
138 inchild(badds);
139 inchild(bades);
140 inchild(badfs);
141 inchild(badgs);
142 inchild(badss);
143 }
144
145 exit(0);
146 }