Fix the syscallwx target which is affected by both mimmutable(2) and
authoranton <anton@openbsd.org>
Mon, 9 Jan 2023 11:50:01 +0000 (11:50 +0000)
committeranton <anton@openbsd.org>
Mon, 9 Jan 2023 11:50:01 +0000 (11:50 +0000)
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
regress/usr.bin/lastcomm/gadget.S [new file with mode: 0644]
regress/usr.bin/lastcomm/syscallwx.c

index f05b16e..b9a9764 100644 (file)
@@ -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 (file)
index 0000000..dc0ca6c
--- /dev/null
@@ -0,0 +1,28 @@
+/*     $OpenBSD: gadget.S,v 1.1 2023/01/09 11:50:01 anton Exp $        */
+
+#include <sys/syscall.h>
+#include <machine/asm.h>
+
+#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
index 0eff81e..cc1e276 100644 (file)
@@ -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 <mortimer@openbsd.org>
  * Copyright (c) 2019 Alexander Bluhm <bluhm@openbsd.org>
 
 #include <err.h>
 #include <signal.h>
+#include <string.h>
 #include <unistd.h>
 
-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);