/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2019 Joyent, Inc. */ #include #include #include #include #include #include #include /* * Load a bunch of bad selectors into the seg regs: this will typically cause * the child process to core dump, but it shouldn't panic the kernel... * * It's especially interesting to run this on CPU0. */ unsigned short selector; static void badds(void) { __asm__ volatile("movw %0, %%ds" : : "r" (selector)); } static void bades(void) { __asm__ volatile("movw %0, %%es" : : "r" (selector)); } static void badfs(void) { __asm__ volatile("movw %0, %%fs" : : "r" (selector)); } static void badgs(void) { __asm__ volatile("movw %0, %%gs" : : "r" (selector)); } static void badss(void) { __asm__ volatile("movw %0, %%ss" : : "r" (selector)); } static void resetseg(uint_t seg) { ucontext_t ucp; volatile int done = 0; int rc = getcontext(&ucp); if (done) { (void) getcontext(&ucp); return; } if (rc == 0) { done = 1; ucp.uc_mcontext.gregs[seg] = selector; (void) setcontext(&ucp); } abort(); } static void resetcs(void) { return (resetseg(CS)); } static void resetds(void) { return (resetseg(DS)); } static void resetes(void) { return (resetseg(ES)); } static void resetfs(void) { return (resetseg(FS)); } static void resetgs(void) { return (resetseg(GS)); } static void resetss(void) { return (resetseg(SS)); } static void inchild(void (*func)()) { pid_t pid; switch ((pid = fork())) { case 0: func(); exit(EXIT_SUCCESS); case -1: exit(EXIT_FAILURE); default: (void) waitpid(pid, NULL, 0); return; } } int main(int argc, char *argv[]) { struct rlimit rl = { 0, }; if (setrlimit(RLIMIT_CORE, &rl) != 0) { err(EXIT_FAILURE, "failed to disable cores"); } for (selector = 0; selector < 512; selector++) { inchild(resetcs); inchild(resetds); inchild(resetes); inchild(resetfs); inchild(resetgs); inchild(resetss); inchild(badds); inchild(bades); inchild(badfs); inchild(badgs); inchild(badss); } exit(EXIT_SUCCESS); }