github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/syscalls/linux/sys_seccomp.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linux 16 17 import ( 18 "github.com/SagerNet/gvisor/pkg/abi/linux" 19 "github.com/SagerNet/gvisor/pkg/bpf" 20 "github.com/SagerNet/gvisor/pkg/errors/linuxerr" 21 "github.com/SagerNet/gvisor/pkg/hostarch" 22 "github.com/SagerNet/gvisor/pkg/sentry/arch" 23 "github.com/SagerNet/gvisor/pkg/sentry/kernel" 24 ) 25 26 // userSockFprog is equivalent to Linux's struct sock_fprog on amd64. 27 // 28 // +marshal 29 type userSockFprog struct { 30 // Len is the length of the filter in BPF instructions. 31 Len uint16 32 33 _ [6]byte // padding for alignment 34 35 // Filter is a user pointer to the struct sock_filter array that makes up 36 // the filter program. Filter is a uint64 rather than a hostarch.Addr 37 // because hostarch.Addr is actually uintptr, which is not a fixed-size 38 // type. 39 Filter uint64 40 } 41 42 // seccomp applies a seccomp policy to the current task. 43 func seccomp(t *kernel.Task, mode, flags uint64, addr hostarch.Addr) error { 44 // We only support SECCOMP_SET_MODE_FILTER at the moment. 45 if mode != linux.SECCOMP_SET_MODE_FILTER { 46 // Unsupported mode. 47 return linuxerr.EINVAL 48 } 49 50 tsync := flags&linux.SECCOMP_FILTER_FLAG_TSYNC != 0 51 52 // The only flag we support now is SECCOMP_FILTER_FLAG_TSYNC. 53 if flags&^linux.SECCOMP_FILTER_FLAG_TSYNC != 0 { 54 // Unsupported flag. 55 return linuxerr.EINVAL 56 } 57 58 var fprog userSockFprog 59 if _, err := fprog.CopyIn(t, addr); err != nil { 60 return err 61 } 62 filter := make([]linux.BPFInstruction, int(fprog.Len)) 63 if _, err := linux.CopyBPFInstructionSliceIn(t, hostarch.Addr(fprog.Filter), filter); err != nil { 64 return err 65 } 66 compiledFilter, err := bpf.Compile(filter) 67 if err != nil { 68 t.Debugf("Invalid seccomp-bpf filter: %v", err) 69 return linuxerr.EINVAL 70 } 71 72 return t.AppendSyscallFilter(compiledFilter, tsync) 73 } 74 75 // Seccomp implements linux syscall seccomp(2). 76 func Seccomp(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 77 return 0, nil, seccomp(t, args[0].Uint64(), args[1].Uint64(), args[2].Pointer()) 78 }