diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 389824b25..10d7b97c2 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -131,6 +131,7 @@ go_library( "//pkg/cpuid", "//pkg/eventchannel", "//pkg/log", + "//pkg/metric", "//pkg/refs", "//pkg/secio", "//pkg/sentry/arch", diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 0318adb35..2a39ebc68 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -21,6 +21,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/bits" + "gvisor.googlesource.com/gvisor/pkg/metric" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -60,6 +61,8 @@ const ( ERESTART_RESTARTBLOCK = SyscallRestartErrno(516) ) +var vsyscallCount = metric.MustCreateNewUint64Metric("/kernel/vsyscall_count", false /* sync */, "Number of times vsyscalls were invoked by the application") + // Error implements error.Error. func (e SyscallRestartErrno) Error() string { // Descriptions are borrowed from strace. @@ -325,6 +328,8 @@ func (*runSyscallExit) execute(t *Task) taskRunState { // indicated by an execution fault at address addr. doVsyscall returns the // task's next run state. func (t *Task) doVsyscall(addr usermem.Addr, sysno uintptr) taskRunState { + vsyscallCount.Increment() + // Grab the caller up front, to make sure there's a sensible stack. caller := t.Arch().Native(uintptr(0)) if _, err := t.CopyIn(usermem.Addr(t.Arch().Stack()), caller); err != nil { diff --git a/pkg/sentry/mm/proc_pid_maps.go b/pkg/sentry/mm/proc_pid_maps.go index 0bf1cdb51..247ee45ef 100644 --- a/pkg/sentry/mm/proc_pid_maps.go +++ b/pkg/sentry/mm/proc_pid_maps.go @@ -53,6 +53,22 @@ func (mm *MemoryManager) ReadSeqFileData(ctx context.Context, handle seqfile.Seq Handle: &vmaAddr, }) } + + // We always emulate vsyscall, so advertise it here. Everything about a + // vsyscall region is static, so just hard code the maps entry since we + // don't have a real vma backing it. The vsyscall region is at the end of + // the virtual address space so nothing should be mapped after it (if + // something is really mapped in the tiny ~10 MiB segment afterwards, we'll + // get the sorting on the maps file wrong at worst; but that's not possible + // on any current platform). + // + // Artifically adjust the seqfile handle so we only output vsyscall entry once. + if vsyscallEnd := usermem.Addr(0xffffffffff601000); start != vsyscallEnd { + data = append(data, seqfile.SeqData{ + Buf: []byte("ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"), + Handle: &vsyscallEnd, + }) + } return data, 1 }