From 0277d7d6e93221d2000d0f629227ce18e6ba3a7d Mon Sep 17 00:00:00 2001
From: Justine Tunney <jtunney@gmail.com>
Date: Mon, 8 Aug 2022 11:41:08 -0700
Subject: [PATCH] Rewrite Linux pledge() code so it can be a payload

It's now possible to build our pledge() polyfill as a dynamic shared
object that can be injected into a glibc executable using LD_PRELOAD
---
 libc/calls/calls.h                         |    1 +
 libc/calls/calls.mk                        |   11 +-
 libc/calls/execve.c                        |    6 +-
 libc/calls/getprogramexecutablename.greg.c |    6 +-
 libc/calls/memfd_create.c                  |   35 +
 libc/calls/parsepromises.c                 |   66 +
 libc/calls/pledge-linux.c                  | 1625 ++++++++++++++++++++
 libc/calls/pledge.c                        | 1568 +------------------
 libc/calls/pledge.h                        |   16 +
 libc/calls/pledge.internal.h               |   13 +-
 libc/calls/raise.c                         |    7 +-
 libc/calls/unveil.c                        |    6 +-
 libc/intrin/exit.c                         |   18 +-
 libc/intrin/exit1.greg.c                   |    7 +
 libc/intrin/promises.c                     |    4 +-
 libc/intrin/promises.internal.h            |    1 +
 libc/runtime/runtime.h                     |    1 -
 libc/sysv/calls/memfd_create.s             |    2 -
 libc/sysv/calls/sys_memfd_create.s         |    2 +
 libc/sysv/consts.sh                        |    8 -
 libc/sysv/consts/CANBSIZ.S                 |    2 -
 libc/sysv/consts/IPPORT_RESERVED.S         |    2 -
 libc/sysv/consts/MFD_ALLOW_SEALING.S       |    2 -
 libc/sysv/consts/MFD_CLOEXEC.S             |    2 -
 libc/sysv/consts/mfd.h                     |   13 +-
 libc/sysv/syscalls.sh                      |    2 +-
 test/libc/calls/pledge2_test.c             |   30 +-
 test/libc/calls/pledge_test.c              |   22 +-
 test/libc/calls/unveil_test.c              |    2 +-
 test/tool/build/pledge_test.sh             |   14 +-
 test/tool/net/lunix_test.lua               |    2 +-
 third_party/chibicc/test/test.mk           |    8 +-
 third_party/lua/lunix.c                    |    1 +
 tool/build/build.mk                        |   19 +
 tool/build/pledge.c                        |   25 +-
 tool/build/sandbox.c                       |   28 +
 tool/net/redbean.c                         |    3 +-
 37 files changed, 1980 insertions(+), 1600 deletions(-)
 create mode 100644 libc/calls/memfd_create.c
 create mode 100644 libc/calls/parsepromises.c
 create mode 100644 libc/calls/pledge-linux.c
 create mode 100644 libc/calls/pledge.h
 delete mode 100644 libc/sysv/calls/memfd_create.s
 create mode 100644 libc/sysv/calls/sys_memfd_create.s
 delete mode 100644 libc/sysv/consts/CANBSIZ.S
 delete mode 100644 libc/sysv/consts/IPPORT_RESERVED.S
 delete mode 100644 libc/sysv/consts/MFD_ALLOW_SEALING.S
 delete mode 100644 libc/sysv/consts/MFD_CLOEXEC.S
 create mode 100644 tool/build/sandbox.c

diff --git a/libc/calls/calls.h b/libc/calls/calls.h
index 478f985ec..dbe977a71 100644
--- a/libc/calls/calls.h
+++ b/libc/calls/calls.h
@@ -123,6 +123,7 @@ int killpg(int, int);
 int link(const char *, const char *) dontthrow;
 int linkat(int, const char *, int, const char *, int);
 int madvise(void *, uint64_t, int);
+int memfd_create(const char *, unsigned int);
 int mincore(void *, size_t, unsigned char *);
 int mkdir(const char *, uint32_t);
 int mkdirat(int, const char *, uint32_t);
diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk
index 1dca6c8a0..51363dccb 100644
--- a/libc/calls/calls.mk
+++ b/libc/calls/calls.mk
@@ -188,11 +188,20 @@ o/$(MODE)/libc/calls/_timespec_frommicros.o:		\
 		OVERRIDE_CFLAGS +=			\
 			-O2
 
-o/$(MODE)/libc/calls/pledge.o				\
+o/$(MODE)/libc/calls/pledge-linux.o			\
 o/$(MODE)/libc/calls/unveil.o:				\
 		OVERRIDE_CFLAGS +=			\
 			-DSTACK_FRAME_UNLIMITED
 
+# we want -Os because:
+#   it makes a big difference
+# we need pic because:
+#   so it can be an LD_PRELOAD payload
+o/$(MODE)/libc/calls/pledge-linux.o:			\
+		OVERRIDE_CFLAGS +=			\
+			-Os				\
+			-fPIC
+
 LIBC_CALLS_LIBS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)))
 LIBC_CALLS_SRCS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_SRCS))
 LIBC_CALLS_HDRS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_HDRS))
diff --git a/libc/calls/execve.c b/libc/calls/execve.c
index cf87257d9..25536f63d 100644
--- a/libc/calls/execve.c
+++ b/libc/calls/execve.c
@@ -19,6 +19,8 @@
 #include "libc/bits/likely.h"
 #include "libc/bits/weaken.h"
 #include "libc/calls/calls.h"
+#include "libc/calls/pledge.h"
+#include "libc/calls/pledge.internal.h"
 #include "libc/calls/strace.internal.h"
 #include "libc/calls/syscall-nt.internal.h"
 #include "libc/calls/syscall-sysv.internal.h"
@@ -30,8 +32,6 @@
 #include "libc/sysv/consts/o.h"
 #include "libc/sysv/errfuns.h"
 
