github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/seccheck/syscall.go (about) 1 // Copyright 2022 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 seccheck 16 17 import ( 18 "github.com/metacubex/gvisor/pkg/abi/sentry" 19 ) 20 21 // SyscallType is an enum that denotes different types of syscall points. There 22 // are 2 types of syscall point: fully-schematized and raw. Schematizes are 23 // points that have syscall specific format, e.g. open => {path, flags, mode}. 24 // Raw uses a generic schema that contains syscall number and 6 arguments. Each 25 // of these type have a corresponding enter and exit points. Exit points include 26 // return value and errno information. 27 type SyscallType int 28 29 const ( 30 // SyscallEnter represents schematized/enter syscall. 31 SyscallEnter SyscallType = iota 32 // SyscallExit represents schematized/exit syscall. 33 SyscallExit 34 // SyscallRawEnter represents raw/enter syscall. 35 SyscallRawEnter 36 // SyscallRawExit represents raw/exit syscall. 37 SyscallRawExit 38 39 syscallTypesCount 40 ) 41 42 // SyscallFlagListener is an interface that is notified when syscall point enablement changes. 43 // 44 // It is used to notify the kernel's syscall table about syscall points, without introducing a 45 // direct dependency on it. 46 type SyscallFlagListener interface { 47 // UpdateSecCheck is called each time the system call point enablement may have changed. 48 // This is called with seccheck.State.mu held, so it is expected to be fast and not re-entrant 49 // with seccheck.State functions that attempt to re-lock it. 50 UpdateSecCheck(state *State) 51 } 52 53 const ( 54 syscallPoints = (sentry.MaxSyscallNum + 1) * int(syscallTypesCount) 55 ) 56 57 // Fields that are common for many syscalls. 58 const ( 59 // FieldSyscallPath is an optional field to collect path from an FD. Given 60 // that many syscalls operate on FDs, this const is used across syscalls. 61 FieldSyscallPath Field = iota 62 ) 63 64 // Fields for execve*(2) syscalls. 65 const ( 66 // FieldSyscallExecveEnvv is an optional field to collect list of environment 67 // variables. Start after FieldSyscallPath because execveat(2) can collect 68 // path from FD. 69 FieldSyscallExecveEnvv = FieldSyscallPath + 1 70 ) 71 72 // GetPointForSyscall translates the syscall number to the corresponding Point. 73 func GetPointForSyscall(typ SyscallType, sysno uintptr) Point { 74 return Point(sysno)*Point(syscallTypesCount) + Point(typ) + pointLengthBeforeSyscalls 75 } 76 77 // SyscallEnabled checks if the corresponding point for the syscall is enabled. 78 func (s *State) SyscallEnabled(typ SyscallType, sysno uintptr) bool { 79 // Prevent overflow. 80 if sysno >= sentry.MaxSyscallNum { 81 return false 82 } 83 return s.Enabled(GetPointForSyscall(typ, sysno)) 84 }