From 8d426b73818cf07aeee3db88478a00b80ad9aafe Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Thu, 10 Jun 2021 12:43:10 -0700 Subject: Parse mmap protection and flags in strace PiperOrigin-RevId: 378712518 --- pkg/refs/refcounter.go | 6 +-- pkg/sentry/strace/BUILD | 2 +- pkg/sentry/strace/clone.go | 46 +++++++++---------- pkg/sentry/strace/linux64_amd64.go | 2 +- pkg/sentry/strace/linux64_arm64.go | 2 +- pkg/sentry/strace/mmap.go | 92 ++++++++++++++++++++++++++++++++++++++ pkg/sentry/strace/open.go | 42 +++++++++-------- pkg/sentry/strace/strace.go | 4 ++ pkg/sentry/strace/syscalls.go | 6 +++ pkg/sentry/watchdog/watchdog.go | 6 +-- 10 files changed, 157 insertions(+), 51 deletions(-) create mode 100644 pkg/sentry/strace/mmap.go (limited to 'pkg') diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 4aecb8007..1bbcae045 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -261,8 +261,8 @@ func (l *LeakMode) Get() interface{} { } // String implements flag.Value. -func (l *LeakMode) String() string { - switch *l { +func (l LeakMode) String() string { + switch l { case UninitializedLeakChecking: return "uninitialized" case NoLeakChecking: @@ -272,7 +272,7 @@ func (l *LeakMode) String() string { case LeaksLogTraces: return "log-traces" } - panic(fmt.Sprintf("invalid ref leak mode %d", *l)) + panic(fmt.Sprintf("invalid ref leak mode %d", l)) } // leakMode stores the current mode for the reference leak checker. diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index 1fbbd133c..369541c7a 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -11,6 +11,7 @@ go_library( "futex.go", "linux64_amd64.go", "linux64_arm64.go", + "mmap.go", "open.go", "poll.go", "ptrace.go", @@ -35,7 +36,6 @@ go_library( "//pkg/sentry/socket", "//pkg/sentry/socket/netlink", "//pkg/sentry/syscalls/linux", - "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/strace/clone.go b/pkg/sentry/strace/clone.go index ab1060426..bfb4d7f5c 100644 --- a/pkg/sentry/strace/clone.go +++ b/pkg/sentry/strace/clone.go @@ -15,98 +15,98 @@ package strace import ( - "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi" + "gvisor.dev/gvisor/pkg/abi/linux" ) // CloneFlagSet is the set of clone(2) flags. var CloneFlagSet = abi.FlagSet{ { - Flag: unix.CLONE_VM, + Flag: linux.CLONE_VM, Name: "CLONE_VM", }, { - Flag: unix.CLONE_FS, + Flag: linux.CLONE_FS, Name: "CLONE_FS", }, { - Flag: unix.CLONE_FILES, + Flag: linux.CLONE_FILES, Name: "CLONE_FILES", }, { - Flag: unix.CLONE_SIGHAND, + Flag: linux.CLONE_SIGHAND, Name: "CLONE_SIGHAND", }, { - Flag: unix.CLONE_PTRACE, + Flag: linux.CLONE_PTRACE, Name: "CLONE_PTRACE", }, { - Flag: unix.CLONE_VFORK, + Flag: linux.CLONE_VFORK, Name: "CLONE_VFORK", }, { - Flag: unix.CLONE_PARENT, + Flag: linux.CLONE_PARENT, Name: "CLONE_PARENT", }, { - Flag: unix.CLONE_THREAD, + Flag: linux.CLONE_THREAD, Name: "CLONE_THREAD", }, { - Flag: unix.CLONE_NEWNS, + Flag: linux.CLONE_NEWNS, Name: "CLONE_NEWNS", }, { - Flag: unix.CLONE_SYSVSEM, + Flag: linux.CLONE_SYSVSEM, Name: "CLONE_SYSVSEM", }, { - Flag: unix.CLONE_SETTLS, + Flag: linux.CLONE_SETTLS, Name: "CLONE_SETTLS", }, { - Flag: unix.CLONE_PARENT_SETTID, + Flag: linux.CLONE_PARENT_SETTID, Name: "CLONE_PARENT_SETTID", }, { - Flag: unix.CLONE_CHILD_CLEARTID, + Flag: linux.CLONE_CHILD_CLEARTID, Name: "CLONE_CHILD_CLEARTID", }, { - Flag: unix.CLONE_DETACHED, + Flag: linux.CLONE_DETACHED, Name: "CLONE_DETACHED", }, { - Flag: unix.CLONE_UNTRACED, + Flag: linux.CLONE_UNTRACED, Name: "CLONE_UNTRACED", }, { - Flag: unix.CLONE_CHILD_SETTID, + Flag: linux.CLONE_CHILD_SETTID, Name: "CLONE_CHILD_SETTID", }, { - Flag: unix.CLONE_NEWUTS, + Flag: linux.CLONE_NEWUTS, Name: "CLONE_NEWUTS", }, { - Flag: unix.CLONE_NEWIPC, + Flag: linux.CLONE_NEWIPC, Name: "CLONE_NEWIPC", }, { - Flag: unix.CLONE_NEWUSER, + Flag: linux.CLONE_NEWUSER, Name: "CLONE_NEWUSER", }, { - Flag: unix.CLONE_NEWPID, + Flag: linux.CLONE_NEWPID, Name: "CLONE_NEWPID", }, { - Flag: unix.CLONE_NEWNET, + Flag: linux.CLONE_NEWNET, Name: "CLONE_NEWNET", }, { - Flag: unix.CLONE_IO, + Flag: linux.CLONE_IO, Name: "CLONE_IO", }, } diff --git a/pkg/sentry/strace/linux64_amd64.go b/pkg/sentry/strace/linux64_amd64.go index d66befe81..6ce1bb592 100644 --- a/pkg/sentry/strace/linux64_amd64.go +++ b/pkg/sentry/strace/linux64_amd64.go @@ -33,7 +33,7 @@ var linuxAMD64 = SyscallMap{ 6: makeSyscallInfo("lstat", Path, Stat), 7: makeSyscallInfo("poll", PollFDs, Hex, Hex), 8: makeSyscallInfo("lseek", Hex, Hex, Hex), - 9: makeSyscallInfo("mmap", Hex, Hex, Hex, Hex, FD, Hex), + 9: makeSyscallInfo("mmap", Hex, Hex, MmapProt, MmapFlags, FD, Hex), 10: makeSyscallInfo("mprotect", Hex, Hex, Hex), 11: makeSyscallInfo("munmap", Hex, Hex), 12: makeSyscallInfo("brk", Hex), diff --git a/pkg/sentry/strace/linux64_arm64.go b/pkg/sentry/strace/linux64_arm64.go index 1a2d7d75f..ce5594301 100644 --- a/pkg/sentry/strace/linux64_arm64.go +++ b/pkg/sentry/strace/linux64_arm64.go @@ -246,7 +246,7 @@ var linuxARM64 = SyscallMap{ 219: makeSyscallInfo("keyctl", Hex, Hex, Hex, Hex, Hex), 220: makeSyscallInfo("clone", CloneFlags, Hex, Hex, Hex, Hex), 221: makeSyscallInfo("execve", Path, ExecveStringVector, ExecveStringVector), - 222: makeSyscallInfo("mmap", Hex, Hex, Hex, Hex, FD, Hex), + 222: makeSyscallInfo("mmap", Hex, Hex, MmapProt, MmapFlags, FD, Hex), 223: makeSyscallInfo("fadvise64", FD, Hex, Hex, Hex), 224: makeSyscallInfo("swapon", Hex, Hex), 225: makeSyscallInfo("swapoff", Hex), diff --git a/pkg/sentry/strace/mmap.go b/pkg/sentry/strace/mmap.go new file mode 100644 index 000000000..0035be586 --- /dev/null +++ b/pkg/sentry/strace/mmap.go @@ -0,0 +1,92 @@ +// Copyright 2021 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 strace + +import ( + "gvisor.dev/gvisor/pkg/abi" + "gvisor.dev/gvisor/pkg/abi/linux" +) + +// ProtectionFlagSet represents the protection to mmap(2). +var ProtectionFlagSet = abi.FlagSet{ + { + Flag: linux.PROT_READ, + Name: "PROT_READ", + }, + { + Flag: linux.PROT_WRITE, + Name: "PROT_WRITE", + }, + { + Flag: linux.PROT_EXEC, + Name: "PROT_EXEC", + }, +} + +// MmapFlagSet is the set of mmap(2) flags. +var MmapFlagSet = abi.FlagSet{ + { + Flag: linux.MAP_SHARED, + Name: "MAP_SHARED", + }, + { + Flag: linux.MAP_PRIVATE, + Name: "MAP_PRIVATE", + }, + { + Flag: linux.MAP_FIXED, + Name: "MAP_FIXED", + }, + { + Flag: linux.MAP_ANONYMOUS, + Name: "MAP_ANONYMOUS", + }, + { + Flag: linux.MAP_GROWSDOWN, + Name: "MAP_GROWSDOWN", + }, + { + Flag: linux.MAP_DENYWRITE, + Name: "MAP_DENYWRITE", + }, + { + Flag: linux.MAP_EXECUTABLE, + Name: "MAP_EXECUTABLE", + }, + { + Flag: linux.MAP_LOCKED, + Name: "MAP_LOCKED", + }, + { + Flag: linux.MAP_NORESERVE, + Name: "MAP_NORESERVE", + }, + { + Flag: linux.MAP_POPULATE, + Name: "MAP_POPULATE", + }, + { + Flag: linux.MAP_NONBLOCK, + Name: "MAP_NONBLOCK", + }, + { + Flag: linux.MAP_STACK, + Name: "MAP_STACK", + }, + { + Flag: linux.MAP_HUGETLB, + Name: "MAP_HUGETLB", + }, +} diff --git a/pkg/sentry/strace/open.go b/pkg/sentry/strace/open.go index 5769360da..e7c7649f4 100644 --- a/pkg/sentry/strace/open.go +++ b/pkg/sentry/strace/open.go @@ -15,61 +15,61 @@ package strace import ( - "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi" + "gvisor.dev/gvisor/pkg/abi/linux" ) // OpenMode represents the mode to open(2) a file. var OpenMode = abi.ValueSet{ - unix.O_RDWR: "O_RDWR", - unix.O_WRONLY: "O_WRONLY", - unix.O_RDONLY: "O_RDONLY", + linux.O_RDWR: "O_RDWR", + linux.O_WRONLY: "O_WRONLY", + linux.O_RDONLY: "O_RDONLY", } // OpenFlagSet is the set of open(2) flags. var OpenFlagSet = abi.FlagSet{ { - Flag: unix.O_APPEND, + Flag: linux.O_APPEND, Name: "O_APPEND", }, { - Flag: unix.O_ASYNC, + Flag: linux.O_ASYNC, Name: "O_ASYNC", }, { - Flag: unix.O_CLOEXEC, + Flag: linux.O_CLOEXEC, Name: "O_CLOEXEC", }, { - Flag: unix.O_CREAT, + Flag: linux.O_CREAT, Name: "O_CREAT", }, { - Flag: unix.O_DIRECT, + Flag: linux.O_DIRECT, Name: "O_DIRECT", }, { - Flag: unix.O_DIRECTORY, + Flag: linux.O_DIRECTORY, Name: "O_DIRECTORY", }, { - Flag: unix.O_EXCL, + Flag: linux.O_EXCL, Name: "O_EXCL", }, { - Flag: unix.O_NOATIME, + Flag: linux.O_NOATIME, Name: "O_NOATIME", }, { - Flag: unix.O_NOCTTY, + Flag: linux.O_NOCTTY, Name: "O_NOCTTY", }, { - Flag: unix.O_NOFOLLOW, + Flag: linux.O_NOFOLLOW, Name: "O_NOFOLLOW", }, { - Flag: unix.O_NONBLOCK, + Flag: linux.O_NONBLOCK, Name: "O_NONBLOCK", }, { @@ -77,18 +77,22 @@ var OpenFlagSet = abi.FlagSet{ Name: "O_PATH", }, { - Flag: unix.O_SYNC, + Flag: linux.O_SYNC, Name: "O_SYNC", }, { - Flag: unix.O_TRUNC, + Flag: linux.O_TMPFILE, + Name: "O_TMPFILE", + }, + { + Flag: linux.O_TRUNC, Name: "O_TRUNC", }, } func open(val uint64) string { - s := OpenMode.Parse(val & unix.O_ACCMODE) - if flags := OpenFlagSet.Parse(val &^ unix.O_ACCMODE); flags != "" { + s := OpenMode.Parse(val & linux.O_ACCMODE) + if flags := OpenFlagSet.Parse(val &^ linux.O_ACCMODE); flags != "" { s += "|" + flags } return s diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index ec5d5f846..af7088847 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -489,6 +489,10 @@ func (i *SyscallInfo) pre(t *kernel.Task, args arch.SyscallArguments, maximumBlo output = append(output, epollEvents(t, args[arg].Pointer(), 0 /* numEvents */, uint64(maximumBlobSize))) case SelectFDSet: output = append(output, fdSet(t, int(args[0].Int()), args[arg].Pointer())) + case MmapProt: + output = append(output, ProtectionFlagSet.Parse(uint64(args[arg].Uint()))) + case MmapFlags: + output = append(output, MmapFlagSet.Parse(uint64(args[arg].Uint()))) case Oct: output = append(output, "0o"+strconv.FormatUint(args[arg].Uint64(), 8)) case Hex: diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 7e69b9279..5893443a7 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -238,6 +238,12 @@ const ( // EpollEvents is an array of struct epoll_event. It is the events // argument in epoll_wait(2)/epoll_pwait(2). EpollEvents + + // MmapProt is the protection argument in mmap(2). + MmapProt + + // MmapFlags is the flags argument in mmap(2). + MmapFlags ) // defaultFormat is the syscall argument format to use if the actual format is diff --git a/pkg/sentry/watchdog/watchdog.go b/pkg/sentry/watchdog/watchdog.go index dfe85f31d..8d563d53a 100644 --- a/pkg/sentry/watchdog/watchdog.go +++ b/pkg/sentry/watchdog/watchdog.go @@ -115,14 +115,14 @@ func (a *Action) Get() interface{} { } // String returns Action's string representation. -func (a *Action) String() string { - switch *a { +func (a Action) String() string { + switch a { case LogWarning: return "logWarning" case Panic: return "panic" default: - panic(fmt.Sprintf("Invalid watchdog action: %d", *a)) + panic(fmt.Sprintf("Invalid watchdog action: %d", a)) } } -- cgit v1.2.3