commit c3a280dc1210c679cf7324f76d8f023a3feb4750
Author: Yawning Angel <[email protected]>
Date:   Thu Dec 29 02:18:02 2016 +0000

    Bug 21093: Go back to using gosecco for seccomp rule compilation.
    
    This means that there is no longer a dependency on libseccomp at all,
    yay.
---
 .gitignore                                         |   1 -
 ChangeLog                                          |   1 +
 Makefile                                           |   6 +-
 README.md                                          |   1 -
 data/tor-amd64.seccomp                             |  38 +
 data/tor-common-amd64.seccomp                      | 125 +++
 data/tor-obfs4-amd64.seccomp                       |  58 ++
 data/torbrowser-amd64.seccomp                      | 210 +++++
 src/cmd/gen-seccomp/main.go                        |  61 --
 src/cmd/gen-seccomp/seccomp.go                     | 120 ---
 src/cmd/gen-seccomp/seccomp_firefox.go             | 215 ------
 src/cmd/gen-seccomp/seccomp_tor.go                 | 595 --------------
 .../internal/sandbox/seccomp.go                    |  71 +-
 vendor/manifest                                    |   6 -
 .../github.com/seccomp/libseccomp-golang/LICENSE   |  22 -
 .../github.com/seccomp/libseccomp-golang/README    |  26 -
 .../seccomp/libseccomp-golang/seccomp.go           | 857 ---------------------
 .../seccomp/libseccomp-golang/seccomp_internal.go  | 506 ------------
 .../seccomp/libseccomp-golang/seccomp_test.go      | 457 -----------
 19 files changed, 492 insertions(+), 2884 deletions(-)

diff --git a/.gitignore b/.gitignore
index 9334d77..659d2b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,6 @@ bin/
 pkg/
 data/revision
 data/tbb_stub.so
