diff options
author | 2019-09-23 08:34:07 +0000 | |
---|---|---|
committer | 2019-09-23 08:34:07 +0000 | |
commit | 8566a01b6d708d28fbf35571408d9d212d8fd984 (patch) | |
tree | 36ba547d12b44a22291c461facc4ea80088f7856 | |
parent | Make the code that calculates the min/max priorities identical to the arm64 (diff) | |
download | wireguard-openbsd-8566a01b6d708d28fbf35571408d9d212d8fd984.tar.xz wireguard-openbsd-8566a01b6d708d28fbf35571408d9d212d8fd984.zip |
Add lastcomm(1) test for system call from writeable memory. This
requires that /usr/obj is mounted wxallowed, otherwise the test is
skipped. Split the stack map test into two stack pointer validation
tests, one during syscall and one in the trap handler.
Currently the tests during system call fail on amd64 as the signal
handler is not executed properly. On i386 and arm64 they pass. On
armv7 something else is broken.
-rw-r--r-- | regress/usr.bin/lastcomm/Makefile | 52 | ||||
-rw-r--r-- | regress/usr.bin/lastcomm/callstack.c (renamed from regress/usr.bin/lastcomm/stackmap.c) | 15 | ||||
-rw-r--r-- | regress/usr.bin/lastcomm/syscallwx.c | 50 | ||||
-rw-r--r-- | regress/usr.bin/lastcomm/trapstack.c | 84 |
4 files changed, 186 insertions, 15 deletions
diff --git a/regress/usr.bin/lastcomm/Makefile b/regress/usr.bin/lastcomm/Makefile index d9c62b52b3d..026ccba11e3 100644 --- a/regress/usr.bin/lastcomm/Makefile +++ b/regress/usr.bin/lastcomm/Makefile @@ -1,13 +1,29 @@ -# $OpenBSD: Makefile,v 1.5 2019/09/10 19:01:24 bluhm Exp $ +# $OpenBSD: Makefile,v 1.6 2019/09/23 08:34:07 bluhm Exp $ # Start with a clean /var/account/acct accounting file and turn on # process accounting with accton(8). Each test executes a command # with a unique name and checks the flags in the lastcomm(1) output. # Run tests with fork, map, core, xsig, pledge, trap accounting. -PROGS= crash stackmap -WARNINGS= Yes -CLEANFILES= regress-* +.if ! (make(clean) || make(cleandir) || make(obj)) + +MOUNT_OBJ !!= mount | grep ^$$(df -P . | tail -1 | awk '{ print $$1 }') + +.if "${MOUNT_OBJ:M*wxallowed*}" == "" +REGRESS_SKIP_TARGETS += run-syscallwx +.endif + +.endif + +.if ${MACHINE} == amd64 || ${MACHINE} == armv7 +# calling trapsignal() from syscall path does not work on amd64 +REGRESS_EXPECTED_FAILURES += run-callstack run-syscallwx +.endif + +PROGS= crash trapstack callstack syscallwx +WARNINGS= Yes +LDADD_syscallwx= -z wxneeded +CLEANFILES= regress-* REGRESS_SETUP_ONCE = setup-rotate # Rotate accouting files and keep statistics, from /etc/daily. @@ -29,13 +45,29 @@ run-fork: ./regress-fork -c '( : ) &' lastcomm regress-fork | grep -q ' -F ' -REGRESS_TARGETS += run-stackmap -run-stackmap: stackmap +REGRESS_TARGETS += run-trapstack +run-trapstack: trapstack + @echo '\n======== $@ ========' + # Use invalid stack pointer, trap, SIGSEGV handler, check -M flag. + cp -f trapstack regress-trapstack + ./regress-trapstack + lastcomm regress-trapstack | grep -q ' -MT ' + +REGRESS_TARGETS += run-callstack +run-callstack: callstack + @echo '\n======== $@ ========' + # Use invalid stack pointer, syscall, SIGSEGV handler, check -M flag. + cp -f callstack regress-callstack + ./regress-callstack + lastcomm regress-callstack | grep -q ' -MT ' + +REGRESS_TARGETS += run-syscallwx +run-syscallwx: syscallwx @echo '\n======== $@ ========' - # Use invalid stack pointer, run SIGSEGV handler, check the -M flag. - cp -f stackmap regress-stackmap - ./regress-stackmap - lastcomm regress-stackmap | grep -q ' -MT ' + # Use writable syscall code, run SIGSEGV handler, check -M flag. + cp -f syscallwx regress-syscallwx + ./regress-syscallwx + lastcomm regress-syscallwx | grep -q ' -MT ' REGRESS_TARGETS += run-core run-core: diff --git a/regress/usr.bin/lastcomm/stackmap.c b/regress/usr.bin/lastcomm/callstack.c index 66a82fe8182..c2a21f2bddb 100644 --- a/regress/usr.bin/lastcomm/stackmap.c +++ b/regress/usr.bin/lastcomm/callstack.c @@ -1,4 +1,4 @@ -/* $OpenBSD: stackmap.c,v 1.1 2019/09/10 19:01:24 bluhm Exp $ */ +/* $OpenBSD: callstack.c,v 1.1 2019/09/23 08:34:07 bluhm Exp $ */ /* * Copyright (c) 2018 Todd Mortimer <mortimer@openbsd.org> * Copyright (c) 2019 Alexander Bluhm <bluhm@openbsd.org> @@ -32,6 +32,7 @@ main(int argc, char *argv[]) stack_t ss; struct sigaction act; void (**newstack)(void); + long pagesize; ss.ss_sp = malloc(SIGSTKSZ); if (ss.ss_sp == NULL) @@ -46,21 +47,25 @@ main(int argc, char *argv[]) act.sa_flags = SA_ONSTACK; /* set up an alt stack on the heap that just calls doexit */ - newstack = malloc(SIGSTKSZ); + pagesize = sysconf(_SC_PAGESIZE); + if (pagesize == -1) + err(1, "sysconf"); + newstack = malloc(pagesize > SIGSTKSZ ? pagesize : SIGSTKSZ); if (newstack == NULL) err(1, "malloc newstack"); - newstack[0] = doexit; + /* allow stack to change half a page up and down. */ + newstack[pagesize/sizeof(*newstack)/2] = doexit; if (sigaction(SIGSEGV, &act, NULL) == -1) err(1, "sigaction"); - pivot(newstack); + pivot(&newstack[pagesize/sizeof(*newstack)/2]); return 3; } void handler(int signum) { - _exit(0); + _exit(0); } void diff --git a/regress/usr.bin/lastcomm/syscallwx.c b/regress/usr.bin/lastcomm/syscallwx.c new file mode 100644 index 00000000000..0eff81e6ff5 --- /dev/null +++ b/regress/usr.bin/lastcomm/syscallwx.c @@ -0,0 +1,50 @@ +/* $OpenBSD: syscallwx.c,v 1.1 2019/09/23 08:34:07 bluhm Exp $ */ +/* + * Copyright (c) 2018 Todd Mortimer <mortimer@openbsd.org> + * Copyright (c) 2019 Alexander Bluhm <bluhm@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 <sys/mman.h> + +#include <err.h> +#include <signal.h> +#include <unistd.h> + +void handler(int); + +int +main(int argc, char *argv[]) +{ + pid_t pid; + + pid = getpid(); + if (pid == -1) + err(1, "getpid"); + /* map kill system call in libc writeable */ + if (mprotect(kill, 100, PROT_EXEC | PROT_WRITE | PROT_READ) == -1) + err(1, "mprotect"); + + if (signal(SIGSEGV, handler) == SIG_ERR) + err(1, "signal"); + if (kill(pid, SIGABRT) == -1) + err(1, "kill"); + return 3; +} + +void +handler(int signum) +{ + _exit(0); +} diff --git a/regress/usr.bin/lastcomm/trapstack.c b/regress/usr.bin/lastcomm/trapstack.c new file mode 100644 index 00000000000..8737e112b55 --- /dev/null +++ b/regress/usr.bin/lastcomm/trapstack.c @@ -0,0 +1,84 @@ +/* $OpenBSD: trapstack.c,v 1.1 2019/09/23 08:34:07 bluhm Exp $ */ +/* + * Copyright (c) 2018 Todd Mortimer <mortimer@openbsd.org> + * Copyright (c) 2019 Alexander Bluhm <bluhm@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 <sys/mman.h> + +#include <err.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> + +#include "pivot.h" + +void handler(int); +void dotrap(void); + +static char *trapmap; + +int +main(int argc, char *argv[]) +{ + stack_t ss; + struct sigaction act; + void (**newstack)(void); + long pagesize; + + ss.ss_sp = malloc(SIGSTKSZ); + if (ss.ss_sp == NULL) + err(1, "malloc sigstack"); + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + if (sigaltstack(&ss, NULL) == -1) + err(1, "sigaltstack"); + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_ONSTACK; + + /* set up an alt stack on the heap that just calls dotrap */ + pagesize = sysconf(_SC_PAGESIZE); + if (pagesize == -1) + err(1, "sysconf"); + newstack = malloc(pagesize > SIGSTKSZ ? pagesize : SIGSTKSZ); + if (newstack == NULL) + err(1, "malloc newstack"); + /* allow stack to change half a page up and down. */ + newstack[pagesize/sizeof(*newstack)/2] = dotrap; + + trapmap = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, 0, -1, 0); + if (trapmap == NULL) + err(1, "mmap"); + + if (sigaction(SIGSEGV, &act, NULL) == -1) + err(1, "sigaction"); + pivot(&newstack[pagesize/sizeof(*newstack)/2]); + return 3; +} + +void +handler(int signum) +{ + _exit(0); +} + +void +dotrap(void) +{ + trapmap[0] = 'x'; + exit(2); +} |