summaryrefslogtreecommitdiffstats
path: root/plugin/rpcplugin/sandbox/seccomp_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/rpcplugin/sandbox/seccomp_linux.go')
-rw-r--r--plugin/rpcplugin/sandbox/seccomp_linux.go178
1 files changed, 0 insertions, 178 deletions
diff --git a/plugin/rpcplugin/sandbox/seccomp_linux.go b/plugin/rpcplugin/sandbox/seccomp_linux.go
deleted file mode 100644
index afe86e90a..000000000
--- a/plugin/rpcplugin/sandbox/seccomp_linux.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "syscall"
- "unsafe"
-
- "github.com/pkg/errors"
- "golang.org/x/net/bpf"
- "golang.org/x/sys/unix"
-)
-
-const (
- SECCOMP_RET_ALLOW = 0x7fff0000
- SECCOMP_RET_ERRNO = 0x00050000
-)
-
-const (
- EM_X86_64 = 62
-
- __AUDIT_ARCH_64BIT = 0x80000000
- __AUDIT_ARCH_LE = 0x40000000
-
- AUDIT_ARCH_X86_64 = EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE
-
- nrSize = 4
- archOffset = nrSize
- ipOffset = archOffset + 4
- argsOffset = ipOffset + 8
-)
-
-type SeccompCondition interface {
- Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction
-}
-
-func seccompArgLowWord(arg int, littleEndian bool) uint32 {
- offset := uint32(argsOffset + arg*8)
- if !littleEndian {
- offset += 4
- }
- return offset
-}
-
-func seccompArgHighWord(arg int, littleEndian bool) uint32 {
- offset := uint32(argsOffset + arg*8)
- if littleEndian {
- offset += 4
- }
- return offset
-}
-
-type SeccompArgHasNoBits struct {
- Arg int
- Mask uint64
-}
-
-func (c SeccompArgHasNoBits) Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction {
- return []bpf.Instruction{
- bpf.LoadAbsolute{Off: seccompArgHighWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask >> 32), SkipTrue: skipFalseSentinel},
- bpf.LoadAbsolute{Off: seccompArgLowWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask), SkipTrue: skipFalseSentinel},
- }
-}
-
-type SeccompArgHasAnyBit struct {
- Arg int
- Mask uint64
-}
-
-func (c SeccompArgHasAnyBit) Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction {
- return []bpf.Instruction{
- bpf.LoadAbsolute{Off: seccompArgHighWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask >> 32), SkipTrue: 2},
- bpf.LoadAbsolute{Off: seccompArgLowWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask), SkipFalse: skipFalseSentinel},
- }
-}
-
-type SeccompArgEquals struct {
- Arg int
- Value uint64
-}
-
-func (c SeccompArgEquals) Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction {
- return []bpf.Instruction{
- bpf.LoadAbsolute{Off: seccompArgHighWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(c.Value >> 32), SkipFalse: skipFalseSentinel},
- bpf.LoadAbsolute{Off: seccompArgLowWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(c.Value), SkipFalse: skipFalseSentinel},
- }
-}
-
-type SeccompConditions struct {
- All []SeccompCondition
-}
-
-type SeccompSyscall struct {
- Syscall uint32
- Any []SeccompConditions
-}
-
-func SeccompFilter(arch uint32, allowedSyscalls []SeccompSyscall) (filter []bpf.Instruction) {
- filter = append(filter,
- bpf.LoadAbsolute{Off: archOffset, Size: 4},
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: arch, SkipTrue: 1},
- bpf.RetConstant{Val: uint32(SECCOMP_RET_ERRNO | unix.EPERM)},
- )
-
- filter = append(filter, bpf.LoadAbsolute{Off: 0, Size: nrSize})
- for _, s := range allowedSyscalls {
- if s.Any != nil {
- syscallStart := len(filter)
- filter = append(filter, bpf.Instruction(nil))
- for _, cs := range s.Any {
- anyStart := len(filter)
- for _, c := range cs.All {
- filter = append(filter, c.Filter((arch&__AUDIT_ARCH_LE) != 0, 255)...)
- }
- filter = append(filter, bpf.RetConstant{Val: SECCOMP_RET_ALLOW})
- for i := anyStart; i < len(filter); i++ {
- if jump, ok := filter[i].(bpf.JumpIf); ok {
- if len(filter)-i-1 > 255 {
- panic("condition too long")
- }
- if jump.SkipFalse == 255 {
- jump.SkipFalse = uint8(len(filter) - i - 1)
- }
- if jump.SkipTrue == 255 {
- jump.SkipTrue = uint8(len(filter) - i - 1)
- }
- filter[i] = jump
- }
- }
- }
- filter = append(filter, bpf.RetConstant{Val: uint32(SECCOMP_RET_ERRNO | unix.EPERM)})
- if len(filter)-syscallStart-1 > 255 {
- panic("conditions too long")
- }
- filter[syscallStart] = bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(s.Syscall), SkipFalse: uint8(len(filter) - syscallStart - 1)}
- } else {
- filter = append(filter,
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(s.Syscall), SkipFalse: 1},
- bpf.RetConstant{Val: SECCOMP_RET_ALLOW},
- )
- }
- }
-
- return append(filter, bpf.RetConstant{Val: uint32(SECCOMP_RET_ERRNO | unix.EPERM)})
-}
-
-func EnableSeccompFilter(filter []bpf.Instruction) error {
- assembled, err := bpf.Assemble(filter)
- if err != nil {
- return errors.Wrapf(err, "unable to assemble filter")
- }
-
- sockFilter := make([]unix.SockFilter, len(filter))
- for i, instruction := range assembled {
- sockFilter[i].Code = instruction.Op
- sockFilter[i].Jt = instruction.Jt
- sockFilter[i].Jf = instruction.Jf
- sockFilter[i].K = instruction.K
- }
-
- prog := unix.SockFprog{
- Len: uint16(len(sockFilter)),
- Filter: &sockFilter[0],
- }
-
- if _, _, errno := syscall.Syscall(syscall.SYS_PRCTL, unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, uintptr(unsafe.Pointer(&prog))); errno != 0 {
- return errors.Wrapf(syscall.Errno(errno), "syscall error")
- }
-
- return nil
-}