1 /* $OpenBSD: trapstack.c,v 1.2 2020/11/07 23:36:24 bluhm Exp $ */ 2 /* 3 * Copyright (c) 2018 Todd Mortimer <mortimer@openbsd.org> 4 * Copyright (c) 2019 Alexander Bluhm <bluhm@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/mman.h> 20 21 #include <err.h> 22 #include <stdlib.h> 23 #include <signal.h> 24 #include <unistd.h> 25 26 #include "pivot.h" 27 28 void handler(int); 29 void dotrap(void); 30 31 static volatile char *trapmap; 32 33 int 34 main(int argc, char *argv[]) 35 { 36 stack_t ss; 37 struct sigaction act; 38 void (**newstack)(void); 39 long pagesize; 40 41 ss.ss_sp = malloc(SIGSTKSZ); 42 if (ss.ss_sp == NULL) 43 err(1, "malloc sigstack"); 44 ss.ss_size = SIGSTKSZ; 45 ss.ss_flags = 0; 46 if (sigaltstack(&ss, NULL) == -1) 47 err(1, "sigaltstack"); 48 49 act.sa_handler = handler; 50 sigemptyset(&act.sa_mask); 51 act.sa_flags = SA_ONSTACK; 52 53 /* set up an alt stack on the heap that just calls dotrap */ 54 pagesize = sysconf(_SC_PAGESIZE); 55 if (pagesize == -1) 56 err(1, "sysconf"); 57 newstack = malloc(pagesize > SIGSTKSZ ? pagesize : SIGSTKSZ); 58 if (newstack == NULL) 59 err(1, "malloc newstack"); 60 /* allow stack to change half a page up and down. */ 61 newstack[pagesize/sizeof(*newstack)/2] = dotrap; 62 63 trapmap = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, 64 -1, 0); 65 if (trapmap == MAP_FAILED) 66 err(1, "mmap"); 67 68 if (sigaction(SIGSEGV, &act, NULL) == -1) 69 err(1, "sigaction"); 70 pivot(&newstack[pagesize/sizeof(*newstack)/2]); 71 return 3; 72 } 73 74 void 75 handler(int signum) 76 { 77 _exit(0); 78 } 79 80 void 81 dotrap(void) 82 { 83 trapmap[0] = 'x'; 84 exit(2); 85 } 86