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 }