github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/seccomp/seccomp_unsafe.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 seccomp 16 17 import ( 18 "unsafe" 19 20 "golang.org/x/sys/unix" 21 "github.com/SagerNet/gvisor/pkg/abi/linux" 22 ) 23 24 // SetFilter installs the given BPF program. 25 // 26 // This is safe to call from an afterFork context. 27 // 28 //go:nosplit 29 func SetFilter(instrs []linux.BPFInstruction) unix.Errno { 30 // PR_SET_NO_NEW_PRIVS is required in order to enable seccomp. See seccomp(2) for details. 31 if _, _, errno := unix.RawSyscall6(unix.SYS_PRCTL, linux.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0, 0); errno != 0 { 32 return errno 33 } 34 35 sockProg := linux.SockFprog{ 36 Len: uint16(len(instrs)), 37 Filter: (*linux.BPFInstruction)(unsafe.Pointer(&instrs[0])), 38 } 39 return seccomp(linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, unsafe.Pointer(&sockProg)) 40 } 41 42 func isKillProcessAvailable() (bool, error) { 43 action := uint32(linux.SECCOMP_RET_KILL_PROCESS) 44 if errno := seccomp(linux.SECCOMP_GET_ACTION_AVAIL, 0, unsafe.Pointer(&action)); errno != 0 { 45 // EINVAL: SECCOMP_GET_ACTION_AVAIL not in this kernel yet. 46 // EOPNOTSUPP: SECCOMP_RET_KILL_PROCESS not supported. 47 if errno == unix.EINVAL || errno == unix.EOPNOTSUPP { 48 return false, nil 49 } 50 return false, errno 51 } 52 return true, nil 53 } 54 55 // seccomp calls seccomp(2). This is safe to call from an afterFork context. 56 // 57 //go:nosplit 58 func seccomp(op, flags uint32, ptr unsafe.Pointer) unix.Errno { 59 if _, _, errno := unix.RawSyscall(SYS_SECCOMP, uintptr(op), uintptr(flags), uintptr(ptr)); errno != 0 { 60 return errno 61 } 62 return 0 63 }