File: syscall.go

package info (click to toggle)
golang-gvisor-gvisor 0.0~20240729.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,276 kB
  • sloc: asm: 3,361; ansic: 1,197; cpp: 348; makefile: 92; python: 89; sh: 83
file content (84 lines) | stat: -rw-r--r-- 3,071 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2022 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package seccheck

import (
	"gvisor.dev/gvisor/pkg/abi/sentry"
)

// SyscallType is an enum that denotes different types of syscall points. There
// are 2 types of syscall point: fully-schematized and raw. Schematizes are
// points that have syscall specific format, e.g. open => {path, flags, mode}.
// Raw uses a generic schema that contains syscall number and 6 arguments. Each
// of these type have a corresponding enter and exit points. Exit points include
// return value and errno information.
type SyscallType int

const (
	// SyscallEnter represents schematized/enter syscall.
	SyscallEnter SyscallType = iota
	// SyscallExit represents schematized/exit syscall.
	SyscallExit
	// SyscallRawEnter represents raw/enter syscall.
	SyscallRawEnter
	// SyscallRawExit represents raw/exit syscall.
	SyscallRawExit

	syscallTypesCount
)

// SyscallFlagListener is an interface that is notified when syscall point enablement changes.
//
// It is used to notify the kernel's syscall table about syscall points, without introducing a
// direct dependency on it.
type SyscallFlagListener interface {
	// UpdateSecCheck is called each time the system call point enablement may have changed.
	// This is called with seccheck.State.mu held, so it is expected to be fast and not re-entrant
	// with seccheck.State functions that attempt to re-lock it.
	UpdateSecCheck(state *State)
}

const (
	syscallPoints = (sentry.MaxSyscallNum + 1) * int(syscallTypesCount)
)

// Fields that are common for many syscalls.
const (
	// FieldSyscallPath is an optional field to collect path from an FD. Given
	// that many syscalls operate on FDs, this const is used across syscalls.
	FieldSyscallPath Field = iota
)

// Fields for execve*(2) syscalls.
const (
	// FieldSyscallExecveEnvv is an optional field to collect list of environment
	// variables. Start after FieldSyscallPath because execveat(2) can collect
	// path from FD.
	FieldSyscallExecveEnvv = FieldSyscallPath + 1
)

// GetPointForSyscall translates the syscall number to the corresponding Point.
func GetPointForSyscall(typ SyscallType, sysno uintptr) Point {
	return Point(sysno)*Point(syscallTypesCount) + Point(typ) + pointLengthBeforeSyscalls
}

// SyscallEnabled checks if the corresponding point for the syscall is enabled.
func (s *State) SyscallEnabled(typ SyscallType, sysno uintptr) bool {
	// Prevent overflow.
	if sysno >= sentry.MaxSyscallNum {
		return false
	}
	return s.Enabled(GetPointForSyscall(typ, sysno))
}