From c0a6b811701bdbfe01fb72ed4246ca86eedef8aa Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 9 Jan 2023 11:50:01 +0000 Subject: [PATCH] Fix the syscallwx target which is affected by both mimmutable(2) and xonly by using a new gadget routine written in assembler with the sole purpose of issuing a syscall. Since it needs to be copied to wx memory, place it in the rodata section. --- regress/usr.bin/lastcomm/Makefile | 3 ++- regress/usr.bin/lastcomm/gadget.S | 28 ++++++++++++++++++++++++++ regress/usr.bin/lastcomm/syscallwx.c | 30 ++++++++++++++++------------ 3 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 regress/usr.bin/lastcomm/gadget.S diff --git a/regress/usr.bin/lastcomm/Makefile b/regress/usr.bin/lastcomm/Makefile index f05b16e083d..b9a97649e73 100644 --- a/regress/usr.bin/lastcomm/Makefile +++ b/regress/usr.bin/lastcomm/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.10 2021/09/28 08:51:18 kettenis Exp $ +# $OpenBSD: Makefile,v 1.11 2023/01/09 11:50:01 anton Exp $ # Start with a clean /var/account/acct accounting file and turn on # process accounting with accton(8). Each test executes a command @@ -22,6 +22,7 @@ REGRESS_EXPECTED_FAILURES += run-callstack run-syscallwx PROGS= crash trapstack callstack syscallwx unveil WARNINGS= Yes +SRCS_syscallwx= syscallwx.c gadget.S LDADD_syscallwx= -Wl,-z,wxneeded CLEANFILES= regress-* diff --git a/regress/usr.bin/lastcomm/gadget.S b/regress/usr.bin/lastcomm/gadget.S new file mode 100644 index 00000000000..dc0ca6cc8bb --- /dev/null +++ b/regress/usr.bin/lastcomm/gadget.S @@ -0,0 +1,28 @@ +/* $OpenBSD: gadget.S,v 1.1 2023/01/09 11:50:01 anton Exp $ */ + +#include +#include + +#if !defined(_ASM_TYPE_FUNCTION) +#define _ASM_TYPE_FUNCTION @function +#endif + + .section .rodata + .globl gadget_getpid + .type gadget_getpid,_ASM_TYPE_FUNCTION +gadget_getpid: +#if defined(__amd64__) + mov $SYS_getpid, %eax + syscall + ret +#elif defined(__aarch64__) + ldr x8, #SYS_getpid + svc 0 + dsb nsh + isb + ret +#else +#error "Missing gadget." +#endif + + .space 4096 diff --git a/regress/usr.bin/lastcomm/syscallwx.c b/regress/usr.bin/lastcomm/syscallwx.c index 0eff81e6ff5..cc1e276ca51 100644 --- a/regress/usr.bin/lastcomm/syscallwx.c +++ b/regress/usr.bin/lastcomm/syscallwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscallwx.c,v 1.1 2019/09/23 08:34:07 bluhm Exp $ */ +/* $OpenBSD: syscallwx.c,v 1.2 2023/01/09 11:50:01 anton Exp $ */ /* * Copyright (c) 2018 Todd Mortimer * Copyright (c) 2019 Alexander Bluhm @@ -20,30 +20,34 @@ #include #include +#include #include -void handler(int); +extern void gadget_getpid(void); +static 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"); + union { + void *p; + void (*gadget)(void); + } addr; + int psz = getpagesize(); if (signal(SIGSEGV, handler) == SIG_ERR) err(1, "signal"); - if (kill(pid, SIGABRT) == -1) - err(1, "kill"); + + addr.p = mmap(NULL, psz, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (addr.p == NULL) + err(1, "mmap"); + memcpy(addr.p, gadget_getpid, psz); + addr.gadget(); return 3; } -void +static void handler(int signum) { _exit(0); -- 2.20.1