diff options
author | 2018-04-13 20:05:04 +0000 | |
---|---|---|
committer | 2018-04-13 20:05:04 +0000 | |
commit | 897fc685943471cf985a0fe38ba076ea6fe74fa5 (patch) | |
tree | 2ec905ca066ebe4823fd4681fa444fee66d251a8 | |
parent | Use TIOCGWINSZ to reduce the default -Owidth during interactive use (diff) | |
download | wireguard-openbsd-897fc685943471cf985a0fe38ba076ea6fe74fa5.tar.xz wireguard-openbsd-897fc685943471cf985a0fe38ba076ea6fe74fa5.zip |
Add a test for stack pivots that trigger page faults.
"Regress is always open for commits" @deraadt
-rw-r--r-- | regress/sys/kern/stackpivot/Makefile | 13 | ||||
-rw-r--r-- | regress/sys/kern/stackpivot/pagefault/Makefile | 9 | ||||
-rw-r--r-- | regress/sys/kern/stackpivot/pagefault/stackpivot.c | 60 | ||||
-rw-r--r-- | regress/sys/kern/stackpivot/pivot.h | 12 | ||||
-rw-r--r-- | regress/sys/kern/stackpivot/syscall/Makefile | 9 | ||||
-rw-r--r-- | regress/sys/kern/stackpivot/syscall/stackpivot.c (renamed from regress/sys/kern/stackpivot/stackpivot.c) | 11 |
6 files changed, 97 insertions, 17 deletions
diff --git a/regress/sys/kern/stackpivot/Makefile b/regress/sys/kern/stackpivot/Makefile index f09897c049f..0dd6af71e8c 100644 --- a/regress/sys/kern/stackpivot/Makefile +++ b/regress/sys/kern/stackpivot/Makefile @@ -1,18 +1,15 @@ -PROG= stackpivot - -run-regress-${PROG}: ${PROG} - rm -f ./${PROG}.core - if ./${PROG}; then false; else true; fi - if [ ! -e ./${PROG}.core ]; then echo "No coredump"; false; fi - .if ${MACHINE} != "amd64" && \ ${MACHINE} != "i386" REGRESS_TARGETS=run-regress-skiparch run-regress-skiparch: # Need stack pivot asm for this arch @echo SKIPPED +.include <bsd.regress.mk> +.else +SUBDIR += syscall +SUBDIR += pagefault +.include <bsd.subdir.mk> .endif -.include <bsd.regress.mk> diff --git a/regress/sys/kern/stackpivot/pagefault/Makefile b/regress/sys/kern/stackpivot/pagefault/Makefile new file mode 100644 index 00000000000..a374d550960 --- /dev/null +++ b/regress/sys/kern/stackpivot/pagefault/Makefile @@ -0,0 +1,9 @@ + +PROG= stackpivot + +run-regress-${PROG}: ${PROG} + rm -f ./${PROG}.core + if ./${PROG}; then false; else true; fi + if [ ! -e ./${PROG}.core ]; then echo "No coredump"; false; fi + +.include <bsd.regress.mk> diff --git a/regress/sys/kern/stackpivot/pagefault/stackpivot.c b/regress/sys/kern/stackpivot/pagefault/stackpivot.c new file mode 100644 index 00000000000..0d31e43f840 --- /dev/null +++ b/regress/sys/kern/stackpivot/pagefault/stackpivot.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 Todd Mortimer <mortimer@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "../pivot.h" + +static size_t *realstack; +static char *scan; +static size_t scansize = UINT16_MAX; + +/* scan some memory crossing a page boundary */ +size_t dowork() { + size_t b = 0; + size_t i; + for (i = 0; i < scansize; ++i) + b += *scan++; + return b; +} + +void doexit() { + exit(0); +} + +void unpivot() { + pivot(realstack); +} + +int main() { + + /* allocate some memory to scan */ + scan = malloc(scansize); + + /* set up a rop chain on the real stack for syscalls */ + size_t stack[10]; + stack[0] = (size_t)doexit; + realstack = stack; + + /* set up a basic alt stack on the heap that does some work */ + size_t *newstack = calloc(10, sizeof(size_t)); + newstack[0] = (size_t)dowork; + newstack[1] = (size_t)unpivot; + pivot(newstack); + return 0; +} diff --git a/regress/sys/kern/stackpivot/pivot.h b/regress/sys/kern/stackpivot/pivot.h new file mode 100644 index 00000000000..4f13a45bacf --- /dev/null +++ b/regress/sys/kern/stackpivot/pivot.h @@ -0,0 +1,12 @@ +#ifndef REGRESS_PIVOT_H +#define REGRESS_PIVOT_H + +static void pivot(size_t *newstack) { +#if defined(__amd64__) + asm("mov %0, %%rsp; retq;" ::"r"(newstack)); +#elif defined(__i386__) + asm("mov %0, %%esp; retl;" ::"r"(newstack)); +#endif +} + +#endif diff --git a/regress/sys/kern/stackpivot/syscall/Makefile b/regress/sys/kern/stackpivot/syscall/Makefile new file mode 100644 index 00000000000..a374d550960 --- /dev/null +++ b/regress/sys/kern/stackpivot/syscall/Makefile @@ -0,0 +1,9 @@ + +PROG= stackpivot + +run-regress-${PROG}: ${PROG} + rm -f ./${PROG}.core + if ./${PROG}; then false; else true; fi + if [ ! -e ./${PROG}.core ]; then echo "No coredump"; false; fi + +.include <bsd.regress.mk> diff --git a/regress/sys/kern/stackpivot/stackpivot.c b/regress/sys/kern/stackpivot/syscall/stackpivot.c index a5fae8c8321..2208ff48d31 100644 --- a/regress/sys/kern/stackpivot/stackpivot.c +++ b/regress/sys/kern/stackpivot/syscall/stackpivot.c @@ -17,23 +17,16 @@ #include <stdio.h> #include <stdlib.h> -void pivot(size_t *newstack) { -#if defined(__amd64__) - asm("mov %0, %%rsp; retq;" ::"r"(newstack)); -#elif defined(__i386__) - asm("mov %0, %%esp; retl;" ::"r"(newstack)); -#endif -} +#include "../pivot.h" void doexit() { exit(0); } int main() { + /* set up an alt stack on the heap that just calls doexit */ size_t *newstack = calloc(10, sizeof(size_t)); - /* set up a basic alt stack on the heap that just calls doexit */ newstack[0] = (size_t)doexit; - /* program should be killed in this function call */ pivot(newstack); return 0; } |