summaryrefslogtreecommitdiffhomepage
path: root/pkg/seccomp/seccomp_unsafe.go
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-11-20 22:55:41 -0800
committerShentubot <shentubot@google.com>2018-11-20 22:56:51 -0800
commiteaac94d91c28b745c51c33dd352ed9bfdd671b8c (patch)
treee552c91970be74c3a315bb6aa5eea157cb153890 /pkg/seccomp/seccomp_unsafe.go
parent5236b78242677612ac71b19cee85b3bf4cca4008 (diff)
Use RET_KILL_PROCESS if available in kernel
RET_KILL_THREAD doesn't work well for Go because it will kill only the offending thread and leave the process hanging. RET_TRAP can be masked out and it's not guaranteed to kill the process. RET_KILL_PROCESS is available since 4.14. For older kernel, continue to use RET_TRAP as this is the best option (likely to kill process, easy to debug). PiperOrigin-RevId: 222357867 Change-Id: Icc1d7d731274b16c2125b7a1ba4f7883fbdb2cbd
Diffstat (limited to 'pkg/seccomp/seccomp_unsafe.go')
-rw-r--r--pkg/seccomp/seccomp_unsafe.go30
1 files changed, 24 insertions, 6 deletions
diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go
index dd009221a..a31c6471d 100644
--- a/pkg/seccomp/seccomp_unsafe.go
+++ b/pkg/seccomp/seccomp_unsafe.go
@@ -36,22 +36,40 @@ type sockFprog struct {
//
//go:nosplit
func SetFilter(instrs []linux.BPFInstruction) syscall.Errno {
- // SYS_SECCOMP is not available in syscall package.
- const SYS_SECCOMP = 317
-
// PR_SET_NO_NEW_PRIVS is required in order to enable seccomp. See seccomp(2) for details.
if _, _, errno := syscall.RawSyscall(syscall.SYS_PRCTL, linux.PR_SET_NO_NEW_PRIVS, 1, 0); errno != 0 {
return errno
}
- // TODO: Use SECCOMP_FILTER_FLAG_KILL_PROCESS when available.
sockProg := sockFprog{
Len: uint16(len(instrs)),
Filter: (*linux.BPFInstruction)(unsafe.Pointer(&instrs[0])),
}
- if _, _, errno := syscall.RawSyscall(SYS_SECCOMP, linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, uintptr(unsafe.Pointer(&sockProg))); errno != 0 {
- return errno
+ return seccomp(linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, unsafe.Pointer(&sockProg))
+}
+
+func isKillProcessAvailable() (bool, error) {
+ action := uint32(linux.SECCOMP_RET_KILL_PROCESS)
+ if errno := seccomp(linux.SECCOMP_GET_ACTION_AVAIL, 0, unsafe.Pointer(&action)); errno != 0 {
+ // EINVAL: SECCOMP_GET_ACTION_AVAIL not in this kernel yet.
+ // EOPNOTSUPP: SECCOMP_RET_KILL_PROCESS not supported.
+ if errno == syscall.EINVAL || errno == syscall.EOPNOTSUPP {
+ return false, nil
+ }
+ return false, errno
}
+ return true, nil
+}
+// seccomp calls seccomp(2). This is safe to call from an afterFork context.
+//
+//go:nosplit
+func seccomp(op, flags uint32, ptr unsafe.Pointer) syscall.Errno {
+ // SYS_SECCOMP is not available in syscall package.
+ const SYS_SECCOMP = 317
+
+ if _, _, errno := syscall.RawSyscall(SYS_SECCOMP, uintptr(op), uintptr(flags), uintptr(ptr)); errno != 0 {
+ return errno
+ }
return 0
}