-int sys_pledge_linux(unsigned long);
-
 /**
  * Replaces current process with program.
  *
@@ -72,7 +72,7 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
     if (!IsWindows()) {
       rc = 0;
       if (IsLinux() && __execpromises && weaken(sys_pledge_linux)) {
-        rc = weaken(sys_pledge_linux)(__execpromises);
+        rc = weaken(sys_pledge_linux)(__execpromises, __pledge_mode, false);
       }
       if (!rc) {
         rc = sys_execve(prog, argv, envp);
diff --git a/libc/calls/getprogramexecutablename.greg.c b/libc/calls/getprogramexecutablename.greg.c
index 58840a714..b4ed59c71 100644
--- a/libc/calls/getprogramexecutablename.greg.c
+++ b/libc/calls/getprogramexecutablename.greg.c
@@ -136,6 +136,6 @@ char *GetProgramExecutableName(void) {
   return program_executable_name;
 }
 
-const void *const GetProgramExecutableNameCtor[] initarray = {
-    GetProgramExecutableName,
-};
+/* const void *const GetProgramExecutableNameCtor[] initarray = { */
+/*     GetProgramExecutableName, */
+/* }; */
diff --git a/libc/calls/memfd_create.c b/libc/calls/memfd_create.c
new file mode 100644
index 000000000..f83f6b680
--- /dev/null
+++ b/libc/calls/memfd_create.c
@@ -0,0 +1,35 @@
+/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
+│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2022 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or 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 "libc/calls/calls.h"
+#include "libc/calls/strace.internal.h"
+#include "libc/calls/syscall-sysv.internal.h"
+
+/**
+ * Creates anonymous file.
+ *
+ * @param name is used for the `/proc/self/fd/FD` symlink
+ * @param flags can have `MFD_CLOEXEC`, `MFD_ALLOW_SEALING`
+ * @raise ENOSYS if not RHEL8+
+ */
+int memfd_create(const char *name, unsigned int flags) {
+  int rc;
+  rc = sys_memfd_create(name, flags);
+  STRACE("memfd_create(%#s, %#x) → %d% m", name, flags, rc);
+  return rc;
+}
diff --git a/libc/calls/parsepromises.c b/libc/calls/parsepromises.c
new file mode 100644
index 000000000..3929d63d5
--- /dev/null
+++ b/libc/calls/parsepromises.c
@@ -0,0 +1,66 @@
+/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
+│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2022 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or 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 "libc/calls/pledge.internal.h"
+#include "libc/macros.internal.h"
+#include "libc/str/str.h"
+
+static int FindPromise(const char *name) {
+  int i;
+  for (i = 0; i < ARRAYLEN(kPledge); ++i) {
+    if (!strcasecmp(name, kPledge[i].name)) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Parses the arguments to pledge() into a bitmask.
+ *
+ * @return 0 on success, or -1 if invalid
+ */
+int ParsePromises(const char *promises, unsigned long *out) {
+  int rc = 0;
+  int promise;
+  unsigned long ipromises;
+  char *tok, *state, *start, buf[256];
+  if (promises) {
+    ipromises = -1;
+    if (memccpy(buf, promises, 0, sizeof(buf))) {
+      start = buf;
+      while ((tok = strtok_r(start, " \t\r\n", &state))) {
+        if ((promise = FindPromise(tok)) != -1) {
+          ipromises &= ~(1ULL << promise);
+        } else {
+          rc = -1;
+          break;
+        }
+        start = 0;
+      }
+    } else {
+      rc = -1;
+    }
+  } else {
+    ipromises = 0;
+  }
+  if (!rc) {
+    *out = ipromises;
+  }
+  return rc;
+}
diff --git a/libc/calls/pledge-linux.c b/libc/calls/pledge-linux.c
new file mode 100644
index 000000000..bb316bc2d
--- /dev/null
+++ b/libc/calls/pledge-linux.c
@@ -0,0 +1,1625 @@
+/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
+│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2022 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or 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 "libc/bits/likely.h"
+#include "libc/calls/calls.h"
+#include "libc/calls/pledge.internal.h"
+#include "libc/calls/struct/bpf.h"
+#include "libc/calls/struct/filter.h"
+#include "libc/calls/struct/seccomp.h"
+#include "libc/calls/struct/sigaction.h"
+#include "libc/calls/syscall_support-sysv.internal.h"
+#include "libc/intrin/kprintf.h"
+#include "libc/intrin/promises.internal.h"
+#include "libc/macros.internal.h"
+#include "libc/nexgen32e/bsr.h"
+#include "libc/runtime/runtime.h"
+#include "libc/runtime/stack.h"
+#include "libc/sysv/consts/audit.h"
+#include "libc/sysv/consts/nrlinux.h"
+#include "libc/sysv/consts/o.h"
+#include "libc/sysv/consts/pr.h"
+#include "libc/sysv/consts/prot.h"
+
+/**
+ * @fileoverview OpenBSD pledge() Polyfill Payload for GNU/Systemd
+ *
+ * This file contains only the minimum amount of Linux-specific code
+ * that's necessary to get a pledge() policy installed. This file is
+ * designed to not use static or tls memory or libc depnedencies, so
+ * it can be transplanted into codebases and injected into programs.
+ */
+
+#define Eperm       1
+#define Sigabrt     6
+#define Enosys      38
+#define Sigsys      31
+#define Sig_Setmask 2
+#define Sa_Siginfo  4
+#define Sa_Restorer 0x04000000
+#define Sa_Restart  0x10000000
+
+#define SPECIAL   0xf000
+#define ADDRLESS  0x2000
+#define INET      0x8000
+#define LOCK      0x4000
+#define NOEXEC    0x8000
+#define EXEC      0x4000
+#define READONLY  0x8000
+#define WRITEONLY 0x4000
+#define CREATONLY 0x2000
+#define STDIO     0x8000
+#define THREAD    0x8000
+#define TTY       0x8000
+#define UNIX      0x4000
+#define NOBITS    0x8000
+#define NOSIGSYS  0x8000
+#define RESTRICT  0x1000
+
+#define PLEDGE(pledge) pledge, ARRAYLEN(pledge)
+#define OFF(f)         offsetof(struct seccomp_data, f)
+
+#define AbortPledge(reason) \
+  do {                      \
+    asm("hlt");             \
+    unreachable;            \
+  } while (0)
+
+struct Filter {
+  size_t n;
+  struct sock_filter p[700];
+};
+
+static const uint16_t kPledgeDefault[] = {
+    __NR_linux_exit,  // thread return / exit()
+};
+
+// the stdio contains all the benign system calls. openbsd makes the
+// assumption that preexisting file descriptors are trustworthy. we
+// implement checking for these as a simple linear scan rather than
+// binary search, since there doesn't appear to be any measurable
+// difference in the latency of sched_yield() if it's at the start of
+// the bpf script or the end.
+static const uint16_t kPledgeStdio[] = {
+    __NR_linux_sigreturn,             //
+    __NR_linux_restart_syscall,       //
+    __NR_linux_exit_group,            //
+    __NR_linux_sched_yield,           //
+    __NR_linux_sched_getaffinity,     //
+    __NR_linux_clock_getres,          //
+    __NR_linux_clock_gettime,         //
+    __NR_linux_clock_nanosleep,       //
+    __NR_linux_close_range,           //
+    __NR_linux_close,                 //
+    __NR_linux_write,                 //
+    __NR_linux_writev,                //
+    __NR_linux_pwrite,                //
+    __NR_linux_pwritev,               //
+    __NR_linux_pwritev2,              //
+    __NR_linux_read,                  //
+    __NR_linux_readv,                 //
+    __NR_linux_pread,                 //
+    __NR_linux_preadv,                //
+    __NR_linux_preadv2,               //
+    __NR_linux_dup,                   //
+    __NR_linux_dup2,                  //
+    __NR_linux_dup3,                  //
+    __NR_linux_fchdir,                //
+    __NR_linux_fcntl | STDIO,         //
+    __NR_linux_fstat,                 //
+    __NR_linux_fsync,                 //
+    __NR_linux_sysinfo,               //
+    __NR_linux_fdatasync,             //
+    __NR_linux_ftruncate,             //
+    __NR_linux_getdents,              //
+    __NR_linux_getrandom,             //
+    __NR_linux_getgroups,             //
+    __NR_linux_getpgid,               //
+    __NR_linux_getpgrp,               //
+    __NR_linux_getpid,                //
+    __NR_linux_gettid,                //
+    __NR_linux_getuid,                //
+    __NR_linux_getgid,                //
+    __NR_linux_getsid,                //
+    __NR_linux_getppid,               //
+    __NR_linux_geteuid,               //
+    __NR_linux_getegid,               //
+    __NR_linux_getrlimit,             //
+    __NR_linux_getresgid,             //
+    __NR_linux_getresuid,             //
+    __NR_linux_getitimer,             //
+    __NR_linux_setitimer,             //
+    __NR_linux_timerfd_create,        //
+    __NR_linux_timerfd_settime,       //
+    __NR_linux_timerfd_gettime,       //
+    __NR_linux_copy_file_range,       //
+    __NR_linux_gettimeofday,          //
+    __NR_linux_sendfile,              //
+    __NR_linux_vmsplice,              //
+    __NR_linux_splice,                //
+    __NR_linux_lseek,                 //
+    __NR_linux_tee,                   //
+    __NR_linux_brk,                   //
+    __NR_linux_msync,                 //
+    __NR_linux_mmap | NOEXEC,         //
+    __NR_linux_mremap,                //
+    __NR_linux_munmap,                //
+    __NR_linux_mincore,               //
+    __NR_linux_madvise,               //
+    __NR_linux_fadvise,               //
+    __NR_linux_mprotect | NOEXEC,     //
+    __NR_linux_arch_prctl,            //
+    __NR_linux_migrate_pages,         //
+    __NR_linux_sync_file_range,       //
+    __NR_linux_set_tid_address,       //
+    __NR_linux_nanosleep,             //
+    __NR_linux_pipe,                  //
+    __NR_linux_pipe2,                 //
+    __NR_linux_poll,                  //
+    __NR_linux_ppoll,                 //
+    __NR_linux_select,                //
+    __NR_linux_pselect6,              //
+    __NR_linux_epoll_create,          //
+    __NR_linux_epoll_create1,         //
+    __NR_linux_epoll_ctl,             //
+    __NR_linux_epoll_wait,            //
+    __NR_linux_epoll_pwait,           //
+    __NR_linux_epoll_pwait2,          //
+    __NR_linux_recvfrom,              //
+    __NR_linux_sendto | ADDRLESS,     //
+    __NR_linux_ioctl | RESTRICT,      //
+    __NR_linux_alarm,                 //
+    __NR_linux_pause,                 //
+    __NR_linux_shutdown,              //
+    __NR_linux_eventfd,               //
+    __NR_linux_eventfd2,              //
+    __NR_linux_signalfd,              //
+    __NR_linux_signalfd4,             //
+    __NR_linux_sigaction | NOSIGSYS,  //
+    __NR_linux_sigaltstack,           //
+    __NR_linux_sigprocmask,           //
+    __NR_linux_sigsuspend,            //
+    __NR_linux_sigpending,            //
+    __NR_linux_socketpair,            //
+    __NR_linux_getrusage,             //
+    __NR_linux_times,                 //
+    __NR_linux_umask,                 //
+    __NR_linux_wait4,                 //
+    __NR_linux_uname,                 //
+    __NR_linux_prctl | STDIO,         //
+    __NR_linux_clone | THREAD,        //
+    __NR_linux_futex,                 //
+    __NR_linux_set_robust_list,       //
+    __NR_linux_get_robust_list,       //
+    __NR_linux_prlimit | STDIO,       //
+};
+
+static const uint16_t kPledgeFlock[] = {
+    __NR_linux_flock,         //
+    __NR_linux_fcntl | LOCK,  //
+};
+
+static const uint16_t kPledgeRpath[] = {
+    __NR_linux_chdir,              //
+    __NR_linux_getcwd,             //
+    __NR_linux_open | READONLY,    //
+    __NR_linux_openat | READONLY,  //
+    __NR_linux_stat,               //
+    __NR_linux_lstat,              //
+    __NR_linux_fstat,              //
+    __NR_linux_fstatat,            //
+    __NR_linux_access,             //
+    __NR_linux_faccessat,          //
+    __NR_linux_faccessat2,         //
+    __NR_linux_readlink,           //
+    __NR_linux_readlinkat,         //
+    __NR_linux_statfs,             //
+    __NR_linux_fstatfs,            //
+};
+
+static const uint16_t kPledgeWpath[] = {
+    __NR_linux_getcwd,              //
+    __NR_linux_open | WRITEONLY,    //
+    __NR_linux_openat | WRITEONLY,  //
+    __NR_linux_stat,                //
+    __NR_linux_fstat,               //
+    __NR_linux_lstat,               //
+    __NR_linux_fstatat,             //
+    __NR_linux_access,              //
+    __NR_linux_faccessat,           //
+    __NR_linux_faccessat2,          //
+    __NR_linux_readlinkat,          //
+    __NR_linux_chmod | NOBITS,      //
+    __NR_linux_fchmod | NOBITS,     //
+    __NR_linux_fchmodat | NOBITS,   //
+};
+
+static const uint16_t kPledgeCpath[] = {
+    __NR_linux_open | CREATONLY,    //
+    __NR_linux_openat | CREATONLY,  //
+    __NR_linux_creat | RESTRICT,    //
+    __NR_linux_rename,              //
+    __NR_linux_renameat,            //
+    __NR_linux_renameat2,           //
+    __NR_linux_link,                //
+    __NR_linux_linkat,              //
+    __NR_linux_symlink,             //
+    __NR_linux_symlinkat,           //
+    __NR_linux_rmdir,               //
+    __NR_linux_unlink,              //
+    __NR_linux_unlinkat,            //
+    __NR_linux_mkdir,               //
+    __NR_linux_mkdirat,             //
+};
+
+static const uint16_t kPledgeDpath[] = {
+    __NR_linux_mknod,    //
+    __NR_linux_mknodat,  //
+};
+
+static const uint16_t kPledgeFattr[] = {
+    __NR_linux_chmod | NOBITS,     //
+    __NR_linux_fchmod | NOBITS,    //
+    __NR_linux_fchmodat | NOBITS,  //
+    __NR_linux_utime,              //
+    __NR_linux_utimes,             //
+    __NR_linux_futimesat,          //
+    __NR_linux_utimensat,          //
+};
+
+static const uint16_t kPledgeInet[] = {
+    __NR_linux_socket | INET,          //
+    __NR_linux_listen,                 //
+    __NR_linux_bind,                   //
+    __NR_linux_sendto,                 //
+    __NR_linux_connect,                //
+    __NR_linux_accept,                 //
+    __NR_linux_accept4,                //
+    __NR_linux_getsockopt | RESTRICT,  //
+    __NR_linux_setsockopt | RESTRICT,  //
+    __NR_linux_getpeername,            //
+    __NR_linux_getsockname,            //
+};
+
+static const uint16_t kPledgeUnix[] = {
+    __NR_linux_socket | UNIX,          //
+    __NR_linux_listen,                 //
+    __NR_linux_bind,                   //
+    __NR_linux_connect,                //
+    __NR_linux_sendto,                 //
+    __NR_linux_accept,                 //
+    __NR_linux_accept4,                //
+    __NR_linux_getsockopt | RESTRICT,  //
+    __NR_linux_setsockopt | RESTRICT,  //
+    __NR_linux_getpeername,            //
+    __NR_linux_getsockname,            //
+};
+
+static const uint16_t kPledgeDns[] = {
+    __NR_linux_socket | INET,      //
+    __NR_linux_bind,               //
+    __NR_linux_sendto,             //
+    __NR_linux_connect,            //
+    __NR_linux_recvfrom,           //
+    __NR_linux_fstatat,            //
+    __NR_linux_openat | READONLY,  //
+    __NR_linux_read,               //
+    __NR_linux_close,              //
+};
+
+static const uint16_t kPledgeTty[] = {
+    __NR_linux_ioctl | TTY,  //
+};
+
+static const uint16_t kPledgeRecvfd[] = {
+    __NR_linux_recvmsg,   //
+    __NR_linux_recvmmsg,  //
+};
+
+static const uint16_t kPledgeSendfd[] = {
+    __NR_linux_sendmsg,   //
+    __NR_linux_sendmmsg,  //
+};
+
+static const uint16_t kPledgeProc[] = {
+    __NR_linux_fork,                    //
+    __NR_linux_vfork,                   //
+    __NR_linux_clone | RESTRICT,        //
+    __NR_linux_kill,                    //
+    __NR_linux_setsid,                  //
+    __NR_linux_setpgid,                 //
+    __NR_linux_prlimit,                 //
+    __NR_linux_setrlimit,               //
+    __NR_linux_getpriority,             //
+    __NR_linux_setpriority,             //
+    __NR_linux_ioprio_get,              //
+    __NR_linux_ioprio_set,              //
+    __NR_linux_sched_getscheduler,      //
+    __NR_linux_sched_setscheduler,      //
+    __NR_linux_sched_get_priority_min,  //
+    __NR_linux_sched_get_priority_max,  //
+    __NR_linux_sched_getaffinity,       //
+    __NR_linux_sched_setaffinity,       //
+    __NR_linux_sched_getparam,          //
+    __NR_linux_sched_setparam,          //
+    __NR_linux_tkill,                   //
+    __NR_linux_tgkill,                  //
+};
+
+static const uint16_t kPledgeId[] = {
+    __NR_linux_setuid,       //
+    __NR_linux_setreuid,     //
+    __NR_linux_setresuid,    //
+    __NR_linux_setgid,       //
+    __NR_linux_setregid,     //
+    __NR_linux_setresgid,    //
+    __NR_linux_setgroups,    //
+    __NR_linux_prlimit,      //
+    __NR_linux_setrlimit,    //
+    __NR_linux_getpriority,  //
+    __NR_linux_setpriority,  //
+    __NR_linux_setfsuid,     //
+    __NR_linux_setfsgid,     //
+};
+
+static const uint16_t kPledgeSettime[] = {
+    __NR_linux_settimeofday,   //
+    __NR_linux_clock_adjtime,  //
+};
+
+static const uint16_t kPledgeProtExec[] = {
+    __NR_linux_mmap | EXEC,  //
+    __NR_linux_mprotect,     //
+};
+
+static const uint16_t kPledgeExec[] = {
+    __NR_linux_execve,    //
+    __NR_linux_execveat,  //
+};
+
+static const uint16_t kPledgeUnveil[] = {
+    __NR_linux_landlock_create_ruleset,  //
+    __NR_linux_landlock_add_rule,        //
+    __NR_linux_landlock_restrict_self,   //
+};
+
+// placeholder group
+//
+// pledge.com checks this to do auto-unveiling
+static const uint16_t kPledgeVminfo[] = {
+    __NR_linux_sched_yield,  //
+};
+
+// placeholder group
+//
+// pledge.com uses this to auto-unveil /tmp and $TMPPATH with rwc
+// permissions. pledge() alone (without unveil() too) offers very
+// little security here. consider using them together.
+static const uint16_t kPledgeTmppath[] = {
+    __NR_linux_lstat,     //
+    __NR_linux_unlink,    //
+    __NR_linux_unlinkat,  //
+};
+
+const struct Pledges kPledge[PROMISE_LEN_] = {
+    [PROMISE_STDIO] = {"stdio", PLEDGE(kPledgeStdio)},             //
+    [PROMISE_RPATH] = {"rpath", PLEDGE(kPledgeRpath)},             //
+    [PROMISE_WPATH] = {"wpath", PLEDGE(kPledgeWpath)},             //
+    [PROMISE_CPATH] = {"cpath", PLEDGE(kPledgeCpath)},             //
+    [PROMISE_DPATH] = {"dpath", PLEDGE(kPledgeDpath)},             //
+    [PROMISE_FLOCK] = {"flock", PLEDGE(kPledgeFlock)},             //
+    [PROMISE_FATTR] = {"fattr", PLEDGE(kPledgeFattr)},             //
+    [PROMISE_INET] = {"inet", PLEDGE(kPledgeInet)},                //
+    [PROMISE_UNIX] = {"unix", PLEDGE(kPledgeUnix)},                //
+    [PROMISE_DNS] = {"dns", PLEDGE(kPledgeDns)},                   //
+    [PROMISE_TTY] = {"tty", PLEDGE(kPledgeTty)},                   //
+    [PROMISE_RECVFD] = {"recvfd", PLEDGE(kPledgeRecvfd)},          //
+    [PROMISE_SENDFD] = {"sendfd", PLEDGE(kPledgeSendfd)},          //
+    [PROMISE_PROC] = {"proc", PLEDGE(kPledgeProc)},                //
+    [PROMISE_EXEC] = {"exec", PLEDGE(kPledgeExec)},                //
+    [PROMISE_ID] = {"id", PLEDGE(kPledgeId)},                      //
+    [PROMISE_UNVEIL] = {"unveil", PLEDGE(kPledgeUnveil)},          //
+    [PROMISE_SETTIME] = {"settime", PLEDGE(kPledgeSettime)},       //
+    [PROMISE_PROT_EXEC] = {"prot_exec", PLEDGE(kPledgeProtExec)},  //
+    [PROMISE_VMINFO] = {"vminfo", PLEDGE(kPledgeVminfo)},          //
+    [PROMISE_TMPPATH] = {"tmppath", PLEDGE(kPledgeTmppath)},       //
+};
+
+static const struct sock_filter kPledgeStart[] = {
+    // make sure this isn't an i386 binary or something
+    BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(arch)),
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
+    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
+    // each filter assumes ordinal is already loaded into accumulator
+    BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+    // forbid some system calls with ENOSYS (rather than EPERM)
+    BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, __NR_linux_memfd_secret, 5, 0),
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_rseq, 4, 0),
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_memfd_create, 3, 0),
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat2, 2, 0),
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_clone3, 1, 0),
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_statx, 0, 1),
+    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (Enosys & SECCOMP_RET_DATA)),
+};
+
+static const struct sock_filter kFilterIgnoreExitGroup[] = {
+    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_exit_group, 0, 1),
+    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (Eperm & SECCOMP_RET_DATA)),
+};
+
+static privileged unsigned long StrLen(const char *s) {
+  unsigned long n = 0;
+  while (*s++) ++n;
+  return n;
+}
+
+static privileged void *MemCpy(void *d, const void *s, unsigned long n) {
+  unsigned long i = 0;
+  for (; i < n; ++i) ((char *)d)[i] = ((char *)s)[i];
+  return (char *)d + n;
+}
+
+static privileged char *FixCpy(char p[17], uint64_t x, uint8_t k) {
+  while (k > 0) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
+  *p = '\0';
+  return p;
+}
+
+static privileged char *HexCpy(char p[17], uint64_t x) {
+  return FixCpy(p, x, ROUNDUP(x ? bsrl(x) + 1 : 1, 4));
+}
+
+static privileged int GetPid(void) {
+  int ax;
+  asm volatile("syscall"
+               : "=a"(ax)
+               : "0"(__NR_linux_getpid)
+               : "rcx", "r11", "memory");
+  return ax;
+}
+
+static privileged int GetTid(void) {
+  int ax;
+  asm volatile("syscall"
+               : "=a"(ax)
+               : "0"(__NR_linux_gettid)
+               : "rcx", "r11", "memory");
+  return ax;
+}
+
+static privileged void Log(const char *s, ...) {
+  int ax;
+  va_list va;
+  va_start(va, s);
+  do {
+    asm volatile("syscall"
+                 : "=a"(ax)
+                 : "0"(__NR_linux_write), "D"(2), "S"(s), "d"(StrLen(s))
+                 : "rcx", "r11", "memory");
+  } while ((s = va_arg(va, const char *)));
+  va_end(va);
+}
+
+static privileged int Prctl(int op, long a, void *b, long c, long d) {
+  int rc;
+  va_list va;
+  asm volatile("mov\t%5,%%r10\n\t"
+               "mov\t%6,%%r8\n\t"
+               "syscall"
+               : "=a"(rc)
+               : "0"(__NR_linux_prctl), "D"(op), "S"(a), "d"(b), "g"(c), "g"(d)
+               : "rcx", "r8", "r10", "r11", "memory");
+  return rc;
+}
+
+static privileged int SigAction(int sig, struct sigaction *act,
+                                struct sigaction *old) {
+  int ax;
+  act->sa_flags |= Sa_Restorer;
+  act->sa_restorer = &__restore_rt;
+  asm volatile("mov\t%5,%%r10\n\t"
+               "syscall"
+               : "=a"(ax)
+               : "0"(__NR_linux_sigaction), "D"(sig), "S"(act), "d"(old), "g"(8)
+               : "rcx", "r10", "r11", "memory");
+  return ax;
+}
+
+static privileged int SigProcMask(int how, int64_t set, int64_t *old) {
+  int ax;
+  asm volatile("mov\t%5,%%r10\n\t"
+               "syscall"
+               : "=a"(ax)
+               : "0"(__NR_linux_sigprocmask), "D"(how), "S"(&set), "d"(old),
+                 "g"(8)
+               : "rcx", "r10", "r11", "memory");
+  return ax;
+}
+
+static privileged void KillThisProcess(void) {
+  int ax;
+  struct sigaction dfl = {.sa_sigaction = SIG_DFL};
+  if (!SigAction(Sigabrt, &dfl, 0)) {
+    SigProcMask(Sig_Setmask, -1, 0);
+    asm volatile("syscall"
+                 : "=a"(ax)
+                 : "0"(__NR_linux_kill), "D"(GetPid()), "S"(Sigabrt)
+                 : "rcx", "r11", "memory");
+    SigProcMask(Sig_Setmask, 0, 0);
+  }
+  asm volatile("syscall"
+               : "=a"(ax)
+               : "0"(__NR_linux_exit_group), "D"(128 + Sigabrt)
+               : "rcx", "r11", "memory");
+}
+
+static privileged void KillThisThread(void) {
+  int ax;
+  struct sigaction dfl = {.sa_sigaction = SIG_DFL};
+  if (!SigAction(Sigabrt, &dfl, 0)) {
+    SigProcMask(Sig_Setmask, -1, 0);
+    asm volatile("syscall"
+                 : "=a"(ax)
+                 : "0"(__NR_linux_tkill), "D"(GetTid()), "S"(Sigabrt)
+                 : "rcx", "r11", "memory");
+    SigProcMask(Sig_Setmask, 0, 0);
+  }
+  asm volatile("syscall"
+               : /* no outputs */
+               : "a"(__NR_linux_exit), "D"(128 + Sigabrt)
+               : "rcx", "r11", "memory");
+}
+
+static privileged bool HasSyscall(struct Pledges *p, uint16_t n) {
+  int i;
+  for (i = 0; i < p->len; ++i) {
+    if ((p->syscalls[i] & 0x0fff) == n) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static privileged void OnSigSys(int sig, siginfo_t *si, ucontext_t *ctx) {
+  int i;
+  bool found;
+  char ord[17], rip[17];
+  enum PledgeMode mode = si->si_errno;
+  ctx->uc_mcontext.rax = -Eperm;
+  FixCpy(ord, si->si_syscall, 12);
+  HexCpy(rip, ctx->uc_mcontext.rip);
+  for (found = i = 0; i < ARRAYLEN(kPledge); ++i) {
+    if (HasSyscall(kPledge + i, si->si_syscall)) {
+      Log("error: has not pledged ", kPledge[i].name,  //
+          " (ord=", ord, " rip=", rip, ")\n", 0);
+      found = true;
+      break;
+    }
+  }
+  if (!found) {
+    Log("error: unsupported syscall (ord=", ord, " rip=", rip, ")\n", 0);
+  }
+  switch (mode) {
+    case kPledgeModeKillProcess:
+      KillThisProcess();
+      // fallthrough
+    case kPledgeModeKillThread:
+      KillThisThread();
+      unreachable;
+    default:
+      break;
+  }
+}
+
+static privileged void MonitorSigSys(void) {
+  int ax;
+  struct sigaction sa = {
+      .sa_sigaction = OnSigSys,
+      .sa_flags = Sa_Siginfo | Sa_Restart,
+  };
+  // we block changing sigsys once pledge is installed
+  // so we aren't terribly concerned if this will fail
+  SigAction(Sigsys, &sa, 0);
+}
+
+static privileged void AppendFilter(struct Filter *f, struct sock_filter *p,
+                                    size_t n) {
+  if (UNLIKELY(f->n + n > ARRAYLEN(f->p))) {
+    AbortPledge("need to increase array size");
+  }
+  MemCpy(f->p + f->n, p, n * sizeof(*f->p));
+  f->n += n;
+}
+
+// The following system calls are allowed:
+//
+//   - write(2) to allow logging
+//   - kill(getpid(), SIGABRT) to abort process
+//   - tkill(gettid(), SIGABRT) to abort thread
+//   - sigaction(SIGABRT) to force default signal handler
+//   - sigprocmask() to force signal delivery
+//
+static privileged void AllowMonitor(struct Filter *f) {
+  struct sock_filter fragment[] = {
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_write, 0, 4),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 1),
+      BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_kill, 0, 6),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, GetPid(), 0, 3),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, Sigabrt, 0, 1),
+      BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_tkill, 0, 6),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, GetTid(), 0, 3),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, Sigabrt, 0, 1),
+      BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_sigaction, 0, 4),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, Sigabrt, 0, 1),
+      BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_sigprocmask, 0, 1),
+      BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// SYSCALL is only allowed in the .privileged section
+// We assume program image is loaded in 32-bit spaces
+static privileged void AppendOriginVerification(struct Filter *f) {
+  long x = (long)__privileged_start;
+  long y = (long)__privileged_end;
+  struct sock_filter fragment[] = {
+      /*L0*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer) + 4),
+      /*L1*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 2),
+      /*L2*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer)),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, x, 0, 5 - 4),
+      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, y, 0, 6 - 5),
+      /*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
+      /*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L7*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The first argument of sys_clone_linux() must NOT have:
+//
+//   - CLONE_NEWNS    (0x00020000)
+//   - CLONE_PTRACE   (0x00002000)
+//   - CLONE_UNTRACED (0x00800000)
+//
+static privileged void AllowCloneRestrict(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_clone, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x00822000),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The first argument of sys_clone_linux() must have:
+//
+//   - CLONE_VM       (0x00000100)
+//   - CLONE_FS       (0x00000200)
+//   - CLONE_FILES    (0x00000400)
+//   - CLONE_THREAD   (0x00010000)
+//   - CLONE_SIGHAND  (0x00000800)
+//
+// The first argument of sys_clone_linux() must NOT have:
+//
+//   - CLONE_NEWNS    (0x00020000)
+//   - CLONE_PTRACE   (0x00002000)
+//   - CLONE_UNTRACED (0x00800000)
+//
+static privileged void AllowCloneThread(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_clone, 0, 9 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x00010f00),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x00010f00, 0, 8 - 4),
+      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x00822000),
+      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L9*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The second argument of ioctl() must be one of:
+//
+//   - FIONREAD (0x541b)
+//   - FIONBIO  (0x5421)
+//   - FIOCLEX  (0x5451)
+//   - FIONCLEX (0x5450)
+//
+static privileged void AllowIoctlStdio(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_ioctl, 0, 8 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x541b, 3, 0),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5421, 2, 0),
+      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5451, 1, 0),
+      /*L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5450, 0, 1),
+      /*L6*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L8*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The second argument of ioctl() must be one of:
+//
+//   - TCGETS     (0x5401)
+//   - TCSETS     (0x5402)
+//   - TCSETSW    (0x5403)
+//   - TCSETSF    (0x5404)
+//   - TIOCGWINSZ (0x5413)
+//   - TIOCSPGRP  (0x5410)
+//   - TIOCGPGRP  (0x540f)
+//   - TIOCSWINSZ (0x5414)
+//   - TCFLSH     (0x540b)
+//   - TCXONC     (0x540a)
+//   - TCSBRK     (0x5409)
+//   - TIOCSBRK   (0x5427)
+//
+static privileged void AllowIoctlTty(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_ioctl, 0, 16 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5401, 11, 0),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5402, 10, 0),
+      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5403, 9, 0),
+      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5404, 8, 0),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5413, 7, 0),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5410, 6, 0),
+      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x540f, 5, 0),
+      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5414, 4, 0),
+      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x540b, 3, 0),
+      /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x540a, 2, 0),
+      /*L12*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5409, 1, 0),
+      /*L13*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5427, 0, 1),
+      /*L14*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L15*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L16*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The level argument of setsockopt() must be one of:
+//
+//   - SOL_IP     (0)
+//   - SOL_SOCKET (1)
+//   - SOL_TCP    (6)
+//
+// The optname argument of setsockopt() must be one of:
+//
+//   - TCP_NODELAY          (0x01)
+//   - TCP_CORK             (0x03)
+//   - TCP_KEEPIDLE         (0x04)
+//   - TCP_KEEPINTVL        (0x05)
+//   - SO_TYPE              (0x03)
+//   - SO_ERROR             (0x04)
+//   - SO_DONTROUTE         (0x05)
+//   - SO_REUSEPORT         (0x0f)
+//   - SO_REUSEADDR         (0x02)
+//   - SO_KEEPALIVE         (0x09)
+//   - SO_RCVTIMEO          (0x14)
+//   - SO_SNDTIMEO          (0x15)
+//   - IP_RECVTTL           (0x0c)
+//   - IP_RECVERR           (0x0b)
+//   - TCP_FASTOPEN         (0x17)
+//   - TCP_FASTOPEN_CONNECT (0x1e)
+//
+static privileged void AllowSetsockoptRestrict(struct Filter *f) {
+  static const int nr = __NR_linux_setsockopt;
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 21 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 2, 0),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
+      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 0, 20 - 5),
+      /* L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0f, 13, 0),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x03, 12, 0),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0c, 11, 0),
+      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x13, 10, 0),
+      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 9, 0),
+      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x09, 8, 0),
+      /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x14, 7, 0),
+      /*L12*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x01, 6, 0),
+      /*L13*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0b, 5, 0),
+      /*L14*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x04, 4, 0),
+      /*L15*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x05, 3, 0),
+      /*L16*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x17, 2, 0),
+      /*L17*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x1e, 1, 0),
+      /*L18*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x15, 0, 1),
+      /*L19*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L20*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L21*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The level argument of getsockopt() must be one of:
+//
+//   - SOL_SOCKET (1)
+//   - SOL_TCP    (6)
+//
+// The optname argument of getsockopt() must be one of:
+//
+//   - SO_TYPE      (0x03)
+//   - SO_REUSEPORT (0x0f)
+//   - SO_REUSEADDR (0x02)
+//   - SO_KEEPALIVE (0x09)
+//   - SO_RCVTIMEO  (0x14)
+//   - SO_SNDTIMEO  (0x15)
+//
+static privileged void AllowGetsockoptRestrict(struct Filter *f) {
+  static const int nr = __NR_linux_getsockopt;
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 13 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 0, 12 - 4),
+      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x03, 5, 0),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0f, 4, 0),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 3, 0),
+      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x09, 2, 0),
+      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x14, 1, 0),
+      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x15, 0, 1),
+      /*L11*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L12*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L13*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The flags parameter of mmap() must not have:
+//
+//   - MAP_LOCKED   (0x02000)
+//   - MAP_NONBLOCK (0x10000)
+//   - MAP_HUGETLB  (0x40000)
+//
+static privileged void AllowMmapExec(struct Filter *f) {
+  long y = (long)__privileged_end;
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])),  // flags
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x52000),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 4),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The prot parameter of mmap() may only have:
+//
+//   - PROT_NONE  (0)
+//   - PROT_READ  (1)
+//   - PROT_WRITE (2)
+//
+// The flags parameter must not have:
+//
+//   - MAP_LOCKED   (0x02000)
+//   - MAP_POPULATE (0x08000)
+//   - MAP_NONBLOCK (0x10000)
+//   - MAP_HUGETLB  (0x40000)
+//
+static privileged void AllowMmapNoexec(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 9 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),  // prot
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 4),
+      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])),  // flags
+      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x5a000),
+      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L9*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The prot parameter of mprotect() may only have:
+//
+//   - PROT_NONE  (0)
+//   - PROT_READ  (1)
+//   - PROT_WRITE (2)
+//
+static privileged void AllowMprotectNoexec(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mprotect, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),  // prot
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The open() system call is permitted only when
+//
+//   - (flags & O_ACCMODE) == O_RDONLY
+//
+// The flags parameter of open() must not have:
+//
+//   - O_CREAT     (000000100)
+//   - O_TRUNC     (000001000)
+//   - __O_TMPFILE (020000000)
+//
+static privileged void AllowOpenReadonly(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_open, 0, 9 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDONLY, 0, 8 - 4),
+      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020001100),
+      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L9*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The open() system call is permitted only when
+//
+//   - (flags & O_ACCMODE) == O_RDONLY
+//
+// The flags parameter of open() must not have:
+//
+//   - O_CREAT     (000000100)
+//   - O_TRUNC     (000001000)
+//   - __O_TMPFILE (020000000)
+//
+static privileged void AllowOpenatReadonly(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat, 0, 9 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDONLY, 0, 8 - 4),
+      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020001100),
+      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L9*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The open() system call is permitted only when
+//
+//   - (flags & O_ACCMODE) == O_WRONLY
+//   - (flags & O_ACCMODE) == O_RDWR
+//
+// The open() flags parameter must not contain
+//
+//   - O_CREAT     (000000100)
+//   - __O_TMPFILE (020000000)
+//
+static privileged void AllowOpenWriteonly(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_open, 0, 10 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_WRONLY, 1, 0),
+      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDWR, 0, 9 - 5),
+      /* L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L6*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020000100),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /* L8*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /* L9*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L10*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The open() system call is permitted only when
+//
+//   - (flags & O_ACCMODE) == O_WRONLY
+//   - (flags & O_ACCMODE) == O_RDWR
+//
+// The openat() flags parameter must not contain
+//
+//   - O_CREAT     (000000100)
+//   - __O_TMPFILE (020000000)
+//
+static privileged void AllowOpenatWriteonly(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat, 0, 10 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_WRONLY, 1, 0),
+      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDWR, 0, 9 - 5),
+      /* L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L6*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020000100),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /* L8*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /* L9*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L10*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// If the flags parameter of open() has one of:
+//
+//   - O_CREAT     (000000100)
+//   - __O_TMPFILE (020000000)
+//
+// Then the mode parameter must not have:
+//
+//   - S_ISVTX (01000 sticky)
+//   - S_ISGID (02000 setgid)
+//   - S_ISUID (04000 setuid)
+//
+static privileged void AllowOpenCreatonly(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_open, 0, 12 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 000000100),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 000000100, 7 - 4, 0),
+      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020200000),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 020200000, 0, 10 - 7),
+      /* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L8*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
+      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L10*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L11*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L12*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// If the flags parameter of openat() has one of:
+//
+//   - O_CREAT     (000000100)
+//   - __O_TMPFILE (020000000)
+//
+// Then the mode parameter must not have:
+//
+//   - S_ISVTX (01000 sticky)
+//   - S_ISGID (02000 setgid)
+//   - S_ISUID (04000 setuid)
+//
+static privileged void AllowOpenatCreatonly(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat, 0, 12 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 000000100),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 000000100, 7 - 4, 0),
+      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020200000),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 020200000, 0, 10 - 7),
+      /* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])),
+      /* L8*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
+      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L10*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L11*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L12*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// Then the mode parameter must not have:
+//
+//   - S_ISVTX (01000 sticky)
+//   - S_ISGID (02000 setgid)
+//   - S_ISUID (04000 setuid)
+//
+static privileged void AllowCreatRestrict(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_creat, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The second argument of fcntl() must be one of:
+//
+//   - F_DUPFD (0)
+//   - F_DUPFD_CLOEXEC (1030)
+//   - F_GETFD (1)
+//   - F_SETFD (2)
+//   - F_GETFL (3)
+//   - F_SETFL (4)
+//
+static privileged void AllowFcntlStdio(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fcntl, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1030, 4 - 3, 0),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 5, 5 - 4, 0),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The second argument of fcntl() must be one of:
+//
+//   - F_GETLK (5)
+//   - F_SETLK (6)
+//   - F_SETLKW (7)
+//
+static privileged void AllowFcntlLock(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fcntl, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 5, 0, 5 - 3),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 8, 5 - 4, 0),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The addr parameter of sendto() must be
+//
+//   - NULL
+//
+static privileged void AllowSendtoAddrless(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_sendto, 0, 7 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4]) + 0),
+      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 3),
+      /*L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4]) + 4),
+      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 5),
+      /*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L7*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The sig parameter of sigaction() must NOT be
+//
+//   - SIGSYS (31) [always eperm]
+//
+static privileged void AllowSigactionNosigsys(struct Filter *f) {
+  static const int nr = __NR_linux_sigaction;
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 31, 0, 1),
+      /*L3*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | Eperm),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The family parameter of socket() must be one of:
+//
+//   - AF_INET  (0x02)
+//   - AF_INET6 (0x0a)
+//
+// The type parameter of socket() will ignore:
+//
+//   - SOCK_CLOEXEC  (0x80000)
+//   - SOCK_NONBLOCK (0x00800)
+//
+// The type parameter of socket() must be one of:
+//
+//   - SOCK_STREAM (0x01)
+//   - SOCK_DGRAM  (0x02)
+//
+// The protocol parameter of socket() must be one of:
+//
+//   - 0
+//   - IPPROTO_ICMP (0x01)
+//   - IPPROTO_TCP  (0x06)
+//   - IPPROTO_UDP  (0x11)
+//
+static privileged void AllowSocketInet(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 15 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 1, 0),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0a, 0, 14 - 4),
+      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x01, 1, 0),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 0, 14 - 8),
+      /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x00, 3, 0),
+      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x01, 2, 0),
+      /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x06, 1, 0),
+      /*L12*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x11, 0, 1),
+      /*L13*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L14*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L15*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The family parameter of socket() must be one of:
+//
+//   - AF_UNIX (1)
+//   - AF_LOCAL (1)
+//
+// The type parameter of socket() will ignore:
+//
+//   - SOCK_CLOEXEC  (0x80000)
+//   - SOCK_NONBLOCK (0x00800)
+//
+// The type parameter of socket() must be one of:
+//
+//   - SOCK_STREAM (1)
+//   - SOCK_DGRAM  (2)
+//
+// The protocol parameter of socket() must be one of:
+//
+//   - 0
+//
+static privileged void AllowSocketUnix(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 11 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 0, 10 - 3),
+      /* L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800),
+      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 10 - 7),
+      /* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /* L9*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L10*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L11*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The first parameter of prctl() can be any of
+//
+//   - PR_SET_NAME         (15)
+//   - PR_GET_NAME         (16)
+//   - PR_GET_SECCOMP      (21)
+//   - PR_SET_SECCOMP      (22)
+//   - PR_SET_NO_NEW_PRIVS (38)
+//   - PR_CAPBSET_READ     (23)
+//   - PR_CAPBSET_DROP     (24)
+//
+static privileged void AllowPrctlStdio(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prctl, 0, 11 - 1),
+      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
+      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 15, 6, 0),
+      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 16, 5, 0),
+      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 21, 4, 0),
+      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 3, 0),
+      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 23, 2, 0),
+      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 24, 1, 0),
+      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 38, 0, 1),
+      /* L9*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L10*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L11*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The mode parameter of chmod() can't have the following:
+//
+//   - S_ISVTX (01000 sticky)
+//   - S_ISGID (02000 setgid)
+//   - S_ISUID (04000 setuid)
+//
+static privileged void AllowChmodNobits(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_chmod, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The mode parameter of fchmod() can't have the following:
+//
+//   - S_ISVTX (01000 sticky)
+//   - S_ISGID (02000 setgid)
+//   - S_ISUID (04000 setuid)
+//
+static privileged void AllowFchmodNobits(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fchmod, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The mode parameter of fchmodat() can't have the following:
+//
+//   - S_ISVTX (01000 sticky)
+//   - S_ISGID (02000 setgid)
+//   - S_ISUID (04000 setuid)
+//
+static privileged void AllowFchmodatNobits(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fchmodat, 0, 6 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
+      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L6*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+// The new_limit parameter of prlimit() must be
+//
+//   - NULL (0)
+//
+static privileged void AllowPrlimitStdio(struct Filter *f) {
+  static const struct sock_filter fragment[] = {
+      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prlimit, 0, 7 - 1),
+      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
+      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 3),
+      /*L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2]) + 4),
+      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
+      /*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      /*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+      /*L7*/ /* next filter */
+  };
+  AppendFilter(f, PLEDGE(fragment));
+}
+
+static privileged int CountUnspecial(const uint16_t *p, size_t len) {
+  int i, count;
+  for (count = i = 0; i < len; ++i) {
+    if (!(p[i] & SPECIAL)) {
+      ++count;
+    }
+  }
+  return count;
+}
+
+static privileged void AppendPledge(struct Filter *f,   //
+                                    const uint16_t *p,  //
+                                    size_t len) {       //
+  int i, j, count;
+
+  // handle ordinals which allow syscalls regardless of args
+  // we put in extra effort here to reduce num of bpf instrs
+  if ((count = CountUnspecial(p, len))) {
+    if (count < 256) {
+      for (j = i = 0; i < len; ++i) {
+        if (p[i] & SPECIAL) continue;
+        // jump to ALLOW rule below if accumulator equals ordinal
+        struct sock_filter fragment[] = {
+            BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,  // instruction
+                     p[i],                       // operand
+                     count - j - 1,              // jump if true displacement
+                     j == count - 1),            // jump if false displacement
+        };
+        AppendFilter(f, PLEDGE(fragment));
+        ++j;
+      }
+      struct sock_filter fragment[] = {
+          BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
+      };
+      AppendFilter(f, PLEDGE(fragment));
+    } else {
+      AbortPledge("list of ordinals exceeds max displacement");
+    }
+  }
+
+  // handle "special" ordinals which use hand-crafted bpf
+  for (i = 0; i < len; ++i) {
+    if (!(p[i] & SPECIAL)) continue;
+    switch (p[i]) {
+      case __NR_linux_mmap | EXEC:
+        AllowMmapExec(f);
+        break;
+      case __NR_linux_mmap | NOEXEC:
+        AllowMmapNoexec(f);
+        break;
+      case __NR_linux_mprotect | NOEXEC:
+        AllowMprotectNoexec(f);
+        break;
+      case __NR_linux_chmod | NOBITS:
+        AllowChmodNobits(f);
+        break;
+      case __NR_linux_fchmod | NOBITS:
+        AllowFchmodNobits(f);
+        break;
+      case __NR_linux_fchmodat | NOBITS:
+        AllowFchmodatNobits(f);
+        break;
+      case __NR_linux_sigaction | NOSIGSYS:
+        AllowSigactionNosigsys(f);
+        break;
+      case __NR_linux_prctl | STDIO:
+        AllowPrctlStdio(f);
+        break;
+      case __NR_linux_open | CREATONLY:
+        AllowOpenCreatonly(f);
+        break;
+      case __NR_linux_openat | CREATONLY:
+        AllowOpenatCreatonly(f);
+        break;
+      case __NR_linux_open | READONLY:
+        AllowOpenReadonly(f);
+        break;
+      case __NR_linux_openat | READONLY:
+        AllowOpenatReadonly(f);
+        break;
+      case __NR_linux_open | WRITEONLY:
+        AllowOpenWriteonly(f);
+        break;
+      case __NR_linux_openat | WRITEONLY:
+        AllowOpenatWriteonly(f);
+        break;
+      case __NR_linux_setsockopt | RESTRICT:
+        AllowSetsockoptRestrict(f);
+        break;
+      case __NR_linux_getsockopt | RESTRICT:
+        AllowGetsockoptRestrict(f);
+        break;
+      case __NR_linux_creat | RESTRICT:
+        AllowCreatRestrict(f);
+        break;
+      case __NR_linux_fcntl | STDIO:
+        AllowFcntlStdio(f);
+        break;
+      case __NR_linux_fcntl | LOCK:
+        AllowFcntlLock(f);
+        break;
+      case __NR_linux_ioctl | RESTRICT:
+        AllowIoctlStdio(f);
+        break;
+      case __NR_linux_ioctl | TTY:
+        AllowIoctlTty(f);
+        break;
+      case __NR_linux_socket | INET:
+        AllowSocketInet(f);
+        break;
+      case __NR_linux_socket | UNIX:
+        AllowSocketUnix(f);
+        break;
+      case __NR_linux_sendto | ADDRLESS:
+        AllowSendtoAddrless(f);
+        break;
+      case __NR_linux_clone | RESTRICT:
+        AllowCloneRestrict(f);
+        break;
+      case __NR_linux_clone | THREAD:
+        AllowCloneThread(f);
+        break;
+      case __NR_linux_prlimit | STDIO:
+        AllowPrlimitStdio(f);
+        break;
+      default:
+        AbortPledge("switch forgot to define a special ordinal");
+    }
+  }
+}
+
+/**
+ * Installs SECCOMP BPF filter on Linux thread.
+ *
+ * @param ipromises is inverted integer bitmask of pledge() promises
+ * @param mode configures the course of action on sandbox violations
+ * @param want_msyscall if set will cause syscall origin checking to be
+ *     enabled, but only if `exec` hasn't been pledged
+ * @return 0 on success, or negative error number on error
+ * @asyncsignalsafe
+ * @threadsafe
+ * @vforksafe
+ */
+privileged int sys_pledge_linux(unsigned long ipromises,  //
+                                enum PledgeMode mode,     //
+                                bool want_msyscall) {     //
+  int i, rc = -1;
+  struct Filter f;
+  struct sock_filter sf[1] = {BPF_STMT(BPF_RET | BPF_K, 0)};
+  CheckLargeStackAllocation(&f, sizeof(f));
+  f.n = 0;
+
+  // set up the seccomp filter
+  AppendFilter(&f, PLEDGE(kPledgeStart));
+  if (ipromises == -1) {
+    // if we're pledging empty string, then avoid triggering a sigsys
+    // when _Exit() gets called since we need to fallback to _Exit1()
+    AppendFilter(&f, PLEDGE(kFilterIgnoreExitGroup));
+  }
+  if (want_msyscall && !(~ipromises & (1ul << PROMISE_EXEC))) {
+    AppendOriginVerification(&f);
+  }
+  AppendPledge(&f, PLEDGE(kPledgeDefault));
+  for (i = 0; i < ARRAYLEN(kPledge); ++i) {
+    if (~ipromises & (1ul << i)) {
+      AppendPledge(&f, kPledge[i].syscalls, kPledge[i].len);
+    }
+  }
+
+  // now determine what we'll do on sandbox violations
+  if (~ipromises & (1ul << PROMISE_EXEC)) {
+    // our sigsys error message handler can't be inherited across
+    // execve() boundaries so if you've pledged exec then that'll
+    // mean no error messages for you.
+    switch (mode) {
+      case kPledgeModeKillThread:
+        sf[0].k = SECCOMP_RET_KILL_THREAD;
+        break;
+      case kPledgeModeKillProcess:
+        sf[0].k = SECCOMP_RET_KILL_PROCESS;
+        break;
+      case kPledgeModeErrno:
+        sf[0].k = SECCOMP_RET_ERRNO | Eperm;
+        break;
+      default:
+        unreachable;
+    }
+    AppendFilter(&f, PLEDGE(sf));
+  } else {
+    // if we haven't pledged exec, then we can monitor SIGSYS
+    // and print a helpful error message when things do break
+    // to avoid tls / static memory, we embed mode within bpf
+    MonitorSigSys();
+    AllowMonitor(&f);
+    sf[0].k = SECCOMP_RET_TRAP | (mode & SECCOMP_RET_DATA);
+    AppendFilter(&f, PLEDGE(sf));
+  }
+
+  // register our seccomp filter with the kernel
+  if ((rc = Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) != -1) {
+    struct sock_fprog sandbox = {.len = f.n, .filter = f.p};
+    rc = Prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &sandbox, 0, 0);
+  }
+
+  return rc;
+}
diff --git a/libc/calls/pledge.c b/libc/calls/pledge.c
index 77b2e50e9..4232e5fec 100644
--- a/libc/calls/pledge.c
+++ b/libc/calls/pledge.c
@@ -16,1518 +16,57 @@
 │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
 │ PERFORMANCE OF THIS SOFTWARE.                                                │
 ╚─────────────────────────────────────────────────────────────────────────────*/
-#include "libc/assert.h"
-#include "libc/bits/likely.h"
 #include "libc/calls/calls.h"
+#include "libc/calls/pledge.internal.h"
+#include "libc/calls/state.internal.h"
 #include "libc/calls/strace.internal.h"
-#include "libc/calls/struct/bpf.h"
-#include "libc/calls/struct/filter.h"
-#include "libc/calls/struct/seccomp.h"
-#include "libc/calls/struct/sigaction.h"
 #include "libc/calls/syscall-sysv.internal.h"
-#include "libc/fmt/itoa.h"
-#include "libc/intrin/kprintf.h"
+#include "libc/dce.h"
+#include "libc/errno.h"
 #include "libc/intrin/promises.internal.h"
-#include "libc/intrin/spinlock.h"
-#include "libc/limits.h"
-#include "libc/macros.internal.h"
-#include "libc/nexgen32e/bsr.h"
-#include "libc/nexgen32e/threaded.h"
 #include "libc/runtime/runtime.h"
-#include "libc/runtime/stack.h"
-#include "libc/str/str.h"
-#include "libc/sysv/consts/audit.h"
-#include "libc/sysv/consts/kern.h"
-#include "libc/sysv/consts/nrlinux.h"
-#include "libc/sysv/consts/o.h"
-#include "libc/sysv/consts/pr.h"
-#include "libc/sysv/consts/prot.h"
-#include "libc/sysv/consts/sa.h"
-#include "libc/sysv/consts/sig.h"
 #include "libc/sysv/errfuns.h"
 
