summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-12-18 10:27:16 -0800
committerShentubot <shentubot@google.com>2018-12-18 10:28:28 -0800
commit03226cd95055aee73d4e4dfcb4954490b4fd8a2d (patch)
tree8d7fad1c742f44825746e55f5f3c2ef8a9ee65b2 /pkg/sentry/kernel
parente7b47844d969673cec06ea745d577155131ecf3b (diff)
Add BPFAction type with Stringer
PiperOrigin-RevId: 226018694 Change-Id: I98965e26fe565f37e98e5df5f997363ab273c91b
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r--pkg/sentry/kernel/seccomp.go53
-rw-r--r--pkg/sentry/kernel/task_syscall.go18
2 files changed, 28 insertions, 43 deletions
diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go
index d6dc45bbd..cec179246 100644
--- a/pkg/sentry/kernel/seccomp.go
+++ b/pkg/sentry/kernel/seccomp.go
@@ -27,24 +27,6 @@ import (
const maxSyscallFilterInstructions = 1 << 15
-type seccompResult int
-
-const (
- // seccompResultDeny indicates that a syscall should not be executed.
- seccompResultDeny seccompResult = iota
-
- // seccompResultAllow indicates that a syscall should be executed.
- seccompResultAllow
-
- // seccompResultKill indicates that the task should be killed immediately,
- // with the exit status indicating that the task was killed by SIGSYS.
- seccompResultKill
-
- // seccompResultTrace indicates that a ptracer was successfully notified as
- // a result of a SECCOMP_RET_TRACE.
- seccompResultTrace
-)
-
// seccompData is equivalent to struct seccomp_data, which contains the data
// passed to seccomp-bpf filters.
type seccompData struct {
@@ -83,48 +65,47 @@ func seccompSiginfo(t *Task, errno, sysno int32, ip usermem.Addr) *arch.SignalIn
// in because vsyscalls do not use the values in t.Arch().)
//
// Preconditions: The caller must be running on the task goroutine.
-func (t *Task) checkSeccompSyscall(sysno int32, args arch.SyscallArguments, ip usermem.Addr) seccompResult {
- result := t.evaluateSyscallFilters(sysno, args, ip)
- switch result & linux.SECCOMP_RET_ACTION {
+func (t *Task) checkSeccompSyscall(sysno int32, args arch.SyscallArguments, ip usermem.Addr) linux.BPFAction {
+ result := linux.BPFAction(t.evaluateSyscallFilters(sysno, args, ip))
+ action := result & linux.SECCOMP_RET_ACTION
+ switch action {
case linux.SECCOMP_RET_TRAP:
// "Results in the kernel sending a SIGSYS signal to the triggering
// task without executing the system call. ... The SECCOMP_RET_DATA
// portion of the return value will be passed as si_errno." -
// Documentation/prctl/seccomp_filter.txt
- t.SendSignal(seccompSiginfo(t, int32(result&linux.SECCOMP_RET_DATA), sysno, ip))
- return seccompResultDeny
+ t.SendSignal(seccompSiginfo(t, int32(result.Data()), sysno, ip))
case linux.SECCOMP_RET_ERRNO:
// "Results in the lower 16-bits of the return value being passed to
// userland as the errno without executing the system call."
- t.Arch().SetReturn(-uintptr(result & linux.SECCOMP_RET_DATA))
- return seccompResultDeny
+ t.Arch().SetReturn(-uintptr(result.Data()))
case linux.SECCOMP_RET_TRACE:
// "When returned, this value will cause the kernel to attempt to
// notify a ptrace()-based tracer prior to executing the system call.
// If there is no tracer present, -ENOSYS is returned to userland and
// the system call is not executed."
- if t.ptraceSeccomp(uint16(result & linux.SECCOMP_RET_DATA)) {
- return seccompResultTrace
+ if !t.ptraceSeccomp(result.Data()) {
+ // This useless-looking temporary is needed because Go.
+ tmp := uintptr(syscall.ENOSYS)
+ t.Arch().SetReturn(-tmp)
+ return linux.SECCOMP_RET_ERRNO
}
- // This useless-looking temporary is needed because Go.
- tmp := uintptr(syscall.ENOSYS)
- t.Arch().SetReturn(-tmp)
- return seccompResultDeny
case linux.SECCOMP_RET_ALLOW:
// "Results in the system call being executed."
- return seccompResultAllow
case linux.SECCOMP_RET_KILL_THREAD:
// "Results in the task exiting immediately without executing the
// system call. The exit status of the task will be SIGSYS, not
// SIGKILL."
- fallthrough
- default: // consistent with Linux
- return seccompResultKill
+
+ default:
+ // consistent with Linux
+ return linux.SECCOMP_RET_KILL_THREAD
}
+ return action
}
func (t *Task) evaluateSyscallFilters(sysno int32, args arch.SyscallArguments, ip usermem.Addr) uint32 {
@@ -155,7 +136,7 @@ func (t *Task) evaluateSyscallFilters(sysno int32, args arch.SyscallArguments, i
thisRet, err := bpf.Exec(f.([]bpf.Program)[i], input)
if err != nil {
t.Debugf("seccomp-bpf filter %d returned error: %v", i, err)
- thisRet = linux.SECCOMP_RET_KILL_THREAD
+ thisRet = uint32(linux.SECCOMP_RET_KILL_THREAD)
}
// "If multiple filters exist, the return value for the evaluation of a
// given system call will always use the highest precedent value." -
diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go
index 2a39ebc68..9e43f089a 100644
--- a/pkg/sentry/kernel/task_syscall.go
+++ b/pkg/sentry/kernel/task_syscall.go
@@ -199,16 +199,16 @@ func (t *Task) doSyscall() taskRunState {
// is rare), not needed for correctness.
if t.syscallFilters.Load() != nil {
switch r := t.checkSeccompSyscall(int32(sysno), args, usermem.Addr(t.Arch().IP())); r {
- case seccompResultDeny:
+ case linux.SECCOMP_RET_ERRNO, linux.SECCOMP_RET_TRAP:
t.Debugf("Syscall %d: denied by seccomp", sysno)
return (*runSyscallExit)(nil)
- case seccompResultAllow:
+ case linux.SECCOMP_RET_ALLOW:
// ok
- case seccompResultKill:
+ case linux.SECCOMP_RET_KILL_THREAD:
t.Debugf("Syscall %d: killed by seccomp", sysno)
t.PrepareExit(ExitStatus{Signo: int(linux.SIGSYS)})
return (*runExit)(nil)
- case seccompResultTrace:
+ case linux.SECCOMP_RET_TRACE:
t.Debugf("Syscall %d: stopping for PTRACE_EVENT_SECCOMP", sysno)
return (*runSyscallAfterPtraceEventSeccomp)(nil)
default:
@@ -345,14 +345,18 @@ func (t *Task) doVsyscall(addr usermem.Addr, sysno uintptr) taskRunState {
args := t.Arch().SyscallArgs()
if t.syscallFilters.Load() != nil {
switch r := t.checkSeccompSyscall(int32(sysno), args, addr); r {
- case seccompResultDeny:
+ case linux.SECCOMP_RET_ERRNO, linux.SECCOMP_RET_TRAP:
t.Debugf("vsyscall %d, caller %x: denied by seccomp", sysno, t.Arch().Value(caller))
return (*runApp)(nil)
- case seccompResultAllow:
+ case linux.SECCOMP_RET_ALLOW:
// ok
- case seccompResultTrace:
+ case linux.SECCOMP_RET_TRACE:
t.Debugf("vsyscall %d, caller %x: stopping for PTRACE_EVENT_SECCOMP", sysno, t.Arch().Value(caller))
return &runVsyscallAfterPtraceEventSeccomp{addr, sysno, caller}
+ case linux.SECCOMP_RET_KILL_THREAD:
+ t.Debugf("vsyscall %d: killed by seccomp", sysno)
+ t.PrepareExit(ExitStatus{Signo: int(linux.SIGSYS)})
+ return (*runExit)(nil)
default:
panic(fmt.Sprintf("Unknown seccomp result %d", r))
}