-data/*.bpf
 src/cmd/sandboxed-tor-browser/internal/data/bindata.go
 *.swp
 *~
diff --git a/ChangeLog b/ChangeLog
index 8bcc45b..4f3a908 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 Changes in version 0.0.3 - UNRELEASED:
+ * Bug 21903: Go back to using gosecco for seccomp rule compilation.
  * Bug 20940: Deprecate x86 support.
  * Bug 20778: Check for updates in the background.
  * Bug 20851: If the incremental update fails, fall back to the complete
diff --git a/Makefile b/Makefile
index 67f6723..78c9a4c 100644
--- a/Makefile
+++ b/Makefile
@@ -9,9 +9,8 @@ sandboxed-tor-browser: static-assets
        gb build -tags $(GTK3TAG) cmd/sandboxed-tor-browser
        mv ./bin/sandboxed-tor-browser-$(GTK3TAG) ./bin/sandboxed-tor-browser
 
-static-assets: go-bindata gen-seccomp tbb_stub
+static-assets: go-bindata tbb_stub
        git rev-parse --short HEAD > data/revision
-       ./bin/gen-seccomp -o ./data
        ./bin/go-bindata -nometadata -pkg data -prefix data -o 
./src/cmd/sandboxed-tor-browser/internal/data/bindata.go data/...
 
 tbb_stub: go-bindata
@@ -20,9 +19,6 @@ tbb_stub: go-bindata
 go-bindata:
        gb build github.com/jteeuwen/go-bindata/go-bindata
 
-gen-seccomp:
-       gb build cmd/gen-seccomp
-
 clean:
        rm -f ./src/cmd/sandboxed-tor-browser/internal/data/bindata.go
        rm -f ./data/revision
diff --git a/README.md b/README.md
index badb125..675ee2f 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,6 @@ Build time dependencies:
  * A C compiler
  * gb (https://getgb.io/ Yes I know it's behind fucking cloudflare)
  * Go (Tested with 1.7.x)
- * libseccomp2 >= 2.2.1
  * libnotify
 
 Things that the sandbox breaks:
diff --git a/data/tor-amd64.seccomp b/data/tor-amd64.seccomp
new file mode 100644
index 0000000..097052a
--- /dev/null
+++ b/data/tor-amd64.seccomp
@@ -0,0 +1,38 @@
+# tor binary (x86_64) specific seccomp whitelist.
+#
+# This is based off of tor's src/common/sandbox.c
+
+#
+# Extra constant definitions needed for filtering.
+#
+
+FUTEX_WAIT=0
+FUTEX_WAKE=1
+FUTEX_FD=2
+FUTEX_REQUEUE=3
+FUTEX_CMP_REQUEUE=4
+FUTEX_WAKE_OP=5
+#FUTEX_LOCK_PI=6
+#FUTEX_UNLOCK_PI=7
+FUTEX_WAIT_BITSET=9
+FUTEX_PRIVATE_FLAG=128
+FUTEX_CLOCK_REALTIME=256
+
+FUTEX_WAIT_PRIVATE=FUTEX_WAIT | FUTEX_PRIVATE_FLAG
+FUTEX_WAKE_PRIVATE=FUTEX_WAKE | FUTEX_PRIVATE_FLAG
+FUTEX_CMP_REQUEUE_PRIVATE=FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG
+FUTEX_WAKE_OP_PRIVATE=FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG
+#FUTEX_LOCK_PI_PRIVATE=FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG
+#FUTEX_UNLOCK_PI_PRIVATE=FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG
+FUTEX_WAIT_BITSET_PRIVATE=FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG
+
+#
+# System calls allowed with filtering.
+#  * mmap: Asan (arg2 == PROT_READ|PROT_WRITE && arg3 == 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE)
+#               (arg2 == PROT_NONE && arg3 == 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE)
+#
+
+futex: arg1 == FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME || arg1 == 
FUTEX_WAKE_PRIVATE || arg1 == FUTEX_WAIT_PRIVATE
+mprotect: arg2 == PROT_READ || arg2 == PROT_NONE
+mmap: (arg2 == PROT_READ && arg3 == MAP_PRIVATE) || (arg2 == PROT_NONE && arg3 
== MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE) || (arg2 == PROT_READ|PROT_WRITE && 
arg3 == MAP_PRIVATE|MAP_ANONYMOUS) || (arg2 == PROT_READ|PROT_WRITE && arg3 == 
MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK) || (arg2 == PROT_READ|PROT_WRITE && arg3 
== MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE) || (arg2 == PROT_READ|PROT_WRITE && 
arg3 == MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS) || (arg2 == PROT_READ|PROT_EXEC && 
arg3 == MAP_PRIVATE|MAP_DENYWRITE) || (arg2 == PROT_READ|PROT_WRITE && arg3 == 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE) || (arg2 == PROT_NONE && 
arg3 == MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE)
+setsockopt: arg1 == SOL_SOCKET && (arg2 == SO_REUSEADDR || arg2 == SO_SNDBUF 
|| arg2 == SO_RCVBUF)
diff --git a/data/tor-common-amd64.seccomp b/data/tor-common-amd64.seccomp
new file mode 100644
index 0000000..59ce3e1
--- /dev/null
+++ b/data/tor-common-amd64.seccomp
@@ -0,0 +1,125 @@
+# tor binary (x86_64) common seccomp whitelist.
+#
+# This is based off of tor's src/common/sandbox.c and is the whitelist for
+# calls that aren't affected by the presence of obfs4proxy.  gosecco's compiler
+# doesn't allow multiple rules for the same system call that aren't identical.
+
+#
+# Extra constant definitions needed for filtering.
+#
+
+MADV_FREE=8
+MREMAP_MAYMOVE=1
+
+SIG_BLOCK=1
+SIG_SETMASK=2
+
+PF_INET=AF_INET
+PF_INET6=AF_INET6
+PF_LOCAL=AF_LOCAL
+PF_UNIX=AF_UNIX
+POLLIN=1
+
+MASKED_CLOEXEC_NONBLOCK = 0xFFF7F7FF
+
+#
+# System calls allowed unconditionally without argument filtering.
+#
+
+access: 1
+brk: 1
+clock_gettime: 1
+close: 1
+clone: 1
+epoll_create: 1
+epoll_wait: 1
+eventfd2: 1
+pipe2: 1
+pipe: 1
+fstat: 1
+getdents: 1
+getdents64: 1
+getegid: 1
+geteuid: 1
+getgid: 1
+getrlimit: 1
+gettimeofday: 1
+gettid: 1
+getuid: 1
+lseek: 1
+mkdir: 1
+munmap: 1
+prlimit64: 1
+read: 1
+rt_sigreturn: 1
+sched_getaffinity: 1
+sched_yield: 1
+sendmsg: 1
+set_robust_list: 1
+setrlimit: 1
+sigaltstack: 1
+stat: 1
+uname: 1
+wait4: 1
+write: 1
+writev: 1
+exit_group: 1
+exit: 1
+getrandom: 1
+sysinfo: 1
+bind: 1
+listen: 1
+connect: 1
+getsockname: 1
+recvmsg: 1
+recvfrom: 1
+sendto: 1
+unlink: 1
+
+# tor's sandbox filters these, but we can't because we are not in the tor
+# daemon's process space.
+chown: 1
+chmod: 1
+open: 1
+openat: 1
+rename: 1
+
+# Calls made prior to tor's UseSeccomp being enabled.
+arch_prctl: 1
+chdir: 1
+execve: 1
+getpid: 1
+kill: 1
+restart_syscall: 1
+set_tid_address: 1
+unshare: 1
+rt_sigaction: 1
+
+# XXX: This is only required for ASAN builds, so this should be included at
+# runtime.
+readlink: 1
+
+#
+# System calls allowed with filtering.
+#
+# Note:
+#  * socket:
+#     * tor explicitly allows PF_FILE separately from PF_UNIX which is
+#       pointless/nonsensical under Linux.
+#     * Tor allows socket(PF_NETLINK, SOCK_RAW, 0) but will accept no.
+#
+
+time: arg0 == 0
+madvise: arg2 == MADV_FREE
+umask: arg0 == 022
+rt_sigprocmask: arg0 == SIG_BLOCK || arg0 == SIG_SETMASK
+epoll_ctl: arg1 == EPOLL_CTL_ADD || arg1 == EPOLL_CTL_MOD || arg1 == 
EPOLL_CTL_DEL
+prctl: (arg0 == PR_SET_DUMPABLE && arg1 == 0) || arg0 == PR_SET_PDEATHSIG
+flock: arg1 == (LOCK_EX | LOCK_NB) || arg1 == LOCK_UN
+mremap: arg3 == MREMAP_MAYMOVE
+accept4: argL3 & MASKED_CLOEXEC_NONBLOCK == 0 && argH3 == 0
+poll: arg1 == POLLIN && arg2 == 10
+socket: argH1 == 0 && (arg0 == PF_INET && argL1 & MASKED_CLOEXEC_NONBLOCK == 
SOCK_STREAM && arg2 == IPPROTO_TCP) || (arg0 == PF_INET && argL1 & 
MASKED_CLOEXEC_NONBLOCK == SOCK_STREAM && arg2 == IPPROTO_IP) || (arg0 == 
PF_INET && argL1 & MASKED_CLOEXEC_NONBLOCK == SOCK_DGRAM && arg2 == IPPROTO_IP) 
|| (arg0 == PF_INET && argL1 & MASKED_CLOEXEC_NONBLOCK == SOCK_DGRAM && arg2 == 
IPPROTO_UDP) || (arg0 == PF_INET6 && argL1 & MASKED_CLOEXEC_NONBLOCK == 
SOCK_STREAM && arg2 == IPPROTO_TCP) || (arg0 == PF_INET6 && argL1 & 
MASKED_CLOEXEC_NONBLOCK == SOCK_STREAM && arg2 == IPPROTO_IP) || (arg0 == 
PF_INET6 && argL1 & MASKED_CLOEXEC_NONBLOCK == SOCK_DGRAM && arg2 == 
IPPROTO_IP) || (arg0 == PF_INET6 && argL1 & MASKED_CLOEXEC_NONBLOCK == 
SOCK_DGRAM && arg2 == IPPROTO_UDP) || (arg0 == PF_UNIX && argL1 & 
MASKED_CLOEXEC_NONBLOCK == SOCK_STREAM && arg2 == 0) || (arg0 == PF_UNIX && 
argL1 & MASKED_CLOEXEC_NONBLOCK == SOCK_DGRAM && arg2 == 0)
+getsockopt: arg1 == SOL_SOCKET && arg2 == SO_ERROR
+socketpair: arg0 == PF_LOCAL && (arg1 == SOCK_STREAM || arg1 == SOCK_STREAM | 
SOCK_CLOEXEC)
+fcntl: arg1 == F_GETFL || (arg1 == F_SETFL && (arg2 == O_RDWR|O_NONBLOCK || 
arg2 == O_RDONLY |O_NONBLOCK)) || arg1 == F_GETFD || (arg1 == F_SETFD && arg2 
== FD_CLOEXEC)
diff --git a/data/tor-obfs4-amd64.seccomp b/data/tor-obfs4-amd64.seccomp
new file mode 100644
index 0000000..b7ac52d
--- /dev/null
+++ b/data/tor-obfs4-amd64.seccomp
@@ -0,0 +1,58 @@
+# tor binary (x86_64) obfs4proxy seccomp whitelist.
+#
+# These are the rules that should apply to tor and obfs4proxy.  Eventually,
+# obfs4proxy should live in it's own container so this file should go away.
+
+#
+# Extra constant definitions needed for filtering.
+#
+
+FUTEX_WAIT=0
+FUTEX_WAKE=1
+FUTEX_FD=2
+FUTEX_REQUEUE=3
+FUTEX_CMP_REQUEUE=4
+FUTEX_WAKE_OP=5
+#FUTEX_LOCK_PI=6
+#FUTEX_UNLOCK_PI=7
+FUTEX_WAIT_BITSET=9
+FUTEX_PRIVATE_FLAG=128
+FUTEX_CLOCK_REALTIME=256
+
+FUTEX_WAIT_PRIVATE=FUTEX_WAIT | FUTEX_PRIVATE_FLAG
+FUTEX_WAKE_PRIVATE=FUTEX_WAKE | FUTEX_PRIVATE_FLAG
+FUTEX_CMP_REQUEUE_PRIVATE=FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG
+FUTEX_WAKE_OP_PRIVATE=FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG
+#FUTEX_LOCK_PI_PRIVATE=FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG
+#FUTEX_UNLOCK_PI_PRIVATE=FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG
+FUTEX_WAIT_BITSET_PRIVATE=FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG
+
+
+#
+# obfs4proxy specific system calls allowed unconditionally without argument
+# filtering.
+#
+
+mincore: 1
+dup2: 1
+select: 1
+mkdirat: 1
+fsync: 1
+getpeername: 1
+getppid: 1
+
+#
+# obfs4proxy specific system calls allowed with filtering.
+#
+
+epoll_create1: arg0 == EPOLL_CLOEXEC
+
+#
+# System calls allowed with filtering that obfs4proxy/tor want to allow
+# different things for.
+#
+
+futex: arg1 == FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME || arg1 == 
FUTEX_WAKE_PRIVATE || arg1 == FUTEX_WAIT_PRIVATE || arg1 == FUTEX_WAKE || arg1 
== FUTEX_WAIT
+mprotect: arg2 == PROT_READ || arg2 == PROT_NONE || arg2 == 
PROT_READ|PROT_WRITE
+mmap: (arg2 == PROT_READ && arg3 == MAP_PRIVATE) || (arg2 == PROT_NONE && arg3 
== MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE) || (arg2 == PROT_READ|PROT_WRITE && 
arg3 == MAP_PRIVATE|MAP_ANONYMOUS) || (arg2 == PROT_READ|PROT_WRITE && arg3 == 
MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK) || (arg2 == PROT_READ|PROT_WRITE && arg3 
== MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE) || (arg2 == PROT_READ|PROT_WRITE && 
arg3 == MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS) || (arg2 == PROT_READ|PROT_EXEC && 
arg3 == MAP_PRIVATE|MAP_DENYWRITE) || (arg2 == PROT_READ|PROT_WRITE && arg3 == 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE) || (arg2 == PROT_NONE && 
arg3 == MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE) || (arg2 == 
PROT_NONE && arg3 == MAP_PRIVATE|MAP_ANONYMOUS) || (arg2 == PROT_NONE && arg3 
== MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS)
+setsockopt: (arg1 == SOL_SOCKET && (arg2 == SO_REUSEADDR || arg2 == SO_SNDBUF 
|| arg2 == SO_RCVBUF || arg2 == SO_BROADCAST)) || (arg1 == SOL_TCP && arg2 == 
TCP_NODELAY) || (arg1 == SOL_IPV6 && arg2 == IPV6_V6ONLY)
diff --git a/data/torbrowser-amd64.seccomp b/data/torbrowser-amd64.seccomp
new file mode 100644
index 0000000..a2c2817
--- /dev/null
+++ b/data/torbrowser-amd64.seccomp
@@ -0,0 +1,210 @@
+# Tor Browser (x86_64) seccomp whitelist.
+#
+# This is based off of:
+# 
https://github.com/subgraph/subgraph-oz-profiles/blob/master/torbrowser-launcher-whitelist.seccomp
+# 
https://github.com/mozilla/gecko-dev/blob/master/security/sandbox/linux/SandboxFilter.cpp
+
+#
+# Extra constant definitions needed for filtering.
+#
+
+FIONREAD = 0x541b
+TCGETS = 0x5401
+TIOCGPGRP = 0x540f
+
+MADV_NORMAL=0
+MADV_DONTNEED=4
+MADV_FREE=8
+
+FUTEX_WAIT=0
+FUTEX_WAKE=1
+FUTEX_FD=2
+FUTEX_REQUEUE=3
+FUTEX_CMP_REQUEUE=4
+FUTEX_WAKE_OP=5
+#FUTEX_LOCK_PI=6
+#FUTEX_UNLOCK_PI=7
+FUTEX_WAIT_BITSET=9
+FUTEX_PRIVATE_FLAG=128
+FUTEX_CLOCK_REALTIME=256
+
+FUTEX_WAIT_PRIVATE=FUTEX_WAIT | FUTEX_PRIVATE_FLAG
+FUTEX_WAKE_PRIVATE=FUTEX_WAKE | FUTEX_PRIVATE_FLAG
+FUTEX_CMP_REQUEUE_PRIVATE=FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG
+FUTEX_WAKE_OP_PRIVATE=FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG
+#FUTEX_LOCK_PI_PRIVATE=FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG
+#FUTEX_UNLOCK_PI_PRIVATE=FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG
+FUTEX_WAIT_BITSET_PRIVATE=FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG
+
+#
+# System calls allowed unconditionally without argument filtering.
+#
+
+clock_gettime: 1
+clock_getres: 1
+gettimeofday: 1
+nanosleep: 1
+sched_yield: 1
+
+open: 1
+openat: 1
+pread64: 1
+read: 1
+recvfrom: 1
+pwrite64: 1
+sendto: 1
+write: 1
+writev: 1
+close: 1
+
+access: 1
+creat: 1
+chmod: 1
+chdir: 1
+dup2: 1
+dup: 1
+fadvise64: 1
+fallocate: 1
+fcntl: 1
+fchmod: 1
+fchown: 1
+fchdir: 1
+fdatasync: 1
+fstat: 1
+fstatfs: 1
+ftruncate: 1
+fsync: 1
+getcwd: 1
+getdents: 1
+getdents64: 1
+link: 1
+lseek: 1
+lstat: 1
+mkdir: 1
+name_to_handle_at: 1
+newfstatat: 1
+pipe: 1
+pipe2: 1
+readahead: 1
+readlink: 1
+readlinkat: 1
+rename: 1
+rmdir: 1
+stat: 1
+splice: 1
+statfs: 1
+symlink: 1
+unlink: 1
+utime: 1
+utimes: 1
+
+accept4: 1
+bind: 1
+connect: 1
+epoll_create: 1
+epoll_create1: 1
+epoll_ctl: 1
+epoll_wait: 1
+eventfd2: 1
+getsockname: 1
+getsockopt: 1
+getpeername: 1
+listen: 1
+poll: 1
+ppoll: 1
+recvmsg: 1
+socketpair: 1
+select: 1
+sendmsg: 1
+setsockopt: 1
+shutdown: 1
+
+inotify_add_watch: 1
+inotify_init1: 1
+inotify_rm_watch: 1
+
+brk: 1
+mincore: 1
+mmap: 1
+mprotect: 1
+mremap: 1
+munmap: 1
+
+shmdt: 1
+shmat: 1
+shmctl: 1
+shmget: 1
+
+alarm: 1
+execve: 1
+getrandom: 1
+getrlimit: 1
+getrusage: 1
+getpgrp: 1
+getppid: 1
+getpid: 1
+getpriority: 1
+getresgid: 1
+getresuid: 1
+gettid: 1
+getuid: 1
+geteuid: 1
+getgid: 1
+getegid: 1
+rt_sigaction: 1
+rt_sigprocmask: 1
+rt_sigreturn: 1
+rt_tgsigqueueinfo: 1
+sigaltstack: 1
+
+arch_prctl: 1
+capset: 1
+capget: 1
+clone: 1
+exit: 1
+exit_group: 1
+kill: 1
+restart_syscall: 1
+seccomp: 1
+sched_getaffinity: 1
+sched_setscheduler: 1
+setpriority: 1
+set_robust_list: 1
+setsid: 1
+set_tid_address: 1
+setresuid: 1
+setresgid: 1
+sysinfo: 1
+tgkill: 1
+umask: 1
+uname: 1
+unshare: 1
+wait4: 1
+
+# XXX: This is only required for ASAN builds, so this should be included at
+# runtime.
+setrlimit: 1
+
+#
+# System calls allowed with filtering.
+#
+# Note: Because we patch PulseAudio from tbb_stub.so, we can omit all PI futex
+# calls.
+#
+
+futex: arg1 == FUTEX_CMP_REQUEUE_PRIVATE || arg1 == FUTEX_WAIT || arg1 == 
FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME || arg1 == FUTEX_WAIT_PRIVATE || 
arg1 == FUTEX_WAKE || arg1 == FUTEX_WAKE_OP_PRIVATE || arg1 == 
FUTEX_WAKE_PRIVATE || arg1 == FUTEX_WAIT_BITSET_PRIVATE
+madvise: arg2 == MADV_NORMAL || arg2 == MADV_DONTNEED || arg2 == MADV_FREE
+ioctl: arg1 == FIONREAD || arg1 == TCGETS || arg1 == TIOCGPGRP
+prctl: arg0 == PR_SET_NAME || arg0 == PR_GET_NAME || arg0 == PR_GET_TIMERSLACK 
|| arg0 == PR_SET_SECCOMP
+socket: arg0 == AF_UNIX
+
+# Calls that other people think we should have but we deny:
+#
+# Firefox:
+#  * quotactl - gracefully deals with rejection.
+#
+# Subgraph (all probably python):
+#  * vfork
+#  * memfd_create
+#  * personality
+#  * mlock
diff --git a/src/cmd/gen-seccomp/main.go b/src/cmd/gen-seccomp/main.go
deleted file mode 100644
index 8216166..0000000
--- a/src/cmd/gen-seccomp/main.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// gen-seccomp.go - Pre-generate seccomp rules.
-// Copyright (C) 2016  Yawning Angel.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-package main
-
-import (
-       "flag"
-       "log"
-       "os"
-       "path/filepath"
-)
-
-func main() {
-       outFlag := flag.String("o", "", "output directory")
-       flag.Parse()
-
-       outDir, err := filepath.Abs(*outFlag)
-       if err != nil {
-               log.Fatalf("failed to get absolute path: %v", err)
-       }
-
-       // Tor Browser (amd64)
-       f, err := os.Create(filepath.Join(outDir, "tor-amd64.bpf"))
-       if err != nil {
-               log.Fatalf("failed to create output: %v", err)
-       }
-       if err = compileTorSeccompProfile(f, false); err != nil {
-               log.Fatalf("failed to create tor amd64 profile: %v", err)
-       }
-
-       // Tor Browser + obfs4proxy (amd64)
-       f, err = os.Create(filepath.Join(outDir, "tor-obfs4-amd64.bpf"))
-       if err != nil {
-               log.Fatalf("failed to create output: %v", err)
-       }
-       if err = compileTorSeccompProfile(f, true); err != nil {
-               log.Fatalf("failed to create tor-obfs4 amd64 profile: %v", err)
-       }
-
-       // Firefox (amd64)
-       f, err = os.Create(filepath.Join(outDir, "torbrowser-amd64.bpf"))
-       if err != nil {
-               log.Fatalf("failed to create output: %v", err)
-       }
-       if err = compileTorBrowserSeccompProfile(f); err != nil {
-               log.Fatalf("failed to create firefox amd64 profile: %v", err)
-       }
-}
diff --git a/src/cmd/gen-seccomp/seccomp.go b/src/cmd/gen-seccomp/seccomp.go
deleted file mode 100644
index b016f4c..0000000
--- a/src/cmd/gen-seccomp/seccomp.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// secomp.go - Sandbox seccomp rules.
-// Copyright (C) 2016  Yawning Angel.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-package main
-
-import (
-       "fmt"
-
-       seccomp "github.com/seccomp/libseccomp-golang"
-)
-
-const (
-       madvNormal    = 0 // MADV_NORMAL
-       madvDontneed  = 4 // MADV_DONTNEED
-       madvFree      = 8 // MADV_FREE
-       mremapMaymove = 1
-
-       sigBlock   = 1 // SIG_BLOCK
-       sigSetmask = 2 // SIG_SETMASK
-
-       futexWait          = 0
-       futexWake          = 1
-       futexFd            = 2
-       futexRequeue       = 3
-       futexCmpRequeue    = 4
-       futexWakeOp        = 5
-       futexLockPi        = 6
-       futexUnlockPi      = 7
-       futexTrylockPi     = 8
-       futexWaitBitset    = 9
-       futexWakeBitset    = 10
-       futexWaitRequeuePi = 11
-       futexCmpRequeuePi  = 12
-
-       futexPrivateFlag   = 128
-       futexClockRealtime = 256
-
-       futexWaitPrivate          = futexWait | futexPrivateFlag
-       futexWakePrivate          = futexWake | futexPrivateFlag
-       futexRequeuePrivate       = futexRequeue | futexPrivateFlag
-       futexCmpRequeuePrivate    = futexCmpRequeue | futexPrivateFlag
-       futexWakeOpPrivate        = futexWakeOp | futexPrivateFlag
-       futexLockPiPrivate        = futexLockPi | futexPrivateFlag
-       futexUnlockPiPrivate      = futexUnlockPi | futexPrivateFlag
-       futexTrylockPiPrivate     = futexTrylockPi | futexPrivateFlag
-       futexWaitBitsetPrivate    = futexWaitBitset | futexPrivateFlag
-       futexWakeBitsetPrivate    = futexWakeBitset | futexPrivateFlag
-       futexWaitRequeuePiPrivate = futexWaitRequeuePi | futexPrivateFlag
-       futexCmpRequeuePiPrivate  = futexCmpRequeuePi | futexPrivateFlag
-
-       pollIn = 1
-
-       fionread  = 0x541b
-       tcgets    = 0x5401
-       tiocgpgrp = 0x540f
-)
-
-func newWhitelist() (*seccomp.ScmpFilter, error) {
-       actENOSYS := seccomp.ActErrno.SetReturnCode(38)
-       f, err := seccomp.NewFilter(actENOSYS)
-       if err != nil {
-               return nil, err
-       }
-
-       if err = f.AddArch(seccomp.ArchAMD64); err != nil {
-               f.Release()
-               return nil, err
-       }
-       if err = f.SetBadArchAction(seccomp.ActKill); err != nil {
-               return nil, err
-       }
-
-       return f, nil
-}
-
-func allowSyscalls(f *seccomp.ScmpFilter, calls []string) error {
-       for _, scallName := range calls {
-               scall, err := seccomp.GetSyscallFromName(scallName)
-               if err != nil {
-                       return fmt.Errorf("seccomp: unknown system call: %v", 
scallName)
-               }
-               if err = f.AddRule(scall, seccomp.ActAllow); err != nil {
-                       return err
-               }
-       }
-       return nil
-}
-
-func allowCmpEq(f *seccomp.ScmpFilter, scallName string, arg uint, values 
...uint64) error {
-       scall, err := seccomp.GetSyscallFromName(scallName)
-       if err != nil {
-               return fmt.Errorf("seccomp: unknown system call: %v", scallName)
-       }
-
-       // Allow if the arg matches any of the values.  Implemented as multiple
-       // rules.
-       for _, v := range values {
-               argIsEqual, err := seccomp.MakeCondition(arg, 
seccomp.CompareEqual, v)
-               if err != nil {
-                       return err
-               }
-               if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{argIsEqual}); err != nil {
-                       return err
-               }
-       }
-       return nil
-}
diff --git a/src/cmd/gen-seccomp/seccomp_firefox.go 
b/src/cmd/gen-seccomp/seccomp_firefox.go
deleted file mode 100644
index 427c5f9..0000000
--- a/src/cmd/gen-seccomp/seccomp_firefox.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// secomp_firefox.go - Firefox sandbox seccomp rules.
-// Copyright (C) 2016  Yawning Angel.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-package main
-
-import (
-       "os"
-       "syscall"
-)
-
-func compileTorBrowserSeccompProfile(fd *os.File) error {
-       defer fd.Close()
-
-       f, err := newWhitelist()
-       if err != nil {
-               return err
-       }
-       defer f.Release()
-
-       // TODO; Filter the arguments on more of these calls.
-       //
-       // Maybe draaw inspiration from:
-       // 
https://github.com/mozilla/gecko-dev/blob/master/security/sandbox/linux/SandboxFilter.cpp
-       allowedNoArgs := []string{
-               "clock_gettime",
-               "clock_getres",
-               "gettimeofday",
-               "nanosleep",
-               "sched_yield",
-
-               "open",
-               "openat",
-               "pread64",
-               "read",
-               "recvfrom",
-               "pwrite64",
-               "sendto",
-               "write",
-               "writev",
-               "close",
-
-               "access",
-               "creat",
-               "chmod",
-               "chdir",
-               "dup2",
-               "dup",
-               "fadvise64",
-               "fallocate",
-               "fcntl",
-               "fchmod",
-               "fchown",
-               "fchdir",
-               "fdatasync",
-               "fstat",
-               "fstatfs",
-               "ftruncate",
-               "fsync",
-               "getcwd",
-               "getdents",
-               "getdents64",
-               "link",
-               "lseek",
-               "lstat",
-               "mkdir",
-               "name_to_handle_at",
-               "newfstatat",
-               "pipe",
-               "pipe2",
-               "readahead",
-               "readlink",
-               "readlinkat",
-               "rename",
-               "rmdir",
-               "stat",
-               "splice",
-               "statfs",
-               "symlink",
-               "unlink",
-               "utime",
-               "utimes",
-
-               "accept4",
-               "bind",
-               "connect",
-               "epoll_create",
-               "epoll_create1",
-               "epoll_ctl",
-               "epoll_wait",
-               "eventfd2",
-               "getsockname",
-               "getsockopt",
-               "getpeername",
-               "listen",
-               "poll",
-               "ppoll",
-               "recvmsg",
-               "socketpair",
-               "select",
-               "sendmsg",
-               "setsockopt",
-               "shutdown",
-
-               "inotify_add_watch",
-               "inotify_init1",
-               "inotify_rm_watch",
-
-               "brk",
-               "mincore",
-               "mmap",
-               "mprotect",
-               "mremap",
-               "munmap",
-
-               "shmdt",
-               "shmat",
-               "shmctl",
-               "shmget",
-
-               "alarm",
-               "execve",
-               "getrandom",
-               "getrlimit",
-               "getrusage",
-               "getpgrp",
-               "getppid",
-               "getpid",
-               "getpriority",
-               "getresgid",
-               "getresuid",
-               "gettid",
-               "getuid",
-               "geteuid",
-               "getgid",
-               "getegid",
-               "rt_sigaction",
-               "rt_sigprocmask",
-               "rt_sigreturn",
-               "sigaltstack",
-
-               "arch_prctl",
-               "capset",
-               "capget",
-               "clone",
-               "exit",
-               "exit_group",
-               "kill",
-               "restart_syscall",
-               "seccomp",
-               "sched_getaffinity",
-               "sched_setscheduler",
-               "setpriority",
-               "set_robust_list",
-               "setsid",
-               "set_tid_address",
-               "setresuid",
-               "setresgid",
-               "sysinfo",
-               "tgkill",
-               "umask",
-               "uname",
-               "unshare",
-               "wait4",
-
-               // ASAN explodes if this doesn't work.  Sigh.
-               "setrlimit",
-
-               // Firefox uses this, but will take no for an answer.
-               // "quotactl",
-
-               // Subgraph's profile has these, but that's for Tor Browser 
Launcher.
-               //
-               // "vfork",
-               // "memfd_create", (PulseAudio?  Won't work in our container.)
-               // "personality",
-               // "mlock",
-       }
-       if err = allowSyscalls(f, allowedNoArgs); err != nil {
-               return err
-       }
-
-       // Because we patch PulseAudio's mutex creation, we can omit all PI 
futex
-       // calls.
-       if err = allowCmpEq(f, "futex", 1, futexWait, futexWaitPrivate, 
futexWakePrivate, futexCmpRequeuePrivate, futexWakeOpPrivate, 
futexWaitBitsetPrivate|futexClockRealtime, futexWake, futexWaitBitsetPrivate); 
err != nil {
-               return err
-       }
-
-       if err = allowCmpEq(f, "madvise", 2, madvNormal, madvDontneed, 
madvFree); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "ioctl", 1, fionread, tcgets, tiocgpgrp); err != 
nil {
-               return err
-       }
-       if err = allowCmpEq(f, "prctl", 0, syscall.PR_SET_NAME, 
syscall.PR_GET_NAME, syscall.PR_GET_TIMERSLACK, syscall.PR_SET_SECCOMP); err != 
nil {
-               return err
-       }
-       if err = allowCmpEq(f, "socket", 0, syscall.AF_UNIX); err != nil {
-               return err
-       }
-
-       return f.ExportBPF(fd)
-}
diff --git a/src/cmd/gen-seccomp/seccomp_tor.go 
b/src/cmd/gen-seccomp/seccomp_tor.go
deleted file mode 100644
index e6501e3..0000000
--- a/src/cmd/gen-seccomp/seccomp_tor.go
+++ /dev/null
@@ -1,595 +0,0 @@
-// secomp_tor.go - Sandbox tor seccomp rules.
-// Copyright (C) 2016  Yawning Angel.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-package main
-
-import (
-       "os"
-       "syscall"
-
-       seccomp "github.com/seccomp/libseccomp-golang"
-)
-
-var maskedCloexecNonblock = ^(uint64(syscall.SOCK_CLOEXEC | 
syscall.SOCK_NONBLOCK))
-
-func compileTorSeccompProfile(fd *os.File, useBridges bool) error {
-       defer fd.Close()
-
-       f, err := newWhitelist()
-       if err != nil {
-               return err
-       }
-       defer f.Release()
-
-       allowedNoArgs := []string{
-               "access",
-               "brk",
-               "clock_gettime",
-               "close",
-               "clone",
-               "epoll_create",
-               "epoll_wait",
-               "eventfd2",
-               "pipe2",
-               "pipe",
-               "fstat",
-               "getdents",
-               "getdents64",
-               "getegid",
-               "geteuid",
-               "getgid",
-               "getrlimit",
-               "gettimeofday",
-               "gettid",
-               "getuid",
-               "lseek",
-               "mkdir",
-               "munmap",
-               "prlimit64",
-               "read",
-               "rt_sigreturn",
-               "sched_getaffinity",
-               "sched_yield",
-               "sendmsg",
-               "set_robust_list",
-               "setrlimit",
-               "sigaltstack",
-               "stat",
-               "uname",
-               "wait4",
-               "write",
-               "writev",
-               "exit_group",
-               "exit",
-               "getrandom",
-               "sysinfo",
-               "bind",
-               "listen",
-               "connect",
-               "getsockname",
-               "recvmsg",
-               "recvfrom",
-               "sendto",
-               "unlink",
-
-               // Calls that tor can filter, but I can't due to not being in
-               // the tor daemon's process space.
-               "chown",
-               "chmod",
-               "open",
-               "openat",
-               "rename",
-
-               // Calls made prior to tor's UseSeccomp being installed.
-               "arch_prctl",
-               "chdir",
-               "execve",
-               "getpid",
-               "kill",
-               "restart_syscall",
-               "set_tid_address",
-               "unshare",
-               "rt_sigaction", // Tor filters this but libc does more.
-
-               "readlink", // ASAN needs this.
-       }
-       if err = allowSyscalls(f, allowedNoArgs); err != nil {
-               return err
-       }
-
-       if err = allowCmpEq(f, "time", 0, 0); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "madvise", 2, madvFree); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "umask", 0, 022); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "rt_sigprocmask", 0, sigBlock, sigSetmask); err 
!= nil {
-               return err
-       }
-       if err = allowCmpEq(f, "epoll_ctl", 1, syscall.EPOLL_CTL_ADD, 
syscall.EPOLL_CTL_MOD, syscall.EPOLL_CTL_DEL); err != nil {
-               return err
-       }
-       if err = torFilterPrctl(f); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "mprotect", 2, syscall.PROT_READ, 
syscall.PROT_NONE); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "flock", 1, syscall.LOCK_EX|syscall.LOCK_NB, 
syscall.LOCK_UN); err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "futex", 1, 
futexWaitBitsetPrivate|futexClockRealtime, futexWaitPrivate, futexWakePrivate); 
err != nil {
-               return err
-       }
-       if err = allowCmpEq(f, "mremap", 3, mremapMaymove); err != nil {
-               return err
-       }
-       if err = torFilterAccept4(f); err != nil {
-               return err
-       }
-       if err = torFilterPoll(f); err != nil {
-               return err
-       }
-       if err = torFilterSocket(f); err != nil {
-               return err
-       }
-       if err = torFilterSetsockopt(f); err != nil {
-               return err
-       }
-       if err = torFilterGetsockopt(f); err != nil {
-               return err
-       }
-       if err = torFilterSocketpair(f); err != nil {
-               return err
-       }
-       if err = torFilterMmap(f); err != nil {
-               return err
-       }
-       if err = torFilterFcntl(f); err != nil {
-               return err
-       }
-
-       if useBridges {
-               // XXX: One day, all the PTs will live in their own containers.
-               //
-               // Till then, just whitelist the extra calls obfs4proxy needs.
-               obfsCalls := []string{
-                       "mincore",
-                       "dup2",
-                       "select",
-                       "mkdirat",
-                       "fsync",
-                       "getpeername",
-                       "getppid",
-               }
-               if err = allowSyscalls(f, obfsCalls); err != nil {
-                       return err
-               }
-
-               // `mmap` -> `arg2 == PROT_NONE && (arg3 == 
MAP_PRIVATE|MAP_ANONYMOUS || arg3 == MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS)`
-               if err = allowCmpEq(f, "epoll_create1", 0, 
syscall.EPOLL_CLOEXEC); err != nil {
-                       return err
-               }
-               if err = allowCmpEq(f, "mprotect", 2, 
syscall.PROT_READ|syscall.PROT_WRITE); err != nil {
-                       return err
-               }
-               if err = allowCmpEq(f, "futex", 1, futexWake, futexWait); err 
!= nil {
-                       return err
-               }
-               if err = obfsFilterSetsockopt(f); err != nil {
-                       return err
-               }
-               if err = obfsFilterMmap(f); err != nil {
-                       return err
-               }
-       }
-
-       return f.ExportBPF(fd)
-}
-
-func torFilterPrctl(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("prctl")
-       if err != nil {
-               return err
-       }
-
-       isPrSetDumpable, err := seccomp.MakeCondition(0, seccomp.CompareEqual, 
syscall.PR_SET_DUMPABLE)
-       if err != nil {
-               return err
-       }
-       arg1IsZero, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 0)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isPrSetDumpable, arg1IsZero}); err != nil {
-               return err
-       }
-
-       isPrSetDeathsig, err := seccomp.MakeCondition(0, seccomp.CompareEqual, 
syscall.PR_SET_PDEATHSIG)
-       if err != nil {
-               return err
-       }
-       return f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isPrSetDeathsig})
-}
-
-func torFilterAccept4(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("accept4")
-       if err != nil {
-               return err
-       }
-
-       cond, err := seccomp.MakeCondition(3, seccomp.CompareMaskedEqual, 
maskedCloexecNonblock, 0)
-       if err != nil {
-               return nil
-       }
-
-       return f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{cond})
-}
-
-func torFilterPoll(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("poll")
-       if err != nil {
-               return err
-       }
-
-       isPollIn, err := seccomp.MakeCondition(1, seccomp.CompareEqual, pollIn)
-       if err != nil {
-               return err
-       }
-       timeoutIsTen, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 10)
-       if err != nil {
-               return err
-       }
-       return f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isPollIn, timeoutIsTen})
-}
-
-func torFilterSocket(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("socket")
-       if err != nil {
-               return err
-       }
-
-       makeCondType := func(t uint64) (seccomp.ScmpCondition, error) {
-               return seccomp.MakeCondition(1, seccomp.CompareMaskedEqual, 
maskedCloexecNonblock, t)
-       }
-
-       // tor allows PF_FILE, which is PF_LOCAL on Linux, not sure why.
-
-       for _, d := range []uint64{syscall.AF_INET, syscall.AF_INET6} {
-               isDomain, err := seccomp.MakeCondition(0, seccomp.CompareEqual, 
d)
-               if err != nil {
-                       return err
-               }
-
-               for _, t := range []uint64{syscall.SOCK_STREAM, 
syscall.SOCK_DGRAM} {
-                       protocols := []uint64{syscall.IPPROTO_IP, 
syscall.IPPROTO_UDP}
-                       if t == syscall.SOCK_STREAM {
-                               protocols = append(protocols, 
syscall.IPPROTO_TCP)
-                       }
-
-                       isType, err := makeCondType(t)
-                       if err != nil {
-                               return err
-                       }
-
-                       for _, p := range protocols {
-                               isProtocol, err := seccomp.MakeCondition(2, 
seccomp.CompareEqual, p)
-                               if err != nil {
-                                       return err
-                               }
-
-                               if err = f.AddRuleConditional(scall, 
seccomp.ActAllow, []seccomp.ScmpCondition{isDomain, isType, isProtocol}); err 
!= nil {
-                                       return err
-                               }
-                       }
-               }
-       }
-
-       isAfLocal, err := seccomp.MakeCondition(0, seccomp.CompareEqual, 
syscall.AF_LOCAL)
-       if err != nil {
-               return err
-       }
-       for _, t := range []uint64{syscall.SOCK_STREAM, syscall.SOCK_DGRAM} {
-               isType, err := makeCondType(t)
-               if err != nil {
-                       return err
-               }
-               isProtocol, err := seccomp.MakeCondition(2, 
seccomp.CompareEqual, 0)
-               if err != nil {
-                       return err
-               }
-               if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isAfLocal, isType, isProtocol}); err != nil {
-                       return err
-               }
-       }
-
-       // tor allows socket(AF_NETLINK, SOCK_RAW, 0), which is used to check 
it's
-       // IP address, but will take "no".
-
-       return nil
-}
-
-func torFilterSetsockopt(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("setsockopt")
-       if err != nil {
-               return err
-       }
-
-       isSolSocket, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.SOL_SOCKET)
-       if err != nil {
-               return err
-       }
-
-       okOpts := []uint64{
-               syscall.SO_REUSEADDR,
-               syscall.SO_SNDBUF,
-               syscall.SO_RCVBUF,
-       }
-
-       for _, opt := range okOpts {
-               isOpt, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
opt)
-               if err != nil {
-                       return err
-               }
-               if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isSolSocket, isOpt}); err != nil {
-                       return err
-               }
-       }
-
-       return nil
-}
-
-func torFilterGetsockopt(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("getsockopt")
-       if err != nil {
-               return err
-       }
-
-       isSolSocket, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.SOL_SOCKET)
-       if err != nil {
-               return err
-       }
-       optIsError, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.SO_ERROR)
-       if err != nil {
-               return err
-       }
-       return f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isSolSocket, optIsError})
-}
-
-func torFilterSocketpair(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("socketpair")
-       if err != nil {
-               return err
-       }
-
-       isPfLocal, err := seccomp.MakeCondition(0, seccomp.CompareEqual, 
syscall.AF_LOCAL)
-       if err != nil {
-               return err
-       }
-
-       // XXX: src/common/compat.c:tor_socketpair looks like it uses 
SOCK_CLOEXEC,
-       //  but according to strace, fcntl is used to actually set the flag 
(6.0.6).
-       okTypes := []uint64{
-               syscall.SOCK_STREAM,
-               syscall.SOCK_STREAM | syscall.SOCK_CLOEXEC,
-       }
-       for _, t := range okTypes {
-               isType, err := seccomp.MakeCondition(1, seccomp.CompareEqual, t)
-               if err != nil {
-                       return err
-               }
-               if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isPfLocal, isType}); err != nil {
-                       return err
-               }
-       }
-       return nil
-}
-
-func torFilterMmap(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("mmap")
-       if err != nil {
-               return err
-       }
-
-       // (arg2 == PROT_READ && arg3 == MAP_PRIVATE)
-       isProtRead, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.PROT_READ)
-       if err != nil {
-               return err
-       }
-       isPrivate, err := seccomp.MakeCondition(3, seccomp.CompareEqual, 
syscall.MAP_PRIVATE)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isProtRead, isPrivate}); err != nil {
-               return err
-       }
-
-       // (arg2 == PROT_NONE && arg3 == MAP_PRIVATE | MAP_ANONYMOUS | 
MAP_NORESERVE)
-       isProtNone, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.PROT_NONE)
-       if err != nil {
-               return err
-       }
-       isProtNoneFlags, err := seccomp.MakeCondition(3, seccomp.CompareEqual, 
syscall.MAP_PRIVATE|syscall.MAP_ANONYMOUS|syscall.MAP_NORESERVE)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isProtNone, isProtNoneFlags}); err != nil {
-               return err
-       }
-
-       isProtReadWrite, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.PROT_READ|syscall.PROT_WRITE)
-       if err != nil {
-               return err
-       }
-       rwFlags := []uint64{
-               syscall.MAP_PRIVATE | syscall.MAP_ANONYMOUS,
-               syscall.MAP_PRIVATE | syscall.MAP_ANONYMOUS | syscall.MAP_STACK,
-               syscall.MAP_PRIVATE | syscall.MAP_FIXED | syscall.MAP_DENYWRITE,
-               syscall.MAP_PRIVATE | syscall.MAP_FIXED | syscall.MAP_ANONYMOUS,
-               syscall.MAP_PRIVATE | syscall.MAP_DENYWRITE,
-       }
-       for _, flag := range rwFlags {
-               isFlag, err := seccomp.MakeCondition(3, seccomp.CompareEqual, 
flag)
-               if err != nil {
-                       return err
-               }
-               if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isProtReadWrite, isFlag}); err != nil {
-                       return err
-               }
-       }
-
-       //  (arg2 == PROT_READ | PROT_EXEC && arg3 == MAP_PRIVATE | 
MAP_DENYWRITE)
-       // This is needed for ld-linux.so.
-       isProtReadExec, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.PROT_READ|syscall.PROT_EXEC)
-       if err != nil {
-               return err
-       }
-       isProtReadExecFlags, err := seccomp.MakeCondition(3, 
seccomp.CompareEqual, syscall.MAP_PRIVATE|syscall.MAP_DENYWRITE)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isProtReadExec, isProtReadExecFlags}); err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func torFilterFcntl(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("fcntl")
-       if err != nil {
-               return err
-       }
-
-       isFGetfl, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.F_GETFL)
-       if err != nil {
-               return err
-       }
-       isFGetfd, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.F_GETFD)
-       if err != nil {
-               return err
-       }
-
-       isFSetfl, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.F_SETFL)
-       if err != nil {
-               return err
-       }
-       isFSetflFlags, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.O_RDWR|syscall.O_NONBLOCK)
-       if err != nil {
-               return err
-       }
-
-       isFSetfd, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.F_SETFD)
-       if err != nil {
-               return err
-       }
-       isFdCloexec, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.FD_CLOEXEC)
-       if err != nil {
-               return err
-       }
-
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isFGetfl}); err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isFGetfd}); err != nil {
-               return err
-       }
-
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isFSetfl, isFSetflFlags}); err != nil {
-               return err
-       }
-
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isFSetfd, isFdCloexec}); err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func obfsFilterSetsockopt(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("setsockopt")
-       if err != nil {
-               return err
-       }
-
-       isSolTcp, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.SOL_TCP)
-       if err != nil {
-               return err
-       }
-       isTcpNodelay, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.TCP_NODELAY)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isSolTcp, isTcpNodelay}); err != nil {
-               return err
-       }
-
-       isSolSocket, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.SOL_SOCKET)
-       if err != nil {
-               return err
-       }
-       isSoBroadcast, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.SO_BROADCAST)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isSolSocket, isSoBroadcast}); err != nil {
-               return err
-       }
-
-       isSolIpv6, err := seccomp.MakeCondition(1, seccomp.CompareEqual, 
syscall.SOL_IPV6)
-       if err != nil {
-               return err
-       }
-       isIpv6Only, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.IPV6_V6ONLY)
-       if err != nil {
-               return err
-       }
-       if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isSolIpv6, isIpv6Only}); err != nil {
-               return err
-       }
-
-       return nil
-}
-
-// `mmap` -> `arg2 == PROT_NONE && (arg3 == MAP_PRIVATE|MAP_ANONYMOUS || arg3 
== MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS)`
-func obfsFilterMmap(f *seccomp.ScmpFilter) error {
-       scall, err := seccomp.GetSyscallFromName("mmap")
-       if err != nil {
-               return err
-       }
-
-       isProtNone, err := seccomp.MakeCondition(2, seccomp.CompareEqual, 
syscall.PROT_NONE)
-       if err != nil {
-               return err
-       }
-       protNoneFlags := []uint64{
-               syscall.MAP_PRIVATE | syscall.MAP_ANONYMOUS,
-               syscall.MAP_PRIVATE | syscall.MAP_FIXED | syscall.MAP_ANONYMOUS,
-       }
-       for _, flag := range protNoneFlags {
-               isFlag, err := seccomp.MakeCondition(3, seccomp.CompareEqual, 
flag)
-               if err != nil {
-                       return err
-               }
-               if err = f.AddRuleConditional(scall, seccomp.ActAllow, 
[]seccomp.ScmpCondition{isProtNone, isFlag}); err != nil {
-                       return err
-               }
-       }
-       return nil
-}
diff --git a/src/cmd/sandboxed-tor-browser/internal/sandbox/seccomp.go 
b/src/cmd/sandboxed-tor-browser/internal/sandbox/seccomp.go
index c88005e..9d5ec90 100644
--- a/src/cmd/sandboxed-tor-browser/internal/sandbox/seccomp.go
+++ b/src/cmd/sandboxed-tor-browser/internal/sandbox/seccomp.go
@@ -17,34 +17,81 @@
 package sandbox
 
 import (
+       "encoding/binary"
+       "fmt"
        "os"
        "runtime"
 
+       "github.com/twtiger/gosecco"
+       "github.com/twtiger/gosecco/parser"
+
        "cmd/sandboxed-tor-browser/internal/data"
 )
 
 func installTorSeccompProfile(fd *os.File, useBridges bool) error {
-       assetFile := "tor-"
-       if useBridges {
-               assetFile = assetFile + "obfs4-"
-       }
-       assetFile = assetFile + runtime.GOARCH + ".bpf"
+       commonAssetFile := "tor-common-" + runtime.GOARCH + ".seccomp"
 
-       bpf, err := data.Asset(assetFile)
-       if err != nil {
-               return err
+       assets := []string{commonAssetFile}
+       if useBridges {
+               assets = append(assets, "tor-obfs4-"+runtime.GOARCH+".seccomp")
+       } else {
+               assets = append(assets, "tor-"+runtime.GOARCH+".seccomp")
        }
 
-       return writeBuffer(fd, bpf)
+       return installSeccomp(fd, assets)
 }
 
 func installTorBrowserSeccompProfile(fd *os.File) error {
-       assetFile := "torbrowser-" + runtime.GOARCH + ".bpf"
+       assetFile := "torbrowser-" + runtime.GOARCH + ".seccomp"
+
+       return installSeccomp(fd, []string{assetFile})
+}
+
+func installSeccomp(fd *os.File, ruleAssets []string) error {
+       defer fd.Close()
 
-       bpf, err := data.Asset(assetFile)
+       settings := gosecco.SeccompSettings{
+               DefaultPositiveAction: "allow",
+               DefaultNegativeAction: "ENOSYS",
+               DefaultPolicyAction:   "ENOSYS",
+               ActionOnX32:           "kill",
+               ActionOnAuditFailure:  "kill",
+       }
+
+       if len(ruleAssets) == 0 {
+               return fmt.Errorf("installSeccomp() called with no rules")
+       }
+
+       // Combine the rules into a single source.
+       var sources []parser.Source
+       for _, asset := range ruleAssets {
+               rules, err := data.Asset(asset)
+               if err != nil {
+                       return err
+               }
+               source := &parser.StringSource{
+                       Name:    asset,
+                       Content: string(rules),
+               }
+               sources = append(sources, source)
+       }
+
+       // Compile the combined source into bpf bytecode.
+       combined := parser.CombineSources(sources...)
+       bpf, err := gosecco.PrepareSource(combined, settings)
        if err != nil {
                return err
        }
 
-       return writeBuffer(fd, bpf)
+       // Install the bpf bytecode.
+       if size, limit := len(bpf), 0xffff; size > limit {
+               return fmt.Errorf("filter program too big: %d bpf instructions 
(limit = %d)", size, limit)
+       }
+       for _, rule := range bpf {
+               if err := binary.Write(fd, binary.LittleEndian, rule); err != 
nil {
+                       return err
+               }
+       }
+
+       return nil
 }
diff --git a/vendor/manifest b/vendor/manifest
index 04dfc33..a783eed 100644
--- a/vendor/manifest
+++ b/vendor/manifest
@@ -38,12 +38,6 @@
                        "branch": "master"
                },
                {
-                       "importpath": "github.com/seccomp/libseccomp-golang",
-                       "repository": 
"https://github.com/seccomp/libseccomp-golang";,
-                       "revision": "32f571b70023028bd57d9288c20efbcb237f3ce0",
-                       "branch": "master"
-               },
-               {
                        "importpath": "github.com/twtiger/gosecco",
                        "repository": "https://github.com/twtiger/gosecco";,
                        "revision": "81110d334ed7a530d99ad620375855246f21d524",
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/LICENSE 
b/vendor/src/github.com/seccomp/libseccomp-golang/LICENSE
deleted file mode 100644
index 81cf60d..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2015 Matthew Heon <[email protected]>
-Copyright (c) 2015 Paul Moore <[email protected]>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-- Redistributions of source code must retain the above copyright notice,
-  this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/README 
b/vendor/src/github.com/seccomp/libseccomp-golang/README
deleted file mode 100644
index 64cab69..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/README
+++ /dev/null
@@ -1,26 +0,0 @@
-libseccomp-golang: Go Language Bindings for the libseccomp Project
-===============================================================================
-https://github.com/seccomp/libseccomp-golang
-https://github.com/seccomp/libseccomp
-
-The libseccomp library provides an easy to use, platform independent, interface
-to the Linux Kernel's syscall filtering mechanism.  The libseccomp API is
-designed to abstract away the underlying BPF based syscall filter language and
-present a more conventional function-call based filtering interface that should
-be familiar to, and easily adopted by, application developers.
-
-The libseccomp-golang library provides a Go based interface to the libseccomp
-library.
-
-* Online Resources
-
-The library source repository currently lives on GitHub at the following URLs:
-
-       -> https://github.com/seccomp/libseccomp-golang
-       -> https://github.com/seccomp/libseccomp
-
-The project mailing list is currently hosted on Google Groups at the URL below,
-please note that a Google account is not required to subscribe to the mailing
-list.
-
-       -> https://groups.google.com/d/forum/libseccomp
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp.go 
b/vendor/src/github.com/seccomp/libseccomp-golang/seccomp.go
deleted file mode 100644
index b2c010f..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp.go
+++ /dev/null
@@ -1,857 +0,0 @@
-// +build linux
-
-// Public API specification for libseccomp Go bindings
-// Contains public API for the bindings
-
-// Package seccomp provides bindings for libseccomp, a library wrapping the 
Linux
-// seccomp syscall. Seccomp enables an application to restrict system call use
-// for itself and its children.
-package seccomp
-
-import (
-       "fmt"
-       "os"
-       "runtime"
-       "strings"
-       "sync"
-       "syscall"
-       "unsafe"
-)
-
-// C wrapping code
-
-// #cgo pkg-config: libseccomp
-// #include <stdlib.h>
-// #include <seccomp.h>
-import "C"
-
-// Exported types
-
-// ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
-// per-architecture basis.
-type ScmpArch uint
-
-// ScmpAction represents an action to be taken on a filter rule match in
-// libseccomp
-type ScmpAction uint
-
-// ScmpCompareOp represents a comparison operator which can be used in a filter
-// rule
-type ScmpCompareOp uint
-
-// ScmpCondition represents a rule in a libseccomp filter context
-type ScmpCondition struct {
-       Argument uint          `json:"argument,omitempty"`
-       Op       ScmpCompareOp `json:"operator,omitempty"`
-       Operand1 uint64        `json:"operand_one,omitempty"`
-       Operand2 uint64        `json:"operand_two,omitempty"`
-}
-
-// ScmpSyscall represents a Linux System Call
-type ScmpSyscall int32
-
-// Exported Constants
-
-const (
-       // Valid architectures recognized by libseccomp
-       // ARM64 and all MIPS architectures are unsupported by versions of the
-       // library before v2.2 and will return errors if used
-
-       // ArchInvalid is a placeholder to ensure uninitialized ScmpArch
-       // variables are invalid
-       ArchInvalid ScmpArch = iota
-       // ArchNative is the native architecture of the kernel
-       ArchNative ScmpArch = iota
-       // ArchX86 represents 32-bit x86 syscalls
-       ArchX86 ScmpArch = iota
-       // ArchAMD64 represents 64-bit x86-64 syscalls
-       ArchAMD64 ScmpArch = iota
-       // ArchX32 represents 64-bit x86-64 syscalls (32-bit pointers)
-       ArchX32 ScmpArch = iota
-       // ArchARM represents 32-bit ARM syscalls
-       ArchARM ScmpArch = iota
-       // ArchARM64 represents 64-bit ARM syscalls
-       ArchARM64 ScmpArch = iota
-       // ArchMIPS represents 32-bit MIPS syscalls
-       ArchMIPS ScmpArch = iota
-       // ArchMIPS64 represents 64-bit MIPS syscalls
-       ArchMIPS64 ScmpArch = iota
-       // ArchMIPS64N32 represents 64-bit MIPS syscalls (32-bit pointers)
-       ArchMIPS64N32 ScmpArch = iota
-       // ArchMIPSEL represents 32-bit MIPS syscalls (little endian)
-       ArchMIPSEL ScmpArch = iota
-       // ArchMIPSEL64 represents 64-bit MIPS syscalls (little endian)
-       ArchMIPSEL64 ScmpArch = iota
-       // ArchMIPSEL64N32 represents 64-bit MIPS syscalls (little endian,
-       // 32-bit pointers)
-       ArchMIPSEL64N32 ScmpArch = iota
-       // ArchPPC represents 32-bit POWERPC syscalls
-       ArchPPC ScmpArch = iota
-       // ArchPPC64 represents 64-bit POWER syscalls (big endian)
-       ArchPPC64 ScmpArch = iota
-       // ArchPPC64LE represents 64-bit POWER syscalls (little endian)
-       ArchPPC64LE ScmpArch = iota
-       // ArchS390 represents 31-bit System z/390 syscalls
-       ArchS390 ScmpArch = iota
-       // ArchS390X represents 64-bit System z/390 syscalls
-       ArchS390X ScmpArch = iota
-)
-
-const (
-       // Supported actions on filter match
-
-       // ActInvalid is a placeholder to ensure uninitialized ScmpAction
-       // variables are invalid
-       ActInvalid ScmpAction = iota
-       // ActKill kills the process
-       ActKill ScmpAction = iota
-       // ActTrap throws SIGSYS
-       ActTrap ScmpAction = iota
-       // ActErrno causes the syscall to return a negative error code. This
-       // code can be set with the SetReturnCode method
-       ActErrno ScmpAction = iota
-       // ActTrace causes the syscall to notify tracing processes with the
-       // given error code. This code can be set with the SetReturnCode method
-       ActTrace ScmpAction = iota
-       // ActAllow permits the syscall to continue execution
-       ActAllow ScmpAction = iota
-)
-
-const (
-       // These are comparison operators used in conditional seccomp rules
-       // They are used to compare the value of a single argument of a syscall
-       // against a user-defined constant
-
-       // CompareInvalid is a placeholder to ensure uninitialized ScmpCompareOp
-       // variables are invalid
-       CompareInvalid ScmpCompareOp = iota
-       // CompareNotEqual returns true if the argument is not equal to the
-       // given value
-       CompareNotEqual ScmpCompareOp = iota
-       // CompareLess returns true if the argument is less than the given value
-       CompareLess ScmpCompareOp = iota
-       // CompareLessOrEqual returns true if the argument is less than or equal
-       // to the given value
-       CompareLessOrEqual ScmpCompareOp = iota
-       // CompareEqual returns true if the argument is equal to the given value
-       CompareEqual ScmpCompareOp = iota
-       // CompareGreaterEqual returns true if the argument is greater than or
-       // equal to the given value
-       CompareGreaterEqual ScmpCompareOp = iota
-       // CompareGreater returns true if the argument is greater than the given
-       // value
-       CompareGreater ScmpCompareOp = iota
-       // CompareMaskedEqual returns true if the argument is equal to the given
-       // value, when masked (bitwise &) against the second given value
-       CompareMaskedEqual ScmpCompareOp = iota
-)
-
-// Helpers for types
-
-// GetArchFromString returns an ScmpArch constant from a string representing an
-// architecture
-func GetArchFromString(arch string) (ScmpArch, error) {
-       switch strings.ToLower(arch) {
-       case "x86":
-               return ArchX86, nil
-       case "amd64", "x86-64", "x86_64", "x64":
-               return ArchAMD64, nil
-       case "x32":
-               return ArchX32, nil
-       case "arm":
-               return ArchARM, nil
-       case "arm64", "aarch64":
-               return ArchARM64, nil
-       case "mips":
-               return ArchMIPS, nil
-       case "mips64":
-               return ArchMIPS64, nil
-       case "mips64n32":
-               return ArchMIPS64N32, nil
-       case "mipsel":
-               return ArchMIPSEL, nil
-       case "mipsel64":
-               return ArchMIPSEL64, nil
-       case "mipsel64n32":
-               return ArchMIPSEL64N32, nil
-       case "ppc":
-               return ArchPPC, nil
-       case "ppc64":
-               return ArchPPC64, nil
-       case "ppc64le":
-               return ArchPPC64LE, nil
-       case "s390":
-               return ArchS390, nil
-       case "s390x":
-               return ArchS390X, nil
-       default:
-               return ArchInvalid, fmt.Errorf("cannot convert unrecognized 
string %s", arch)
-       }
-}
-
-// String returns a string representation of an architecture constant
-func (a ScmpArch) String() string {
-       switch a {
-       case ArchX86:
-               return "x86"
-       case ArchAMD64:
-               return "amd64"
-       case ArchX32:
-               return "x32"
-       case ArchARM:
-               return "arm"
-       case ArchARM64:
-               return "arm64"
-       case ArchMIPS:
-               return "mips"
-       case ArchMIPS64:
-               return "mips64"
-       case ArchMIPS64N32:
-               return "mips64n32"
-       case ArchMIPSEL:
-               return "mipsel"
-       case ArchMIPSEL64:
-               return "mipsel64"
-       case ArchMIPSEL64N32:
-               return "mipsel64n32"
-       case ArchPPC:
-               return "ppc"
-       case ArchPPC64:
-               return "ppc64"
-       case ArchPPC64LE:
-               return "ppc64le"
-       case ArchS390:
-               return "s390"
-       case ArchS390X:
-               return "s390x"
-       case ArchNative:
-               return "native"
-       case ArchInvalid:
-               return "Invalid architecture"
-       default:
-               return "Unknown architecture"
-       }
-}
-
-// String returns a string representation of a comparison operator constant
-func (a ScmpCompareOp) String() string {
-       switch a {
-       case CompareNotEqual:
-               return "Not equal"
-       case CompareLess:
-               return "Less than"
-       case CompareLessOrEqual:
-               return "Less than or equal to"
-       case CompareEqual:
-               return "Equal"
-       case CompareGreaterEqual:
-               return "Greater than or equal to"
-       case CompareGreater:
-               return "Greater than"
-       case CompareMaskedEqual:
-               return "Masked equality"
-       case CompareInvalid:
-               return "Invalid comparison operator"
-       default:
-               return "Unrecognized comparison operator"
-       }
-}
-
-// String returns a string representation of a seccomp match action
-func (a ScmpAction) String() string {
-       switch a & 0xFFFF {
-       case ActKill:
-               return "Action: Kill Process"
-       case ActTrap:
-               return "Action: Send SIGSYS"
-       case ActErrno:
-               return fmt.Sprintf("Action: Return error code %d", (a >> 16))
-       case ActTrace:
-               return fmt.Sprintf("Action: Notify tracing processes with code 
%d",
-                       (a >> 16))
-       case ActAllow:
-               return "Action: Allow system call"
-       default:
-               return "Unrecognized Action"
-       }
-}
-
-// SetReturnCode adds a return code to a supporting ScmpAction, clearing any
-// existing code Only valid on ActErrno and ActTrace. Takes no action 
otherwise.
-// Accepts 16-bit return code as argument.
-// Returns a valid ScmpAction of the original type with the new error code set.
-func (a ScmpAction) SetReturnCode(code int16) ScmpAction {
-       aTmp := a & 0x0000FFFF
-       if aTmp == ActErrno || aTmp == ActTrace {
-               return (aTmp | (ScmpAction(code)&0xFFFF)<<16)
-       }
-       return a
-}
-
-// GetReturnCode returns the return code of an ScmpAction
-func (a ScmpAction) GetReturnCode() int16 {
-       return int16(a >> 16)
-}
-
-// General utility functions
-
-// GetLibraryVersion returns the version of the library the bindings are built
-// against.
-// The version is formatted as follows: Major.Minor.Micro
-func GetLibraryVersion() (major, minor, micro int) {
-       return verMajor, verMinor, verMicro
-}
-
-// Syscall functions
-
-// GetName retrieves the name of a syscall from its number.
-// Acts on any syscall number.
-// Returns either a string containing the name of the syscall, or an error.
-func (s ScmpSyscall) GetName() (string, error) {
-       return s.GetNameByArch(ArchNative)
-}
-
-// GetNameByArch retrieves the name of a syscall from its number for a given
-// architecture.
-// Acts on any syscall number.
-// Accepts a valid architecture constant.
-// Returns either a string containing the name of the syscall, or an error.
-// if the syscall is unrecognized or an issue occurred.
-func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
-       if err := sanitizeArch(arch); err != nil {
-               return "", err
-       }
-
-       cString := C.seccomp_syscall_resolve_num_arch(arch.toNative(), C.int(s))
-       if cString == nil {
-               return "", fmt.Errorf("could not resolve syscall name")
-       }
-       defer C.free(unsafe.Pointer(cString))
-
-       finalStr := C.GoString(cString)
-       return finalStr, nil
-}
-
-// GetSyscallFromName returns the number of a syscall by name on the kernel's
-// native architecture.
-// Accepts a string containing the name of a syscall.
-// Returns the number of the syscall, or an error if no syscall with that name
-// was found.
-func GetSyscallFromName(name string) (ScmpSyscall, error) {
-       cString := C.CString(name)
-       defer C.free(unsafe.Pointer(cString))
-
-       result := C.seccomp_syscall_resolve_name(cString)
-       if result == scmpError {
-               return 0, fmt.Errorf("could not resolve name to syscall")
-       }
-
-       return ScmpSyscall(result), nil
-}
-
-// GetSyscallFromNameByArch returns the number of a syscall by name for a given
-// architecture's ABI.
-// Accepts the name of a syscall and an architecture constant.
-// Returns the number of the syscall, or an error if an invalid architecture is
-// passed or a syscall with that name was not found.
-func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) 
{
-       if err := sanitizeArch(arch); err != nil {
-               return 0, err
-       }
-
-       cString := C.CString(name)
-       defer C.free(unsafe.Pointer(cString))
-
-       result := C.seccomp_syscall_resolve_name_arch(arch.toNative(), cString)
-       if result == scmpError {
-               return 0, fmt.Errorf("could not resolve name to syscall")
-       }
-
-       return ScmpSyscall(result), nil
-}
-
-// MakeCondition creates and returns a new condition to attach to a filter 
rule.
-// Associated rules will only match if this condition is true.
-// Accepts the number the argument we are checking, and a comparison operator
-// and value to compare to.
-// The rule will match if argument $arg (zero-indexed) of the syscall is
-// $COMPARE_OP the provided comparison value.
-// Some comparison operators accept two values. Masked equals, for example,
-// will mask $arg of the syscall with the second value provided (via bitwise
-// AND) and then compare against the first value provided.
-// For example, in the less than or equal case, if the syscall argument was
-// 0 and the value provided was 1, the condition would match, as 0 is less
-// than or equal to 1.
-// Return either an error on bad argument or a valid ScmpCondition struct.
-func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) 
(ScmpCondition, error) {
-       var condStruct ScmpCondition
-
-       if comparison == CompareInvalid {
-               return condStruct, fmt.Errorf("invalid comparison operator")
-       } else if arg > 5 {
-               return condStruct, fmt.Errorf("syscalls only have up to 6 
arguments")
-       } else if len(values) > 2 {
-               return condStruct, fmt.Errorf("conditions can have at most 2 
arguments")
-       } else if len(values) == 0 {
-               return condStruct, fmt.Errorf("must provide at least one value 
to compare against")
-       }
-
-       condStruct.Argument = arg
-       condStruct.Op = comparison
-       condStruct.Operand1 = values[0]
-       if len(values) == 2 {
-               condStruct.Operand2 = values[1]
-       } else {
-               condStruct.Operand2 = 0 // Unused
-       }
-
-       return condStruct, nil
-}
-
-// Utility Functions
-
-// GetNativeArch returns architecture token representing the native kernel
-// architecture
-func GetNativeArch() (ScmpArch, error) {
-       arch := C.seccomp_arch_native()
-
-       return archFromNative(arch)
-}
-
-// Public Filter API
-
-// ScmpFilter represents a filter context in libseccomp.
-// A filter context is initially empty. Rules can be added to it, and it can
-// then be loaded into the kernel.
-type ScmpFilter struct {
-       filterCtx C.scmp_filter_ctx
-       valid     bool
-       lock      sync.Mutex
-}
-
-// NewFilter creates and returns a new filter context.
-// Accepts a default action to be taken for syscalls which match no rules in
-// the filter.
-// Returns a reference to a valid filter context, or nil and an error if the
-// filter context could not be created or an invalid default action was given.
-func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
-       if err := sanitizeAction(defaultAction); err != nil {
-               return nil, err
-       }
-
-       fPtr := C.seccomp_init(defaultAction.toNative())
-       if fPtr == nil {
-               return nil, fmt.Errorf("could not create filter")
-       }
-
-       filter := new(ScmpFilter)
-       filter.filterCtx = fPtr
-       filter.valid = true
-       runtime.SetFinalizer(filter, filterFinalizer)
-
-       return filter, nil
-}
-
-// IsValid determines whether a filter context is valid to use.
-// Some operations (Release and Merge) render filter contexts invalid and
-// consequently prevent further use.
-func (f *ScmpFilter) IsValid() bool {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       return f.valid
-}
-
-// Reset resets a filter context, removing all its existing state.
-// Accepts a new default action to be taken for syscalls which do not match.
-// Returns an error if the filter or action provided are invalid.
-func (f *ScmpFilter) Reset(defaultAction ScmpAction) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if err := sanitizeAction(defaultAction); err != nil {
-               return err
-       } else if !f.valid {
-               return errBadFilter
-       }
-
-       retCode := C.seccomp_reset(f.filterCtx, defaultAction.toNative())
-       if retCode != 0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// Release releases a filter context, freeing its memory. Should be called 
after
-// loading into the kernel, when the filter is no longer needed.
-// After calling this function, the given filter is no longer valid and cannot
-// be used.
-// Release() will be invoked automatically when a filter context is garbage
-// collected, but can also be called manually to free memory.
-func (f *ScmpFilter) Release() {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if !f.valid {
-               return
-       }
-
-       f.valid = false
-       C.seccomp_release(f.filterCtx)
-}
-
-// Merge merges two filter contexts.
-// The source filter src will be released as part of the process, and will no
-// longer be usable or valid after this call.
-// To be merged, filters must NOT share any architectures, and all their
-// attributes (Default Action, Bad Arch Action, No New Privs and TSync bools)
-// must match.
-// The filter src will be merged into the filter this is called on.
-// The architectures of the src filter not present in the destination, and all
-// associated rules, will be added to the destination.
-// Returns an error if merging the filters failed.
-func (f *ScmpFilter) Merge(src *ScmpFilter) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       src.lock.Lock()
-       defer src.lock.Unlock()
-
-       if !src.valid || !f.valid {
-               return fmt.Errorf("one or more of the filter contexts is 
invalid or uninitialized")
-       }
-
-       // Merge the filters
-       retCode := C.seccomp_merge(f.filterCtx, src.filterCtx)
-       if syscall.Errno(-1*retCode) == syscall.EINVAL {
-               return fmt.Errorf("filters could not be merged due to a 
mismatch in attributes or invalid filter")
-       } else if retCode != 0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       src.valid = false
-
-       return nil
-}
-
-// IsArchPresent checks if an architecture is present in a filter.
-// If a filter contains an architecture, it uses its default action for
-// syscalls which do not match rules in it, and its rules can match syscalls
-// for that ABI.
-// If a filter does not contain an architecture, all syscalls made to that
-// kernel ABI will fail with the filter's default Bad Architecture Action
-// (by default, killing the process).
-// Accepts an architecture constant.
-// Returns true if the architecture is present in the filter, false otherwise,
-// and an error on an invalid filter context, architecture constant, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) IsArchPresent(arch ScmpArch) (bool, error) {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if err := sanitizeArch(arch); err != nil {
-               return false, err
-       } else if !f.valid {
-               return false, errBadFilter
-       }
-
-       retCode := C.seccomp_arch_exist(f.filterCtx, arch.toNative())
-       if syscall.Errno(-1*retCode) == syscall.EEXIST {
-               // -EEXIST is "arch not present"
-               return false, nil
-       } else if retCode != 0 {
-               return false, syscall.Errno(-1 * retCode)
-       }
-
-       return true, nil
-}
-
-// AddArch adds an architecture to the filter.
-// Accepts an architecture constant.
-// Returns an error on invalid filter context or architecture token, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) AddArch(arch ScmpArch) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if err := sanitizeArch(arch); err != nil {
-               return err
-       } else if !f.valid {
-               return errBadFilter
-       }
-
-       // Libseccomp returns -EEXIST if the specified architecture is already
-       // present. Succeed silently in this case, as it's not fatal, and the
-       // architecture is present already.
-       retCode := C.seccomp_arch_add(f.filterCtx, arch.toNative())
-       if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// RemoveArch removes an architecture from the filter.
-// Accepts an architecture constant.
-// Returns an error on invalid filter context or architecture token, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) RemoveArch(arch ScmpArch) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if err := sanitizeArch(arch); err != nil {
-               return err
-       } else if !f.valid {
-               return errBadFilter
-       }
-
-       // Similar to AddArch, -EEXIST is returned if the arch is not present
-       // Succeed silently in that case, this is not fatal and the architecture
-       // is not present in the filter after RemoveArch
-       retCode := C.seccomp_arch_remove(f.filterCtx, arch.toNative())
-       if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// Load loads a filter context into the kernel.
-// Returns an error if the filter context is invalid or the syscall failed.
-func (f *ScmpFilter) Load() error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if !f.valid {
-               return errBadFilter
-       }
-
-       if retCode := C.seccomp_load(f.filterCtx); retCode != 0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// GetDefaultAction returns the default action taken on a syscall which does 
not
-// match a rule in the filter, or an error if an issue was encountered
-// retrieving the value.
-func (f *ScmpFilter) GetDefaultAction() (ScmpAction, error) {
-       action, err := f.getFilterAttr(filterAttrActDefault)
-       if err != nil {
-               return 0x0, err
-       }
-
-       return actionFromNative(action)
-}
-
-// GetBadArchAction returns the default action taken on a syscall for an
-// architecture not in the filter, or an error if an issue was encountered
-// retrieving the value.
-func (f *ScmpFilter) GetBadArchAction() (ScmpAction, error) {
-       action, err := f.getFilterAttr(filterAttrActBadArch)
-       if err != nil {
-               return 0x0, err
-       }
-
-       return actionFromNative(action)
-}
-
-// GetNoNewPrivsBit returns the current state the No New Privileges bit will 
be set
-// to on the filter being loaded, or an error if an issue was encountered
-// retrieving the value.
-// The No New Privileges bit tells the kernel that new processes run with 
exec()
-// cannot gain more privileges than the process that ran exec().
-// For example, a process with No New Privileges set would be unable to exec
-// setuid/setgid executables.
-func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) {
-       noNewPrivs, err := f.getFilterAttr(filterAttrNNP)
-       if err != nil {
-               return false, err
-       }
-
-       if noNewPrivs == 0 {
-               return false, nil
-       }
-
-       return true, nil
-}
-
-// GetTsyncBit returns whether Thread Synchronization will be enabled on the
-// filter being loaded, or an error if an issue was encountered retrieving the
-// value.
-// Thread Sync ensures that all members of the thread group of the calling
-// process will share the same Seccomp filter set.
-// Tsync is a fairly recent addition to the Linux kernel and older kernels
-// lack support. If the running kernel does not support Tsync and it is
-// requested in a filter, Libseccomp will not enable TSync support and will
-// proceed as normal.
-// This function is unavailable before v2.2 of libseccomp and will return an
-// error.
-func (f *ScmpFilter) GetTsyncBit() (bool, error) {
-       tSync, err := f.getFilterAttr(filterAttrTsync)
-       if err != nil {
-               return false, err
-       }
-
-       if tSync == 0 {
-               return false, nil
-       }
-
-       return true, nil
-}
-
-// SetBadArchAction sets the default action taken on a syscall for an
-// architecture not in the filter, or an error if an issue was encountered
-// setting the value.
-func (f *ScmpFilter) SetBadArchAction(action ScmpAction) error {
-       if err := sanitizeAction(action); err != nil {
-               return err
-       }
-
-       return f.setFilterAttr(filterAttrActBadArch, action.toNative())
-}
-
-// SetNoNewPrivsBit sets the state of the No New Privileges bit, which will be
-// applied on filter load, or an error if an issue was encountered setting the
-// value.
-// Filters with No New Privileges set to 0 can only be loaded if the process
-// has the CAP_SYS_ADMIN capability.
-func (f *ScmpFilter) SetNoNewPrivsBit(state bool) error {
-       var toSet C.uint32_t = 0x0
-
-       if state {
-               toSet = 0x1
-       }
-
-       return f.setFilterAttr(filterAttrNNP, toSet)
-}
-
-// SetTsync sets whether Thread Synchronization will be enabled on the filter
-// being loaded. Returns an error if setting Tsync failed, or the filter is
-// invalid.
-// Thread Sync ensures that all members of the thread group of the calling
-// process will share the same Seccomp filter set.
-// Tsync is a fairly recent addition to the Linux kernel and older kernels
-// lack support. If the running kernel does not support Tsync and it is
-// requested in a filter, Libseccomp will not enable TSync support and will
-// proceed as normal.
-// This function is unavailable before v2.2 of libseccomp and will return an
-// error.
-func (f *ScmpFilter) SetTsync(enable bool) error {
-       var toSet C.uint32_t = 0x0
-
-       if enable {
-               toSet = 0x1
-       }
-
-       return f.setFilterAttr(filterAttrTsync, toSet)
-}
-
-// SetSyscallPriority sets a syscall's priority.
-// This provides a hint to the filter generator in libseccomp about the
-// importance of this syscall. High-priority syscalls are placed
-// first in the filter code, and incur less overhead (at the expense of
-// lower-priority syscalls).
-func (f *ScmpFilter) SetSyscallPriority(call ScmpSyscall, priority uint8) 
error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if !f.valid {
-               return errBadFilter
-       }
-
-       if retCode := C.seccomp_syscall_priority(f.filterCtx, C.int(call),
-               C.uint8_t(priority)); retCode != 0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// AddRule adds a single rule for an unconditional action on a syscall.
-// Accepts the number of the syscall and the action to be taken on the call
-// being made.
-// Returns an error if an issue was encountered adding the rule.
-func (f *ScmpFilter) AddRule(call ScmpSyscall, action ScmpAction) error {
-       return f.addRuleGeneric(call, action, false, nil)
-}
-
-// AddRuleExact adds a single rule for an unconditional action on a syscall.
-// Accepts the number of the syscall and the action to be taken on the call
-// being made.
-// No modifications will be made to the rule, and it will fail to add if it
-// cannot be applied to the current architecture without modification.
-// The rule will function exactly as described, but it may not function 
identically
-// (or be able to be applied to) all architectures.
-// Returns an error if an issue was encountered adding the rule.
-func (f *ScmpFilter) AddRuleExact(call ScmpSyscall, action ScmpAction) error {
-       return f.addRuleGeneric(call, action, true, nil)
-}
-
-// AddRuleConditional adds a single rule for a conditional action on a syscall.
-// Returns an error if an issue was encountered adding the rule.
-// All conditions must match for the rule to match.
-// There is a bug in library versions below v2.2.1 which can, in some cases,
-// cause conditions to be lost when more than one are used. Consequently,
-// AddRuleConditional is disabled on library versions lower than v2.2.1
-func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, 
conds []ScmpCondition) error {
-       return f.addRuleGeneric(call, action, false, conds)
-}
-
-// AddRuleConditionalExact adds a single rule for a conditional action on a
-// syscall.
-// No modifications will be made to the rule, and it will fail to add if it
-// cannot be applied to the current architecture without modification.
-// The rule will function exactly as described, but it may not function 
identically
-// (or be able to be applied to) all architectures.
-// Returns an error if an issue was encountered adding the rule.
-// There is a bug in library versions below v2.2.1 which can, in some cases,
-// cause conditions to be lost when more than one are used. Consequently,
-// AddRuleConditionalExact is disabled on library versions lower than v2.2.1
-func (f *ScmpFilter) AddRuleConditionalExact(call ScmpSyscall, action 
ScmpAction, conds []ScmpCondition) error {
-       return f.addRuleGeneric(call, action, true, conds)
-}
-
-// ExportPFC output PFC-formatted, human-readable dump of a filter context's
-// rules to a file.
-// Accepts file to write to (must be open for writing).
-// Returns an error if writing to the file fails.
-func (f *ScmpFilter) ExportPFC(file *os.File) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       fd := file.Fd()
-
-       if !f.valid {
-               return errBadFilter
-       }
-
-       if retCode := C.seccomp_export_pfc(f.filterCtx, C.int(fd)); retCode != 
0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// ExportBPF outputs Berkeley Packet Filter-formatted, kernel-readable dump of 
a
-// filter context's rules to a file.
-// Accepts file to write to (must be open for writing).
-// Returns an error if writing to the file fails.
-func (f *ScmpFilter) ExportBPF(file *os.File) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       fd := file.Fd()
-
-       if !f.valid {
-               return errBadFilter
-       }
-
-       if retCode := C.seccomp_export_bpf(f.filterCtx, C.int(fd)); retCode != 
0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
diff --git 
a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go 
b/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go
deleted file mode 100644
index ab67a3d..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go
+++ /dev/null
@@ -1,506 +0,0 @@
-// +build linux
-
-// Internal functions for libseccomp Go bindings
-// No exported functions
-
-package seccomp
-
-import (
-       "fmt"
-       "os"
-       "syscall"
-)
-
-// Unexported C wrapping code - provides the C-Golang interface
-// Get the seccomp header in scope
-// Need stdlib.h for free() on cstrings
-
-// #cgo pkg-config: libseccomp
-/*
-#include <stdlib.h>
-#include <seccomp.h>
-
-#if SCMP_VER_MAJOR < 2
-#error Minimum supported version of Libseccomp is v2.1.0
-#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 1
-#error Minimum supported version of Libseccomp is v2.1.0
-#endif
-
-#define ARCH_BAD ~0
-
-const uint32_t C_ARCH_BAD = ARCH_BAD;
-
-#ifndef SCMP_ARCH_AARCH64
-#define SCMP_ARCH_AARCH64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS
-#define SCMP_ARCH_MIPS ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS64
-#define SCMP_ARCH_MIPS64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS64N32
-#define SCMP_ARCH_MIPS64N32 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL
-#define SCMP_ARCH_MIPSEL ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL64
-#define SCMP_ARCH_MIPSEL64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL64N32
-#define SCMP_ARCH_MIPSEL64N32 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_PPC
-#define SCMP_ARCH_PPC ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_PPC64
-#define SCMP_ARCH_PPC64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_PPC64LE
-#define SCMP_ARCH_PPC64LE ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_S390
-#define SCMP_ARCH_S390 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_S390X
-#define SCMP_ARCH_S390X ARCH_BAD
-#endif
-
-const uint32_t C_ARCH_NATIVE       = SCMP_ARCH_NATIVE;
-const uint32_t C_ARCH_X86          = SCMP_ARCH_X86;
-const uint32_t C_ARCH_X86_64       = SCMP_ARCH_X86_64;
-const uint32_t C_ARCH_X32          = SCMP_ARCH_X32;
-const uint32_t C_ARCH_ARM          = SCMP_ARCH_ARM;
-const uint32_t C_ARCH_AARCH64      = SCMP_ARCH_AARCH64;
-const uint32_t C_ARCH_MIPS         = SCMP_ARCH_MIPS;
-const uint32_t C_ARCH_MIPS64       = SCMP_ARCH_MIPS64;
-const uint32_t C_ARCH_MIPS64N32    = SCMP_ARCH_MIPS64N32;
-const uint32_t C_ARCH_MIPSEL       = SCMP_ARCH_MIPSEL;
-const uint32_t C_ARCH_MIPSEL64     = SCMP_ARCH_MIPSEL64;
-const uint32_t C_ARCH_MIPSEL64N32  = SCMP_ARCH_MIPSEL64N32;
-const uint32_t C_ARCH_PPC          = SCMP_ARCH_PPC;
-const uint32_t C_ARCH_PPC64        = SCMP_ARCH_PPC64;
-const uint32_t C_ARCH_PPC64LE      = SCMP_ARCH_PPC64LE;
-const uint32_t C_ARCH_S390         = SCMP_ARCH_S390;
-const uint32_t C_ARCH_S390X        = SCMP_ARCH_S390X;
-
-const uint32_t C_ACT_KILL          = SCMP_ACT_KILL;
-const uint32_t C_ACT_TRAP          = SCMP_ACT_TRAP;
-const uint32_t C_ACT_ERRNO         = SCMP_ACT_ERRNO(0);
-const uint32_t C_ACT_TRACE         = SCMP_ACT_TRACE(0);
-const uint32_t C_ACT_ALLOW         = SCMP_ACT_ALLOW;
-
-// If TSync is not supported, make sure it doesn't map to a supported filter 
attribute
-// Don't worry about major version < 2, the minimum version checks should 
catch that case
-#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 2
-#define SCMP_FLTATR_CTL_TSYNC _SCMP_CMP_MIN
-#endif
-
-const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT;
-const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH;
-const uint32_t C_ATTRIBUTE_NNP     = (uint32_t)SCMP_FLTATR_CTL_NNP;
-const uint32_t C_ATTRIBUTE_TSYNC   = (uint32_t)SCMP_FLTATR_CTL_TSYNC;
-
-const int      C_CMP_NE            = (int)SCMP_CMP_NE;
-const int      C_CMP_LT            = (int)SCMP_CMP_LT;
-const int      C_CMP_LE            = (int)SCMP_CMP_LE;
-const int      C_CMP_EQ            = (int)SCMP_CMP_EQ;
-const int      C_CMP_GE            = (int)SCMP_CMP_GE;
-const int      C_CMP_GT            = (int)SCMP_CMP_GT;
-const int      C_CMP_MASKED_EQ     = (int)SCMP_CMP_MASKED_EQ;
-
-const int      C_VERSION_MAJOR     = SCMP_VER_MAJOR;
-const int      C_VERSION_MINOR     = SCMP_VER_MINOR;
-const int      C_VERSION_MICRO     = SCMP_VER_MICRO;
-
-typedef struct scmp_arg_cmp* scmp_cast_t;
-
-// Wrapper to create an scmp_arg_cmp struct
-void*
-make_struct_arg_cmp(
-                    unsigned int arg,
-                    int compare,
-                    uint64_t a,
-                    uint64_t b
-                   )
-{
-       struct scmp_arg_cmp *s = malloc(sizeof(struct scmp_arg_cmp));
-
-       s->arg = arg;
-       s->op = compare;
-       s->datum_a = a;
-       s->datum_b = b;
-
-       return s;
-}
-*/
-import "C"
-
-// Nonexported types
-type scmpFilterAttr uint32
-
-// Nonexported constants
-
-const (
-       filterAttrActDefault scmpFilterAttr = iota
-       filterAttrActBadArch scmpFilterAttr = iota
-       filterAttrNNP        scmpFilterAttr = iota
-       filterAttrTsync      scmpFilterAttr = iota
-)
-
-const (
-       // An error return from certain libseccomp functions
-       scmpError C.int = -1
-       // Comparison boundaries to check for architecture validity
-       archStart ScmpArch = ArchNative
-       archEnd   ScmpArch = ArchS390X
-       // Comparison boundaries to check for action validity
-       actionStart ScmpAction = ActKill
-       actionEnd   ScmpAction = ActAllow
-       // Comparison boundaries to check for comparison operator validity
-       compareOpStart ScmpCompareOp = CompareNotEqual
-       compareOpEnd   ScmpCompareOp = CompareMaskedEqual
-)
-
-var (
-       // Error thrown on bad filter context
-       errBadFilter = fmt.Errorf("filter is invalid or uninitialized")
-       // Constants representing library major, minor, and micro versions
-       verMajor = int(C.C_VERSION_MAJOR)
-       verMinor = int(C.C_VERSION_MINOR)
-       verMicro = int(C.C_VERSION_MICRO)
-)
-
-// Nonexported functions
-
-// Check if library version is greater than or equal to the given one
-func checkVersionAbove(major, minor, micro int) bool {
-       return (verMajor > major) ||
-               (verMajor == major && verMinor > minor) ||
-               (verMajor == major && verMinor == minor && verMicro >= micro)
-}
-
-// Init function: Verify library version is appropriate
-func init() {
-       if !checkVersionAbove(2, 1, 0) {
-               fmt.Fprintf(os.Stderr, "Libseccomp version too low: minimum 
supported is 2.1.0, detected %d.%d.%d", C.C_VERSION_MAJOR, C.C_VERSION_MINOR, 
C.C_VERSION_MICRO)
-               os.Exit(-1)
-       }
-}
-
-// Filter helpers
-
-// Filter finalizer - ensure that kernel context for filters is freed
-func filterFinalizer(f *ScmpFilter) {
-       f.Release()
-}
-
-// Get a raw filter attribute
-func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if !f.valid {
-               return 0x0, errBadFilter
-       }
-
-       if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
-               return 0x0, fmt.Errorf("the thread synchronization attribute is 
not supported in this version of the library")
-       }
-
-       var attribute C.uint32_t
-
-       retCode := C.seccomp_attr_get(f.filterCtx, attr.toNative(), &attribute)
-       if retCode != 0 {
-               return 0x0, syscall.Errno(-1 * retCode)
-       }
-
-       return attribute, nil
-}
-
-// Set a raw filter attribute
-func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) 
error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if !f.valid {
-               return errBadFilter
-       }
-
-       if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
-               return fmt.Errorf("the thread synchronization attribute is not 
supported in this version of the library")
-       }
-
-       retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
-       if retCode != 0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// DOES NOT LOCK OR CHECK VALIDITY
-// Assumes caller has already done this
-// Wrapper for seccomp_rule_add_... functions
-func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact 
bool, cond C.scmp_cast_t) error {
-       var length C.uint
-       if cond != nil {
-               length = 1
-       } else {
-               length = 0
-       }
-
-       var retCode C.int
-       if exact {
-               retCode = C.seccomp_rule_add_exact_array(f.filterCtx, 
action.toNative(), C.int(call), length, cond)
-       } else {
-               retCode = C.seccomp_rule_add_array(f.filterCtx, 
action.toNative(), C.int(call), length, cond)
-       }
-
-       if syscall.Errno(-1*retCode) == syscall.EFAULT {
-               return fmt.Errorf("unrecognized syscall")
-       } else if syscall.Errno(-1*retCode) == syscall.EPERM {
-               return fmt.Errorf("requested action matches default action of 
filter")
-       } else if retCode != 0 {
-               return syscall.Errno(-1 * retCode)
-       }
-
-       return nil
-}
-
-// Generic add function for filter rules
-func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact 
bool, conds []ScmpCondition) error {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       if !f.valid {
-               return errBadFilter
-       }
-
-       if len(conds) == 0 {
-               if err := f.addRuleWrapper(call, action, exact, nil); err != 
nil {
-                       return err
-               }
-       } else {
-               // We don't support conditional filtering in library version 
v2.1
-               if !checkVersionAbove(2, 2, 1) {
-                       return fmt.Errorf("conditional filtering requires 
libseccomp version >= 2.2.1")
-               }
-
-               for _, cond := range conds {
-                       cmpStruct := 
C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), 
C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
-                       defer C.free(cmpStruct)
-
-                       if err := f.addRuleWrapper(call, action, exact, 
C.scmp_cast_t(cmpStruct)); err != nil {
-                               return err
-                       }
-               }
-       }
-
-       return nil
-}
-
-// Generic Helpers
-
-// Helper - Sanitize Arch token input
-func sanitizeArch(in ScmpArch) error {
-       if in < archStart || in > archEnd {
-               return fmt.Errorf("unrecognized architecture")
-       }
-
-       if in.toNative() == C.C_ARCH_BAD {
-               return fmt.Errorf("architecture is not supported on this 
version of the library")
-       }
-
-       return nil
-}
-
-func sanitizeAction(in ScmpAction) error {
-       inTmp := in & 0x0000FFFF
-       if inTmp < actionStart || inTmp > actionEnd {
-               return fmt.Errorf("unrecognized action")
-       }
-
-       if inTmp != ActTrace && inTmp != ActErrno && (in&0xFFFF0000) != 0 {
-               return fmt.Errorf("highest 16 bits must be zeroed except for 
Trace and Errno")
-       }
-
-       return nil
-}
-
-func sanitizeCompareOp(in ScmpCompareOp) error {
-       if in < compareOpStart || in > compareOpEnd {
-               return fmt.Errorf("unrecognized comparison operator")
-       }
-
-       return nil
-}
-
-func archFromNative(a C.uint32_t) (ScmpArch, error) {
-       switch a {
-       case C.C_ARCH_X86:
-               return ArchX86, nil
-       case C.C_ARCH_X86_64:
-               return ArchAMD64, nil
-       case C.C_ARCH_X32:
-               return ArchX32, nil
-       case C.C_ARCH_ARM:
-               return ArchARM, nil
-       case C.C_ARCH_NATIVE:
-               return ArchNative, nil
-       case C.C_ARCH_AARCH64:
-               return ArchARM64, nil
-       case C.C_ARCH_MIPS:
-               return ArchMIPS, nil
-       case C.C_ARCH_MIPS64:
-               return ArchMIPS64, nil
-       case C.C_ARCH_MIPS64N32:
-               return ArchMIPS64N32, nil
-       case C.C_ARCH_MIPSEL:
-               return ArchMIPSEL, nil
-       case C.C_ARCH_MIPSEL64:
-               return ArchMIPSEL64, nil
-       case C.C_ARCH_MIPSEL64N32:
-               return ArchMIPSEL64N32, nil
-       case C.C_ARCH_PPC:
-               return ArchPPC, nil
-       case C.C_ARCH_PPC64:
-               return ArchPPC64, nil
-       case C.C_ARCH_PPC64LE:
-               return ArchPPC64LE, nil
-       case C.C_ARCH_S390:
-               return ArchS390, nil
-       case C.C_ARCH_S390X:
-               return ArchS390X, nil
-       default:
-               return 0x0, fmt.Errorf("unrecognized architecture")
-       }
-}
-
-// Only use with sanitized arches, no error handling
-func (a ScmpArch) toNative() C.uint32_t {
-       switch a {
-       case ArchX86:
-               return C.C_ARCH_X86
-       case ArchAMD64:
-               return C.C_ARCH_X86_64
-       case ArchX32:
-               return C.C_ARCH_X32
-       case ArchARM:
-               return C.C_ARCH_ARM
-       case ArchARM64:
-               return C.C_ARCH_AARCH64
-       case ArchMIPS:
-               return C.C_ARCH_MIPS
-       case ArchMIPS64:
-               return C.C_ARCH_MIPS64
-       case ArchMIPS64N32:
-               return C.C_ARCH_MIPS64N32
-       case ArchMIPSEL:
-               return C.C_ARCH_MIPSEL
-       case ArchMIPSEL64:
-               return C.C_ARCH_MIPSEL64
-       case ArchMIPSEL64N32:
-               return C.C_ARCH_MIPSEL64N32
-       case ArchPPC:
-               return C.C_ARCH_PPC
-       case ArchPPC64:
-               return C.C_ARCH_PPC64
-       case ArchPPC64LE:
-               return C.C_ARCH_PPC64LE
-       case ArchS390:
-               return C.C_ARCH_S390
-       case ArchS390X:
-               return C.C_ARCH_S390X
-       case ArchNative:
-               return C.C_ARCH_NATIVE
-       default:
-               return 0x0
-       }
-}
-
-// Only use with sanitized ops, no error handling
-func (a ScmpCompareOp) toNative() C.int {
-       switch a {
-       case CompareNotEqual:
-               return C.C_CMP_NE
-       case CompareLess:
-               return C.C_CMP_LT
-       case CompareLessOrEqual:
-               return C.C_CMP_LE
-       case CompareEqual:
-               return C.C_CMP_EQ
-       case CompareGreaterEqual:
-               return C.C_CMP_GE
-       case CompareGreater:
-               return C.C_CMP_GT
-       case CompareMaskedEqual:
-               return C.C_CMP_MASKED_EQ
-       default:
-               return 0x0
-       }
-}
-
-func actionFromNative(a C.uint32_t) (ScmpAction, error) {
-       aTmp := a & 0xFFFF
-       switch a & 0xFFFF0000 {
-       case C.C_ACT_KILL:
-               return ActKill, nil
-       case C.C_ACT_TRAP:
-               return ActTrap, nil
-       case C.C_ACT_ERRNO:
-               return ActErrno.SetReturnCode(int16(aTmp)), nil
-       case C.C_ACT_TRACE:
-               return ActTrace.SetReturnCode(int16(aTmp)), nil
-       case C.C_ACT_ALLOW:
-               return ActAllow, nil
-       default:
-               return 0x0, fmt.Errorf("unrecognized action")
-       }
-}
-
-// Only use with sanitized actions, no error handling
-func (a ScmpAction) toNative() C.uint32_t {
-       switch a & 0xFFFF {
-       case ActKill:
-               return C.C_ACT_KILL
-       case ActTrap:
-               return C.C_ACT_TRAP
-       case ActErrno:
-               return C.C_ACT_ERRNO | (C.uint32_t(a) >> 16)
-       case ActTrace:
-               return C.C_ACT_TRACE | (C.uint32_t(a) >> 16)
-       case ActAllow:
-               return C.C_ACT_ALLOW
-       default:
-               return 0x0
-       }
-}
-
-// Internal only, assumes safe attribute
-func (a scmpFilterAttr) toNative() uint32 {
-       switch a {
-       case filterAttrActDefault:
-               return uint32(C.C_ATTRIBUTE_DEFAULT)
-       case filterAttrActBadArch:
-               return uint32(C.C_ATTRIBUTE_BADARCH)
-       case filterAttrNNP:
-               return uint32(C.C_ATTRIBUTE_NNP)
-       case filterAttrTsync:
-               return uint32(C.C_ATTRIBUTE_TSYNC)
-       default:
-               return 0x0
-       }
-}
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_test.go 
b/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_test.go
deleted file mode 100644
index b3a49d2..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_test.go
+++ /dev/null
@@ -1,457 +0,0 @@
-// +build linux
-
-// Tests for public API of libseccomp Go bindings
-
-package seccomp
-
-import (
-       "fmt"
-       "syscall"
-       "testing"
-)
-
-// Type Function Tests
-
-func TestActionSetReturnCode(t *testing.T) {
-       if ActInvalid.SetReturnCode(0x0010) != ActInvalid {
-               t.Errorf("Able to set a return code on invalid action!")
-       }
-
-       codeSet := ActErrno.SetReturnCode(0x0001)
-       if codeSet == ActErrno || codeSet.GetReturnCode() != 0x0001 {
-               t.Errorf("Could not set return code on ActErrno")
-       }
-}
-
-func TestSyscallGetName(t *testing.T) {
-       call1 := ScmpSyscall(0x1)
-       callFail := ScmpSyscall(0x999)
-
-       name, err := call1.GetName()
-       if err != nil {
-               t.Errorf("Error getting syscall name for number 0x1")
-       } else if len(name) == 0 {
-               t.Errorf("Empty name returned for syscall 0x1")
-       }
-       fmt.Printf("Got name of syscall 0x1 on native arch as %s\n", name)
-
-       _, err = callFail.GetName()
-       if err == nil {
-               t.Errorf("Getting nonexistant syscall should error!")
-       }
-}
-
-func TestSyscallGetNameByArch(t *testing.T) {
-       call1 := ScmpSyscall(0x1)
-       callInvalid := ScmpSyscall(0x999)
-       archGood := ArchAMD64
-       archBad := ArchInvalid
-
-       name, err := call1.GetNameByArch(archGood)
-       if err != nil {
-               t.Errorf("Error getting syscall name for number 0x1 and arch 
AMD64")
-       } else if name != "write" {
-               t.Errorf("Got incorrect name for syscall 0x1 - expected write, 
got %s", name)
-       }
-
-       _, err = call1.GetNameByArch(archBad)
-       if err == nil {
-               t.Errorf("Bad architecture GetNameByArch() should error!")
-       }
-
-       _, err = callInvalid.GetNameByArch(archGood)
-       if err == nil {
-               t.Errorf("Bad syscall GetNameByArch() should error!")
-       }
-
-       _, err = callInvalid.GetNameByArch(archBad)
-       if err == nil {
-               t.Errorf("Bad syscall and bad arch GetNameByArch() should 
error!")
-       }
-}
-
-func TestGetSyscallFromName(t *testing.T) {
-       name1 := "write"
-       nameInval := "NOTASYSCALL"
-
-       syscall, err := GetSyscallFromName(name1)
-       if err != nil {
-               t.Errorf("Error getting syscall number of write: %s", err)
-       }
-       fmt.Printf("Got syscall number of write on native arch as %d\n", 
syscall)
-
-       _, err = GetSyscallFromName(nameInval)
-       if err == nil {
-               t.Errorf("Getting an invalid syscall should error!")
-       }
-}
-
-func TestGetSyscallFromNameByArch(t *testing.T) {
-       name1 := "write"
-       nameInval := "NOTASYSCALL"
-       arch1 := ArchAMD64
-       archInval := ArchInvalid
-
-       syscall, err := GetSyscallFromNameByArch(name1, arch1)
-       if err != nil {
-               t.Errorf("Error getting syscall number of write on AMD64: %s", 
err)
-       }
-       fmt.Printf("Got syscall number of write on AMD64 as %d\n", syscall)
-
-       _, err = GetSyscallFromNameByArch(nameInval, arch1)
-       if err == nil {
-               t.Errorf("Getting invalid syscall with valid arch should error")
-       }
-
-       _, err = GetSyscallFromNameByArch(name1, archInval)
-       if err == nil {
-               t.Errorf("Getting valid syscall for invalid arch should error")
-       }
-
-       _, err = GetSyscallFromNameByArch(nameInval, archInval)
-       if err == nil {
-               t.Errorf("Getting invalid syscall for invalid arch should 
error")
-       }
-}
-
-func TestMakeCondition(t *testing.T) {
-       condition, err := MakeCondition(3, CompareNotEqual, 0x10)
-       if err != nil {
-               t.Errorf("Error making condition struct: %s", err)
-       } else if condition.Argument != 3 || condition.Operand1 != 0x10 ||
-               condition.Operand2 != 0 || condition.Op != CompareNotEqual {
-               t.Errorf("Condition struct was filled incorrectly")
-       }
-
-       condition, err = MakeCondition(3, CompareMaskedEqual, 0x10, 0x20)
-       if err != nil {
-               t.Errorf("Error making condition struct: %s", err)
-       } else if condition.Argument != 3 || condition.Operand1 != 0x10 ||
-               condition.Operand2 != 0x20 || condition.Op != 
CompareMaskedEqual {
-               t.Errorf("Condition struct was filled incorrectly")
-       }
-
-       _, err = MakeCondition(7, CompareNotEqual, 0x10)
-       if err == nil {
-               t.Errorf("Condition struct with bad syscall argument number 
should error")
-       }
-
-       _, err = MakeCondition(3, CompareInvalid, 0x10)
-       if err == nil {
-               t.Errorf("Condition struct with bad comparison operator should 
error")
-       }
-
-       _, err = MakeCondition(3, CompareMaskedEqual, 0x10, 0x20, 0x30)
-       if err == nil {
-               t.Errorf("MakeCondition with more than 2 arguments should fail")
-       }
-
-       _, err = MakeCondition(3, CompareMaskedEqual)
-       if err == nil {
-               t.Errorf("MakeCondition with no arguments should fail")
-       }
-}
-
-// Utility Function Tests
-
-func TestGetNativeArch(t *testing.T) {
-       arch, err := GetNativeArch()
-       if err != nil {
-               t.Errorf("GetNativeArch should not error!")
-       }
-       fmt.Printf("Got native arch of system as %s\n", arch.String())
-}
-
-// Filter Tests
-
-func TestFilterCreateRelease(t *testing.T) {
-       _, err := NewFilter(ActInvalid)
-       if err == nil {
-               t.Errorf("Can create filter with invalid action")
-       }
-
-       filter, err := NewFilter(ActKill)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-
-       if !filter.IsValid() {
-               t.Errorf("Filter created by NewFilter was not valid")
-       }
-
-       filter.Release()
-
-       if filter.IsValid() {
-               t.Errorf("Filter is valid after being released")
-       }
-}
-
-func TestFilterReset(t *testing.T) {
-       filter, err := NewFilter(ActKill)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-       defer filter.Release()
-
-       // Ensure the default action is ActKill
-       action, err := filter.GetDefaultAction()
-       if err != nil {
-               t.Errorf("Error getting default action of filter")
-       } else if action != ActKill {
-               t.Errorf("Default action of filter was set incorrectly!")
-       }
-
-       // Reset with a different default action
-       err = filter.Reset(ActAllow)
-       if err != nil {
-               t.Errorf("Error resetting filter!")
-       }
-
-       valid := filter.IsValid()
-       if !valid {
-               t.Errorf("Filter is no longer valid after reset!")
-       }
-
-       // The default action should no longer be ActKill
-       action, err = filter.GetDefaultAction()
-       if err != nil {
-               t.Errorf("Error getting default action of filter")
-       } else if action != ActAllow {
-               t.Errorf("Default action of filter was set incorrectly!")
-       }
-}
-
-func TestFilterArchFunctions(t *testing.T) {
-       filter, err := NewFilter(ActKill)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-       defer filter.Release()
-
-       arch, err := GetNativeArch()
-       if err != nil {
-               t.Errorf("Error getting native architecture: %s", err)
-       }
-
-       present, err := filter.IsArchPresent(arch)
-       if err != nil {
-               t.Errorf("Error retrieving arch from filter: %s", err)
-       } else if !present {
-               t.Errorf("Filter does not contain native architecture by 
default")
-       }
-
-       // Adding the native arch again should succeed, as it's already present
-       err = filter.AddArch(arch)
-       if err != nil {
-               t.Errorf("Adding arch to filter already containing it should 
succeed")
-       }
-
-       // Make sure we don't add the native arch again
-       prospectiveArch := ArchX86
-       if arch == ArchX86 {
-               prospectiveArch = ArchAMD64
-       }
-
-       // Check to make sure this other arch isn't in the filter
-       present, err = filter.IsArchPresent(prospectiveArch)
-       if err != nil {
-               t.Errorf("Error retrieving arch from filter: %s", err)
-       } else if present {
-               t.Errorf("Arch not added to filter is present")
-       }
-
-       // Try removing the nonexistant arch - should succeed
-       err = filter.RemoveArch(prospectiveArch)
-       if err != nil {
-               t.Errorf("Error removing nonexistant arch: %s", err)
-       }
-
-       // Add an arch, see if it's in the filter
-       err = filter.AddArch(prospectiveArch)
-       if err != nil {
-               t.Errorf("Could not add arch %s to filter: %s",
-                       prospectiveArch.String(), err)
-       }
-
-       present, err = filter.IsArchPresent(prospectiveArch)
-       if err != nil {
-               t.Errorf("Error retrieving arch from filter: %s", err)
-       } else if !present {
-               t.Errorf("Filter does not contain architecture %s after it was 
added",
-                       prospectiveArch.String())
-       }
-
-       // Remove the arch again, make sure it's not in the filter
-       err = filter.RemoveArch(prospectiveArch)
-       if err != nil {
-               t.Errorf("Could not remove arch %s from filter: %s",
-                       prospectiveArch.String(), err)
-       }
-
-       present, err = filter.IsArchPresent(prospectiveArch)
-       if err != nil {
-               t.Errorf("Error retrieving arch from filter: %s", err)
-       } else if present {
-               t.Errorf("Filter contains architecture %s after it was removed",
-                       prospectiveArch.String())
-       }
-}
-
-func TestFilterAttributeGettersAndSetters(t *testing.T) {
-       filter, err := NewFilter(ActKill)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-       defer filter.Release()
-
-       act, err := filter.GetDefaultAction()
-       if err != nil {
-               t.Errorf("Error getting default action: %s", err)
-       } else if act != ActKill {
-               t.Errorf("Default action was set incorrectly")
-       }
-
-       err = filter.SetBadArchAction(ActAllow)
-       if err != nil {
-               t.Errorf("Error setting bad arch action: %s", err)
-       }
-
-       act, err = filter.GetBadArchAction()
-       if err != nil {
-               t.Errorf("Error getting bad arch action")
-       } else if act != ActAllow {
-               t.Errorf("Bad arch action was not set correcly!")
-       }
-
-       err = filter.SetNoNewPrivsBit(false)
-       if err != nil {
-               t.Errorf("Error setting no new privileges bit")
-       }
-
-       privs, err := filter.GetNoNewPrivsBit()
-       if err != nil {
-               t.Errorf("Error getting no new privileges bit!")
-       } else if privs != false {
-               t.Errorf("No new privileges bit was not set correctly")
-       }
-
-       err = filter.SetBadArchAction(ActInvalid)
-       if err == nil {
-               t.Errorf("Setting bad arch action to an invalid action should 
error")
-       }
-}
-
-func TestMergeFilters(t *testing.T) {
-       filter1, err := NewFilter(ActAllow)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-
-       filter2, err := NewFilter(ActAllow)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-
-       // Need to remove the native arch and add another to the second filter
-       // Filters must NOT share architectures to be successfully merged
-       nativeArch, err := GetNativeArch()
-       if err != nil {
-               t.Errorf("Error getting native arch: %s", err)
-       }
-
-       prospectiveArch := ArchAMD64
-       if nativeArch == ArchAMD64 {
-               prospectiveArch = ArchX86
-       }
-
-       err = filter2.AddArch(prospectiveArch)
-       if err != nil {
-               t.Errorf("Error adding architecture to filter: %s", err)
-       }
-
-       err = filter2.RemoveArch(nativeArch)
-       if err != nil {
-               t.Errorf("Error removing architecture from filter: %s", err)
-       }
-
-       err = filter1.Merge(filter2)
-       if err != nil {
-               t.Errorf("Error merging filters: %s", err)
-       }
-
-       if filter2.IsValid() {
-               t.Errorf("Source filter should not be valid after merging")
-       }
-
-       filter3, err := NewFilter(ActKill)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-       defer filter3.Release()
-
-       err = filter1.Merge(filter3)
-       if err == nil {
-               t.Errorf("Attributes should have to match to merge filters")
-       }
-}
-
-func TestRuleAddAndLoad(t *testing.T) {
-       // Test #1: Add a trivial filter
-       filter1, err := NewFilter(ActAllow)
-       if err != nil {
-               t.Errorf("Error creating filter: %s", err)
-       }
-       defer filter1.Release()
-
-       call, err := GetSyscallFromName("getpid")
-       if err != nil {
-               t.Errorf("Error getting syscall number of getpid: %s", err)
-       }
-
-       call2, err := GetSyscallFromName("setreuid")
-       if err != nil {
-               t.Errorf("Error getting syscall number of setreuid: %s", err)
-       }
-
-       uid := syscall.Getuid()
-       euid := syscall.Geteuid()
-
-       err = filter1.AddRule(call, ActErrno.SetReturnCode(0x1))
-       if err != nil {
-               t.Errorf("Error adding rule to restrict syscall: %s", err)
-       }
-
-       cond, err := MakeCondition(1, CompareEqual, uint64(euid))
-       if err != nil {
-               t.Errorf("Error making rule to restrict syscall: %s", err)
-       }
-
-       cond2, err := MakeCondition(0, CompareEqual, uint64(uid))
-       if err != nil {
-               t.Errorf("Error making rule to restrict syscall: %s", err)
-       }
-
-       conditions := []ScmpCondition{cond, cond2}
-
-       err = filter1.AddRuleConditional(call2, ActErrno.SetReturnCode(0x2), 
conditions)
-       if err != nil {
-               t.Errorf("Error adding conditional rule: %s", err)
-       }
-
-       err = filter1.Load()
-       if err != nil {
-               t.Errorf("Error loading filter: %s", err)
-       }
-
-       // Try making a simple syscall, it should error
-       pid := syscall.Getpid()
-       if pid != -1 {
-               t.Errorf("Syscall should have returned error code!")
-       }
-
-       // Try making a Geteuid syscall that should normally succeed
-       err = syscall.Setreuid(uid, euid)
-       if err != syscall.Errno(2) {
-               t.Errorf("Syscall should have returned error code!")
-       }
-}

_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to