/
syscall.go
84 lines (73 loc) · 3 KB
/
syscall.go
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))
}