mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
runsc: Add metric counting calls of unimplemented system calls.
This is useful to determine which syscalls users want but are unimplemented. PiperOrigin-RevId: 518962607
This commit is contained in:
committed by
gVisor bot
parent
bd30e8ba68
commit
68267dccc8
@@ -1540,6 +1540,7 @@ func (k *Kernel) EmitUnimplementedEvent(ctx context.Context, sysno uintptr) {
|
||||
})
|
||||
|
||||
t := TaskFromContext(ctx)
|
||||
IncrementUnimplementedSyscallCounter(sysno)
|
||||
_, _ = k.unimplementedSyscallEmitter.Emit(&uspb.UnimplementedSyscall{
|
||||
Tid: int32(t.ThreadID()),
|
||||
Registers: t.Arch().StateData().Proto(),
|
||||
|
||||
@@ -16,12 +16,14 @@ package kernel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"gvisor.dev/gvisor/pkg/abi"
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/bits"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/metric"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/seccheck"
|
||||
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
|
||||
@@ -37,6 +39,10 @@ const (
|
||||
// LINT.IfChange
|
||||
maxSyscallNum = 2000
|
||||
// LINT.ThenChange(../seccheck/syscall.go)
|
||||
|
||||
// outOfRangeSyscallNumber is used to represent a syscall number that is out of the
|
||||
// range [0, maxSyscallNum] in monitoring.
|
||||
outOfRangeSyscallNumber = "-1"
|
||||
)
|
||||
|
||||
// SyscallSupportLevel is a syscall support levels.
|
||||
@@ -347,6 +353,19 @@ func (s *SyscallTable) MaxSysno() (max uintptr) {
|
||||
// allSyscallTables contains all known tables.
|
||||
var allSyscallTables []*SyscallTable
|
||||
|
||||
var (
|
||||
// unimplementedSyscallCounterInit ensures the following fields are only initialized once.
|
||||
unimplementedSyscallCounterInit sync.Once
|
||||
|
||||
// unimplementedSyscallNumbers maps syscall numbers to their string representation.
|
||||
// Used such that incrementing unimplementedSyscallCounter does not require allocating memory.
|
||||
unimplementedSyscallNumbers map[uintptr]string
|
||||
|
||||
// unimplementedSyscallCounter tracks the number of times each unimplemented syscall has been
|
||||
// called by the sandboxed application.
|
||||
unimplementedSyscallCounter *metric.Uint64Metric
|
||||
)
|
||||
|
||||
// SyscallTables returns a read-only slice of registered SyscallTables.
|
||||
func SyscallTables() []*SyscallTable {
|
||||
return allSyscallTables
|
||||
@@ -371,6 +390,17 @@ func RegisterSyscallTable(s *SyscallTable) {
|
||||
panic(fmt.Sprintf("Duplicate SyscallTable registered for OS %v Arch %v", s.OS, s.Arch))
|
||||
}
|
||||
allSyscallTables = append(allSyscallTables, s)
|
||||
unimplementedSyscallCounterInit.Do(func() {
|
||||
allowedValues := make([]string, maxSyscallNum+2)
|
||||
unimplementedSyscallNumbers = make(map[uintptr]string, len(allowedValues))
|
||||
for i := uintptr(0); i <= maxSyscallNum; i++ {
|
||||
s := strconv.Itoa(int(i))
|
||||
allowedValues[i] = s
|
||||
unimplementedSyscallNumbers[i] = s
|
||||
}
|
||||
allowedValues[len(allowedValues)-1] = outOfRangeSyscallNumber
|
||||
unimplementedSyscallCounter = metric.MustCreateNewUint64Metric("unimplemented_syscalls", true, "Number of times the application tried to call an unimplemented syscall, broken down by syscall number", metric.NewField("sysno", allowedValues))
|
||||
})
|
||||
s.Init()
|
||||
}
|
||||
|
||||
@@ -461,3 +491,17 @@ type SyscallInfo struct {
|
||||
Rval uintptr
|
||||
Errno int
|
||||
}
|
||||
|
||||
// IncrementUnimplementedSyscallCounter increments the "unimplemented syscall" metric for the given
|
||||
// syscall number.
|
||||
// A syscall table must have been initialized prior to calling this function.
|
||||
// +checkescape:all
|
||||
//
|
||||
//go:nosplit
|
||||
func IncrementUnimplementedSyscallCounter(sysno uintptr) {
|
||||
s, found := unimplementedSyscallNumbers[sysno]
|
||||
if !found {
|
||||
s = outOfRangeSyscallNumber
|
||||
}
|
||||
unimplementedSyscallCounter.Increment(s)
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ func Error(name string, err error, note string, urls []string) kernel.Syscall {
|
||||
return kernel.Syscall{
|
||||
Name: name,
|
||||
Fn: func(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
|
||||
kernel.IncrementUnimplementedSyscallCounter(sysno)
|
||||
return 0, nil, err
|
||||
},
|
||||
SupportLevel: kernel.SupportUnimplemented,
|
||||
|
||||
Reference in New Issue
Block a user