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 volatile int done = 0; 61 62 int rc = getcontext(&ucp); 63 if (done) { 64 (void) getcontext(&ucp); 65 return; 66 } 67 68 if (rc == 0) { 69 done = 1; 70 ucp.uc_mcontext.gregs[seg] = selector; 71 setcontext(&ucp); 72 } 73 abort(); 74 } 75 76 static void 77 resetcs(void) 78 { 79 return (resetseg(CS)); 80 } 81 82 static void 83 resetds(void) 84 { 85 return (resetseg(DS)); 86 } 87 88 static void 89 resetes(void) 90 { 91 return (resetseg(ES)); 92 } 93 94 static void 95 resetfs(void) 96 { 97 return (resetseg(FS)); 98 } 99 100 static void 101 resetgs(void) 102 { 103 return (resetseg(GS)); 104 } 105 106 static void 107 resetss(void) 108 { 109 return (resetseg(SS)); 110 } 111 112 static void 113 inchild(void (*func)()) 114 { 115 pid_t pid; 116 117 switch ((pid = fork())) { 118 case 0: 119 func(); 120 exit(0); 121 case -1: 122 exit(1); 123 default: 124 (void) waitpid(pid, NULL, 0); 125 return; 126 } 127 128 } 129 130 int 131 main(int argc, char *argv[]) 132 { 133 for (selector = 0; selector < 8194; selector++) { 134 inchild(resetcs); 135 inchild(resetds); 136 inchild(resetes); 137 inchild(resetfs); 138 inchild(resetgs); 139 inchild(resetss); 140 inchild(badds); 141 inchild(bades); 142 inchild(badfs); 143 inchild(badgs); 144 inchild(badss); 145 } 146 147 exit(0); 148 }