[tor-commits] [sandboxed-tor-browser/master] Bug 21093: Go back to using gosecco for seccomp rule compilation.

yawning at torproject.org yawning at torproject.org
Thu Dec 29 07:18:33 UTC 2016


commit c3a280dc1210c679cf7324f76d8f023a3feb4750
Author: Yawning Angel <yawning at schwanenlied.me>
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 <mheon at redhat.com>
-Copyright (c) 2015 Paul Moore <pmoore at redhat.com>
-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!")
-	}
-}



More information about the tor-commits mailing list