gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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  	"gvisor.dev/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  }