-#define SPECIAL   0xf000
-#define ADDRLESS  0x2000
-#define INET      0x8000
-#define LOCK      0x4000
-#define NOEXEC    0x8000
-#define EXEC      0x4000
-#define READONLY  0x8000
-#define WRITEONLY 0x4000
-#define CREATONLY 0x2000
-#define STDIO     0x8000
-#define THREAD    0x8000
-#define TTY       0x8000
-#define UNIX      0x4000
-#define NOBITS    0x8000
-#define NOSIGSYS  0x8000
-#define RESTRICT  0x1000
-
-// TODO(jart): fix chibicc
-#ifdef __chibicc__
-#define OFF(f) -1
-#else
-#define OFF(f) offsetof(struct seccomp_data, f)
-#endif
-
-#define PLEDGE(pledge) pledge, ARRAYLEN(pledge)
-
-#define AbortPledge(reason) \
-  do {                      \
-    assert(!reason);        \
-    asm("hlt");             \
-    unreachable;            \
-  } while (0)
-
-struct Filter {
-  size_t n;
-  struct sock_filter p[700];
-};
-
-static const uint16_t kPledgeLinuxDefault[] = {
-    __NR_linux_exit,  // thread return / exit()
-};
-
-// the stdio contains all the benign system calls. openbsd makes the
-// assumption that preexisting file descriptors are trustworthy. we
-// implement checking for these as a simple linear scan rather than
-// binary search, since there doesn't appear to be any measurable
-// difference in the latency of sched_yield() if it's at the start of
-// the bpf script or the end.
-static const uint16_t kPledgeLinuxStdio[] = {
-    __NR_linux_sigreturn,             //
-    __NR_linux_restart_syscall,       //
-    __NR_linux_exit_group,            //
-    __NR_linux_sched_yield,           //
-    __NR_linux_sched_getaffinity,     //
-    __NR_linux_clock_getres,          //
-    __NR_linux_clock_gettime,         //
-    __NR_linux_clock_nanosleep,       //
-    __NR_linux_close_range,           //
-    __NR_linux_close,                 //
-    __NR_linux_write,                 //
-    __NR_linux_writev,                //
-    __NR_linux_pwrite,                //
-    __NR_linux_pwritev,               //
-    __NR_linux_pwritev2,              //
-    __NR_linux_read,                  //
-    __NR_linux_readv,                 //
-    __NR_linux_pread,                 //
-    __NR_linux_preadv,                //
-    __NR_linux_preadv2,               //
-    __NR_linux_dup,                   //
-    __NR_linux_dup2,                  //
-    __NR_linux_dup3,                  //
-    __NR_linux_fchdir,                //
-    __NR_linux_fcntl | STDIO,         //
-    __NR_linux_fstat,                 //
-    __NR_linux_fsync,                 //
-    __NR_linux_sysinfo,               //
-    __NR_linux_fdatasync,             //
-    __NR_linux_ftruncate,             //
-    __NR_linux_getdents,              //
-    __NR_linux_getrandom,             //
-    __NR_linux_getgroups,             //
-    __NR_linux_getpgid,               //
-    __NR_linux_getpgrp,               //
-    __NR_linux_getpid,                //
-    __NR_linux_gettid,                //
-    __NR_linux_getuid,                //
-    __NR_linux_getgid,                //
-    __NR_linux_getsid,                //
-    __NR_linux_getppid,               //
-    __NR_linux_geteuid,               //
-    __NR_linux_getegid,               //
-    __NR_linux_getrlimit,             //
-    __NR_linux_getresgid,             //
-    __NR_linux_getresuid,             //
-    __NR_linux_getitimer,             //
-    __NR_linux_setitimer,             //
-    __NR_linux_timerfd_create,        //
-    __NR_linux_timerfd_settime,       //
-    __NR_linux_timerfd_gettime,       //
-    __NR_linux_copy_file_range,       //
-    __NR_linux_gettimeofday,          //
-    __NR_linux_sendfile,              //
-    __NR_linux_vmsplice,              //
-    __NR_linux_splice,                //
-    __NR_linux_lseek,                 //
-    __NR_linux_tee,                   //
-    __NR_linux_brk,                   //
-    __NR_linux_msync,                 //
-    __NR_linux_mmap | NOEXEC,         //
-    __NR_linux_mremap,                //
-    __NR_linux_munmap,                //
-    __NR_linux_mincore,               //
-    __NR_linux_madvise,               //
-    __NR_linux_fadvise,               //
-    __NR_linux_mprotect | NOEXEC,     //
-    __NR_linux_arch_prctl,            //
-    __NR_linux_migrate_pages,         //
-    __NR_linux_sync_file_range,       //
-    __NR_linux_set_tid_address,       //
-    __NR_linux_nanosleep,             //
-    __NR_linux_pipe,                  //
-    __NR_linux_pipe2,                 //
-    __NR_linux_poll,                  //
-    __NR_linux_ppoll,                 //
-    __NR_linux_select,                //
-    __NR_linux_pselect6,              //
-    __NR_linux_epoll_create,          //
-    __NR_linux_epoll_create1,         //
-    __NR_linux_epoll_ctl,             //
-    __NR_linux_epoll_wait,            //
-    __NR_linux_epoll_pwait,           //
-    __NR_linux_epoll_pwait2,          //
-    __NR_linux_recvfrom,              //
-    __NR_linux_sendto | ADDRLESS,     //
-    __NR_linux_ioctl | RESTRICT,      //
-    __NR_linux_alarm,                 //
-    __NR_linux_pause,                 //
-    __NR_linux_shutdown,              //
-    __NR_linux_eventfd,               //
-    __NR_linux_eventfd2,              //
-    __NR_linux_signalfd,              //
-    __NR_linux_signalfd4,             //
-    __NR_linux_sigaction | NOSIGSYS,  //
-    __NR_linux_sigaltstack,           //
-    __NR_linux_sigprocmask,           //
-    __NR_linux_sigsuspend,            //
-    __NR_linux_sigpending,            //
-    __NR_linux_socketpair,            //
-    __NR_linux_getrusage,             //
-    __NR_linux_times,                 //
-    __NR_linux_umask,                 //
-    __NR_linux_wait4,                 //
-    __NR_linux_uname,                 //
-    __NR_linux_prctl | STDIO,         //
-    __NR_linux_clone | THREAD,        //
-    __NR_linux_futex,                 //
-    __NR_linux_set_robust_list,       //
-    __NR_linux_get_robust_list,       //
-    __NR_linux_prlimit | STDIO,       //
-};
-
-static const uint16_t kPledgeLinuxFlock[] = {
-    __NR_linux_flock,         //
-    __NR_linux_fcntl | LOCK,  //
-};
-
-static const uint16_t kPledgeLinuxRpath[] = {
-    __NR_linux_chdir,              //
-    __NR_linux_getcwd,             //
-    __NR_linux_open | READONLY,    //
-    __NR_linux_openat | READONLY,  //
-    __NR_linux_stat,               //
-    __NR_linux_lstat,              //
-    __NR_linux_fstat,              //
-    __NR_linux_fstatat,            //
-    __NR_linux_access,             //
-    __NR_linux_faccessat,          //
-    __NR_linux_faccessat2,         //
-    __NR_linux_readlink,           //
-    __NR_linux_readlinkat,         //
-    __NR_linux_statfs,             //
-    __NR_linux_fstatfs,            //
-};
-
-static const uint16_t kPledgeLinuxWpath[] = {
-    __NR_linux_getcwd,              //
-    __NR_linux_open | WRITEONLY,    //
-    __NR_linux_openat | WRITEONLY,  //
-    __NR_linux_stat,                //
-    __NR_linux_fstat,               //
-    __NR_linux_lstat,               //
-    __NR_linux_fstatat,             //
-    __NR_linux_access,              //
-    __NR_linux_faccessat,           //
-    __NR_linux_faccessat2,          //
-    __NR_linux_readlinkat,          //
-    __NR_linux_chmod | NOBITS,      //
-    __NR_linux_fchmod | NOBITS,     //
-    __NR_linux_fchmodat | NOBITS,   //
-};
-
-static const uint16_t kPledgeLinuxCpath[] = {
-    __NR_linux_open | CREATONLY,    //
-    __NR_linux_openat | CREATONLY,  //
-    __NR_linux_creat | RESTRICT,    //
-    __NR_linux_rename,              //
-    __NR_linux_renameat,            //
-    __NR_linux_renameat2,           //
-    __NR_linux_link,                //
-    __NR_linux_linkat,              //
-    __NR_linux_symlink,             //
-    __NR_linux_symlinkat,           //
-    __NR_linux_rmdir,               //
-    __NR_linux_unlink,              //
-    __NR_linux_unlinkat,            //
-    __NR_linux_mkdir,               //
-    __NR_linux_mkdirat,             //
-};
-
-static const uint16_t kPledgeLinuxDpath[] = {
-    __NR_linux_mknod,    //
-    __NR_linux_mknodat,  //
-};
-
-static const uint16_t kPledgeLinuxFattr[] = {
-    __NR_linux_chmod | NOBITS,     //
-    __NR_linux_fchmod | NOBITS,    //
-    __NR_linux_fchmodat | NOBITS,  //
-    __NR_linux_utime,              //
-    __NR_linux_utimes,             //
-    __NR_linux_futimesat,          //
-    __NR_linux_utimensat,          //
-};
-
-static const uint16_t kPledgeLinuxInet[] = {
-    __NR_linux_socket | INET,          //
-    __NR_linux_listen,                 //
-    __NR_linux_bind,                   //
-    __NR_linux_sendto,                 //
-    __NR_linux_connect,                //
-    __NR_linux_accept,                 //
-    __NR_linux_accept4,                //
-    __NR_linux_getsockopt | RESTRICT,  //
-    __NR_linux_setsockopt | RESTRICT,  //
-    __NR_linux_getpeername,            //
-    __NR_linux_getsockname,            //
-};
-
-static const uint16_t kPledgeLinuxUnix[] = {
-    __NR_linux_socket | UNIX,          //
-    __NR_linux_listen,                 //
-    __NR_linux_bind,                   //
-    __NR_linux_connect,                //
-    __NR_linux_sendto,                 //
-    __NR_linux_accept,                 //
-    __NR_linux_accept4,                //
-    __NR_linux_getsockopt | RESTRICT,  //
-    __NR_linux_setsockopt | RESTRICT,  //
-    __NR_linux_getpeername,            //
-    __NR_linux_getsockname,            //
-};
-
-static const uint16_t kPledgeLinuxDns[] = {
-    __NR_linux_socket | INET,      //
-    __NR_linux_bind,               //
-    __NR_linux_sendto,             //
-    __NR_linux_connect,            //
-    __NR_linux_recvfrom,           //
-    __NR_linux_fstatat,            //
-    __NR_linux_openat | READONLY,  //
-    __NR_linux_read,               //
-    __NR_linux_close,              //
-};
-
-static const uint16_t kPledgeLinuxTty[] = {
-    __NR_linux_ioctl | TTY,  //
-};
-
-static const uint16_t kPledgeLinuxRecvfd[] = {
-    __NR_linux_recvmsg,   //
-    __NR_linux_recvmmsg,  //
-};
-
-static const uint16_t kPledgeLinuxSendfd[] = {
-    __NR_linux_sendmsg,   //
-    __NR_linux_sendmmsg,  //
-};
-
-static const uint16_t kPledgeLinuxProc[] = {
-    __NR_linux_fork,                    //
-    __NR_linux_vfork,                   //
-    __NR_linux_clone | RESTRICT,        //
-    __NR_linux_kill,                    //
-    __NR_linux_setsid,                  //
-    __NR_linux_setpgid,                 //
-    __NR_linux_prlimit,                 //
-    __NR_linux_setrlimit,               //
-    __NR_linux_getpriority,             //
-    __NR_linux_setpriority,             //
-    __NR_linux_ioprio_get,              //
-    __NR_linux_ioprio_set,              //
-    __NR_linux_sched_getscheduler,      //
-    __NR_linux_sched_setscheduler,      //
-    __NR_linux_sched_get_priority_min,  //
-    __NR_linux_sched_get_priority_max,  //
-    __NR_linux_sched_getaffinity,       //
-    __NR_linux_sched_setaffinity,       //
-    __NR_linux_sched_getparam,          //
-    __NR_linux_sched_setparam,          //
-    __NR_linux_tgkill,                  //
-};
-
-static const uint16_t kPledgeLinuxId[] = {
-    __NR_linux_setuid,       //
-    __NR_linux_setreuid,     //
-    __NR_linux_setresuid,    //
-    __NR_linux_setgid,       //
-    __NR_linux_setregid,     //
-    __NR_linux_setresgid,    //
-    __NR_linux_setgroups,    //
-    __NR_linux_prlimit,      //
-    __NR_linux_setrlimit,    //
-    __NR_linux_getpriority,  //
-    __NR_linux_setpriority,  //
-    __NR_linux_setfsuid,     //
-    __NR_linux_setfsgid,     //
-};
-
-static const uint16_t kPledgeLinuxSettime[] = {
-    __NR_linux_settimeofday,   //
-    __NR_linux_clock_adjtime,  //
-};
-
-static const uint16_t kPledgeLinuxProtExec[] = {
-    __NR_linux_mmap | EXEC,  //
-    __NR_linux_mprotect,     //
-};
-
-static const uint16_t kPledgeLinuxExec[] = {
-    __NR_linux_execve,    //
-    __NR_linux_execveat,  //
-};
-
-static const uint16_t kPledgeLinuxUnveil[] = {
-    __NR_linux_landlock_create_ruleset,  //
-    __NR_linux_landlock_add_rule,        //
-    __NR_linux_landlock_restrict_self,   //
-};
-
-// placeholder group
-//
-// pledge.com checks this to do auto-unveiling
-static const uint16_t kPledgeLinuxVminfo[] = {
-    __NR_linux_sched_yield,  //
-};
-
-// placeholder group
-//
-// pledge.com uses this to auto-unveil /tmp and $TMPPATH with rwc
-// permissions. pledge() alone (without unveil() too) offers very
-// little security here. consider using them together.
-static const uint16_t kPledgeLinuxTmppath[] = {
-    __NR_linux_lstat,     //
-    __NR_linux_unlink,    //
-    __NR_linux_unlinkat,  //
-};
-
-static const struct Pledges {
-  const char *name;
-  const uint16_t *syscalls;
-  const size_t len;
-} kPledgeLinux[] = {
-    [PROMISE_STDIO] = {"stdio", PLEDGE(kPledgeLinuxStdio)},             //
-    [PROMISE_RPATH] = {"rpath", PLEDGE(kPledgeLinuxRpath)},             //
-    [PROMISE_WPATH] = {"wpath", PLEDGE(kPledgeLinuxWpath)},             //
-    [PROMISE_CPATH] = {"cpath", PLEDGE(kPledgeLinuxCpath)},             //
-    [PROMISE_DPATH] = {"dpath", PLEDGE(kPledgeLinuxDpath)},             //
-    [PROMISE_FLOCK] = {"flock", PLEDGE(kPledgeLinuxFlock)},             //
-    [PROMISE_FATTR] = {"fattr", PLEDGE(kPledgeLinuxFattr)},             //
-    [PROMISE_INET] = {"inet", PLEDGE(kPledgeLinuxInet)},                //
-    [PROMISE_UNIX] = {"unix", PLEDGE(kPledgeLinuxUnix)},                //
-    [PROMISE_DNS] = {"dns", PLEDGE(kPledgeLinuxDns)},                   //
-    [PROMISE_TTY] = {"tty", PLEDGE(kPledgeLinuxTty)},                   //
-    [PROMISE_RECVFD] = {"recvfd", PLEDGE(kPledgeLinuxRecvfd)},          //
-    [PROMISE_SENDFD] = {"sendfd", PLEDGE(kPledgeLinuxSendfd)},          //
-    [PROMISE_PROC] = {"proc", PLEDGE(kPledgeLinuxProc)},                //
-    [PROMISE_EXEC] = {"exec", PLEDGE(kPledgeLinuxExec)},                //
-    [PROMISE_ID] = {"id", PLEDGE(kPledgeLinuxId)},                      //
-    [PROMISE_UNVEIL] = {"unveil", PLEDGE(kPledgeLinuxUnveil)},          //
-    [PROMISE_SETTIME] = {"settime", PLEDGE(kPledgeLinuxSettime)},       //
-    [PROMISE_PROT_EXEC] = {"prot_exec", PLEDGE(kPledgeLinuxProtExec)},  //
-    [PROMISE_VMINFO] = {"vminfo", PLEDGE(kPledgeLinuxVminfo)},          //
-    [PROMISE_TMPPATH] = {"tmppath", PLEDGE(kPledgeLinuxTmppath)},       //
-};
-
-static const struct sock_filter kFilterStart[] = {
-    // make sure this isn't an i386 binary or something
-    BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(arch)),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
-    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
-    // each filter assumes ordinal is already loaded into accumulator
-    BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-    // forbid some system calls with ENOSYS (rather than EPERM)
-    BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, __NR_linux_memfd_secret, 5, 0),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_rseq, 4, 0),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_memfd_create, 3, 0),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat2, 2, 0),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_clone3, 1, 0),
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_statx, 0, 1),
-    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (38 & SECCOMP_RET_DATA)),
-};
-
-static const struct sock_filter kFilterIgnoreExitGroup[] = {
-    BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_exit_group, 0, 1),
-    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (1 & SECCOMP_RET_DATA)),
-};
-
-static void Log(const char *s, ...) {
-  va_list va;
-  va_start(va, s);
-  do {
-    write(2, s, strlen(s));
-  } while ((s = va_arg(va, const char *)));
-  va_end(va);
-}
-
-static bool HasSyscall(struct Pledges *p, uint16_t n) {
-  int i;
-  for (i = 0; i < p->len; ++i) {
-    if ((p->syscalls[i] & 0x0fff) == n) {
-      return true;
-    }
-  }
-  return false;
-}
-
-static char *FixCpy(char p[17], uint64_t x, uint8_t k) {
-  while (k > 0) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
-  *p = '\0';
-  return p;
-}
-
-static char *HexCpy(char p[17], uint64_t x) {
-  return FixCpy(p, x, ROUNDUP(x ? bsrl(x) + 1 : 1, 4));
-}
-
-static void OnSigSys(int sig, siginfo_t *si, ucontext_t *ctx) {
-  int i;
-  bool found;
-  char ord[17], rip[17];
-  struct sigaction dfl = {.sa_sigaction = SIG_DFL};
-  ctx->uc_mcontext.rax = -si->si_errno;
-  FixCpy(ord, si->si_syscall, 12);
-  HexCpy(rip, ctx->uc_mcontext.rip);
-  for (found = i = 0; i < ARRAYLEN(kPledgeLinux); ++i) {
-    if (HasSyscall(kPledgeLinux + i, si->si_syscall)) {
-      Log("error: has not pledged ", kPledgeLinux[i].name,  //
-          " (ord=", ord, " rip=", rip, ")\n", 0);
-      found = true;
-      break;
-    }
-  }
-  if (!found) {
-    Log("error: unsupported syscall (ord=", ord, " rip=", rip, ")\n", 0);
-  }
-  switch (__pledge_mode) {
-    case SECCOMP_RET_KILL_PROCESS:
-      if (!sigaction(SIGABRT, &dfl, 0)) {
-        sys_kill(getpid(), SIGABRT, 1);
-      }
-      _Exit(128 + SIGABRT);
-    case SECCOMP_RET_KILL_THREAD:
-      if (!sigaction(SIGABRT, &dfl, 0)) {
-        sys_tgkill(getpid(), gettid(), SIGABRT);
-      }
-      _Exit1(128 + SIGABRT);
-    default:
-      break;
-  }
-}
-
-static void MonitorSigSys(void) {
-  static _Thread_local bool once;
-  if (once) return;
-  once = true;
-  struct sigaction sa = {
-      .sa_sigaction = OnSigSys,
-      .sa_flags = SA_SIGINFO | SA_RESTART,
-  };
-  if (sigaction(SIGSYS, &sa, 0)) {
-    AbortPledge("sigaction failed");
-  }
-}
-
-static void AppendFilter(struct Filter *f, struct sock_filter *p, size_t n) {
-  if (UNLIKELY(f->n + n > ARRAYLEN(f->p))) {
-    AbortPledge("need to increase array size");
-  }
-  memcpy(f->p + f->n, p, n * sizeof(*f->p));
-  f->n += n;
-}
-
-// SYSCALL is only allowed in the .privileged section
-// We assume program image is loaded in 32-bit spaces
-static void AppendOriginVerification(struct Filter *f) {
-  intptr_t x = (intptr_t)__privileged_start;
-  intptr_t y = (intptr_t)__privileged_end;
-  assert(0 < x && x < y && y < INT_MAX);
-  struct sock_filter fragment[] = {
-      /*L0*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer) + 4),
-      /*L1*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 2),
-      /*L2*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(instruction_pointer)),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, x, 0, 5 - 4),
-      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, y, 0, 6 - 5),
-      /*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
-      /*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L7*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The first argument of sys_clone_linux() must NOT have:
-//
-//   - CLONE_NEWNS    (0x00020000)
-//   - CLONE_PTRACE   (0x00002000)
-//   - CLONE_UNTRACED (0x00800000)
-//
-static void AllowCloneRestrict(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_clone, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x00822000),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The first argument of sys_clone_linux() must have:
-//
-//   - CLONE_VM       (0x00000100)
-//   - CLONE_FS       (0x00000200)
-//   - CLONE_FILES    (0x00000400)
-//   - CLONE_THREAD   (0x00010000)
-//   - CLONE_SIGHAND  (0x00000800)
-//
-// The first argument of sys_clone_linux() must NOT have:
-//
-//   - CLONE_NEWNS    (0x00020000)
-//   - CLONE_PTRACE   (0x00002000)
-//   - CLONE_UNTRACED (0x00800000)
-//
-static void AllowCloneThread(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_clone, 0, 9 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x00010f00),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x00010f00, 0, 8 - 4),
-      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x00822000),
-      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L9*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The second argument of ioctl() must be one of:
-//
-//   - FIONREAD (0x541b)
-//   - FIONBIO  (0x5421)
-//   - FIOCLEX  (0x5451)
-//   - FIONCLEX (0x5450)
-//
-static void AllowIoctlStdio(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_ioctl, 0, 8 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x541b, 3, 0),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5421, 2, 0),
-      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5451, 1, 0),
-      /*L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5450, 0, 1),
-      /*L6*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L8*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The second argument of ioctl() must be one of:
-//
-//   - TCGETS     (0x5401)
-//   - TCSETS     (0x5402)
-//   - TCSETSW    (0x5403)
-//   - TCSETSF    (0x5404)
-//   - TIOCGWINSZ (0x5413)
-//   - TIOCSPGRP  (0x5410)
-//   - TIOCGPGRP  (0x540f)
-//   - TIOCSWINSZ (0x5414)
-//   - TCFLSH     (0x540b)
-//   - TCXONC     (0x540a)
-//   - TCSBRK     (0x5409)
-//   - TIOCSBRK   (0x5427)
-//
-static void AllowIoctlTty(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_ioctl, 0, 16 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5401, 11, 0),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5402, 10, 0),
-      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5403, 9, 0),
-      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5404, 8, 0),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5413, 7, 0),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5410, 6, 0),
-      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x540f, 5, 0),
-      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5414, 4, 0),
-      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x540b, 3, 0),
-      /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x540a, 2, 0),
-      /*L12*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5409, 1, 0),
-      /*L13*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x5427, 0, 1),
-      /*L14*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L15*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L16*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The level argument of setsockopt() must be one of:
-//
-//   - SOL_IP     (0)
-//   - SOL_SOCKET (1)
-//   - SOL_TCP    (6)
-//
-// The optname argument of setsockopt() must be one of:
-//
-//   - TCP_NODELAY          (0x01)
-//   - TCP_CORK             (0x03)
-//   - TCP_KEEPIDLE         (0x04)
-//   - TCP_KEEPINTVL        (0x05)
-//   - SO_TYPE              (0x03)
-//   - SO_ERROR             (0x04)
-//   - SO_DONTROUTE         (0x05)
-//   - SO_REUSEPORT         (0x0f)
-//   - SO_REUSEADDR         (0x02)
-//   - SO_KEEPALIVE         (0x09)
-//   - SO_RCVTIMEO          (0x14)
-//   - SO_SNDTIMEO          (0x15)
-//   - IP_RECVTTL           (0x0c)
-//   - IP_RECVERR           (0x0b)
-//   - TCP_FASTOPEN         (0x17)
-//   - TCP_FASTOPEN_CONNECT (0x1e)
-//
-static void AllowSetsockoptRestrict(struct Filter *f) {
-  static const int nr = __NR_linux_setsockopt;
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 21 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 2, 0),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
-      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 0, 20 - 5),
-      /* L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0f, 13, 0),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x03, 12, 0),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0c, 11, 0),
-      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x13, 10, 0),
-      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 9, 0),
-      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x09, 8, 0),
-      /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x14, 7, 0),
-      /*L12*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x01, 6, 0),
-      /*L13*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0b, 5, 0),
-      /*L14*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x04, 4, 0),
-      /*L15*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x05, 3, 0),
-      /*L16*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x17, 2, 0),
-      /*L17*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x1e, 1, 0),
-      /*L18*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x15, 0, 1),
-      /*L19*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L20*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L21*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The level argument of getsockopt() must be one of:
-//
-//   - SOL_SOCKET (1)
-//   - SOL_TCP    (6)
-//
-// The optname argument of getsockopt() must be one of:
-//
-//   - SO_TYPE      (0x03)
-//   - SO_REUSEPORT (0x0f)
-//   - SO_REUSEADDR (0x02)
-//   - SO_KEEPALIVE (0x09)
-//   - SO_RCVTIMEO  (0x14)
-//   - SO_SNDTIMEO  (0x15)
-//
-static void AllowGetsockoptRestrict(struct Filter *f) {
-  static const int nr = __NR_linux_getsockopt;
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 13 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 0, 12 - 4),
-      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x03, 5, 0),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0f, 4, 0),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 3, 0),
-      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x09, 2, 0),
-      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x14, 1, 0),
-      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x15, 0, 1),
-      /*L11*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L12*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L13*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The flags parameter of mmap() must not have:
-//
-//   - MAP_LOCKED   (0x02000)
-//   - MAP_NONBLOCK (0x10000)
-//   - MAP_HUGETLB  (0x40000)
-//
-static void AllowMmapExec(struct Filter *f) {
-  intptr_t y = (intptr_t)__privileged_end;
-  assert(0 < y && y < INT_MAX);
-  struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])),  // flags
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x52000),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 5 - 4),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The prot parameter of mmap() may only have:
-//
-//   - PROT_NONE  (0)
-//   - PROT_READ  (1)
-//   - PROT_WRITE (2)
-//
-// The flags parameter must not have:
-//
-//   - MAP_LOCKED   (0x02000)
-//   - MAP_POPULATE (0x08000)
-//   - MAP_NONBLOCK (0x10000)
-//   - MAP_HUGETLB  (0x40000)
-//
-static void AllowMmapNoexec(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mmap, 0, 9 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),  // prot
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 4),
-      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])),  // flags
-      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x5a000),
-      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L9*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The prot parameter of mprotect() may only have:
-//
-//   - PROT_NONE  (0)
-//   - PROT_READ  (1)
-//   - PROT_WRITE (2)
-//
-static void AllowMprotectNoexec(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_mprotect, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),  // prot
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The open() system call is permitted only when
-//
-//   - (flags & O_ACCMODE) == O_RDONLY
-//
-// The flags parameter of open() must not have:
-//
-//   - O_CREAT     (000000100)
-//   - O_TRUNC     (000001000)
-//   - __O_TMPFILE (020000000)
-//
-static void AllowOpenReadonly(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_open, 0, 9 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDONLY, 0, 8 - 4),
-      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020001100),
-      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L9*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The open() system call is permitted only when
-//
-//   - (flags & O_ACCMODE) == O_RDONLY
-//
-// The flags parameter of open() must not have:
-//
-//   - O_CREAT     (000000100)
-//   - O_TRUNC     (000001000)
-//   - __O_TMPFILE (020000000)
-//
-static void AllowOpenatReadonly(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat, 0, 9 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDONLY, 0, 8 - 4),
-      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020001100),
-      /*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L9*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The open() system call is permitted only when
-//
-//   - (flags & O_ACCMODE) == O_WRONLY
-//   - (flags & O_ACCMODE) == O_RDWR
-//
-// The open() flags parameter must not contain
-//
-//   - O_CREAT     (000000100)
-//   - __O_TMPFILE (020000000)
-//
-static void AllowOpenWriteonly(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_open, 0, 10 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_WRONLY, 1, 0),
-      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDWR, 0, 9 - 5),
-      /* L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L6*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020000100),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /* L8*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /* L9*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L10*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The open() system call is permitted only when
-//
-//   - (flags & O_ACCMODE) == O_WRONLY
-//   - (flags & O_ACCMODE) == O_RDWR
-//
-// The openat() flags parameter must not contain
-//
-//   - O_CREAT     (000000100)
-//   - __O_TMPFILE (020000000)
-//
-static void AllowOpenatWriteonly(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat, 0, 10 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, O_ACCMODE),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_WRONLY, 1, 0),
-      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, O_RDWR, 0, 9 - 5),
-      /* L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L6*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020000100),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /* L8*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /* L9*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L10*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// If the flags parameter of open() has one of:
-//
-//   - O_CREAT     (000000100)
-//   - __O_TMPFILE (020000000)
-//
-// Then the mode parameter must not have:
-//
-//   - S_ISVTX (01000 sticky)
-//   - S_ISGID (02000 setgid)
-//   - S_ISUID (04000 setuid)
-//
-static void AllowOpenCreatonly(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_open, 0, 12 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 000000100),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 000000100, 7 - 4, 0),
-      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020200000),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 020200000, 0, 10 - 7),
-      /* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L8*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
-      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L10*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L11*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L12*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// If the flags parameter of openat() has one of:
-//
-//   - O_CREAT     (000000100)
-//   - __O_TMPFILE (020000000)
-//
-// Then the mode parameter must not have:
-//
-//   - S_ISVTX (01000 sticky)
-//   - S_ISGID (02000 setgid)
-//   - S_ISUID (04000 setuid)
-//
-static void AllowOpenatCreatonly(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat, 0, 12 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 000000100),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 000000100, 7 - 4, 0),
-      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 020200000),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 020200000, 0, 10 - 7),
-      /* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])),
-      /* L8*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
-      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L10*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L11*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L12*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// Then the mode parameter must not have:
-//
-//   - S_ISVTX (01000 sticky)
-//   - S_ISGID (02000 setgid)
-//   - S_ISUID (04000 setuid)
-//
-static void AllowCreatRestrict(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_creat, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The second argument of fcntl() must be one of:
-//
-//   - F_DUPFD (0)
-//   - F_DUPFD_CLOEXEC (1030)
-//   - F_GETFD (1)
-//   - F_SETFD (2)
-//   - F_GETFL (3)
-//   - F_SETFL (4)
-//
-static void AllowFcntlStdio(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fcntl, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1030, 4 - 3, 0),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 5, 5 - 4, 0),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The second argument of fcntl() must be one of:
-//
-//   - F_GETLK (5)
-//   - F_SETLK (6)
-//   - F_SETLKW (7)
-//
-static void AllowFcntlLock(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fcntl, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 5, 0, 5 - 3),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 8, 5 - 4, 0),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The addr parameter of sendto() must be
-//
-//   - NULL
-//
-static void AllowSendtoAddrless(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_sendto, 0, 7 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4]) + 0),
-      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 3),
-      /*L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[4]) + 4),
-      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 5),
-      /*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L7*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The sig parameter of sigaction() must NOT be
-//
-//   - SIGSYS (31)
-//
-static void AllowSigactionNosigsys(struct Filter *f) {
-  static const int nr = __NR_linux_sigaction;
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, nr, 0, 5 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 31, 1, 0),
-      /*L3*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L5*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The family parameter of socket() must be one of:
-//
-//   - AF_INET  (0x02)
-//   - AF_INET6 (0x0a)
-//
-// The type parameter of socket() will ignore:
-//
-//   - SOCK_CLOEXEC  (0x80000)
-//   - SOCK_NONBLOCK (0x00800)
-//
-// The type parameter of socket() must be one of:
-//
-//   - SOCK_STREAM (0x01)
-//   - SOCK_DGRAM  (0x02)
-//
-// The protocol parameter of socket() must be one of:
-//
-//   - 0
-//   - IPPROTO_ICMP (0x01)
-//   - IPPROTO_TCP  (0x06)
-//   - IPPROTO_UDP  (0x11)
-//
-static void AllowSocketInet(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 15 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 1, 0),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0a, 0, 14 - 4),
-      /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x01, 1, 0),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x02, 0, 14 - 8),
-      /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x00, 3, 0),
-      /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x01, 2, 0),
-      /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x06, 1, 0),
-      /*L12*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x11, 0, 1),
-      /*L13*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L14*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L15*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The family parameter of socket() must be one of:
-//
-//   - AF_UNIX (1)
-//   - AF_LOCAL (1)
-//
-// The type parameter of socket() will ignore:
-//
-//   - SOCK_CLOEXEC  (0x80000)
-//   - SOCK_NONBLOCK (0x00800)
-//
-// The type parameter of socket() must be one of:
-//
-//   - SOCK_STREAM (1)
-//   - SOCK_DGRAM  (2)
-//
-// The protocol parameter of socket() must be one of:
-//
-//   - 0
-//
-static void AllowSocketUnix(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_socket, 0, 11 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 0, 10 - 3),
-      /* L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800),
-      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 1, 0),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 10 - 7),
-      /* L7*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /* L9*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L10*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L11*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The first parameter of prctl() can be any of
-//
-//   - PR_SET_NAME         (15)
-//   - PR_GET_NAME         (16)
-//   - PR_GET_SECCOMP      (21)
-//   - PR_SET_SECCOMP      (22)
-//   - PR_SET_NO_NEW_PRIVS (38)
-//   - PR_CAPBSET_READ     (23)
-//   - PR_CAPBSET_DROP     (24)
-//
-static void AllowPrctlStdio(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prctl, 0, 11 - 1),
-      /* L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
-      /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 15, 6, 0),
-      /* L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 16, 5, 0),
-      /* L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 21, 4, 0),
-      /* L5*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 22, 3, 0),
-      /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 23, 2, 0),
-      /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 24, 1, 0),
-      /* L8*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 38, 0, 1),
-      /* L9*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L10*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L11*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The mode parameter of chmod() can't have the following:
-//
-//   - S_ISVTX (01000 sticky)
-//   - S_ISGID (02000 setgid)
-//   - S_ISUID (04000 setuid)
-//
-static void AllowChmodNobits(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_chmod, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The mode parameter of fchmod() can't have the following:
-//
-//   - S_ISVTX (01000 sticky)
-//   - S_ISGID (02000 setgid)
-//   - S_ISUID (04000 setuid)
-//
-static void AllowFchmodNobits(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fchmod, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The mode parameter of fchmodat() can't have the following:
-//
-//   - S_ISVTX (01000 sticky)
-//   - S_ISGID (02000 setgid)
-//   - S_ISUID (04000 setuid)
-//
-static void AllowFchmodatNobits(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fchmodat, 0, 6 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 07000),
-      /*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L6*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-// The new_limit parameter of prlimit() must be
-//
-//   - NULL (0)
-//
-static void AllowPrlimitStdio(struct Filter *f) {
-  static const struct sock_filter fragment[] = {
-      /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_prlimit, 0, 7 - 1),
-      /*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])),
-      /*L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 6 - 3),
-      /*L3*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2]) + 4),
-      /*L4*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
-      /*L5*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      /*L6*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-      /*L7*/ /* next filter */
-  };
-  AppendFilter(f, PLEDGE(fragment));
-}
-
-static int CountUnspecial(const uint16_t *p, size_t len) {
-  int i, count;
-  for (count = i = 0; i < len; ++i) {
-    if (!(p[i] & SPECIAL)) {
-      ++count;
-    }
-  }
-  return count;
-}
-
-static void AppendPledge(struct Filter *f, const uint16_t *p, size_t len) {
-  int i, j, count;
-
-  // handle ordinals which allow syscalls regardless of args
-  // we put in extra effort here to reduce num of bpf instrs
-  if ((count = CountUnspecial(p, len))) {
-    if (count < 256) {
-      for (j = i = 0; i < len; ++i) {
-        if (p[i] & SPECIAL) continue;
-        // jump to ALLOW rule below if accumulator equals ordinal
-        struct sock_filter fragment[] = {
-            BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,  // instruction
-                     p[i],                       // operand
-                     count - j - 1,              // jump if true displacement
-                     j == count - 1),            // jump if false displacement
-        };
-        AppendFilter(f, PLEDGE(fragment));
-        ++j;
-      }
-      struct sock_filter fragment[] = {
-          BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
-      };
-      AppendFilter(f, PLEDGE(fragment));
-    } else {
-      AbortPledge("list of ordinals exceeds max displacement");
-    }
-  }
-
-  // handle "special" ordinals which use hand-crafted bpf
-  for (i = 0; i < len; ++i) {
-    if (!(p[i] & SPECIAL)) continue;
-    switch (p[i]) {
-      case __NR_linux_mmap | EXEC:
-        AllowMmapExec(f);
-        break;
-      case __NR_linux_mmap | NOEXEC:
-        AllowMmapNoexec(f);
-        break;
-      case __NR_linux_mprotect | NOEXEC:
-        AllowMprotectNoexec(f);
-        break;
-      case __NR_linux_chmod | NOBITS:
-        AllowChmodNobits(f);
-        break;
-      case __NR_linux_fchmod | NOBITS:
-        AllowFchmodNobits(f);
-        break;
-      case __NR_linux_fchmodat | NOBITS:
-        AllowFchmodatNobits(f);
-        break;
-      case __NR_linux_sigaction | NOSIGSYS:
-        AllowSigactionNosigsys(f);
-        break;
-      case __NR_linux_prctl | STDIO:
-        AllowPrctlStdio(f);
-        break;
-      case __NR_linux_open | CREATONLY:
-        AllowOpenCreatonly(f);
-        break;
-      case __NR_linux_openat | CREATONLY:
-        AllowOpenatCreatonly(f);
-        break;
-      case __NR_linux_open | READONLY:
-        AllowOpenReadonly(f);
-        break;
-      case __NR_linux_openat | READONLY:
-        AllowOpenatReadonly(f);
-        break;
-      case __NR_linux_open | WRITEONLY:
-        AllowOpenWriteonly(f);
-        break;
-      case __NR_linux_openat | WRITEONLY:
-        AllowOpenatWriteonly(f);
-        break;
-      case __NR_linux_setsockopt | RESTRICT:
-        AllowSetsockoptRestrict(f);
-        break;
-      case __NR_linux_getsockopt | RESTRICT:
-        AllowGetsockoptRestrict(f);
-        break;
-      case __NR_linux_creat | RESTRICT:
-        AllowCreatRestrict(f);
-        break;
-      case __NR_linux_fcntl | STDIO:
-        AllowFcntlStdio(f);
-        break;
-      case __NR_linux_fcntl | LOCK:
-        AllowFcntlLock(f);
-        break;
-      case __NR_linux_ioctl | RESTRICT:
-        AllowIoctlStdio(f);
-        break;
-      case __NR_linux_ioctl | TTY:
-        AllowIoctlTty(f);
-        break;
-      case __NR_linux_socket | INET:
-        AllowSocketInet(f);
-        break;
-      case __NR_linux_socket | UNIX:
-        AllowSocketUnix(f);
-        break;
-      case __NR_linux_sendto | ADDRLESS:
-        AllowSendtoAddrless(f);
-        break;
-      case __NR_linux_clone | RESTRICT:
-        AllowCloneRestrict(f);
-        break;
-      case __NR_linux_clone | THREAD:
-        AllowCloneThread(f);
-        break;
-      case __NR_linux_prlimit | STDIO:
-        AllowPrlimitStdio(f);
-        break;
-      default:
-        AbortPledge("switch forgot to define a special ordinal");
-    }
-  }
-}
-
-int sys_pledge_linux(unsigned long ipromises) {
-  int i, rc = -1;
-  struct Filter f;
-  CheckLargeStackAllocation(&f, sizeof(f));
-  f.n = 0;
-
-  // set up the seccomp filter
-  AppendFilter(&f, PLEDGE(kFilterStart));
-  if (ipromises == -1) {
-    // if we're pledging empty string, then avoid triggering a sigsys
-    // when _Exit() gets called since we need to fallback to _Exit1()
-    AppendFilter(&f, PLEDGE(kFilterIgnoreExitGroup));
-  }
-  if (!(~ipromises & (1ul << PROMISE_EXEC))) {
-    AppendOriginVerification(&f);
-  }
-  AppendPledge(&f, PLEDGE(kPledgeLinuxDefault));
-  for (i = 0; i < ARRAYLEN(kPledgeLinux); ++i) {
-    if (~ipromises & (1ul << i)) {
-      AppendPledge(&f, kPledgeLinux[i].syscalls, kPledgeLinux[i].len);
-    }
-  }
-
-  // now determine the default seccomp action
-  // the __pledge_mode global could be set to
-  // - SECCOMP_RET_KILL
-  // - SECCOMP_RET_KILL_THREAD
-  // - SECCOMP_RET_KILL_PROCESS
-  // - SECCOMP_RET_ERRNO | EPERM
-  struct sock_filter filter[1] = {BPF_STMT(BPF_RET | BPF_K, 0)};
-  if (~ipromises & (1ul << PROMISE_EXEC)) {
-    // our sigsys error message handler can't be inherited across
-    // execve() boundaries so if you've pledged exec then that'll
-    // mean no error messages for you.
-    filter[0].k = __pledge_mode;
-    AppendFilter(&f, PLEDGE(filter));
-  } else {
-    // if we haven't pledged exec, then we can monitor SIGSYS
-    // and print a helpful error message when things do break
-    // the handler then decides what to do with __pledge_mode
-    MonitorSigSys();
-    filter[0].k = SECCOMP_RET_TRAP | EPERM;
-    AppendFilter(&f, PLEDGE(filter));
-  }
-
-  // register our seccomp filter with the kernel
-  if ((rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) != -1) {
-    struct sock_fprog sandbox = {.len = f.n, .filter = f.p};
-    rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &sandbox);
-  }
-  return rc;
-}
-
-static int FindPromise(const char *name) {
-  int i;
-  for (i = 0; i < ARRAYLEN(kPledgeLinux); ++i) {
-    if (!strcasecmp(name, kPledgeLinux[i].name)) {
-      return i;
-    }
-  }
-  STRACE("unknown promise %s", name);
-  return -1;
-}
-
-int ParsePromises(const char *promises, unsigned long *out) {
-  int rc = 0;
-  int promise;
-  unsigned long ipromises;
-  char *tok, *state, *start, buf[256];
-  if (promises) {
-    ipromises = -1;
-    if (memccpy(buf, promises, 0, sizeof(buf))) {
-      start = buf;
-      while ((tok = strtok_r(start, " \t\r\n", &state))) {
-        if ((promise = FindPromise(tok)) != -1) {
-          ipromises &= ~(1ULL << promise);
-        } else {
-          rc = einval();
-          break;
-        }
-        start = 0;
-      }
-    } else {
-      rc = einval();
-    }
-  } else {
-    ipromises = 0;
-  }
-  if (!rc) {
-    *out = ipromises;
-  }
-  return rc;
-}
-
 /**
  * Restricts system operations, e.g.
  *
  *     pledge("stdio rfile tty", 0);
  *
  * Pledging causes most system calls to become unavailable. Your system
- * call policy is enforced by the kernel, which means it can propagate
- * across execve() if permitted. Root is not required. This system call
- * is supported on OpenBSD and Linux where it's polyfilled using SECCOMP
- * BPF. The way it works on Linux is, if a forbidden system call is used
- * then the kernel will will the process. On OpenBSD, a helpful message
- * explaining which promise is needed should be emitted to your system
- * log. On Linux, we log that to stderr with one exception: reporting is
- * currently not possible if you pledge exec.
+ * call policy is enforced by the kernel (which means it can propagate
+ * across execve() if permitted). Root access is not required. Support
+ * is limited to Linux and OpenBSD.
  *
- * Timing is everything with pledge. For example, if you're using
- * threads, then you may want to enable them explicitly *before* calling
- * pledge(), since otherwise you'd need "prot_exec":
+ * The promises you give pledge() define which system calls are allowed.
+ * Error messages are logged when sandbox violations occur that well you
+ * which promise was needed, to stderr on Linux and /var/log/messages on
+ * OpenBSD, and the unwatchable termination signal should be SIGABRT.
+ *
+ * Standard error logging can't happen on Linux if you use the `exec`
+ * promise, since we polyfill logging in userspace which can't cross
+ * execve() boundaries. However once you pledge away `exec` it works.
+ * Another inconsistency that pledging `exec` causes, is your process
+ * termination signal may become SIGSYS rather than SIGABRT.
+ *
+ * On Linux, our SECCOMP BPF polyfill offers more configurability in
+ * terms of behavior. It's possible to choose different behaviors that
+ * determine how sandbox violations are handled.
+ *
+ *     __pledge_mode = kPledgeModeKillThread;  // kill thread [default]
+ *     __pledge_mode = kPledgeModeKillProcess; // kill all threads
+ *     __pledge_mode = kPledgeModeErrno;       // just return EPERM
+ *
+ * Timing is everything with pledge. It's designed to be a voluntary
+ * self-imposed security model. That works best when programs perform
+ * permission-hungry operations (e.g. calling GetSymbolTable) towards
+ * the beginning of execution, and then relinquish privilege afterwards
+ * by calling pledge(). Here's an example of where that matters. Your
+ * Cosmopolitan C Library needs to code morph your executable in memory
+ * once you start using threads. But that's only possible to do if you
+ * used the `prot_exec` promise. So the right thing to do here, is to
+ * call __enable_threads() before calling pledge() to force it early.
  *
  *     __enable_threads();
- *     pledge("...", 0);
- *
- * If you want crash reports, then you can avoid needing "rpath" with:
- *
  *     ShowCrashReports();
  *     pledge("...", 0);
  *
@@ -1560,11 +99,10 @@ int ParsePromises(const char *promises, unsigned long *out) {
  * allowed. In that case, the process can only move towards a more
  * restrictive state.
  *
- * pledge() can't filter file system paths or internet addresses. For
- * example, if you enable a category like "inet" then your process will
- * be able to talk to any internet address. The same applies to
- * categories like "wpath" and "cpath"; if enabled, any path the
- * effective user id is permitted to change will be changeable.
+ * pledge() can't filter filesystem paths. See unveil() which lets you
+ * do that. pledge() also can't do address firewalling. For example if
+ * you use the `inet` promise then your process will be able to talk to
+ * *every* internet address including public ones.
  *
  * `promises` is a string that may include any of the following groups
  * delimited by spaces.
@@ -1633,11 +171,16 @@ int ParsePromises(const char *promises, unsigned long *out) {
  *
  * - "settime" allows settimeofday and clock_adjtime.
  *
- * - "exec" allows execve, execveat. If the executable in question needs
- *   a loader, then you'll need rpath and prot_exec too. However that's
- *   not needed if you assimilate your APE binary beforehand, because
- *   security is strongest for static binaries; use the --assimilate
- *   flag or o//tool/build/assimilate.com program.
+ * - "exec" allows execve, execveat. On Linux, using this promise will
+ *   cause (1) system call origin verification to be disabled; (2) error
+ *   logging will be disabled; and (3) your termination signals might
+ *   become SIGSYS instead of SIGABRT. Another thing to note is that
+ *   `exec` alone might not be enough by itself to let your executable
+ *   be executed. For dynamic, interpreted, and ape binaries, you'll
+ *   usually want `rpath` and `prot_exec` too. With APE it's possible to
+ *   work around this requirement, by "assimilating" your binaries
+ *   beforehand. See the assimilate.com program and `--assimilate` flag
+ *   which can be used to turn APE binaries into static native binaries.
  *
  * - "prot_exec" allows mmap(PROT_EXEC) and mprotect(PROT_EXEC). This is
  *   needed to (1) code morph mutexes in __enable_threads(), and it's
@@ -1674,12 +217,13 @@ int ParsePromises(const char *promises, unsigned long *out) {
  * @raise EINVAL if `execpromises` on Linux isn't a subset of `promises`
  * @raise EINVAL if `promises` allows exec and `execpromises` is null
  * @threadsafe
+ * @vforksafe
  */
 int pledge(const char *promises, const char *execpromises) {
   int rc;
   unsigned long ipromises, iexecpromises;
-  if (!(rc = ParsePromises(promises, &ipromises)) &&
-      !(rc = ParsePromises(execpromises, &iexecpromises))) {
+  if (!ParsePromises(promises, &ipromises) &&
+      !ParsePromises(execpromises, &iexecpromises)) {
     if (IsLinux()) {
       // copy exec and execnative from promises to execpromises
       iexecpromises = ~(~iexecpromises | (~ipromises & (1ul << PROMISE_EXEC)));
@@ -1691,15 +235,19 @@ int pledge(const char *promises, const char *execpromises) {
         STRACE("execpromises must be a subset of promises");
         rc = einval();
       } else {
-        rc = sys_pledge_linux(ipromises);
+        rc = sys_pledge_linux(ipromises, __pledge_mode, true);
+        if (rc > -4096u) errno = -rc, rc = -1;
       }
     } else {
       rc = sys_pledge(promises, execpromises);
     }
-    if (!rc && (IsOpenbsd() || (IsLinux() && getpid() == gettid()))) {
+    if (!rc && !__vforked &&
+        (IsOpenbsd() || (IsLinux() && getpid() == gettid()))) {
       __promises = ipromises;
       __execpromises = iexecpromises;
     }
+  } else {
+    rc = einval();
   }
   STRACE("pledge(%#s, %#s) → %d% m", promises, execpromises, rc);
   return rc;
diff --git a/libc/calls/pledge.h b/libc/calls/pledge.h
new file mode 100644
index 000000000..422fab1e4
--- /dev/null
+++ b/libc/calls/pledge.h
@@ -0,0 +1,16 @@
+#ifndef COSMOPOLITAN_LIBC_CALLS_PLEDGE_H_
+#define COSMOPOLITAN_LIBC_CALLS_PLEDGE_H_
+#if !(__ASSEMBLER__ + __LINKER__ + 0)
+COSMOPOLITAN_C_START_
+
+enum PledgeMode {
+  kPledgeModeKillThread,
+  kPledgeModeKillProcess,
+  kPledgeModeErrno,
+};
+
+extern enum PledgeMode __pledge_mode;
+
+COSMOPOLITAN_C_END_
+#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+#endif /* COSMOPOLITAN_LIBC_CALLS_PLEDGE_H_ */
diff --git a/libc/calls/pledge.internal.h b/libc/calls/pledge.internal.h
index 50bd40b1a..ada74cbca 100644
--- a/libc/calls/pledge.internal.h
+++ b/libc/calls/pledge.internal.h
@@ -1,9 +1,20 @@
 #ifndef COSMOPOLITAN_LIBC_CALLS_PLEDGE_INTERNAL_H_
 #define COSMOPOLITAN_LIBC_CALLS_PLEDGE_INTERNAL_H_
+#include "libc/calls/pledge.h"
+#include "libc/intrin/promises.internal.h"
 #if !(__ASSEMBLER__ + __LINKER__ + 0)
 COSMOPOLITAN_C_START_
 
-int ParsePromises(const char *, unsigned long *);
+struct Pledges {
+  const char *name;
+  const uint16_t *syscalls;
+  const size_t len;
+};
+
+hidden extern const struct Pledges kPledge[PROMISE_LEN_];
+
+int sys_pledge_linux(unsigned long, enum PledgeMode, bool) hidden;
+int ParsePromises(const char *, unsigned long *) hidden;
 
 COSMOPOLITAN_C_END_
 #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
diff --git a/libc/calls/raise.c b/libc/calls/raise.c
index 57481ec80..3feddc9a7 100644
--- a/libc/calls/raise.c
+++ b/libc/calls/raise.c
@@ -18,8 +18,10 @@
 ╚─────────────────────────────────────────────────────────────────────────────*/
 #include "libc/calls/calls.h"
 #include "libc/calls/getconsolectrlevent.internal.h"
+#include "libc/calls/internal.h"
 #include "libc/calls/sig.internal.h"
 #include "libc/calls/strace.internal.h"
+#include "libc/calls/struct/sigset.h"
 #include "libc/calls/syscall-sysv.internal.h"
 #include "libc/calls/syscall_support-nt.internal.h"
 #include "libc/intrin/kprintf.h"
@@ -39,7 +41,7 @@ static textwindows inline bool HasWorkingConsole(void) {
 }
 
 /**
- * Sends signal to this process.
+ * Sends signal to this thread.
  *
  * @param sig can be SIGALRM, SIGINT, SIGTERM, SIGKILL, etc.
  * @return 0 on success or -1 w/ errno
@@ -56,8 +58,7 @@ int raise(int sig) {
     x = 1 / x;
     rc = 0;
   } else if (!IsWindows()) {
-    // XXX: should be tkill() or tgkill() on linux
-    rc = sys_kill(getpid(), sig, 1);
+    rc = sys_tkill(gettid(), sig, 0);
   } else {
     if (HasWorkingConsole() && (event = GetConsoleCtrlEvent(sig)) != -1) {
       // XXX: MSDN says "If this parameter is zero, the signal is
diff --git a/libc/calls/unveil.c b/libc/calls/unveil.c
index 5b1327170..7e2b0b4b2 100644
--- a/libc/calls/unveil.c
+++ b/libc/calls/unveil.c
@@ -290,9 +290,9 @@ int sys_unveil_linux(const char *path, const char *permissions) {
  *    possible to use opendir() and go fishing for paths which weren't
  *    previously known.
  *
- * 5. Use ftruncate() rather than truncate(). One of the backdoors with
- *    Landlock is it currently can't restrict truncate() and setxattr()
- *    which permits certain kinds of modifications to files outside the
+ * 5. Use ftruncate() rather than truncate(). One issue Landlock hasn't
+ *    addressed yet is restrictions over truncate() and setxattr() which
+ *    could permit certain kinds of modifications to files outside the
  *    sandbox. When your policy is committed, we install a SECCOMP BPF
  *    filter to disable those calls, however similar trickery may be
  *    possible through other unaddressed calls like ioctl(). Using the
diff --git a/libc/intrin/exit.c b/libc/intrin/exit.c
index 2a0702885..b133fcdd5 100644
--- a/libc/intrin/exit.c
+++ b/libc/intrin/exit.c
@@ -18,6 +18,7 @@
 ╚─────────────────────────────────────────────────────────────────────────────*/
 #include "libc/calls/strace.internal.h"
 #include "libc/dce.h"
+#include "libc/intrin/promises.internal.h"
 #include "libc/nexgen32e/vendor.internal.h"
 #include "libc/nt/runtime.h"
 #include "libc/runtime/runtime.h"
@@ -39,11 +40,18 @@ privileged wontreturn void _Exit(int exitcode) {
   int i;
   STRACE("_Exit(%d)", exitcode);
   if (!IsWindows() && !IsMetal()) {
-    asm volatile("syscall"
-                 : /* no outputs */
-                 : "a"(__NR_exit_group), "D"(exitcode)
-                 : "rcx", "r11", "memory");
-    // this should only be possible on Linux in a pledge ultra sandbox
+    // On Linux _Exit1 (exit) must be called in pledge("") mode. If we
+    // call _Exit (exit_group) when we haven't used pledge("stdio") then
+    // it'll terminate the process instead. On OpenBSD we must not call
+    // _Exit1 (__threxit) because only _Exit (exit) is whitelisted when
+    // operating in pledge("") mode.
+    if (!(IsLinux() && !PLEDGED(STDIO))) {
+      asm volatile("syscall"
+                   : /* no outputs */
+                   : "a"(__NR_exit_group), "D"(exitcode)
+                   : "rcx", "r11", "memory");
+    }
+    // Inline _Exit1() just in case _Exit() isn't allowed by pledge()
     asm volatile("syscall"
                  : /* no outputs */
                  : "a"(__NR_exit), "D"(exitcode)
diff --git a/libc/intrin/exit1.greg.c b/libc/intrin/exit1.greg.c
index 115a58a6a..7dc596e27 100644
--- a/libc/intrin/exit1.greg.c
+++ b/libc/intrin/exit1.greg.c
@@ -19,6 +19,7 @@
 #include "libc/calls/strace.internal.h"
 #include "libc/dce.h"
 #include "libc/intrin/kprintf.h"
+#include "libc/intrin/promises.internal.h"
 #include "libc/nt/thread.h"
 #include "libc/runtime/runtime.h"
 #include "libc/sysv/consts/nr.h"
@@ -35,6 +36,12 @@ privileged wontreturn void _Exit1(int rc) {
   struct WinThread *wt;
   STRACE("_Exit1(%d)", rc);
   if (!IsWindows() && !IsMetal()) {
+    if (IsOpenbsd() && !PLEDGED(STDIO)) {
+      asm volatile("syscall"
+                   : /* no outputs */
+                   : "a"(__NR_exit), "D"(rc)
+                   : "rcx", "r11", "memory");
+    }
     asm volatile("xor\t%%r10d,%%r10d\n\t"
                  "syscall"
                  : /* no outputs */
diff --git a/libc/intrin/promises.c b/libc/intrin/promises.c
index 6707e9997..e276919a5 100644
--- a/libc/intrin/promises.c
+++ b/libc/intrin/promises.c
@@ -16,9 +16,11 @@
 │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
 │ PERFORMANCE OF THIS SOFTWARE.                                                │
 ╚─────────────────────────────────────────────────────────────────────────────*/
+#include "libc/calls/pledge.h"
 #include "libc/intrin/promises.internal.h"
 
 // XXX: should be inherited thread local
-unsigned __pledge_mode;
+//      see also sys_pledge_linux() which is 100% pure
+enum PledgeMode __pledge_mode;
 unsigned long __promises;
 unsigned long __execpromises;
diff --git a/libc/intrin/promises.internal.h b/libc/intrin/promises.internal.h
index a7d1d1c49..e3635c1e3 100644
--- a/libc/intrin/promises.internal.h
+++ b/libc/intrin/promises.internal.h
@@ -22,6 +22,7 @@
 #define PROMISE_PROT_EXEC 18
 #define PROMISE_VMINFO    19
 #define PROMISE_TMPPATH   20
+#define PROMISE_LEN_      21
 
 #define PLEDGED(x) ((~__promises >> PROMISE_##x) & 1)
 
diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h
index 0159269b7..a61b84a82 100644
--- a/libc/runtime/runtime.h
+++ b/libc/runtime/runtime.h
@@ -17,7 +17,6 @@ extern intptr_t __oldstack;                         /* CRT */
 extern uint64_t __nosync;                           /* SYS */
 extern _Atomic(int) __ftrace;                       /* SYS */
 extern _Atomic(int) __strace;                       /* SYS */
-extern uint32_t __pledge_mode;                      /* SYS */
 extern char *program_invocation_name;               /* RII */
 extern char *program_invocation_short_name;         /* RII */
 extern uint64_t __syscount;                         /* RII */
diff --git a/libc/sysv/calls/memfd_create.s b/libc/sysv/calls/memfd_create.s
deleted file mode 100644
index 46aaf3165..000000000
--- a/libc/sysv/calls/memfd_create.s
+++ /dev/null
@@ -1,2 +0,0 @@
-.include "o/libc/sysv/macros.internal.inc"
-.scall memfd_create,0xfffffffffffff13f,globl
diff --git a/libc/sysv/calls/sys_memfd_create.s b/libc/sysv/calls/sys_memfd_create.s
new file mode 100644
index 000000000..7d9e6a215
--- /dev/null
+++ b/libc/sysv/calls/sys_memfd_create.s
@@ -0,0 +1,2 @@
+.include "o/libc/sysv/macros.internal.inc"
+.scall sys_memfd_create,0xfffffffffffff13f,globl,hidden
diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh
index f5dcec4f2..becdfc25c 100755
--- a/libc/sysv/consts.sh
+++ b/libc/sysv/consts.sh
@@ -417,14 +417,6 @@ syscon	at	AT_REMOVEDIR				0x0200			0x80			0x0800			8			0x800			0x0200			# faked
 syscon	at	AT_EACCESS				0x0200			0x10			0x0100			1			0x100			0			# performs check using effective uid/gid; unnecessary nt
 syscon	at	AT_EMPTY_PATH				0x1000			0			0			0			0			0			# linux 2.6.39+; see unlink, O_TMPFILE, etc.
 
-#	memfd_create() flags
-#
-#	Unsupported flags are encoded as 0.
-#
-#	group	name					GNU/Systemd		XNU's Not UNIX!		FreeBSD			OpenBSD			NetBSD			The New Technology	Commentary
-syscon	memfd	MFD_CLOEXEC				1			0			0			0			0			0
-syscon	memfd	MFD_ALLOW_SEALING			2			0			0			0			0			0
-
 #	utimensat() special values
 #
 #	group	name					GNU/Systemd		XNU's Not UNIX!		FreeBSD			OpenBSD			NetBSD			The New Technology	Commentary
diff --git a/libc/sysv/consts/CANBSIZ.S b/libc/sysv/consts/CANBSIZ.S
deleted file mode 100644
index 5dc3cc58f..000000000
--- a/libc/sysv/consts/CANBSIZ.S
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "libc/sysv/consts/syscon.internal.h"
-.syscon termios,CANBSIZ,255,0,0,0,0,0
diff --git a/libc/sysv/consts/IPPORT_RESERVED.S b/libc/sysv/consts/IPPORT_RESERVED.S
deleted file mode 100644
index 5378a313f..000000000
--- a/libc/sysv/consts/IPPORT_RESERVED.S
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "libc/sysv/consts/syscon.internal.h"
-.syscon misc,IPPORT_RESERVED,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400
diff --git a/libc/sysv/consts/MFD_ALLOW_SEALING.S b/libc/sysv/consts/MFD_ALLOW_SEALING.S
deleted file mode 100644
index b1ab94f56..000000000
--- a/libc/sysv/consts/MFD_ALLOW_SEALING.S
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "libc/sysv/consts/syscon.internal.h"
-.syscon memfd,MFD_ALLOW_SEALING,2,0,0,0,0,0
diff --git a/libc/sysv/consts/MFD_CLOEXEC.S b/libc/sysv/consts/MFD_CLOEXEC.S
deleted file mode 100644
index cc293d84c..000000000
--- a/libc/sysv/consts/MFD_CLOEXEC.S
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "libc/sysv/consts/syscon.internal.h"
-.syscon memfd,MFD_CLOEXEC,1,0,0,0,0,0
diff --git a/libc/sysv/consts/mfd.h b/libc/sysv/consts/mfd.h
index 1bbf9b088..eb587ff6f 100644
--- a/libc/sysv/consts/mfd.h
+++ b/libc/sysv/consts/mfd.h
@@ -1,16 +1,7 @@
 #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_MFD_H_
 #define COSMOPOLITAN_LIBC_SYSV_CONSTS_MFD_H_
-#include "libc/runtime/symbolic.h"
-#if !(__ASSEMBLER__ + __LINKER__ + 0)
-COSMOPOLITAN_C_START_
 
-extern const unsigned int MFD_CLOEXEC;
-extern const unsigned int MFD_ALLOW_SEALING;
-
-COSMOPOLITAN_C_END_
-#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
-
-#define MFD_CLOEXEC       SYMBOLIC(MFD_CLOEXEC)
-#define MFD_ALLOW_SEALING SYMBOLIC(MFD_ALLOW_SEALING)
+#define MFD_CLOEXEC       1
+#define MFD_ALLOW_SEALING 2
 
 #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MFD_H_ */
diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh
index 879330f0a..9d40592a0 100755
--- a/libc/sysv/syscalls.sh
+++ b/libc/sysv/syscalls.sh
@@ -350,7 +350,7 @@ scall	sched_getattr		0xfffffffffffff13b	globl #  ├─ karen sandler requires s
 scall	renameat2		0xfffffffffffff13c	globl #  └─ debian founder ian murdock found strangled with vacuum cord
 #scall	seccomp			0xfffffffffffff13d	globl # wrapped manually
 scall	sys_getrandom		0xfff00723321f413e	globl hidden  # Linux 3.17+ and getentropy() on XNU/OpenBSD, coming to NetBSD in 9.2
-scall	memfd_create		0xfffffffffffff13f	globl # wut
+scall	sys_memfd_create	0xfffffffffffff13f	globl hidden
 scall	kexec_file_load		0xfffffffffffff140	globl
 scall	bpf			0xfffffffffffff141	globl
 scall	execveat		0xfffffffffffff142	globl
diff --git a/test/libc/calls/pledge2_test.c b/test/libc/calls/pledge2_test.c
index cb70a8f0a..3d828301a 100644
--- a/test/libc/calls/pledge2_test.c
+++ b/test/libc/calls/pledge2_test.c
@@ -17,10 +17,12 @@
 │ PERFORMANCE OF THIS SOFTWARE.                                                │
 ╚─────────────────────────────────────────────────────────────────────────────*/
 #include "libc/calls/calls.h"
+#include "libc/calls/pledge.internal.h"
 #include "libc/calls/struct/seccomp.h"
 #include "libc/calls/syscall_support-sysv.internal.h"
 #include "libc/dce.h"
 #include "libc/intrin/kprintf.h"
+#include "libc/intrin/promises.internal.h"
 #include "libc/runtime/runtime.h"
 #include "libc/sock/sock.h"
 #include "libc/sysv/consts/af.h"
@@ -58,7 +60,7 @@ void SetUp(void) {
 TEST(pledge, testSoftError) {
   if (IsOpenbsd()) return;
   SPAWN(fork);
-  __pledge_mode = SECCOMP_RET_ERRNO | EPERM;
+  __pledge_mode = kPledgeModeErrno;
   ASSERT_SYS(0, 0, pledge("stdio", 0));
   ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
   _Exit(7);
@@ -67,27 +69,27 @@ TEST(pledge, testSoftError) {
 
 TEST(pledge, testKillThreadMode) {
   SPAWN(fork);
-  __pledge_mode = SECCOMP_RET_KILL_THREAD;
+  __pledge_mode = kPledgeModeKillThread;
   ASSERT_SYS(0, 0, pledge("stdio", 0));
   socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-  TERMS(IsOpenbsd() ? SIGABRT : SIGSYS);
+  TERMS(SIGABRT);
 }
 
 TEST(pledge, testKillProcessMode) {
   SPAWN(fork);
-  __pledge_mode = SECCOMP_RET_KILL_PROCESS;
+  __pledge_mode = kPledgeModeKillProcess;
   ASSERT_SYS(0, 0, pledge("stdio", 0));
   socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-  TERMS(IsOpenbsd() ? SIGABRT : SIGSYS);
+  TERMS(SIGABRT);
 }
 
-TEST(pledge, testLogMessage_onSoftyMode) {
+TEST(pledge, testLogMessage_inSoftyMode) {
   if (IsOpenbsd()) return;
   int fds[2];
   char msg[64] = {0};
   ASSERT_SYS(0, 0, pipe(fds));
   SPAWN(fork);
-  __pledge_mode = SECCOMP_RET_ERRNO | EPERM;
+  __pledge_mode = kPledgeModeErrno;
   ASSERT_SYS(0, 2, dup2(fds[1], 2));
   ASSERT_SYS(0, 0, pledge("stdio", 0));
   ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
@@ -105,11 +107,11 @@ TEST(pledge, testLogMessage_onKillProcess) {
   char msg[64] = {0};
   ASSERT_SYS(0, 0, pipe(fds));
   SPAWN(fork);
-  __pledge_mode = SECCOMP_RET_KILL;
+  __pledge_mode = kPledgeModeKillThread;
   ASSERT_SYS(0, 2, dup2(fds[1], 2));
   ASSERT_SYS(0, 0, pledge("stdio", 0));
   socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-  TERMS(IsOpenbsd() ? SIGABRT : SIGSYS);
+  TERMS(SIGABRT);
   close(fds[1]);
   read(fds[0], msg, sizeof(msg));
   close(fds[0]);
@@ -118,7 +120,7 @@ TEST(pledge, testLogMessage_onKillProcess) {
   }
 }
 
-TEST(pledge, testNoLogPossibleSadly_becausePledgedExec) {
+TEST(pledge, testNoLogOrAbrtsignoPossibleSadly_becausePledgedExec) {
   int fds[2];
   char msg[64] = {0};
   ASSERT_SYS(0, 0, pipe(fds));
@@ -132,3 +134,11 @@ TEST(pledge, testNoLogPossibleSadly_becausePledgedExec) {
   close(fds[0]);
   ASSERT_STREQ("", msg);
 }
+
+TEST(pledge, testDoublePledge_isFine) {
+  SPAWN(fork);
+  __pledge_mode = kPledgeModeKillThread;
+  ASSERT_SYS(0, 0, pledge("stdio", 0));
+  ASSERT_SYS(0, 0, pledge("stdio", 0));
+  EXITS(0);
+}
diff --git a/test/libc/calls/pledge_test.c b/test/libc/calls/pledge_test.c
index 4bf314caf..e8f220066 100644
--- a/test/libc/calls/pledge_test.c
+++ b/test/libc/calls/pledge_test.c
@@ -60,10 +60,6 @@ STATIC_YOINK("zip_uri_support");
 
 char testlib_enable_tmp_setup_teardown;
 
-__attribute__((__constructor__)) static void init(void) {
-  __pledge_mode = SECCOMP_RET_ERRNO | EPERM;
-}
-
 void OnSig(int sig) {
   // do nothing
 }
@@ -89,6 +85,7 @@ void SetUp(void) {
   if (!__is_linux_2_6_23() && !IsOpenbsd()) exit(0);
   ASSERT_SYS(0, 0, extract("/zip/life.elf", "life.elf", 0755));
   ASSERT_SYS(0, 0, extract("/zip/sock.elf", "sock.elf", 0755));
+  __pledge_mode = kPledgeModeErrno;
 }
 
 TEST(pledge, default_allowsExit) {
@@ -112,11 +109,13 @@ TEST(pledge, default_allowsExit) {
   EXPECT_SYS(0, 0, munmap(job, FRAMESIZE));
 }
 
+#if 0
 TEST(pledge, execpromises_notok) {
   if (IsOpenbsd()) return;  // b/c testing linux bpf
   int ws, pid;
   ASSERT_NE(-1, (pid = fork()));
   if (!pid) {
+    __pledge_mode = kPledgeModeErrno;
     ASSERT_SYS(0, 0, pledge("stdio rpath exec", "stdio"));
     execl("sock.elf", "sock.elf", 0);
     _Exit(127);
@@ -157,8 +156,8 @@ TEST(pledge, stdio_forbidsOpeningPasswd1) {
 }
 
 TEST(pledge, stdio_forbidsOpeningPasswd2) {
-  if (!IsOpenbsd()) return;
   int ws, pid;
+  __pledge_mode = kPledgeModeKillProcess;
   ASSERT_NE(-1, (pid = fork()));
   if (!pid) {
     ASSERT_SYS(0, 0, pledge("stdio", 0));
@@ -558,7 +557,6 @@ TEST(pledge_linux, execpromisesIsSuperset_notPossible) {
 }
 
 TEST(pledge_openbsd, execpromises_notok) {
-  if (!IsOpenbsd()) return;
   int ws, pid;
   ASSERT_NE(-1, (pid = fork()));
   if (!pid) {
@@ -567,8 +565,15 @@ TEST(pledge_openbsd, execpromises_notok) {
     _Exit(127);
   }
   EXPECT_NE(-1, wait(&ws));
-  EXPECT_TRUE(WIFSIGNALED(ws));
-  EXPECT_EQ(SIGABRT, WTERMSIG(ws));
+  if (IsOpenbsd()) {
+    EXPECT_TRUE(WIFSIGNALED(ws));
+    EXPECT_EQ(SIGABRT, WTERMSIG(ws));
+  } else {
+    // linux can't be consistent here since we pledged exec
+    // so we return EPERM instead and sock.elf passes along
+    EXPECT_TRUE(WIFEXITED(ws));
+    EXPECT_EQ(128 + EPERM, WEXITSTATUS(ws));
+  }
 }
 
 TEST(pledge_openbsd, bigSyscalls) {
@@ -658,3 +663,4 @@ BENCH(pledge, bench) {
   }
   wait(0);
 }
+#endif
diff --git a/test/libc/calls/unveil_test.c b/test/libc/calls/unveil_test.c
index 8970a9a19..d141dba5b 100644
--- a/test/libc/calls/unveil_test.c
+++ b/test/libc/calls/unveil_test.c
@@ -373,7 +373,7 @@ TEST(unveil, usedTwice_forbidden_worksWithPledge) {
   ASSERT_NE(-1, wait(&ws));
   ASSERT_TRUE(*gotsome);
   ASSERT_TRUE(WIFSIGNALED(ws));
-  ASSERT_EQ(IsOpenbsd() ? SIGABRT : SIGSYS, WTERMSIG(ws));
+  ASSERT_EQ(SIGABRT, WTERMSIG(ws));
   EXPECT_SYS(0, 0, munmap(gotsome, FRAMESIZE));
 }
 
diff --git a/test/tool/build/pledge_test.sh b/test/tool/build/pledge_test.sh
index 6dcb5446c..542cecc61 100755
--- a/test/tool/build/pledge_test.sh
+++ b/test/tool/build/pledge_test.sh
@@ -116,7 +116,7 @@ elif [ "$1" = ape_assimilated_test_suite ]; then
   startit ape assimilated curl.com
   cp o//examples/curl.com $t/assimilated
   o//tool/build/assimilate.com $t/assimilated/curl.com
-  [ "$(o/$m/tool/build/pledge.com -p 'stdio inet dns' $t/assimilated/curl.com https://justine.lol/hello.txt)" = "hello world" ]
+  [ "$(o/$m/tool/build/pledge.com -p 'stdio rpath inet dns' $t/assimilated/curl.com https://justine.lol/hello.txt)" = "hello world" ]
   checkem
 
 elif [ "$1" = ape_native_test_suite ]; then
@@ -131,7 +131,7 @@ elif [ "$1" = ape_native_test_suite ]; then
   checkem
 
   startit ape native curl.com
-  [ "$(o/$m/tool/build/pledge.com -p 'stdio inet dns' o/$m/examples/curl.com https://justine.lol/hello.txt)" = "hello world" ]
+  [ "$(o/$m/tool/build/pledge.com -p 'stdio rpath inet dns' o/$m/examples/curl.com https://justine.lol/hello.txt)" = "hello world" ]
   checkem
 
 elif [ "$1" = setuid_test_suite ]; then
@@ -146,23 +146,23 @@ elif [ "$1" = setuid_test_suite ]; then
   checkem
 
   startit setuid curl.com
-  [ "$($t/pledge.com -p 'stdio inet dns' o/$m/examples/curl.com https://justine.lol/hello.txt)" = "hello world" ]
+  [ "$($t/pledge.com -p 'stdio rpath inet dns' o/$m/examples/curl.com https://justine.lol/hello.txt)" = "hello world" ]
   checkem
 
   startit setuid getuid
-  [ "$($t/pledge.com -pstdio o/$m/examples/printargs.com 2>&1 | grep getuid | grep -o [[:digit:]]*)" = "$(id -u)" ]
+  [ "$($t/pledge.com -p 'stdio rpath proc tty' o/$m/examples/printargs.com 2>&1 | grep getuid | grep -o [[:digit:]]*)" = "$(id -u)" ]
   checkem
 
   startit setuid geteuid
-  [ "$($t/pledge.com -pstdio o/$m/examples/printargs.com 2>&1 | grep geteuid | grep -o [[:digit:]]*)" = "$(id -u)" ]
+  [ "$($t/pledge.com -p 'stdio rpath proc tty' o/$m/examples/printargs.com 2>&1 | grep geteuid | grep -o [[:digit:]]*)" = "$(id -u)" ]
   checkem
 
   startit setuid no capabilities
-  [ "$($t/pledge.com -pstdio o/$m/examples/printargs.com 2>&1 | grep CAP_ | wc -l)" = 0 ]
+  [ "$($t/pledge.com -p 'stdio rpath proc tty' o/$m/examples/printargs.com 2>&1 | grep CAP_ | wc -l)" = 0 ]
   checkem
 
   startit setuid maximum nice
-  $t/pledge.com -np 'stdio proc' o/$m/examples/printargs.com 2>&1 | grep SCHED_IDLE >/dev/null
+  $t/pledge.com -np 'stdio rpath proc tty' o/$m/examples/printargs.com 2>&1 | grep SCHED_IDLE >/dev/null
   checkem
 
   startit setuid chroot
diff --git a/test/tool/net/lunix_test.lua b/test/tool/net/lunix_test.lua
index 3f9531682..b7fdd1b3c 100644
--- a/test/tool/net/lunix_test.lua
+++ b/test/tool/net/lunix_test.lua
@@ -82,7 +82,7 @@ function UnixTest()
       unix.close(reader)
       pid, ws = assert(unix.wait())
       assert(unix.WIFSIGNALED(ws))
-      assert(unix.WTERMSIG(ws) == unix.SIGSYS)
+      assert(unix.WTERMSIG(ws) == unix.SIGABRT)
    elseif GetHostOs() == "OPENBSD" then
       if assert(unix.fork()) == 0 then
          assert(unix.pledge("stdio"))
diff --git a/third_party/chibicc/test/test.mk b/third_party/chibicc/test/test.mk
index 70fbe7d00..a4ea3ea9e 100644
--- a/third_party/chibicc/test/test.mk
+++ b/third_party/chibicc/test/test.mk
@@ -69,10 +69,10 @@ o/$(MODE)/third_party/chibicc/test/%.com.dbg:					\
 		$(APE_NO_MODIFY_SELF)
 	@$(APELINK)
 
-$(THIRD_PARTY_CHIBICC_TEST_OBJS): CC = $(CHIBICC)
-$(THIRD_PARTY_CHIBICC_TEST_OBJS): $(CHIBICC)
-
-.PRECIOUS: $(THIRD_PARTY_CHIBICC_TEST_OBJS)
+o/$(MODE)/third_party/chibicc/test/%.o:						\
+		third_party/chibicc/test/%.c					\
+		$(CHIBICC)
+	@$(COMPILE) -AOBJECTIFY.c $(CHIBICC) $(CHIBICC_FLAGS) $(OUTPUT_OPTION) -c $<
 
 o/$(MODE)/third_party/chibicc/test/int128_test.o: QUOTA = -M1024m
 
diff --git a/third_party/lua/lunix.c b/third_party/lua/lunix.c
index 9fb852c25..29ef80e80 100644
--- a/third_party/lua/lunix.c
+++ b/third_party/lua/lunix.c
@@ -21,6 +21,7 @@
 #include "libc/calls/calls.h"
 #include "libc/calls/ioctl.h"
 #include "libc/calls/makedev.h"
+#include "libc/calls/pledge.h"
 #include "libc/calls/strace.internal.h"
 #include "libc/calls/struct/bpf.h"
 #include "libc/calls/struct/dirent.h"
diff --git a/tool/build/build.mk b/tool/build/build.mk
index 3d7a7cdbf..5e65f707f 100644
--- a/tool/build/build.mk
+++ b/tool/build/build.mk
@@ -117,6 +117,25 @@ o/$(MODE)/tool/build/printf.zip.o: o/$(MODE)/tool/build/printf
 o/$(MODE)/tool/build/dd.zip.o: o/$(MODE)/tool/build/dd
 	@$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) -0 -B -Pbin $(OUTPUT_OPTION) $<
 
+# we need pic because:
+#   so it can be an LD_PRELOAD payload
+o/$(MODE)/tool/build/sandbox.o:				\
+		OVERRIDE_CFLAGS +=			\
+			-fPIC
+
+o/$(MODE)/tool/build/sandbox.so:			\
+		o/$(MODE)/tool/build/sandbox.o		\
+		o/$(MODE)/libc/calls/pledge-linux.o	\
+		o/$(MODE)/libc/sysv/restorert.o
+	@$(COMPILE) -ALINK.so				\
+		$(CC)					\
+		-s					\
+		-shared					\
+		-nostdlib				\
+		-Wl,--gc-sections			\
+		$(LINKARGS)				\
+		$(OUTPUT_OPTION)
+
 .PHONY: o/$(MODE)/tool/build
 o/$(MODE)/tool/build:					\
 		o/$(MODE)/tool/build/emucrt		\
diff --git a/tool/build/pledge.c b/tool/build/pledge.c
index e8cdd3f30..e5d47041c 100644
--- a/tool/build/pledge.c
+++ b/tool/build/pledge.c
@@ -20,6 +20,7 @@
 #include "libc/bits/safemacros.internal.h"
 #include "libc/calls/calls.h"
 #include "libc/calls/landlock.h"
+#include "libc/calls/pledge.h"
 #include "libc/calls/struct/rlimit.h"
 #include "libc/calls/struct/sched_param.h"
 #include "libc/calls/struct/seccomp.h"
@@ -73,6 +74,7 @@ usage: pledge.com [-hnN] PROG ARGS...\n\
   -u UID          call setuid()\n\
   -c PATH         call chroot()\n\
   -v [PERM:]PATH  call unveil(PATH, PERM[rwxc])\n\
+  -k              kill process rather than eperm'ing\n\
   -n              set maximum niceness\n\
   -D              don't drop capabilities\n\
   -N              don't normalize file descriptors\n\
@@ -118,6 +120,7 @@ int ParsePromises(const char *, unsigned long *);
 
 int g_gflag;
 int g_uflag;
+int g_kflag;
 int g_hflag;
 bool g_nice;
 bool g_noclose;
@@ -140,14 +143,16 @@ static void GetOpts(int argc, char *argv[]) {
   g_promises = 0;
   g_fszquota = 256 * 1000 * 1000;
   g_proquota = GetCpuCount() * 100;
-  g_fszquota = 4 * 1000 * 1000 * 1000;
   g_memquota = 4L * 1024 * 1024 * 1024;
   if (!sysinfo(&si)) g_memquota = si.totalram;
-  while ((opt = getopt(argc, argv, "hnNp:u:g:c:C:D:P:M:F:v:")) != -1) {
+  while ((opt = getopt(argc, argv, "hnkNp:u:g:c:C:D:P:M:F:v:")) != -1) {
     switch (opt) {
       case 'n':
         g_nice = true;
         break;
+      case 'k':
+        g_kflag = true;
+        break;
       case 'N':
         g_noclose = true;
         break;
@@ -453,10 +458,12 @@ void ApplyFilesystemPolicy(unsigned long ipromises) {
 
   if (~ipromises & (1ul << PROMISE_PROT_EXEC)) {
     if (UnveilIfExists("/usr/bin/ape", "rx") == -1) {
-      UnveilIfExists(xjoinpaths(firstnonnull(getenv("TMPDIR"),
-                                             firstnonnull(getenv("HOME"), ".")),
-                                ".ape"),
-                     "rx");
+      if ((p = getenv("TMPDIR"))) {
+        UnveilIfExists(xjoinpaths(p, ".ape"), "rx");
+      }
+      if ((p = getenv("HOME"))) {
+        UnveilIfExists(xjoinpaths(p, ".ape"), "rx");
+      }
     }
   }
 
@@ -671,7 +678,11 @@ int main(int argc, char *argv[]) {
   // model. we do this becasue it's only possible to have sigsys print
   // crash messages if we're not pledging exec, which is what this tool
   // always has to do currently.
-  __pledge_mode = SECCOMP_RET_ERRNO | EPERM;
+  if (g_kflag) {
+    __pledge_mode = kPledgeModeKillProcess;
+  } else {
+    __pledge_mode = kPledgeModeErrno;
+  }
 
   // apply sandbox
   if (pledge(g_promises, g_promises) == -1) {
diff --git a/tool/build/sandbox.c b/tool/build/sandbox.c
new file mode 100644
index 000000000..4f1152526
--- /dev/null
+++ b/tool/build/sandbox.c
@@ -0,0 +1,28 @@
+/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
+│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2022 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or 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 "libc/calls/pledge.h"
+#include "libc/calls/pledge.internal.h"
+#include "libc/intrin/promises.internal.h"
+
+hidden char __privileged_start;
+hidden char __privileged_end;
+
+__attribute__((__constructor__)) void InitializeSandbox(void) {
+  sys_pledge_linux(~(1ul << PROMISE_STDIO), kPledgeModeErrno, false);
+}
diff --git a/tool/net/redbean.c b/tool/net/redbean.c
index 1a52d6329..6d4c66b45 100644
--- a/tool/net/redbean.c
+++ b/tool/net/redbean.c
@@ -21,6 +21,7 @@
 #include "libc/bits/safemacros.internal.h"
 #include "libc/calls/calls.h"
 #include "libc/calls/ioctl.h"
+#include "libc/calls/pledge.h"
 #include "libc/calls/struct/dirent.h"
 #include "libc/calls/struct/flock.h"
 #include "libc/calls/struct/iovec.h"
@@ -6587,7 +6588,7 @@ static void UnveilRedbean(void) {
 }
 
 static int EnableSandbox(void) {
-  __pledge_mode = SECCOMP_RET_ERRNO | EPERM;
+  __pledge_mode = kPledgeModeErrno;
   switch (sandboxed) {
     case 0:
       return 0;