[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [sandboxed-tor-browser/master] Bug 21093: Go back to using gosecco for seccomp rule compilation.
commit c3a280dc1210c679cf7324f76d8f023a3feb4750
Author: Yawning Angel <yawning@xxxxxxxxxxxxxxx>
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@xxxxxxxxxx>
-Copyright (c) 2015 Paul Moore <pmoore@xxxxxxxxxx>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/README b/vendor/src/github.com/seccomp/libseccomp-golang/README
deleted file mode 100644
index 64cab69..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/README
+++ /dev/null
@@ -1,26 +0,0 @@
-libseccomp-golang: Go Language Bindings for the libseccomp Project
-===============================================================================
-https://github.com/seccomp/libseccomp-golang
-https://github.com/seccomp/libseccomp
-
-The libseccomp library provides an easy to use, platform independent, interface
-to the Linux Kernel's syscall filtering mechanism. The libseccomp API is
-designed to abstract away the underlying BPF based syscall filter language and
-present a more conventional function-call based filtering interface that should
-be familiar to, and easily adopted by, application developers.
-
-The libseccomp-golang library provides a Go based interface to the libseccomp
-library.
-
-* Online Resources
-
-The library source repository currently lives on GitHub at the following URLs:
-
- -> https://github.com/seccomp/libseccomp-golang
- -> https://github.com/seccomp/libseccomp
-
-The project mailing list is currently hosted on Google Groups at the URL below,
-please note that a Google account is not required to subscribe to the mailing
-list.
-
- -> https://groups.google.com/d/forum/libseccomp
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp.go b/vendor/src/github.com/seccomp/libseccomp-golang/seccomp.go
deleted file mode 100644
index b2c010f..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp.go
+++ /dev/null
@@ -1,857 +0,0 @@
-// +build linux
-
-// Public API specification for libseccomp Go bindings
-// Contains public API for the bindings
-
-// Package seccomp provides bindings for libseccomp, a library wrapping the Linux
-// seccomp syscall. Seccomp enables an application to restrict system call use
-// for itself and its children.
-package seccomp
-
-import (
- "fmt"
- "os"
- "runtime"
- "strings"
- "sync"
- "syscall"
- "unsafe"
-)
-
-// C wrapping code
-
-// #cgo pkg-config: libseccomp
-// #include <stdlib.h>
-// #include <seccomp.h>
-import "C"
-
-// Exported types
-
-// ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
-// per-architecture basis.
-type ScmpArch uint
-
-// ScmpAction represents an action to be taken on a filter rule match in
-// libseccomp
-type ScmpAction uint
-
-// ScmpCompareOp represents a comparison operator which can be used in a filter
-// rule
-type ScmpCompareOp uint
-
-// ScmpCondition represents a rule in a libseccomp filter context
-type ScmpCondition struct {
- Argument uint `json:"argument,omitempty"`
- Op ScmpCompareOp `json:"operator,omitempty"`
- Operand1 uint64 `json:"operand_one,omitempty"`
- Operand2 uint64 `json:"operand_two,omitempty"`
-}
-
-// ScmpSyscall represents a Linux System Call
-type ScmpSyscall int32
-
-// Exported Constants
-
-const (
- // Valid architectures recognized by libseccomp
- // ARM64 and all MIPS architectures are unsupported by versions of the
- // library before v2.2 and will return errors if used
-
- // ArchInvalid is a placeholder to ensure uninitialized ScmpArch
- // variables are invalid
- ArchInvalid ScmpArch = iota
- // ArchNative is the native architecture of the kernel
- ArchNative ScmpArch = iota
- // ArchX86 represents 32-bit x86 syscalls
- ArchX86 ScmpArch = iota
- // ArchAMD64 represents 64-bit x86-64 syscalls
- ArchAMD64 ScmpArch = iota
- // ArchX32 represents 64-bit x86-64 syscalls (32-bit pointers)
- ArchX32 ScmpArch = iota
- // ArchARM represents 32-bit ARM syscalls
- ArchARM ScmpArch = iota
- // ArchARM64 represents 64-bit ARM syscalls
- ArchARM64 ScmpArch = iota
- // ArchMIPS represents 32-bit MIPS syscalls
- ArchMIPS ScmpArch = iota
- // ArchMIPS64 represents 64-bit MIPS syscalls
- ArchMIPS64 ScmpArch = iota
- // ArchMIPS64N32 represents 64-bit MIPS syscalls (32-bit pointers)
- ArchMIPS64N32 ScmpArch = iota
- // ArchMIPSEL represents 32-bit MIPS syscalls (little endian)
- ArchMIPSEL ScmpArch = iota
- // ArchMIPSEL64 represents 64-bit MIPS syscalls (little endian)
- ArchMIPSEL64 ScmpArch = iota
- // ArchMIPSEL64N32 represents 64-bit MIPS syscalls (little endian,
- // 32-bit pointers)
- ArchMIPSEL64N32 ScmpArch = iota
- // ArchPPC represents 32-bit POWERPC syscalls
- ArchPPC ScmpArch = iota
- // ArchPPC64 represents 64-bit POWER syscalls (big endian)
- ArchPPC64 ScmpArch = iota
- // ArchPPC64LE represents 64-bit POWER syscalls (little endian)
- ArchPPC64LE ScmpArch = iota
- // ArchS390 represents 31-bit System z/390 syscalls
- ArchS390 ScmpArch = iota
- // ArchS390X represents 64-bit System z/390 syscalls
- ArchS390X ScmpArch = iota
-)
-
-const (
- // Supported actions on filter match
-
- // ActInvalid is a placeholder to ensure uninitialized ScmpAction
- // variables are invalid
- ActInvalid ScmpAction = iota
- // ActKill kills the process
- ActKill ScmpAction = iota
- // ActTrap throws SIGSYS
- ActTrap ScmpAction = iota
- // ActErrno causes the syscall to return a negative error code. This
- // code can be set with the SetReturnCode method
- ActErrno ScmpAction = iota
- // ActTrace causes the syscall to notify tracing processes with the
- // given error code. This code can be set with the SetReturnCode method
- ActTrace ScmpAction = iota
- // ActAllow permits the syscall to continue execution
- ActAllow ScmpAction = iota
-)
-
-const (
- // These are comparison operators used in conditional seccomp rules
- // They are used to compare the value of a single argument of a syscall
- // against a user-defined constant
-
- // CompareInvalid is a placeholder to ensure uninitialized ScmpCompareOp
- // variables are invalid
- CompareInvalid ScmpCompareOp = iota
- // CompareNotEqual returns true if the argument is not equal to the
- // given value
- CompareNotEqual ScmpCompareOp = iota
- // CompareLess returns true if the argument is less than the given value
- CompareLess ScmpCompareOp = iota
- // CompareLessOrEqual returns true if the argument is less than or equal
- // to the given value
- CompareLessOrEqual ScmpCompareOp = iota
- // CompareEqual returns true if the argument is equal to the given value
- CompareEqual ScmpCompareOp = iota
- // CompareGreaterEqual returns true if the argument is greater than or
- // equal to the given value
- CompareGreaterEqual ScmpCompareOp = iota
- // CompareGreater returns true if the argument is greater than the given
- // value
- CompareGreater ScmpCompareOp = iota
- // CompareMaskedEqual returns true if the argument is equal to the given
- // value, when masked (bitwise &) against the second given value
- CompareMaskedEqual ScmpCompareOp = iota
-)
-
-// Helpers for types
-
-// GetArchFromString returns an ScmpArch constant from a string representing an
-// architecture
-func GetArchFromString(arch string) (ScmpArch, error) {
- switch strings.ToLower(arch) {
- case "x86":
- return ArchX86, nil
- case "amd64", "x86-64", "x86_64", "x64":
- return ArchAMD64, nil
- case "x32":
- return ArchX32, nil
- case "arm":
- return ArchARM, nil
- case "arm64", "aarch64":
- return ArchARM64, nil
- case "mips":
- return ArchMIPS, nil
- case "mips64":
- return ArchMIPS64, nil
- case "mips64n32":
- return ArchMIPS64N32, nil
- case "mipsel":
- return ArchMIPSEL, nil
- case "mipsel64":
- return ArchMIPSEL64, nil
- case "mipsel64n32":
- return ArchMIPSEL64N32, nil
- case "ppc":
- return ArchPPC, nil
- case "ppc64":
- return ArchPPC64, nil
- case "ppc64le":
- return ArchPPC64LE, nil
- case "s390":
- return ArchS390, nil
- case "s390x":
- return ArchS390X, nil
- default:
- return ArchInvalid, fmt.Errorf("cannot convert unrecognized string %s", arch)
- }
-}
-
-// String returns a string representation of an architecture constant
-func (a ScmpArch) String() string {
- switch a {
- case ArchX86:
- return "x86"
- case ArchAMD64:
- return "amd64"
- case ArchX32:
- return "x32"
- case ArchARM:
- return "arm"
- case ArchARM64:
- return "arm64"
- case ArchMIPS:
- return "mips"
- case ArchMIPS64:
- return "mips64"
- case ArchMIPS64N32:
- return "mips64n32"
- case ArchMIPSEL:
- return "mipsel"
- case ArchMIPSEL64:
- return "mipsel64"
- case ArchMIPSEL64N32:
- return "mipsel64n32"
- case ArchPPC:
- return "ppc"
- case ArchPPC64:
- return "ppc64"
- case ArchPPC64LE:
- return "ppc64le"
- case ArchS390:
- return "s390"
- case ArchS390X:
- return "s390x"
- case ArchNative:
- return "native"
- case ArchInvalid:
- return "Invalid architecture"
- default:
- return "Unknown architecture"
- }
-}
-
-// String returns a string representation of a comparison operator constant
-func (a ScmpCompareOp) String() string {
- switch a {
- case CompareNotEqual:
- return "Not equal"
- case CompareLess:
- return "Less than"
- case CompareLessOrEqual:
- return "Less than or equal to"
- case CompareEqual:
- return "Equal"
- case CompareGreaterEqual:
- return "Greater than or equal to"
- case CompareGreater:
- return "Greater than"
- case CompareMaskedEqual:
- return "Masked equality"
- case CompareInvalid:
- return "Invalid comparison operator"
- default:
- return "Unrecognized comparison operator"
- }
-}
-
-// String returns a string representation of a seccomp match action
-func (a ScmpAction) String() string {
- switch a & 0xFFFF {
- case ActKill:
- return "Action: Kill Process"
- case ActTrap:
- return "Action: Send SIGSYS"
- case ActErrno:
- return fmt.Sprintf("Action: Return error code %d", (a >> 16))
- case ActTrace:
- return fmt.Sprintf("Action: Notify tracing processes with code %d",
- (a >> 16))
- case ActAllow:
- return "Action: Allow system call"
- default:
- return "Unrecognized Action"
- }
-}
-
-// SetReturnCode adds a return code to a supporting ScmpAction, clearing any
-// existing code Only valid on ActErrno and ActTrace. Takes no action otherwise.
-// Accepts 16-bit return code as argument.
-// Returns a valid ScmpAction of the original type with the new error code set.
-func (a ScmpAction) SetReturnCode(code int16) ScmpAction {
- aTmp := a & 0x0000FFFF
- if aTmp == ActErrno || aTmp == ActTrace {
- return (aTmp | (ScmpAction(code)&0xFFFF)<<16)
- }
- return a
-}
-
-// GetReturnCode returns the return code of an ScmpAction
-func (a ScmpAction) GetReturnCode() int16 {
- return int16(a >> 16)
-}
-
-// General utility functions
-
-// GetLibraryVersion returns the version of the library the bindings are built
-// against.
-// The version is formatted as follows: Major.Minor.Micro
-func GetLibraryVersion() (major, minor, micro int) {
- return verMajor, verMinor, verMicro
-}
-
-// Syscall functions
-
-// GetName retrieves the name of a syscall from its number.
-// Acts on any syscall number.
-// Returns either a string containing the name of the syscall, or an error.
-func (s ScmpSyscall) GetName() (string, error) {
- return s.GetNameByArch(ArchNative)
-}
-
-// GetNameByArch retrieves the name of a syscall from its number for a given
-// architecture.
-// Acts on any syscall number.
-// Accepts a valid architecture constant.
-// Returns either a string containing the name of the syscall, or an error.
-// if the syscall is unrecognized or an issue occurred.
-func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
- if err := sanitizeArch(arch); err != nil {
- return "", err
- }
-
- cString := C.seccomp_syscall_resolve_num_arch(arch.toNative(), C.int(s))
- if cString == nil {
- return "", fmt.Errorf("could not resolve syscall name")
- }
- defer C.free(unsafe.Pointer(cString))
-
- finalStr := C.GoString(cString)
- return finalStr, nil
-}
-
-// GetSyscallFromName returns the number of a syscall by name on the kernel's
-// native architecture.
-// Accepts a string containing the name of a syscall.
-// Returns the number of the syscall, or an error if no syscall with that name
-// was found.
-func GetSyscallFromName(name string) (ScmpSyscall, error) {
- cString := C.CString(name)
- defer C.free(unsafe.Pointer(cString))
-
- result := C.seccomp_syscall_resolve_name(cString)
- if result == scmpError {
- return 0, fmt.Errorf("could not resolve name to syscall")
- }
-
- return ScmpSyscall(result), nil
-}
-
-// GetSyscallFromNameByArch returns the number of a syscall by name for a given
-// architecture's ABI.
-// Accepts the name of a syscall and an architecture constant.
-// Returns the number of the syscall, or an error if an invalid architecture is
-// passed or a syscall with that name was not found.
-func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
- if err := sanitizeArch(arch); err != nil {
- return 0, err
- }
-
- cString := C.CString(name)
- defer C.free(unsafe.Pointer(cString))
-
- result := C.seccomp_syscall_resolve_name_arch(arch.toNative(), cString)
- if result == scmpError {
- return 0, fmt.Errorf("could not resolve name to syscall")
- }
-
- return ScmpSyscall(result), nil
-}
-
-// MakeCondition creates and returns a new condition to attach to a filter rule.
-// Associated rules will only match if this condition is true.
-// Accepts the number the argument we are checking, and a comparison operator
-// and value to compare to.
-// The rule will match if argument $arg (zero-indexed) of the syscall is
-// $COMPARE_OP the provided comparison value.
-// Some comparison operators accept two values. Masked equals, for example,
-// will mask $arg of the syscall with the second value provided (via bitwise
-// AND) and then compare against the first value provided.
-// For example, in the less than or equal case, if the syscall argument was
-// 0 and the value provided was 1, the condition would match, as 0 is less
-// than or equal to 1.
-// Return either an error on bad argument or a valid ScmpCondition struct.
-func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
- var condStruct ScmpCondition
-
- if comparison == CompareInvalid {
- return condStruct, fmt.Errorf("invalid comparison operator")
- } else if arg > 5 {
- return condStruct, fmt.Errorf("syscalls only have up to 6 arguments")
- } else if len(values) > 2 {
- return condStruct, fmt.Errorf("conditions can have at most 2 arguments")
- } else if len(values) == 0 {
- return condStruct, fmt.Errorf("must provide at least one value to compare against")
- }
-
- condStruct.Argument = arg
- condStruct.Op = comparison
- condStruct.Operand1 = values[0]
- if len(values) == 2 {
- condStruct.Operand2 = values[1]
- } else {
- condStruct.Operand2 = 0 // Unused
- }
-
- return condStruct, nil
-}
-
-// Utility Functions
-
-// GetNativeArch returns architecture token representing the native kernel
-// architecture
-func GetNativeArch() (ScmpArch, error) {
- arch := C.seccomp_arch_native()
-
- return archFromNative(arch)
-}
-
-// Public Filter API
-
-// ScmpFilter represents a filter context in libseccomp.
-// A filter context is initially empty. Rules can be added to it, and it can
-// then be loaded into the kernel.
-type ScmpFilter struct {
- filterCtx C.scmp_filter_ctx
- valid bool
- lock sync.Mutex
-}
-
-// NewFilter creates and returns a new filter context.
-// Accepts a default action to be taken for syscalls which match no rules in
-// the filter.
-// Returns a reference to a valid filter context, or nil and an error if the
-// filter context could not be created or an invalid default action was given.
-func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
- if err := sanitizeAction(defaultAction); err != nil {
- return nil, err
- }
-
- fPtr := C.seccomp_init(defaultAction.toNative())
- if fPtr == nil {
- return nil, fmt.Errorf("could not create filter")
- }
-
- filter := new(ScmpFilter)
- filter.filterCtx = fPtr
- filter.valid = true
- runtime.SetFinalizer(filter, filterFinalizer)
-
- return filter, nil
-}
-
-// IsValid determines whether a filter context is valid to use.
-// Some operations (Release and Merge) render filter contexts invalid and
-// consequently prevent further use.
-func (f *ScmpFilter) IsValid() bool {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- return f.valid
-}
-
-// Reset resets a filter context, removing all its existing state.
-// Accepts a new default action to be taken for syscalls which do not match.
-// Returns an error if the filter or action provided are invalid.
-func (f *ScmpFilter) Reset(defaultAction ScmpAction) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeAction(defaultAction); err != nil {
- return err
- } else if !f.valid {
- return errBadFilter
- }
-
- retCode := C.seccomp_reset(f.filterCtx, defaultAction.toNative())
- if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// Release releases a filter context, freeing its memory. Should be called after
-// loading into the kernel, when the filter is no longer needed.
-// After calling this function, the given filter is no longer valid and cannot
-// be used.
-// Release() will be invoked automatically when a filter context is garbage
-// collected, but can also be called manually to free memory.
-func (f *ScmpFilter) Release() {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return
- }
-
- f.valid = false
- C.seccomp_release(f.filterCtx)
-}
-
-// Merge merges two filter contexts.
-// The source filter src will be released as part of the process, and will no
-// longer be usable or valid after this call.
-// To be merged, filters must NOT share any architectures, and all their
-// attributes (Default Action, Bad Arch Action, No New Privs and TSync bools)
-// must match.
-// The filter src will be merged into the filter this is called on.
-// The architectures of the src filter not present in the destination, and all
-// associated rules, will be added to the destination.
-// Returns an error if merging the filters failed.
-func (f *ScmpFilter) Merge(src *ScmpFilter) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- src.lock.Lock()
- defer src.lock.Unlock()
-
- if !src.valid || !f.valid {
- return fmt.Errorf("one or more of the filter contexts is invalid or uninitialized")
- }
-
- // Merge the filters
- retCode := C.seccomp_merge(f.filterCtx, src.filterCtx)
- if syscall.Errno(-1*retCode) == syscall.EINVAL {
- return fmt.Errorf("filters could not be merged due to a mismatch in attributes or invalid filter")
- } else if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- src.valid = false
-
- return nil
-}
-
-// IsArchPresent checks if an architecture is present in a filter.
-// If a filter contains an architecture, it uses its default action for
-// syscalls which do not match rules in it, and its rules can match syscalls
-// for that ABI.
-// If a filter does not contain an architecture, all syscalls made to that
-// kernel ABI will fail with the filter's default Bad Architecture Action
-// (by default, killing the process).
-// Accepts an architecture constant.
-// Returns true if the architecture is present in the filter, false otherwise,
-// and an error on an invalid filter context, architecture constant, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) IsArchPresent(arch ScmpArch) (bool, error) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeArch(arch); err != nil {
- return false, err
- } else if !f.valid {
- return false, errBadFilter
- }
-
- retCode := C.seccomp_arch_exist(f.filterCtx, arch.toNative())
- if syscall.Errno(-1*retCode) == syscall.EEXIST {
- // -EEXIST is "arch not present"
- return false, nil
- } else if retCode != 0 {
- return false, syscall.Errno(-1 * retCode)
- }
-
- return true, nil
-}
-
-// AddArch adds an architecture to the filter.
-// Accepts an architecture constant.
-// Returns an error on invalid filter context or architecture token, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) AddArch(arch ScmpArch) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeArch(arch); err != nil {
- return err
- } else if !f.valid {
- return errBadFilter
- }
-
- // Libseccomp returns -EEXIST if the specified architecture is already
- // present. Succeed silently in this case, as it's not fatal, and the
- // architecture is present already.
- retCode := C.seccomp_arch_add(f.filterCtx, arch.toNative())
- if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// RemoveArch removes an architecture from the filter.
-// Accepts an architecture constant.
-// Returns an error on invalid filter context or architecture token, or an
-// issue with the call to libseccomp.
-func (f *ScmpFilter) RemoveArch(arch ScmpArch) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if err := sanitizeArch(arch); err != nil {
- return err
- } else if !f.valid {
- return errBadFilter
- }
-
- // Similar to AddArch, -EEXIST is returned if the arch is not present
- // Succeed silently in that case, this is not fatal and the architecture
- // is not present in the filter after RemoveArch
- retCode := C.seccomp_arch_remove(f.filterCtx, arch.toNative())
- if retCode != 0 && syscall.Errno(-1*retCode) != syscall.EEXIST {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// Load loads a filter context into the kernel.
-// Returns an error if the filter context is invalid or the syscall failed.
-func (f *ScmpFilter) Load() error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_load(f.filterCtx); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// GetDefaultAction returns the default action taken on a syscall which does not
-// match a rule in the filter, or an error if an issue was encountered
-// retrieving the value.
-func (f *ScmpFilter) GetDefaultAction() (ScmpAction, error) {
- action, err := f.getFilterAttr(filterAttrActDefault)
- if err != nil {
- return 0x0, err
- }
-
- return actionFromNative(action)
-}
-
-// GetBadArchAction returns the default action taken on a syscall for an
-// architecture not in the filter, or an error if an issue was encountered
-// retrieving the value.
-func (f *ScmpFilter) GetBadArchAction() (ScmpAction, error) {
- action, err := f.getFilterAttr(filterAttrActBadArch)
- if err != nil {
- return 0x0, err
- }
-
- return actionFromNative(action)
-}
-
-// GetNoNewPrivsBit returns the current state the No New Privileges bit will be set
-// to on the filter being loaded, or an error if an issue was encountered
-// retrieving the value.
-// The No New Privileges bit tells the kernel that new processes run with exec()
-// cannot gain more privileges than the process that ran exec().
-// For example, a process with No New Privileges set would be unable to exec
-// setuid/setgid executables.
-func (f *ScmpFilter) GetNoNewPrivsBit() (bool, error) {
- noNewPrivs, err := f.getFilterAttr(filterAttrNNP)
- if err != nil {
- return false, err
- }
-
- if noNewPrivs == 0 {
- return false, nil
- }
-
- return true, nil
-}
-
-// GetTsyncBit returns whether Thread Synchronization will be enabled on the
-// filter being loaded, or an error if an issue was encountered retrieving the
-// value.
-// Thread Sync ensures that all members of the thread group of the calling
-// process will share the same Seccomp filter set.
-// Tsync is a fairly recent addition to the Linux kernel and older kernels
-// lack support. If the running kernel does not support Tsync and it is
-// requested in a filter, Libseccomp will not enable TSync support and will
-// proceed as normal.
-// This function is unavailable before v2.2 of libseccomp and will return an
-// error.
-func (f *ScmpFilter) GetTsyncBit() (bool, error) {
- tSync, err := f.getFilterAttr(filterAttrTsync)
- if err != nil {
- return false, err
- }
-
- if tSync == 0 {
- return false, nil
- }
-
- return true, nil
-}
-
-// SetBadArchAction sets the default action taken on a syscall for an
-// architecture not in the filter, or an error if an issue was encountered
-// setting the value.
-func (f *ScmpFilter) SetBadArchAction(action ScmpAction) error {
- if err := sanitizeAction(action); err != nil {
- return err
- }
-
- return f.setFilterAttr(filterAttrActBadArch, action.toNative())
-}
-
-// SetNoNewPrivsBit sets the state of the No New Privileges bit, which will be
-// applied on filter load, or an error if an issue was encountered setting the
-// value.
-// Filters with No New Privileges set to 0 can only be loaded if the process
-// has the CAP_SYS_ADMIN capability.
-func (f *ScmpFilter) SetNoNewPrivsBit(state bool) error {
- var toSet C.uint32_t = 0x0
-
- if state {
- toSet = 0x1
- }
-
- return f.setFilterAttr(filterAttrNNP, toSet)
-}
-
-// SetTsync sets whether Thread Synchronization will be enabled on the filter
-// being loaded. Returns an error if setting Tsync failed, or the filter is
-// invalid.
-// Thread Sync ensures that all members of the thread group of the calling
-// process will share the same Seccomp filter set.
-// Tsync is a fairly recent addition to the Linux kernel and older kernels
-// lack support. If the running kernel does not support Tsync and it is
-// requested in a filter, Libseccomp will not enable TSync support and will
-// proceed as normal.
-// This function is unavailable before v2.2 of libseccomp and will return an
-// error.
-func (f *ScmpFilter) SetTsync(enable bool) error {
- var toSet C.uint32_t = 0x0
-
- if enable {
- toSet = 0x1
- }
-
- return f.setFilterAttr(filterAttrTsync, toSet)
-}
-
-// SetSyscallPriority sets a syscall's priority.
-// This provides a hint to the filter generator in libseccomp about the
-// importance of this syscall. High-priority syscalls are placed
-// first in the filter code, and incur less overhead (at the expense of
-// lower-priority syscalls).
-func (f *ScmpFilter) SetSyscallPriority(call ScmpSyscall, priority uint8) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_syscall_priority(f.filterCtx, C.int(call),
- C.uint8_t(priority)); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// AddRule adds a single rule for an unconditional action on a syscall.
-// Accepts the number of the syscall and the action to be taken on the call
-// being made.
-// Returns an error if an issue was encountered adding the rule.
-func (f *ScmpFilter) AddRule(call ScmpSyscall, action ScmpAction) error {
- return f.addRuleGeneric(call, action, false, nil)
-}
-
-// AddRuleExact adds a single rule for an unconditional action on a syscall.
-// Accepts the number of the syscall and the action to be taken on the call
-// being made.
-// No modifications will be made to the rule, and it will fail to add if it
-// cannot be applied to the current architecture without modification.
-// The rule will function exactly as described, but it may not function identically
-// (or be able to be applied to) all architectures.
-// Returns an error if an issue was encountered adding the rule.
-func (f *ScmpFilter) AddRuleExact(call ScmpSyscall, action ScmpAction) error {
- return f.addRuleGeneric(call, action, true, nil)
-}
-
-// AddRuleConditional adds a single rule for a conditional action on a syscall.
-// Returns an error if an issue was encountered adding the rule.
-// All conditions must match for the rule to match.
-// There is a bug in library versions below v2.2.1 which can, in some cases,
-// cause conditions to be lost when more than one are used. Consequently,
-// AddRuleConditional is disabled on library versions lower than v2.2.1
-func (f *ScmpFilter) AddRuleConditional(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error {
- return f.addRuleGeneric(call, action, false, conds)
-}
-
-// AddRuleConditionalExact adds a single rule for a conditional action on a
-// syscall.
-// No modifications will be made to the rule, and it will fail to add if it
-// cannot be applied to the current architecture without modification.
-// The rule will function exactly as described, but it may not function identically
-// (or be able to be applied to) all architectures.
-// Returns an error if an issue was encountered adding the rule.
-// There is a bug in library versions below v2.2.1 which can, in some cases,
-// cause conditions to be lost when more than one are used. Consequently,
-// AddRuleConditionalExact is disabled on library versions lower than v2.2.1
-func (f *ScmpFilter) AddRuleConditionalExact(call ScmpSyscall, action ScmpAction, conds []ScmpCondition) error {
- return f.addRuleGeneric(call, action, true, conds)
-}
-
-// ExportPFC output PFC-formatted, human-readable dump of a filter context's
-// rules to a file.
-// Accepts file to write to (must be open for writing).
-// Returns an error if writing to the file fails.
-func (f *ScmpFilter) ExportPFC(file *os.File) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- fd := file.Fd()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_export_pfc(f.filterCtx, C.int(fd)); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// ExportBPF outputs Berkeley Packet Filter-formatted, kernel-readable dump of a
-// filter context's rules to a file.
-// Accepts file to write to (must be open for writing).
-// Returns an error if writing to the file fails.
-func (f *ScmpFilter) ExportBPF(file *os.File) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- fd := file.Fd()
-
- if !f.valid {
- return errBadFilter
- }
-
- if retCode := C.seccomp_export_bpf(f.filterCtx, C.int(fd)); retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go b/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go
deleted file mode 100644
index ab67a3d..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_internal.go
+++ /dev/null
@@ -1,506 +0,0 @@
-// +build linux
-
-// Internal functions for libseccomp Go bindings
-// No exported functions
-
-package seccomp
-
-import (
- "fmt"
- "os"
- "syscall"
-)
-
-// Unexported C wrapping code - provides the C-Golang interface
-// Get the seccomp header in scope
-// Need stdlib.h for free() on cstrings
-
-// #cgo pkg-config: libseccomp
-/*
-#include <stdlib.h>
-#include <seccomp.h>
-
-#if SCMP_VER_MAJOR < 2
-#error Minimum supported version of Libseccomp is v2.1.0
-#elif SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 1
-#error Minimum supported version of Libseccomp is v2.1.0
-#endif
-
-#define ARCH_BAD ~0
-
-const uint32_t C_ARCH_BAD = ARCH_BAD;
-
-#ifndef SCMP_ARCH_AARCH64
-#define SCMP_ARCH_AARCH64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS
-#define SCMP_ARCH_MIPS ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS64
-#define SCMP_ARCH_MIPS64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPS64N32
-#define SCMP_ARCH_MIPS64N32 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL
-#define SCMP_ARCH_MIPSEL ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL64
-#define SCMP_ARCH_MIPSEL64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_MIPSEL64N32
-#define SCMP_ARCH_MIPSEL64N32 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_PPC
-#define SCMP_ARCH_PPC ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_PPC64
-#define SCMP_ARCH_PPC64 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_PPC64LE
-#define SCMP_ARCH_PPC64LE ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_S390
-#define SCMP_ARCH_S390 ARCH_BAD
-#endif
-
-#ifndef SCMP_ARCH_S390X
-#define SCMP_ARCH_S390X ARCH_BAD
-#endif
-
-const uint32_t C_ARCH_NATIVE = SCMP_ARCH_NATIVE;
-const uint32_t C_ARCH_X86 = SCMP_ARCH_X86;
-const uint32_t C_ARCH_X86_64 = SCMP_ARCH_X86_64;
-const uint32_t C_ARCH_X32 = SCMP_ARCH_X32;
-const uint32_t C_ARCH_ARM = SCMP_ARCH_ARM;
-const uint32_t C_ARCH_AARCH64 = SCMP_ARCH_AARCH64;
-const uint32_t C_ARCH_MIPS = SCMP_ARCH_MIPS;
-const uint32_t C_ARCH_MIPS64 = SCMP_ARCH_MIPS64;
-const uint32_t C_ARCH_MIPS64N32 = SCMP_ARCH_MIPS64N32;
-const uint32_t C_ARCH_MIPSEL = SCMP_ARCH_MIPSEL;
-const uint32_t C_ARCH_MIPSEL64 = SCMP_ARCH_MIPSEL64;
-const uint32_t C_ARCH_MIPSEL64N32 = SCMP_ARCH_MIPSEL64N32;
-const uint32_t C_ARCH_PPC = SCMP_ARCH_PPC;
-const uint32_t C_ARCH_PPC64 = SCMP_ARCH_PPC64;
-const uint32_t C_ARCH_PPC64LE = SCMP_ARCH_PPC64LE;
-const uint32_t C_ARCH_S390 = SCMP_ARCH_S390;
-const uint32_t C_ARCH_S390X = SCMP_ARCH_S390X;
-
-const uint32_t C_ACT_KILL = SCMP_ACT_KILL;
-const uint32_t C_ACT_TRAP = SCMP_ACT_TRAP;
-const uint32_t C_ACT_ERRNO = SCMP_ACT_ERRNO(0);
-const uint32_t C_ACT_TRACE = SCMP_ACT_TRACE(0);
-const uint32_t C_ACT_ALLOW = SCMP_ACT_ALLOW;
-
-// If TSync is not supported, make sure it doesn't map to a supported filter attribute
-// Don't worry about major version < 2, the minimum version checks should catch that case
-#if SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR < 2
-#define SCMP_FLTATR_CTL_TSYNC _SCMP_CMP_MIN
-#endif
-
-const uint32_t C_ATTRIBUTE_DEFAULT = (uint32_t)SCMP_FLTATR_ACT_DEFAULT;
-const uint32_t C_ATTRIBUTE_BADARCH = (uint32_t)SCMP_FLTATR_ACT_BADARCH;
-const uint32_t C_ATTRIBUTE_NNP = (uint32_t)SCMP_FLTATR_CTL_NNP;
-const uint32_t C_ATTRIBUTE_TSYNC = (uint32_t)SCMP_FLTATR_CTL_TSYNC;
-
-const int C_CMP_NE = (int)SCMP_CMP_NE;
-const int C_CMP_LT = (int)SCMP_CMP_LT;
-const int C_CMP_LE = (int)SCMP_CMP_LE;
-const int C_CMP_EQ = (int)SCMP_CMP_EQ;
-const int C_CMP_GE = (int)SCMP_CMP_GE;
-const int C_CMP_GT = (int)SCMP_CMP_GT;
-const int C_CMP_MASKED_EQ = (int)SCMP_CMP_MASKED_EQ;
-
-const int C_VERSION_MAJOR = SCMP_VER_MAJOR;
-const int C_VERSION_MINOR = SCMP_VER_MINOR;
-const int C_VERSION_MICRO = SCMP_VER_MICRO;
-
-typedef struct scmp_arg_cmp* scmp_cast_t;
-
-// Wrapper to create an scmp_arg_cmp struct
-void*
-make_struct_arg_cmp(
- unsigned int arg,
- int compare,
- uint64_t a,
- uint64_t b
- )
-{
- struct scmp_arg_cmp *s = malloc(sizeof(struct scmp_arg_cmp));
-
- s->arg = arg;
- s->op = compare;
- s->datum_a = a;
- s->datum_b = b;
-
- return s;
-}
-*/
-import "C"
-
-// Nonexported types
-type scmpFilterAttr uint32
-
-// Nonexported constants
-
-const (
- filterAttrActDefault scmpFilterAttr = iota
- filterAttrActBadArch scmpFilterAttr = iota
- filterAttrNNP scmpFilterAttr = iota
- filterAttrTsync scmpFilterAttr = iota
-)
-
-const (
- // An error return from certain libseccomp functions
- scmpError C.int = -1
- // Comparison boundaries to check for architecture validity
- archStart ScmpArch = ArchNative
- archEnd ScmpArch = ArchS390X
- // Comparison boundaries to check for action validity
- actionStart ScmpAction = ActKill
- actionEnd ScmpAction = ActAllow
- // Comparison boundaries to check for comparison operator validity
- compareOpStart ScmpCompareOp = CompareNotEqual
- compareOpEnd ScmpCompareOp = CompareMaskedEqual
-)
-
-var (
- // Error thrown on bad filter context
- errBadFilter = fmt.Errorf("filter is invalid or uninitialized")
- // Constants representing library major, minor, and micro versions
- verMajor = int(C.C_VERSION_MAJOR)
- verMinor = int(C.C_VERSION_MINOR)
- verMicro = int(C.C_VERSION_MICRO)
-)
-
-// Nonexported functions
-
-// Check if library version is greater than or equal to the given one
-func checkVersionAbove(major, minor, micro int) bool {
- return (verMajor > major) ||
- (verMajor == major && verMinor > minor) ||
- (verMajor == major && verMinor == minor && verMicro >= micro)
-}
-
-// Init function: Verify library version is appropriate
-func init() {
- if !checkVersionAbove(2, 1, 0) {
- fmt.Fprintf(os.Stderr, "Libseccomp version too low: minimum supported is 2.1.0, detected %d.%d.%d", C.C_VERSION_MAJOR, C.C_VERSION_MINOR, C.C_VERSION_MICRO)
- os.Exit(-1)
- }
-}
-
-// Filter helpers
-
-// Filter finalizer - ensure that kernel context for filters is freed
-func filterFinalizer(f *ScmpFilter) {
- f.Release()
-}
-
-// Get a raw filter attribute
-func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return 0x0, errBadFilter
- }
-
- if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
- return 0x0, fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
- }
-
- var attribute C.uint32_t
-
- retCode := C.seccomp_attr_get(f.filterCtx, attr.toNative(), &attribute)
- if retCode != 0 {
- return 0x0, syscall.Errno(-1 * retCode)
- }
-
- return attribute, nil
-}
-
-// Set a raw filter attribute
-func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
- return fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
- }
-
- retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
- if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// DOES NOT LOCK OR CHECK VALIDITY
-// Assumes caller has already done this
-// Wrapper for seccomp_rule_add_... functions
-func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, cond C.scmp_cast_t) error {
- var length C.uint
- if cond != nil {
- length = 1
- } else {
- length = 0
- }
-
- var retCode C.int
- if exact {
- retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
- } else {
- retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
- }
-
- if syscall.Errno(-1*retCode) == syscall.EFAULT {
- return fmt.Errorf("unrecognized syscall")
- } else if syscall.Errno(-1*retCode) == syscall.EPERM {
- return fmt.Errorf("requested action matches default action of filter")
- } else if retCode != 0 {
- return syscall.Errno(-1 * retCode)
- }
-
- return nil
-}
-
-// Generic add function for filter rules
-func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- if !f.valid {
- return errBadFilter
- }
-
- if len(conds) == 0 {
- if err := f.addRuleWrapper(call, action, exact, nil); err != nil {
- return err
- }
- } else {
- // We don't support conditional filtering in library version v2.1
- if !checkVersionAbove(2, 2, 1) {
- return fmt.Errorf("conditional filtering requires libseccomp version >= 2.2.1")
- }
-
- for _, cond := range conds {
- cmpStruct := C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
- defer C.free(cmpStruct)
-
- if err := f.addRuleWrapper(call, action, exact, C.scmp_cast_t(cmpStruct)); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-// Generic Helpers
-
-// Helper - Sanitize Arch token input
-func sanitizeArch(in ScmpArch) error {
- if in < archStart || in > archEnd {
- return fmt.Errorf("unrecognized architecture")
- }
-
- if in.toNative() == C.C_ARCH_BAD {
- return fmt.Errorf("architecture is not supported on this version of the library")
- }
-
- return nil
-}
-
-func sanitizeAction(in ScmpAction) error {
- inTmp := in & 0x0000FFFF
- if inTmp < actionStart || inTmp > actionEnd {
- return fmt.Errorf("unrecognized action")
- }
-
- if inTmp != ActTrace && inTmp != ActErrno && (in&0xFFFF0000) != 0 {
- return fmt.Errorf("highest 16 bits must be zeroed except for Trace and Errno")
- }
-
- return nil
-}
-
-func sanitizeCompareOp(in ScmpCompareOp) error {
- if in < compareOpStart || in > compareOpEnd {
- return fmt.Errorf("unrecognized comparison operator")
- }
-
- return nil
-}
-
-func archFromNative(a C.uint32_t) (ScmpArch, error) {
- switch a {
- case C.C_ARCH_X86:
- return ArchX86, nil
- case C.C_ARCH_X86_64:
- return ArchAMD64, nil
- case C.C_ARCH_X32:
- return ArchX32, nil
- case C.C_ARCH_ARM:
- return ArchARM, nil
- case C.C_ARCH_NATIVE:
- return ArchNative, nil
- case C.C_ARCH_AARCH64:
- return ArchARM64, nil
- case C.C_ARCH_MIPS:
- return ArchMIPS, nil
- case C.C_ARCH_MIPS64:
- return ArchMIPS64, nil
- case C.C_ARCH_MIPS64N32:
- return ArchMIPS64N32, nil
- case C.C_ARCH_MIPSEL:
- return ArchMIPSEL, nil
- case C.C_ARCH_MIPSEL64:
- return ArchMIPSEL64, nil
- case C.C_ARCH_MIPSEL64N32:
- return ArchMIPSEL64N32, nil
- case C.C_ARCH_PPC:
- return ArchPPC, nil
- case C.C_ARCH_PPC64:
- return ArchPPC64, nil
- case C.C_ARCH_PPC64LE:
- return ArchPPC64LE, nil
- case C.C_ARCH_S390:
- return ArchS390, nil
- case C.C_ARCH_S390X:
- return ArchS390X, nil
- default:
- return 0x0, fmt.Errorf("unrecognized architecture")
- }
-}
-
-// Only use with sanitized arches, no error handling
-func (a ScmpArch) toNative() C.uint32_t {
- switch a {
- case ArchX86:
- return C.C_ARCH_X86
- case ArchAMD64:
- return C.C_ARCH_X86_64
- case ArchX32:
- return C.C_ARCH_X32
- case ArchARM:
- return C.C_ARCH_ARM
- case ArchARM64:
- return C.C_ARCH_AARCH64
- case ArchMIPS:
- return C.C_ARCH_MIPS
- case ArchMIPS64:
- return C.C_ARCH_MIPS64
- case ArchMIPS64N32:
- return C.C_ARCH_MIPS64N32
- case ArchMIPSEL:
- return C.C_ARCH_MIPSEL
- case ArchMIPSEL64:
- return C.C_ARCH_MIPSEL64
- case ArchMIPSEL64N32:
- return C.C_ARCH_MIPSEL64N32
- case ArchPPC:
- return C.C_ARCH_PPC
- case ArchPPC64:
- return C.C_ARCH_PPC64
- case ArchPPC64LE:
- return C.C_ARCH_PPC64LE
- case ArchS390:
- return C.C_ARCH_S390
- case ArchS390X:
- return C.C_ARCH_S390X
- case ArchNative:
- return C.C_ARCH_NATIVE
- default:
- return 0x0
- }
-}
-
-// Only use with sanitized ops, no error handling
-func (a ScmpCompareOp) toNative() C.int {
- switch a {
- case CompareNotEqual:
- return C.C_CMP_NE
- case CompareLess:
- return C.C_CMP_LT
- case CompareLessOrEqual:
- return C.C_CMP_LE
- case CompareEqual:
- return C.C_CMP_EQ
- case CompareGreaterEqual:
- return C.C_CMP_GE
- case CompareGreater:
- return C.C_CMP_GT
- case CompareMaskedEqual:
- return C.C_CMP_MASKED_EQ
- default:
- return 0x0
- }
-}
-
-func actionFromNative(a C.uint32_t) (ScmpAction, error) {
- aTmp := a & 0xFFFF
- switch a & 0xFFFF0000 {
- case C.C_ACT_KILL:
- return ActKill, nil
- case C.C_ACT_TRAP:
- return ActTrap, nil
- case C.C_ACT_ERRNO:
- return ActErrno.SetReturnCode(int16(aTmp)), nil
- case C.C_ACT_TRACE:
- return ActTrace.SetReturnCode(int16(aTmp)), nil
- case C.C_ACT_ALLOW:
- return ActAllow, nil
- default:
- return 0x0, fmt.Errorf("unrecognized action")
- }
-}
-
-// Only use with sanitized actions, no error handling
-func (a ScmpAction) toNative() C.uint32_t {
- switch a & 0xFFFF {
- case ActKill:
- return C.C_ACT_KILL
- case ActTrap:
- return C.C_ACT_TRAP
- case ActErrno:
- return C.C_ACT_ERRNO | (C.uint32_t(a) >> 16)
- case ActTrace:
- return C.C_ACT_TRACE | (C.uint32_t(a) >> 16)
- case ActAllow:
- return C.C_ACT_ALLOW
- default:
- return 0x0
- }
-}
-
-// Internal only, assumes safe attribute
-func (a scmpFilterAttr) toNative() uint32 {
- switch a {
- case filterAttrActDefault:
- return uint32(C.C_ATTRIBUTE_DEFAULT)
- case filterAttrActBadArch:
- return uint32(C.C_ATTRIBUTE_BADARCH)
- case filterAttrNNP:
- return uint32(C.C_ATTRIBUTE_NNP)
- case filterAttrTsync:
- return uint32(C.C_ATTRIBUTE_TSYNC)
- default:
- return 0x0
- }
-}
diff --git a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_test.go b/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_test.go
deleted file mode 100644
index b3a49d2..0000000
--- a/vendor/src/github.com/seccomp/libseccomp-golang/seccomp_test.go
+++ /dev/null
@@ -1,457 +0,0 @@
-// +build linux
-
-// Tests for public API of libseccomp Go bindings
-
-package seccomp
-
-import (
- "fmt"
- "syscall"
- "testing"
-)
-
-// Type Function Tests
-
-func TestActionSetReturnCode(t *testing.T) {
- if ActInvalid.SetReturnCode(0x0010) != ActInvalid {
- t.Errorf("Able to set a return code on invalid action!")
- }
-
- codeSet := ActErrno.SetReturnCode(0x0001)
- if codeSet == ActErrno || codeSet.GetReturnCode() != 0x0001 {
- t.Errorf("Could not set return code on ActErrno")
- }
-}
-
-func TestSyscallGetName(t *testing.T) {
- call1 := ScmpSyscall(0x1)
- callFail := ScmpSyscall(0x999)
-
- name, err := call1.GetName()
- if err != nil {
- t.Errorf("Error getting syscall name for number 0x1")
- } else if len(name) == 0 {
- t.Errorf("Empty name returned for syscall 0x1")
- }
- fmt.Printf("Got name of syscall 0x1 on native arch as %s\n", name)
-
- _, err = callFail.GetName()
- if err == nil {
- t.Errorf("Getting nonexistant syscall should error!")
- }
-}
-
-func TestSyscallGetNameByArch(t *testing.T) {
- call1 := ScmpSyscall(0x1)
- callInvalid := ScmpSyscall(0x999)
- archGood := ArchAMD64
- archBad := ArchInvalid
-
- name, err := call1.GetNameByArch(archGood)
- if err != nil {
- t.Errorf("Error getting syscall name for number 0x1 and arch AMD64")
- } else if name != "write" {
- t.Errorf("Got incorrect name for syscall 0x1 - expected write, got %s", name)
- }
-
- _, err = call1.GetNameByArch(archBad)
- if err == nil {
- t.Errorf("Bad architecture GetNameByArch() should error!")
- }
-
- _, err = callInvalid.GetNameByArch(archGood)
- if err == nil {
- t.Errorf("Bad syscall GetNameByArch() should error!")
- }
-
- _, err = callInvalid.GetNameByArch(archBad)
- if err == nil {
- t.Errorf("Bad syscall and bad arch GetNameByArch() should error!")
- }
-}
-
-func TestGetSyscallFromName(t *testing.T) {
- name1 := "write"
- nameInval := "NOTASYSCALL"
-
- syscall, err := GetSyscallFromName(name1)
- if err != nil {
- t.Errorf("Error getting syscall number of write: %s", err)
- }
- fmt.Printf("Got syscall number of write on native arch as %d\n", syscall)
-
- _, err = GetSyscallFromName(nameInval)
- if err == nil {
- t.Errorf("Getting an invalid syscall should error!")
- }
-}
-
-func TestGetSyscallFromNameByArch(t *testing.T) {
- name1 := "write"
- nameInval := "NOTASYSCALL"
- arch1 := ArchAMD64
- archInval := ArchInvalid
-
- syscall, err := GetSyscallFromNameByArch(name1, arch1)
- if err != nil {
- t.Errorf("Error getting syscall number of write on AMD64: %s", err)
- }
- fmt.Printf("Got syscall number of write on AMD64 as %d\n", syscall)
-
- _, err = GetSyscallFromNameByArch(nameInval, arch1)
- if err == nil {
- t.Errorf("Getting invalid syscall with valid arch should error")
- }
-
- _, err = GetSyscallFromNameByArch(name1, archInval)
- if err == nil {
- t.Errorf("Getting valid syscall for invalid arch should error")
- }
-
- _, err = GetSyscallFromNameByArch(nameInval, archInval)
- if err == nil {
- t.Errorf("Getting invalid syscall for invalid arch should error")
- }
-}
-
-func TestMakeCondition(t *testing.T) {
- condition, err := MakeCondition(3, CompareNotEqual, 0x10)
- if err != nil {
- t.Errorf("Error making condition struct: %s", err)
- } else if condition.Argument != 3 || condition.Operand1 != 0x10 ||
- condition.Operand2 != 0 || condition.Op != CompareNotEqual {
- t.Errorf("Condition struct was filled incorrectly")
- }
-
- condition, err = MakeCondition(3, CompareMaskedEqual, 0x10, 0x20)
- if err != nil {
- t.Errorf("Error making condition struct: %s", err)
- } else if condition.Argument != 3 || condition.Operand1 != 0x10 ||
- condition.Operand2 != 0x20 || condition.Op != CompareMaskedEqual {
- t.Errorf("Condition struct was filled incorrectly")
- }
-
- _, err = MakeCondition(7, CompareNotEqual, 0x10)
- if err == nil {
- t.Errorf("Condition struct with bad syscall argument number should error")
- }
-
- _, err = MakeCondition(3, CompareInvalid, 0x10)
- if err == nil {
- t.Errorf("Condition struct with bad comparison operator should error")
- }
-
- _, err = MakeCondition(3, CompareMaskedEqual, 0x10, 0x20, 0x30)
- if err == nil {
- t.Errorf("MakeCondition with more than 2 arguments should fail")
- }
-
- _, err = MakeCondition(3, CompareMaskedEqual)
- if err == nil {
- t.Errorf("MakeCondition with no arguments should fail")
- }
-}
-
-// Utility Function Tests
-
-func TestGetNativeArch(t *testing.T) {
- arch, err := GetNativeArch()
- if err != nil {
- t.Errorf("GetNativeArch should not error!")
- }
- fmt.Printf("Got native arch of system as %s\n", arch.String())
-}
-
-// Filter Tests
-
-func TestFilterCreateRelease(t *testing.T) {
- _, err := NewFilter(ActInvalid)
- if err == nil {
- t.Errorf("Can create filter with invalid action")
- }
-
- filter, err := NewFilter(ActKill)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
-
- if !filter.IsValid() {
- t.Errorf("Filter created by NewFilter was not valid")
- }
-
- filter.Release()
-
- if filter.IsValid() {
- t.Errorf("Filter is valid after being released")
- }
-}
-
-func TestFilterReset(t *testing.T) {
- filter, err := NewFilter(ActKill)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
- defer filter.Release()
-
- // Ensure the default action is ActKill
- action, err := filter.GetDefaultAction()
- if err != nil {
- t.Errorf("Error getting default action of filter")
- } else if action != ActKill {
- t.Errorf("Default action of filter was set incorrectly!")
- }
-
- // Reset with a different default action
- err = filter.Reset(ActAllow)
- if err != nil {
- t.Errorf("Error resetting filter!")
- }
-
- valid := filter.IsValid()
- if !valid {
- t.Errorf("Filter is no longer valid after reset!")
- }
-
- // The default action should no longer be ActKill
- action, err = filter.GetDefaultAction()
- if err != nil {
- t.Errorf("Error getting default action of filter")
- } else if action != ActAllow {
- t.Errorf("Default action of filter was set incorrectly!")
- }
-}
-
-func TestFilterArchFunctions(t *testing.T) {
- filter, err := NewFilter(ActKill)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
- defer filter.Release()
-
- arch, err := GetNativeArch()
- if err != nil {
- t.Errorf("Error getting native architecture: %s", err)
- }
-
- present, err := filter.IsArchPresent(arch)
- if err != nil {
- t.Errorf("Error retrieving arch from filter: %s", err)
- } else if !present {
- t.Errorf("Filter does not contain native architecture by default")
- }
-
- // Adding the native arch again should succeed, as it's already present
- err = filter.AddArch(arch)
- if err != nil {
- t.Errorf("Adding arch to filter already containing it should succeed")
- }
-
- // Make sure we don't add the native arch again
- prospectiveArch := ArchX86
- if arch == ArchX86 {
- prospectiveArch = ArchAMD64
- }
-
- // Check to make sure this other arch isn't in the filter
- present, err = filter.IsArchPresent(prospectiveArch)
- if err != nil {
- t.Errorf("Error retrieving arch from filter: %s", err)
- } else if present {
- t.Errorf("Arch not added to filter is present")
- }
-
- // Try removing the nonexistant arch - should succeed
- err = filter.RemoveArch(prospectiveArch)
- if err != nil {
- t.Errorf("Error removing nonexistant arch: %s", err)
- }
-
- // Add an arch, see if it's in the filter
- err = filter.AddArch(prospectiveArch)
- if err != nil {
- t.Errorf("Could not add arch %s to filter: %s",
- prospectiveArch.String(), err)
- }
-
- present, err = filter.IsArchPresent(prospectiveArch)
- if err != nil {
- t.Errorf("Error retrieving arch from filter: %s", err)
- } else if !present {
- t.Errorf("Filter does not contain architecture %s after it was added",
- prospectiveArch.String())
- }
-
- // Remove the arch again, make sure it's not in the filter
- err = filter.RemoveArch(prospectiveArch)
- if err != nil {
- t.Errorf("Could not remove arch %s from filter: %s",
- prospectiveArch.String(), err)
- }
-
- present, err = filter.IsArchPresent(prospectiveArch)
- if err != nil {
- t.Errorf("Error retrieving arch from filter: %s", err)
- } else if present {
- t.Errorf("Filter contains architecture %s after it was removed",
- prospectiveArch.String())
- }
-}
-
-func TestFilterAttributeGettersAndSetters(t *testing.T) {
- filter, err := NewFilter(ActKill)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
- defer filter.Release()
-
- act, err := filter.GetDefaultAction()
- if err != nil {
- t.Errorf("Error getting default action: %s", err)
- } else if act != ActKill {
- t.Errorf("Default action was set incorrectly")
- }
-
- err = filter.SetBadArchAction(ActAllow)
- if err != nil {
- t.Errorf("Error setting bad arch action: %s", err)
- }
-
- act, err = filter.GetBadArchAction()
- if err != nil {
- t.Errorf("Error getting bad arch action")
- } else if act != ActAllow {
- t.Errorf("Bad arch action was not set correcly!")
- }
-
- err = filter.SetNoNewPrivsBit(false)
- if err != nil {
- t.Errorf("Error setting no new privileges bit")
- }
-
- privs, err := filter.GetNoNewPrivsBit()
- if err != nil {
- t.Errorf("Error getting no new privileges bit!")
- } else if privs != false {
- t.Errorf("No new privileges bit was not set correctly")
- }
-
- err = filter.SetBadArchAction(ActInvalid)
- if err == nil {
- t.Errorf("Setting bad arch action to an invalid action should error")
- }
-}
-
-func TestMergeFilters(t *testing.T) {
- filter1, err := NewFilter(ActAllow)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
-
- filter2, err := NewFilter(ActAllow)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
-
- // Need to remove the native arch and add another to the second filter
- // Filters must NOT share architectures to be successfully merged
- nativeArch, err := GetNativeArch()
- if err != nil {
- t.Errorf("Error getting native arch: %s", err)
- }
-
- prospectiveArch := ArchAMD64
- if nativeArch == ArchAMD64 {
- prospectiveArch = ArchX86
- }
-
- err = filter2.AddArch(prospectiveArch)
- if err != nil {
- t.Errorf("Error adding architecture to filter: %s", err)
- }
-
- err = filter2.RemoveArch(nativeArch)
- if err != nil {
- t.Errorf("Error removing architecture from filter: %s", err)
- }
-
- err = filter1.Merge(filter2)
- if err != nil {
- t.Errorf("Error merging filters: %s", err)
- }
-
- if filter2.IsValid() {
- t.Errorf("Source filter should not be valid after merging")
- }
-
- filter3, err := NewFilter(ActKill)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
- defer filter3.Release()
-
- err = filter1.Merge(filter3)
- if err == nil {
- t.Errorf("Attributes should have to match to merge filters")
- }
-}
-
-func TestRuleAddAndLoad(t *testing.T) {
- // Test #1: Add a trivial filter
- filter1, err := NewFilter(ActAllow)
- if err != nil {
- t.Errorf("Error creating filter: %s", err)
- }
- defer filter1.Release()
-
- call, err := GetSyscallFromName("getpid")
- if err != nil {
- t.Errorf("Error getting syscall number of getpid: %s", err)
- }
-
- call2, err := GetSyscallFromName("setreuid")
- if err != nil {
- t.Errorf("Error getting syscall number of setreuid: %s", err)
- }
-
- uid := syscall.Getuid()
- euid := syscall.Geteuid()
-
- err = filter1.AddRule(call, ActErrno.SetReturnCode(0x1))
- if err != nil {
- t.Errorf("Error adding rule to restrict syscall: %s", err)
- }
-
- cond, err := MakeCondition(1, CompareEqual, uint64(euid))
- if err != nil {
- t.Errorf("Error making rule to restrict syscall: %s", err)
- }
-
- cond2, err := MakeCondition(0, CompareEqual, uint64(uid))
- if err != nil {
- t.Errorf("Error making rule to restrict syscall: %s", err)
- }
-
- conditions := []ScmpCondition{cond, cond2}
-
- err = filter1.AddRuleConditional(call2, ActErrno.SetReturnCode(0x2), conditions)
- if err != nil {
- t.Errorf("Error adding conditional rule: %s", err)
- }
-
- err = filter1.Load()
- if err != nil {
- t.Errorf("Error loading filter: %s", err)
- }
-
- // Try making a simple syscall, it should error
- pid := syscall.Getpid()
- if pid != -1 {
- t.Errorf("Syscall should have returned error code!")
- }
-
- // Try making a Geteuid syscall that should normally succeed
- err = syscall.Setreuid(uid, euid)
- if err != syscall.Errno(2) {
- t.Errorf("Syscall should have returned error code!")
- }
-}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits