From d02b74a5dcfed4bfc8f2f8e545bca4d2afabb296 Mon Sep 17 00:00:00 2001 From: Googler Date: Fri, 27 Apr 2018 10:37:02 -0700 Subject: Check in gVisor. PiperOrigin-RevId: 194583126 Change-Id: Ica1d8821a90f74e7e745962d71801c598c652463 --- pkg/abi/BUILD | 25 ++++ pkg/abi/abi.go | 41 ++++++ pkg/abi/flag.go | 76 +++++++++++ pkg/abi/linux/BUILD | 69 ++++++++++ pkg/abi/linux/aio.go | 20 +++ pkg/abi/linux/ashmem.go | 29 ++++ pkg/abi/linux/binder.go | 20 +++ pkg/abi/linux/bpf.go | 32 +++++ pkg/abi/linux/capability.go | 104 +++++++++++++++ pkg/abi/linux/dev.go | 48 +++++++ pkg/abi/linux/elf.go | 91 +++++++++++++ pkg/abi/linux/errors.go | 172 ++++++++++++++++++++++++ pkg/abi/linux/exec.go | 18 +++ pkg/abi/linux/file.go | 232 ++++++++++++++++++++++++++++++++ pkg/abi/linux/fs.go | 69 ++++++++++ pkg/abi/linux/futex.go | 56 ++++++++ pkg/abi/linux/inotify.go | 97 ++++++++++++++ pkg/abi/linux/ioctl.go | 57 ++++++++ pkg/abi/linux/ip.go | 44 +++++++ pkg/abi/linux/ipc.go | 47 +++++++ pkg/abi/linux/limits.go | 88 +++++++++++++ pkg/abi/linux/linux.go | 38 ++++++ pkg/abi/linux/mm.go | 103 +++++++++++++++ pkg/abi/linux/netdevice.go | 86 ++++++++++++ pkg/abi/linux/netlink.go | 110 ++++++++++++++++ pkg/abi/linux/netlink_route.go | 186 ++++++++++++++++++++++++++ pkg/abi/linux/poll.go | 42 ++++++ pkg/abi/linux/prctl.go | 72 ++++++++++ pkg/abi/linux/rusage.go | 46 +++++++ pkg/abi/linux/sched.go | 30 +++++ pkg/abi/linux/seccomp.go | 38 ++++++ pkg/abi/linux/sem.go | 53 ++++++++ pkg/abi/linux/signal.go | 177 +++++++++++++++++++++++++ pkg/abi/linux/socket.go | 290 ++++++++++++++++++++++++++++++++++++++++ pkg/abi/linux/time.go | 224 +++++++++++++++++++++++++++++++ pkg/abi/linux/tty.go | 292 +++++++++++++++++++++++++++++++++++++++++ pkg/abi/linux/uio.go | 18 +++ pkg/abi/linux/utsname.go | 49 +++++++ 38 files changed, 3289 insertions(+) create mode 100644 pkg/abi/BUILD create mode 100644 pkg/abi/abi.go create mode 100644 pkg/abi/flag.go create mode 100644 pkg/abi/linux/BUILD create mode 100644 pkg/abi/linux/aio.go create mode 100644 pkg/abi/linux/ashmem.go create mode 100644 pkg/abi/linux/binder.go create mode 100644 pkg/abi/linux/bpf.go create mode 100644 pkg/abi/linux/capability.go create mode 100644 pkg/abi/linux/dev.go create mode 100644 pkg/abi/linux/elf.go create mode 100644 pkg/abi/linux/errors.go create mode 100644 pkg/abi/linux/exec.go create mode 100644 pkg/abi/linux/file.go create mode 100644 pkg/abi/linux/fs.go create mode 100644 pkg/abi/linux/futex.go create mode 100644 pkg/abi/linux/inotify.go create mode 100644 pkg/abi/linux/ioctl.go create mode 100644 pkg/abi/linux/ip.go create mode 100644 pkg/abi/linux/ipc.go create mode 100644 pkg/abi/linux/limits.go create mode 100644 pkg/abi/linux/linux.go create mode 100644 pkg/abi/linux/mm.go create mode 100644 pkg/abi/linux/netdevice.go create mode 100644 pkg/abi/linux/netlink.go create mode 100644 pkg/abi/linux/netlink_route.go create mode 100644 pkg/abi/linux/poll.go create mode 100644 pkg/abi/linux/prctl.go create mode 100644 pkg/abi/linux/rusage.go create mode 100644 pkg/abi/linux/sched.go create mode 100644 pkg/abi/linux/seccomp.go create mode 100644 pkg/abi/linux/sem.go create mode 100644 pkg/abi/linux/signal.go create mode 100644 pkg/abi/linux/socket.go create mode 100644 pkg/abi/linux/time.go create mode 100644 pkg/abi/linux/tty.go create mode 100644 pkg/abi/linux/uio.go create mode 100644 pkg/abi/linux/utsname.go (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD new file mode 100644 index 000000000..4d507161f --- /dev/null +++ b/pkg/abi/BUILD @@ -0,0 +1,25 @@ +package(licenses = ["notice"]) # Apache 2.0 + +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_stateify") + +go_stateify( + name = "abi_state", + srcs = [ + "abi.go", + ], + out = "abi_state.go", + package = "abi", +) + +go_library( + name = "abi", + srcs = [ + "abi.go", + "abi_state.go", + "flag.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/abi", + visibility = ["//:sandbox"], + deps = ["//pkg/state"], +) diff --git a/pkg/abi/abi.go b/pkg/abi/abi.go new file mode 100644 index 000000000..a53c2747b --- /dev/null +++ b/pkg/abi/abi.go @@ -0,0 +1,41 @@ +// Copyright 2018 Google Inc. +// +// 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 abi describes the interface between a kernel and userspace. +package abi + +import ( + "fmt" +) + +// OS describes the target operating system for an ABI. +// +// Note that OS is architecture-independent. The details of the OS ABI will +// vary between architectures. +type OS int + +const ( + // Linux is the Linux ABI. + Linux OS = iota +) + +// String implements fmt.Stringer. +func (o OS) String() string { + switch o { + case Linux: + return "linux" + default: + return fmt.Sprintf("OS(%d)", o) + } +} diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go new file mode 100644 index 000000000..0391ccf37 --- /dev/null +++ b/pkg/abi/flag.go @@ -0,0 +1,76 @@ +// Copyright 2018 Google Inc. +// +// 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 abi + +import ( + "fmt" + "math" + "strconv" + "strings" +) + +// A FlagSet is a slice of bit-flags and their name. +type FlagSet []struct { + Flag uint64 + Name string +} + +// Parse returns a pretty version of val, using the flag names for known flags. +// Unknown flags remain numeric. +func (s FlagSet) Parse(val uint64) string { + var flags []string + + for _, f := range s { + if val&f.Flag == f.Flag { + flags = append(flags, f.Name) + val &^= f.Flag + } + } + + if val != 0 { + flags = append(flags, "0x"+strconv.FormatUint(val, 16)) + } + + return strings.Join(flags, "|") +} + +// ValueSet is a slice of syscall values and their name. Parse will replace +// values that exactly match an entry with its name. +type ValueSet []struct { + Value uint64 + Name string +} + +// Parse returns the name of the value associated with `val`. Unknown values +// are converted to hex. +func (e ValueSet) Parse(val uint64) string { + for _, f := range e { + if val == f.Value { + return f.Name + } + } + return fmt.Sprintf("%#x", val) +} + +// ParseName returns the flag value associated with 'name'. Returns false +// if no value is found. +func (e ValueSet) ParseName(name string) (uint64, bool) { + for _, f := range e { + if name == f.Name { + return f.Value, true + } + } + return math.MaxUint64, false +} diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD new file mode 100644 index 000000000..a428e61a3 --- /dev/null +++ b/pkg/abi/linux/BUILD @@ -0,0 +1,69 @@ +# Package linux contains the constants and types needed to inferface with a +# Linux kernel. It should be used instead of syscall or golang.org/x/sys/unix +# when the host OS may not be Linux. + +package(licenses = ["notice"]) # Apache 2.0 + +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_stateify") + +go_stateify( + name = "linux_state", + srcs = [ + "binder.go", + "bpf.go", + "time.go", + "tty.go", + ], + out = "linux_state.go", + package = "linux", +) + +go_library( + name = "linux", + srcs = [ + "aio.go", + "ashmem.go", + "binder.go", + "bpf.go", + "capability.go", + "dev.go", + "elf.go", + "errors.go", + "exec.go", + "file.go", + "fs.go", + "futex.go", + "inotify.go", + "ioctl.go", + "ip.go", + "ipc.go", + "limits.go", + "linux.go", + "linux_state.go", + "mm.go", + "netdevice.go", + "netlink.go", + "netlink_route.go", + "poll.go", + "prctl.go", + "rusage.go", + "sched.go", + "seccomp.go", + "sem.go", + "signal.go", + "socket.go", + "time.go", + "tty.go", + "uio.go", + "utsname.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/abi/linux", + visibility = ["//visibility:public"], + deps = [ + "//pkg/abi", + "//pkg/binary", + "//pkg/bits", + "//pkg/state", + ], +) diff --git a/pkg/abi/linux/aio.go b/pkg/abi/linux/aio.go new file mode 100644 index 000000000..9c39ca2ef --- /dev/null +++ b/pkg/abi/linux/aio.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +const ( + // AIORingSize is sizeof(struct aio_ring). + AIORingSize = 32 +) diff --git a/pkg/abi/linux/ashmem.go b/pkg/abi/linux/ashmem.go new file mode 100644 index 000000000..7fbfd2e68 --- /dev/null +++ b/pkg/abi/linux/ashmem.go @@ -0,0 +1,29 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Constants used by ashmem in pin-related ioctls. +const ( + AshmemNotPurged = 0 + AshmemWasPurged = 1 + AshmemIsUnpinned = 0 + AshmemIsPinned = 1 +) + +// AshmemPin structure is used for pin-related ioctls. +type AshmemPin struct { + Offset uint32 + Len uint32 +} diff --git a/pkg/abi/linux/binder.go b/pkg/abi/linux/binder.go new file mode 100644 index 000000000..b228898f9 --- /dev/null +++ b/pkg/abi/linux/binder.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// BinderVersion structure is used for BINDER_VERSION ioctl. +type BinderVersion struct { + ProtocolVersion int32 +} diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go new file mode 100644 index 000000000..f597ef4f5 --- /dev/null +++ b/pkg/abi/linux/bpf.go @@ -0,0 +1,32 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// BPFInstruction is a raw BPF virtual machine instruction. +type BPFInstruction struct { + // OpCode is the operation to execute. + OpCode uint16 + + // JumpIfTrue is the number of instructions to skip if OpCode is a + // conditional instruction and the condition is true. + JumpIfTrue uint8 + + // JumpIfFalse is the number of instructions to skip if OpCode is a + // conditional instruction and the condition is false. + JumpIfFalse uint8 + + // K is a constant parameter. The meaning depends on the value of OpCode. + K uint32 +} diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go new file mode 100644 index 000000000..1a1bd0ce3 --- /dev/null +++ b/pkg/abi/linux/capability.go @@ -0,0 +1,104 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// A Capability represents the ability to perform a privileged operation. +type Capability int + +// Capabilities defined by Linux. Taken from the kernel's +// include/uapi/linux/capability.h. See capabilities(7) or that file for more +// detailed capability descriptions. +const ( + CAP_CHOWN = Capability(0) + CAP_DAC_OVERRIDE = Capability(1) + CAP_DAC_READ_SEARCH = Capability(2) + CAP_FOWNER = Capability(3) + CAP_FSETID = Capability(4) + CAP_KILL = Capability(5) + CAP_SETGID = Capability(6) + CAP_SETUID = Capability(7) + CAP_SETPCAP = Capability(8) + CAP_LINUX_IMMUTABLE = Capability(9) + CAP_NET_BIND_SERVICE = Capability(10) + CAP_NET_BROAD_CAST = Capability(11) + CAP_NET_ADMIN = Capability(12) + CAP_NET_RAW = Capability(13) + CAP_IPC_LOCK = Capability(14) + CAP_IPC_OWNER = Capability(15) + CAP_SYS_MODULE = Capability(16) + CAP_SYS_RAWIO = Capability(17) + CAP_SYS_CHROOT = Capability(18) + CAP_SYS_PTRACE = Capability(19) + CAP_SYS_PACCT = Capability(20) + CAP_SYS_ADMIN = Capability(21) + CAP_SYS_BOOT = Capability(22) + CAP_SYS_NICE = Capability(23) + CAP_SYS_RESOURCE = Capability(24) + CAP_SYS_TIME = Capability(25) + CAP_SYS_TTY_CONFIG = Capability(26) + CAP_MKNOD = Capability(27) + CAP_LEASE = Capability(28) + CAP_AUDIT_WRITE = Capability(29) + CAP_AUDIT_CONTROL = Capability(30) + CAP_SETFCAP = Capability(31) + CAP_MAC_OVERRIDE = Capability(32) + CAP_MAC_ADMIN = Capability(33) + CAP_SYSLOG = Capability(34) + CAP_WAKE_ALARM = Capability(35) + CAP_BLOCK_SUSPEND = Capability(36) + + // MaxCapability is the highest-numbered capability. + MaxCapability = Capability(36) // CAP_BLOCK_SUSPEND as of 3.11 +) + +// Ok returns true if cp is a supported capability. +func (cp Capability) Ok() bool { + return cp >= 0 && cp <= MaxCapability +} + +// Version numbers used by the capget/capset syscalls, defined in Linux's +// include/uapi/linux/capability.h. +const ( + // LINUX_CAPABILITY_VERSION_1 causes the data pointer to be + // interpreted as a pointer to a single cap_user_data_t. Since capability + // sets are 64 bits and the "capability sets" in cap_user_data_t are 32 + // bits only, this causes the upper 32 bits to be implicitly 0. + LINUX_CAPABILITY_VERSION_1 = 0x19980330 + + // LINUX_CAPABILITY_VERSION_2 and LINUX_CAPABILITY_VERSION_3 cause the + // data pointer to be interpreted as a pointer to an array of 2 + // cap_user_data_t, using the second to store the 32 MSB of each capability + // set. Versions 2 and 3 are identical, but Linux printk's a warning on use + // of version 2 due to a userspace API defect. + LINUX_CAPABILITY_VERSION_2 = 0x20071026 + LINUX_CAPABILITY_VERSION_3 = 0x20080522 + + // HighestCapabilityVersion is the highest supported + // LINUX_CAPABILITY_VERSION_* version. + HighestCapabilityVersion = LINUX_CAPABILITY_VERSION_3 +) + +// CapUserHeader is equivalent to Linux's cap_user_header_t. +type CapUserHeader struct { + Version uint32 + Pid int32 +} + +// CapUserData is equivalent to Linux's cap_user_data_t. +type CapUserData struct { + Effective uint32 + Permitted uint32 + Inheritable uint32 +} diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go new file mode 100644 index 000000000..d3b63063f --- /dev/null +++ b/pkg/abi/linux/dev.go @@ -0,0 +1,48 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// MakeDeviceID encodes a major and minor device number into a single device ID. +// +// Format (see linux/kdev_t.h:new_encode_dev): +// +// Bits 7:0 - minor bits 7:0 +// Bits 19:8 - major bits 11:0 +// Bits 31:20 - minor bits 19:8 +func MakeDeviceID(major uint16, minor uint32) uint32 { + return (minor & 0xff) | ((uint32(major) & 0xfff) << 8) | ((minor >> 8) << 20) +} + +// Character device IDs. +// +// See Documentations/devices.txt and uapi/linux/major.h. +const ( + // TTYAUX_MAJOR is the major device number for alternate TTY devices. + TTYAUX_MAJOR = 5 + + // UNIX98_PTY_MASTER_MAJOR is the initial major device number for + // Unix98 PTY masters. + UNIX98_PTY_MASTER_MAJOR = 128 + + // UNIX98_PTY_SLAVE_MAJOR is the initial major device number for + // Unix98 PTY slaves. + UNIX98_PTY_SLAVE_MAJOR = 136 +) + +// Minor device numbers for TTYAUX_MAJOR. +const ( + // PTMX_MINOR is the minor device number for /dev/ptmx. + PTMX_MINOR = 2 +) diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go new file mode 100644 index 000000000..76c13b677 --- /dev/null +++ b/pkg/abi/linux/elf.go @@ -0,0 +1,91 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Linux auxiliary vector entry types. +const ( + // AT_NULL is the end of the auxiliary vector. + AT_NULL = 0 + + // AT_IGNORE should be ignored. + AT_IGNORE = 1 + + // AT_EXECFD is the file descriptor of the program. + AT_EXECFD = 2 + + // AT_PHDR points to the program headers. + AT_PHDR = 3 + + // AT_PHENT is the size of a program header entry. + AT_PHENT = 4 + + // AT_PHNUM is the number of program headers. + AT_PHNUM = 5 + + // AT_PAGESZ is the system page size. + AT_PAGESZ = 6 + + // AT_BASE is the base address of the interpreter. + AT_BASE = 7 + + // AT_FLAGS are flags. + AT_FLAGS = 8 + + // AT_ENTRY is the program entry point. + AT_ENTRY = 9 + + // AT_NOTELF indicates that the program is not an ELF binary. + AT_NOTELF = 10 + + // AT_UID is the real UID. + AT_UID = 11 + + // AT_EUID is the effective UID. + AT_EUID = 12 + + // AT_GID is the real GID. + AT_GID = 13 + + // AT_EGID is the effective GID. + AT_EGID = 14 + + // AT_PLATFORM is a string identifying the CPU. + AT_PLATFORM = 15 + + // AT_HWCAP are arch-dependent CPU capabilities. + AT_HWCAP = 16 + + // AT_CLKTCK is the frequency used by times(2). + AT_CLKTCK = 17 + + // AT_SECURE indicate secure mode. + AT_SECURE = 23 + + // AT_BASE_PLATFORM is a string identifying the "real" platform. It may + // differ from AT_PLATFORM. + AT_BASE_PLATFORM = 24 + + // AT_RANDOM points to 16-bytes of random data. + AT_RANDOM = 25 + + // AT_HWCAP2 is an extension of AT_HWCAP. + AT_HWCAP2 = 26 + + // AT_EXECFN is the path used to execute the program. + AT_EXECFN = 31 + + // AT_SYSINFO_EHDR is the address of the VDSO. + AT_SYSINFO_EHDR = 33 +) diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go new file mode 100644 index 000000000..b5ddb2b2f --- /dev/null +++ b/pkg/abi/linux/errors.go @@ -0,0 +1,172 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Errno represents a Linux errno value. +type Errno struct { + number int + name string +} + +// Number returns the errno number. +func (e *Errno) Number() int { + return e.number +} + +// Error implements error.Error. +func (e *Errno) Error() string { + return e.name +} + +// Errno values from include/uapi/asm-generic/errno-base.h. +var ( + EPERM = &Errno{1, "operation not permitted"} + ENOENT = &Errno{2, "no such file or directory"} + ESRCH = &Errno{3, "no such process"} + EINTR = &Errno{4, "interrupted system call"} + EIO = &Errno{5, "I/O error"} + ENXIO = &Errno{6, "no such device or address"} + E2BIG = &Errno{7, "argument list too long"} + ENOEXEC = &Errno{8, "exec format error"} + EBADF = &Errno{9, "bad file number"} + ECHILD = &Errno{10, "no child processes"} + EAGAIN = &Errno{11, "try again"} + ENOMEM = &Errno{12, "out of memory"} + EACCES = &Errno{13, "permission denied"} + EFAULT = &Errno{14, "bad address"} + ENOTBLK = &Errno{15, "block device required"} + EBUSY = &Errno{16, "device or resource busy"} + EEXIST = &Errno{17, "file exists"} + EXDEV = &Errno{18, "cross-device link"} + ENODEV = &Errno{19, "no such device"} + ENOTDIR = &Errno{20, "not a directory"} + EISDIR = &Errno{21, "is a directory"} + EINVAL = &Errno{22, "invalid argument"} + ENFILE = &Errno{23, "file table overflow"} + EMFILE = &Errno{24, "too many open files"} + ENOTTY = &Errno{25, "not a typewriter"} + ETXTBSY = &Errno{26, "text file busy"} + EFBIG = &Errno{27, "file too large"} + ENOSPC = &Errno{28, "no space left on device"} + ESPIPE = &Errno{29, "illegal seek"} + EROFS = &Errno{30, "read-only file system"} + EMLINK = &Errno{31, "too many links"} + EPIPE = &Errno{32, "broken pipe"} + EDOM = &Errno{33, "math argument out of domain of func"} + ERANGE = &Errno{34, "math result not representable"} +) + +// Errno values from include/uapi/asm-generic/errno.h. +var ( + EDEADLK = &Errno{35, "resource deadlock would occur"} + ENAMETOOLONG = &Errno{36, "file name too long"} + ENOLCK = &Errno{37, "no record locks available"} + ENOSYS = &Errno{38, "invalid system call number"} + ENOTEMPTY = &Errno{39, "directory not empty"} + ELOOP = &Errno{40, "too many symbolic links encountered"} + EWOULDBLOCK = &Errno{EAGAIN.number, "operation would block"} + ENOMSG = &Errno{42, "no message of desired type"} + EIDRM = &Errno{43, "identifier removed"} + ECHRNG = &Errno{44, "channel number out of range"} + EL2NSYNC = &Errno{45, "level 2 not synchronized"} + EL3HLT = &Errno{46, "level 3 halted"} + EL3RST = &Errno{47, "level 3 reset"} + ELNRNG = &Errno{48, "link number out of range"} + EUNATCH = &Errno{49, "protocol driver not attached"} + ENOCSI = &Errno{50, "no CSI structure available"} + EL2HLT = &Errno{51, "level 2 halted"} + EBADE = &Errno{52, "invalid exchange"} + EBADR = &Errno{53, "invalid request descriptor"} + EXFULL = &Errno{54, "exchange full"} + ENOANO = &Errno{55, "no anode"} + EBADRQC = &Errno{56, "invalid request code"} + EBADSLT = &Errno{57, "invalid slot"} + EDEADLOCK = EDEADLK + EBFONT = &Errno{59, "bad font file format"} + ENOSTR = &Errno{60, "device not a stream"} + ENODATA = &Errno{61, "no data available"} + ETIME = &Errno{62, "timer expired"} + ENOSR = &Errno{63, "out of streams resources"} + ENONET = &Errno{64, "machine is not on the network"} + ENOPKG = &Errno{65, "package not installed"} + EREMOTE = &Errno{66, "object is remote"} + ENOLINK = &Errno{67, "link has been severed"} + EADV = &Errno{68, "advertise error"} + ESRMNT = &Errno{69, "srmount error"} + ECOMM = &Errno{70, "communication error on send"} + EPROTO = &Errno{71, "protocol error"} + EMULTIHOP = &Errno{72, "multihop attempted"} + EDOTDOT = &Errno{73, "RFS specific error"} + EBADMSG = &Errno{74, "not a data message"} + EOVERFLOW = &Errno{75, "value too large for defined data type"} + ENOTUNIQ = &Errno{76, "name not unique on network"} + EBADFD = &Errno{77, "file descriptor in bad state"} + EREMCHG = &Errno{78, "remote address changed"} + ELIBACC = &Errno{79, "can not access a needed shared library"} + ELIBBAD = &Errno{80, "accessing a corrupted shared library"} + ELIBSCN = &Errno{81, ".lib section in a.out corrupted"} + ELIBMAX = &Errno{82, "attempting to link in too many shared libraries"} + ELIBEXEC = &Errno{83, "cannot exec a shared library directly"} + EILSEQ = &Errno{84, "illegal byte sequence"} + ERESTART = &Errno{85, "interrupted system call should be restarted"} + ESTRPIPE = &Errno{86, "streams pipe error"} + EUSERS = &Errno{87, "too many users"} + ENOTSOCK = &Errno{88, "socket operation on non-socket"} + EDESTADDRREQ = &Errno{89, "destination address required"} + EMSGSIZE = &Errno{90, "message too long"} + EPROTOTYPE = &Errno{91, "protocol wrong type for socket"} + ENOPROTOOPT = &Errno{92, "protocol not available"} + EPROTONOSUPPORT = &Errno{93, "protocol not supported"} + ESOCKTNOSUPPORT = &Errno{94, "socket type not supported"} + EOPNOTSUPP = &Errno{95, "operation not supported on transport endpoint"} + EPFNOSUPPORT = &Errno{96, "protocol family not supported"} + EAFNOSUPPORT = &Errno{97, "address family not supported by protocol"} + EADDRINUSE = &Errno{98, "address already in use"} + EADDRNOTAVAIL = &Errno{99, "cannot assign requested address"} + ENETDOWN = &Errno{100, "network is down"} + ENETUNREACH = &Errno{101, "network is unreachable"} + ENETRESET = &Errno{102, "network dropped connection because of reset"} + ECONNABORTED = &Errno{103, "software caused connection abort"} + ECONNRESET = &Errno{104, "connection reset by peer"} + ENOBUFS = &Errno{105, "no buffer space available"} + EISCONN = &Errno{106, "transport endpoint is already connected"} + ENOTCONN = &Errno{107, "transport endpoint is not connected"} + ESHUTDOWN = &Errno{108, "cannot send after transport endpoint shutdown"} + ETOOMANYREFS = &Errno{109, "too many references: cannot splice"} + ETIMEDOUT = &Errno{110, "connection timed out"} + ECONNREFUSED = &Errno{111, "connection refused"} + EHOSTDOWN = &Errno{112, "host is down"} + EHOSTUNREACH = &Errno{113, "no route to host"} + EALREADY = &Errno{114, "operation already in progress"} + EINPROGRESS = &Errno{115, "operation now in progress"} + ESTALE = &Errno{116, "stale file handle"} + EUCLEAN = &Errno{117, "structure needs cleaning"} + ENOTNAM = &Errno{118, "not a XENIX named type file"} + ENAVAIL = &Errno{119, "no XENIX semaphores available"} + EISNAM = &Errno{120, "is a named type file"} + EREMOTEIO = &Errno{121, "remote I/O error"} + EDQUOT = &Errno{122, "quota exceeded"} + ENOMEDIUM = &Errno{123, "no medium found"} + EMEDIUMTYPE = &Errno{124, "wrong medium type"} + ECANCELED = &Errno{125, "operation Canceled"} + ENOKEY = &Errno{126, "required key not available"} + EKEYEXPIRED = &Errno{127, "key has expired"} + EKEYREVOKED = &Errno{128, "key has been revoked"} + EKEYREJECTED = &Errno{129, "key was rejected by service"} + EOWNERDEAD = &Errno{130, "owner died"} + ENOTRECOVERABLE = &Errno{131, "state not recoverable"} + ERFKILL = &Errno{132, "operation not possible due to RF-kill"} + EHWPOISON = &Errno{133, "memory page has hardware error"} +) diff --git a/pkg/abi/linux/exec.go b/pkg/abi/linux/exec.go new file mode 100644 index 000000000..4d81eca54 --- /dev/null +++ b/pkg/abi/linux/exec.go @@ -0,0 +1,18 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// TASK_COMM_LEN is the task command name length. +const TASK_COMM_LEN = 16 diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go new file mode 100644 index 000000000..44672647b --- /dev/null +++ b/pkg/abi/linux/file.go @@ -0,0 +1,232 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import ( + "fmt" + "strings" + + "gvisor.googlesource.com/gvisor/pkg/abi" +) + +// Constants for open(2). +const ( + O_NONBLOCK = 00004000 + O_CLOEXEC = 02000000 + O_PATH = 010000000 +) + +// Constants for fstatat(2). +const ( + AT_SYMLINK_NOFOLLOW = 0x100 +) + +// Constants for mount(2). +const ( + MS_RDONLY = 0x1 + MS_NOSUID = 0x2 + MS_NODEV = 0x4 + MS_NOEXEC = 0x8 + MS_SYNCHRONOUS = 0x10 + MS_REMOUNT = 0x20 + MS_MANDLOCK = 0x40 + MS_DIRSYNC = 0x80 + MS_NOATIME = 0x400 + MS_NODIRATIME = 0x800 + MS_BIND = 0x1000 + MS_MOVE = 0x2000 + MS_REC = 0x4000 + + MS_POSIXACL = 0x10000 + MS_UNBINDABLE = 0x20000 + MS_PRIVATE = 0x40000 + MS_SLAVE = 0x80000 + MS_SHARED = 0x100000 + MS_RELATIME = 0x200000 + MS_KERNMOUNT = 0x400000 + MS_I_VERSION = 0x800000 + MS_STRICTATIME = 0x1000000 + + MS_MGC_VAL = 0xC0ED0000 + MS_MGC_MSK = 0xffff0000 +) + +// Constants for umount2(2). +const ( + MNT_FORCE = 0x1 + MNT_DETACH = 0x2 + MNT_EXPIRE = 0x4 + UMOUNT_NOFOLLOW = 0x8 +) + +// Constants for unlinkat(2). +const ( + AT_REMOVEDIR = 0x200 +) + +// Constants for linkat(2) and fchownat(2). +const ( + AT_SYMLINK_FOLLOW = 0x400 + AT_EMPTY_PATH = 0x1000 +) + +// Constants for all file-related ...at(2) syscalls. +const ( + AT_FDCWD = -100 +) + +// Special values for the ns field in utimensat(2). +const ( + UTIME_NOW = ((1 << 30) - 1) + UTIME_OMIT = ((1 << 30) - 2) +) + +// MaxSymlinkTraversals is the maximum number of links that will be followed by +// the kernel to resolve a symlink. +const MaxSymlinkTraversals = 40 + +// Constants for flock(2). +const ( + LOCK_SH = 1 // shared lock + LOCK_EX = 2 // exclusive lock + LOCK_NB = 4 // or'd with one of the above to prevent blocking + LOCK_UN = 8 // remove lock +) + +// Values for mode_t. +const ( + FileTypeMask = 0170000 + ModeSocket = 0140000 + ModeSymlink = 0120000 + ModeRegular = 0100000 + ModeBlockDevice = 060000 + ModeDirectory = 040000 + ModeCharacterDevice = 020000 + ModeNamedPipe = 010000 + + ModeSetUID = 04000 + ModeSetGID = 02000 + ModeSticky = 01000 + + ModeUserAll = 0700 + ModeUserRead = 0400 + ModeUserWrite = 0200 + ModeUserExec = 0100 + ModeGroupAll = 0070 + ModeGroupRead = 0040 + ModeGroupWrite = 0020 + ModeGroupExec = 0010 + ModeOtherAll = 0007 + ModeOtherRead = 0004 + ModeOtherWrite = 0002 + ModeOtherExec = 0001 + PermissionsMask = 0777 +) + +// Stat represents struct stat. +type Stat struct { + Dev uint64 + Ino uint64 + Nlink uint64 + Mode uint32 + UID uint32 + GID uint32 + X_pad0 int32 + Rdev uint64 + Size int64 + Blksize int64 + Blocks int64 + ATime Timespec + MTime Timespec + CTime Timespec + X_unused [3]int64 +} + +// FileMode represents a mode_t. +type FileMode uint + +// Permissions returns just the permission bits. +func (m FileMode) Permissions() FileMode { + return m & PermissionsMask +} + +// FileType returns just the file type bits. +func (m FileMode) FileType() FileMode { + return m & FileTypeMask +} + +// ExtraBits returns everything but the file type and permission bits. +func (m FileMode) ExtraBits() FileMode { + return m &^ (PermissionsMask | FileTypeMask) +} + +// String returns a string representation of m. +func (m FileMode) String() string { + var s []string + if ft := m.FileType(); ft != 0 { + s = append(s, fileType.Parse(uint64(ft))) + } + if eb := m.ExtraBits(); eb != 0 { + s = append(s, modeExtraBits.Parse(uint64(eb))) + } + s = append(s, fmt.Sprintf("0o%o", m.Permissions())) + return strings.Join(s, "|") +} + +var modeExtraBits = abi.FlagSet{ + { + Flag: ModeSetUID, + Name: "S_ISUID", + }, + { + Flag: ModeSetGID, + Name: "S_ISGID", + }, + { + Flag: ModeSticky, + Name: "S_ISVTX", + }, +} + +var fileType = abi.ValueSet{ + { + Value: ModeSocket, + Name: "S_IFSOCK", + }, + { + Value: ModeSymlink, + Name: "S_IFLINK", + }, + { + Value: ModeRegular, + Name: "S_IFREG", + }, + { + Value: ModeBlockDevice, + Name: "S_IFBLK", + }, + { + Value: ModeDirectory, + Name: "S_IFDIR", + }, + { + Value: ModeCharacterDevice, + Name: "S_IFCHR", + }, + { + Value: ModeNamedPipe, + Name: "S_IFIFO", + }, +} diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go new file mode 100644 index 000000000..00b239351 --- /dev/null +++ b/pkg/abi/linux/fs.go @@ -0,0 +1,69 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Filesystem types used in statfs(2). +// +// See linux/magic.h. +const ( + ANON_INODE_FS_MAGIC = 0x09041934 + DEVPTS_SUPER_MAGIC = 0x00001cd1 + OVERLAYFS_SUPER_MAGIC = 0x794c7630 + PIPEFS_MAGIC = 0x50495045 + RAMFS_MAGIC = 0x09041934 + SOCKFS_MAGIC = 0x534F434B + TMPFS_MAGIC = 0x01021994 + V9FS_MAGIC = 0x01021997 +) + +// Statfs is struct statfs, from uapi/asm-generic/statfs.h. +type Statfs struct { + // Type is one of the filesystem magic values, defined above. + Type uint64 + + // BlockSize is the data block size. + BlockSize int64 + + // Blocks is the number of data blocks in use. + Blocks uint64 + + // BlocksFree is the number of free blocks. + BlocksFree uint64 + + // BlocksAvailable is the number of blocks free for use by + // unprivileged users. + BlocksAvailable uint64 + + // Files is the number of used file nodes on the filesystem. + Files uint64 + + // FileFress is the number of free file nodes on the filesystem. + FilesFree uint64 + + // FSID is the filesystem ID. + FSID [2]int32 + + // NameLength is the maximum file name length. + NameLength uint64 + + // FragmentSize is equivalent to BlockSize. + FragmentSize int64 + + // Flags is the set of filesystem mount flags. + Flags uint64 + + // Spare is unused. + Spare [4]uint64 +} diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go new file mode 100644 index 000000000..f63f5200c --- /dev/null +++ b/pkg/abi/linux/futex.go @@ -0,0 +1,56 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// From and . +// Flags are used in syscall futex(2). +const ( + FUTEX_WAIT = 0 + FUTEX_WAKE = 1 + FUTEX_FD = 2 + FUTEX_REQUEUE = 3 + FUTEX_CMP_REQUEUE = 4 + FUTEX_WAKE_OP = 5 + FUTEX_LOCK_PI = 6 + FUTEX_UNLOCK_PI = 7 + FUTEX_TRYLOCK_PI = 8 + FUTEX_WAIT_BITSET = 9 + FUTEX_WAKE_BITSET = 10 + FUTEX_WAIT_REQUEUE_PI = 11 + FUTEX_CMP_REQUEUE_PI = 12 + + FUTEX_PRIVATE_FLAG = 128 + FUTEX_CLOCK_REALTIME = 256 +) + +// These are flags are from and are used in FUTEX_WAKE_OP +// to define the operations. +const ( + FUTEX_OP_SET = 0 + FUTEX_OP_ADD = 1 + FUTEX_OP_OR = 2 + FUTEX_OP_ANDN = 3 + FUTEX_OP_XOR = 4 + FUTEX_OP_OPARG_SHIFT = 8 + FUTEX_OP_CMP_EQ = 0 + FUTEX_OP_CMP_NE = 1 + FUTEX_OP_CMP_LT = 2 + FUTEX_OP_CMP_LE = 3 + FUTEX_OP_CMP_GT = 4 + FUTEX_OP_CMP_GE = 5 +) + +// FUTEX_TID_MASK is the TID portion of a PI futex word. +const FUTEX_TID_MASK = 0x3fffffff diff --git a/pkg/abi/linux/inotify.go b/pkg/abi/linux/inotify.go new file mode 100644 index 000000000..072a2d146 --- /dev/null +++ b/pkg/abi/linux/inotify.go @@ -0,0 +1,97 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Inotify events observable by userspace. These directly correspond to +// filesystem operations and there may only be a single of them per inotify +// event read from an inotify fd. +const ( + // IN_ACCESS indicates a file was accessed. + IN_ACCESS = 0x00000001 + // IN_MODIFY indicates a file was modified. + IN_MODIFY = 0x00000002 + // IN_ATTRIB indicates a watch target's metadata changed. + IN_ATTRIB = 0x00000004 + // IN_CLOSE_WRITE indicates a writable file was closed. + IN_CLOSE_WRITE = 0x00000008 + // IN_CLOSE_NOWRITE indicates a non-writable file was closed. + IN_CLOSE_NOWRITE = 0x00000010 + // IN_OPEN indicates a file was opened. + IN_OPEN = 0x00000020 + // IN_MOVED_FROM indicates a file was moved from X. + IN_MOVED_FROM = 0x00000040 + // IN_MOVED_TO indicates a file was moved to Y. + IN_MOVED_TO = 0x00000080 + // IN_CREATE indicates a file was created in a watched directory. + IN_CREATE = 0x00000100 + // IN_DELETE indicates a file was deleted in a watched directory. + IN_DELETE = 0x00000200 + // IN_DELETE_SELF indicates a watch target itself was deleted. + IN_DELETE_SELF = 0x00000400 + // IN_MOVE_SELF indicates a watch target itself was moved. + IN_MOVE_SELF = 0x00000800 + // IN_ALL_EVENTS is a mask for all observable userspace events. + IN_ALL_EVENTS = 0x00000fff +) + +// Inotify control events. These may be present in their own events, or ORed +// with other observable events. +const ( + // IN_UNMOUNT indicates the backing filesystem was unmounted. + IN_UNMOUNT = 0x00002000 + // IN_Q_OVERFLOW indicates the event queued overflowed. + IN_Q_OVERFLOW = 0x00004000 + // IN_IGNORED indicates a watch was removed, either implicitly or through + // inotify_rm_watch(2). + IN_IGNORED = 0x00008000 + // IN_ISDIR indicates the subject of an event was a directory. + IN_ISDIR = 0x40000000 +) + +// Feature flags for inotify_add_watch(2). +const ( + // IN_ONLYDIR indicates that a path should be watched only if it's a + // directory. + IN_ONLYDIR = 0x01000000 + // IN_DONT_FOLLOW indicates that the watch path shouldn't be resolved if + // it's a symlink. + IN_DONT_FOLLOW = 0x02000000 + // IN_EXCL_UNLINK indicates events to this watch from unlinked objects + // should be filtered out. + IN_EXCL_UNLINK = 0x04000000 + // IN_MASK_ADD indicates the provided mask should be ORed into any existing + // watch on the provided path. + IN_MASK_ADD = 0x20000000 + // IN_ONESHOT indicates the watch should be removed after one event. + IN_ONESHOT = 0x80000000 +) + +// Feature flags for inotify_init1(2). +const ( + // IN_CLOEXEC is an alias for O_CLOEXEC. It indicates that the inotify + // fd should be closed on exec(2) and friends. + IN_CLOEXEC = 0x00080000 + // IN_NONBLOCK is an alias for O_NONBLOCK. It indicates I/O syscall on the + // inotify fd should not block. + IN_NONBLOCK = 0x00000800 +) + +// ALL_INOTIFY_BITS contains all the bits for all possible inotify events. It's +// defined in the Linux source at "include/linux/inotify.h". +const ALL_INOTIFY_BITS = IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | + IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | + IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_Q_OVERFLOW | + IN_IGNORED | IN_ONLYDIR | IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | + IN_ISDIR | IN_ONESHOT diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go new file mode 100644 index 000000000..35cefbdfc --- /dev/null +++ b/pkg/abi/linux/ioctl.go @@ -0,0 +1,57 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// ioctl(2) requests provided by asm-generic/ioctls.h +// +// These are ordered by request number (low byte). +const ( + TCGETS = 0x00005401 + TCSETS = 0x00005402 + TCSETSW = 0x00005403 + TIOCINQ = 0x0000541b + TIOCOUTQ = 0x00005411 + FIONREAD = TIOCINQ + FIONBIO = 0x00005421 + TIOCGPTN = 0x80045430 + TIOCSPTLCK = 0x40045431 + FIONCLEX = 0x00005450 + FIOCLEX = 0x00005451 +) + +// ioctl(2) requests provided by uapi/linux/android/binder.h +const ( + BinderWriteReadIoctl = 0xc0306201 + BinderSetIdleTimeoutIoctl = 0x40086203 + BinderSetMaxThreadsIoctl = 0x40046205 + BinderSetIdlePriorityIoctl = 0x40046206 + BinderSetContextMgrIoctl = 0x40046207 + BinderThreadExitIoctl = 0x40046208 + BinderVersionIoctl = 0xc0046209 +) + +// ioctl(2) requests provided by drivers/staging/android/uapi/ashmem.h +const ( + AshmemSetNameIoctl = 0x41007701 + AshmemGetNameIoctl = 0x81007702 + AshmemSetSizeIoctl = 0x40087703 + AshmemGetSizeIoctl = 0x00007704 + AshmemSetProtMaskIoctl = 0x40087705 + AshmemGetProtMaskIoctl = 0x00007706 + AshmemPinIoctl = 0x40087707 + AshmemUnpinIoctl = 0x40087708 + AshmemGetPinStatusIoctl = 0x00007709 + AshmemPurgeAllCachesIoctl = 0x0000770a +) diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go new file mode 100644 index 000000000..6b68999ab --- /dev/null +++ b/pkg/abi/linux/ip.go @@ -0,0 +1,44 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// IP protocols +const ( + IPPROTO_IP = 0 + IPPROTO_ICMP = 1 + IPPROTO_IGMP = 2 + IPPROTO_IPIP = 4 + IPPROTO_TCP = 6 + IPPROTO_EGP = 8 + IPPROTO_PUP = 12 + IPPROTO_UDP = 17 + IPPROTO_IDP = 22 + IPPROTO_TP = 29 + IPPROTO_DCCP = 33 + IPPROTO_IPV6 = 41 + IPPROTO_RSVP = 46 + IPPROTO_GRE = 47 + IPPROTO_ESP = 50 + IPPROTO_AH = 51 + IPPROTO_MTP = 92 + IPPROTO_BEETPH = 94 + IPPROTO_ENCAP = 98 + IPPROTO_PIM = 103 + IPPROTO_COMP = 108 + IPPROTO_SCTP = 132 + IPPROTO_UDPLITE = 136 + IPPROTO_MPLS = 137 + IPPROTO_RAW = 255 +) diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go new file mode 100644 index 000000000..5441492e7 --- /dev/null +++ b/pkg/abi/linux/ipc.go @@ -0,0 +1,47 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Control commands used with semctl. Source: //include/uapi/linux/ipc.h. +const ( + IPC_RMID = 0 + IPC_SET = 1 + IPC_STAT = 2 + IPC_INFO = 3 +) + +// resource get request flags. Source: //include/uapi/linux/ipc.h +const ( + IPC_CREAT = 00001000 + IPC_EXCL = 00002000 + IPC_NOWAIT = 00004000 +) + +const IPC_PRIVATE = 0 + +// IPCPerm is equivalent to struct ipc_perm. +type IPCPerm struct { + Key uint32 + UID uint32 + GID uint32 + CUID uint32 + CGID uint32 + Mode uint16 + pad1 uint16 + Seq uint16 + pad2 uint16 + reserved1 uint32 + reserved2 uint32 +} diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go new file mode 100644 index 000000000..e1f0932ec --- /dev/null +++ b/pkg/abi/linux/limits.go @@ -0,0 +1,88 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Resources for getrlimit(2)/setrlimit(2)/prlimit(2). +const ( + RLIMIT_CPU = 0 + RLIMIT_FSIZE = 1 + RLIMIT_DATA = 2 + RLIMIT_STACK = 3 + RLIMIT_CORE = 4 + RLIMIT_RSS = 5 + RLIMIT_NPROC = 6 + RLIMIT_NOFILE = 7 + RLIMIT_MEMLOCK = 8 + RLIMIT_AS = 9 + RLIMIT_LOCKS = 10 + RLIMIT_SIGPENDING = 11 + RLIMIT_MSGQUEUE = 12 + RLIMIT_NICE = 13 + RLIMIT_RTPRIO = 14 + RLIMIT_RTTIME = 15 +) + +// RLimit corresponds to Linux's struct rlimit. +type RLimit struct { + // Cur specifies the soft limit. + Cur uint64 + // Max specifies the hard limit. + Max uint64 +} + +const ( + // RLimInfinity is RLIM_INFINITY on Linux. + RLimInfinity = ^uint64(0) + + // DefaultStackSoftLimit is called _STK_LIM in Linux. + DefaultStackSoftLimit = 8 * 1024 * 1024 + + // DefaultNprocLimit is defined in kernel/fork.c:set_max_threads, and + // called MAX_THREADS / 2 in Linux. + DefaultNprocLimit = FUTEX_TID_MASK / 2 + + // DefaultNofileSoftLimit is called INR_OPEN_CUR in Linux. + DefaultNofileSoftLimit = 1024 + + // DefaultNofileHardLimit is called INR_OPEN_MAX in Linux. + DefaultNofileHardLimit = 4096 + + // DefaultMemlockLimit is called MLOCK_LIMIT in Linux. + DefaultMemlockLimit = 64 * 1094 + + // DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux. + DefaultMsgqueueLimit = 819200 +) + +// InitRLimits is a map of initial rlimits set by Linux in +// include/asm-generic/resource.h. +var InitRLimits = map[int]RLimit{ + RLIMIT_CPU: {RLimInfinity, RLimInfinity}, + RLIMIT_FSIZE: {RLimInfinity, RLimInfinity}, + RLIMIT_DATA: {RLimInfinity, RLimInfinity}, + RLIMIT_STACK: {DefaultStackSoftLimit, RLimInfinity}, + RLIMIT_CORE: {0, RLimInfinity}, + RLIMIT_RSS: {RLimInfinity, RLimInfinity}, + RLIMIT_NPROC: {DefaultNprocLimit, DefaultNprocLimit}, + RLIMIT_NOFILE: {DefaultNofileSoftLimit, DefaultNofileHardLimit}, + RLIMIT_MEMLOCK: {DefaultMemlockLimit, DefaultMemlockLimit}, + RLIMIT_AS: {RLimInfinity, RLimInfinity}, + RLIMIT_LOCKS: {RLimInfinity, RLimInfinity}, + RLIMIT_SIGPENDING: {0, 0}, + RLIMIT_MSGQUEUE: {DefaultMsgqueueLimit, DefaultMsgqueueLimit}, + RLIMIT_NICE: {0, 0}, + RLIMIT_RTPRIO: {0, 0}, + RLIMIT_RTTIME: {RLimInfinity, RLimInfinity}, +} diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go new file mode 100644 index 000000000..a946849c5 --- /dev/null +++ b/pkg/abi/linux/linux.go @@ -0,0 +1,38 @@ +// Copyright 2018 Google Inc. +// +// 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 linux contains the constants and types needed to inferface with a Linux kernel. +package linux + +// NumSoftIRQ is the number of software IRQs, exposed via /proc/stat. +// +// Defined in linux/interrupt.h. +const NumSoftIRQ = 10 + +// Sysinfo is the structure provided by sysinfo on linux versions > 2.3.48. +type Sysinfo struct { + Uptime int64 + Loads [3]uint64 + TotalRAM uint64 + FreeRAM uint64 + SharedRAM uint64 + BufferRAM uint64 + TotalSwap uint64 + FreeSwap uint64 + Procs uint16 + TotalHigh uint64 + FreeHigh uint64 + Unit uint32 + /* The _f field in the glibc version of Sysinfo has size 0 on AMD64 */ +} diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go new file mode 100644 index 000000000..2263653cc --- /dev/null +++ b/pkg/abi/linux/mm.go @@ -0,0 +1,103 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Protections for mmap(2). +const ( + PROT_NONE = 0 + PROT_READ = 1 << 0 + PROT_WRITE = 1 << 1 + PROT_EXEC = 1 << 2 + PROT_SEM = 1 << 3 + PROT_GROWSDOWN = 1 << 24 + PROT_GROWSUP = 1 << 25 +) + +// Flags for mmap(2). +const ( + MAP_SHARED = 1 << 0 + MAP_PRIVATE = 1 << 1 + MAP_FIXED = 1 << 4 + MAP_ANONYMOUS = 1 << 5 + MAP_GROWSDOWN = 1 << 8 + MAP_DENYWRITE = 1 << 11 + MAP_EXECUTABLE = 1 << 12 + MAP_LOCKED = 1 << 13 + MAP_NORESERVE = 1 << 14 + MAP_POPULATE = 1 << 15 + MAP_NONBLOCK = 1 << 16 + MAP_STACK = 1 << 17 + MAP_HUGETLB = 1 << 18 +) + +// Flags for mremap(2). +const ( + MREMAP_MAYMOVE = 1 << 0 + MREMAP_FIXED = 1 << 1 +) + +// Advice for madvise(2). +const ( + MADV_NORMAL = 0 + MADV_RANDOM = 1 + MADV_SEQUENTIAL = 2 + MADV_WILLNEED = 3 + MADV_DONTNEED = 4 + MADV_REMOVE = 9 + MADV_DONTFORK = 10 + MADV_DOFORK = 11 + MADV_MERGEABLE = 12 + MADV_UNMERGEABLE = 13 + MADV_HUGEPAGE = 14 + MADV_NOHUGEPAGE = 15 + MADV_DONTDUMP = 16 + MADV_DODUMP = 17 + MADV_HWPOISON = 100 + MADV_SOFT_OFFLINE = 101 + MADV_NOMAJFAULT = 200 + MADV_DONTCHGME = 201 +) + +// Flags for msync(2). +const ( + MS_ASYNC = 1 << 0 + MS_INVALIDATE = 1 << 1 + MS_SYNC = 1 << 2 +) + +// Policies for get_mempolicy(2)/set_mempolicy(2). +const ( + MPOL_DEFAULT = 0 + MPOL_PREFERRED = 1 + MPOL_BIND = 2 + MPOL_INTERLEAVE = 3 + MPOL_LOCAL = 4 + MPOL_MAX = 5 +) + +// Flags for get_mempolicy(2). +const ( + MPOL_F_NODE = 1 << 0 + MPOL_F_ADDR = 1 << 1 + MPOL_F_MEMS_ALLOWED = 1 << 2 +) + +// Flags for set_mempolicy(2). +const ( + MPOL_F_RELATIVE_NODES = 1 << 14 + MPOL_F_STATIC_NODES = 1 << 15 + + MPOL_MODE_FLAGS = (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES) +) diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go new file mode 100644 index 000000000..88654a1b3 --- /dev/null +++ b/pkg/abi/linux/netdevice.go @@ -0,0 +1,86 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import "gvisor.googlesource.com/gvisor/pkg/binary" + +const ( + // IFNAMSIZ is the size of the name field for IFReq. + IFNAMSIZ = 16 +) + +// IFReq is an interface request. +type IFReq struct { + // IFName is an encoded name, normally null-terminated. This should be + // accessed via the Name and SetName functions. + IFName [IFNAMSIZ]byte + + // Data is the union of the following structures: + // + // struct sockaddr ifr_addr; + // struct sockaddr ifr_dstaddr; + // struct sockaddr ifr_broadaddr; + // struct sockaddr ifr_netmask; + // struct sockaddr ifr_hwaddr; + // short ifr_flags; + // int ifr_ifindex; + // int ifr_metric; + // int ifr_mtu; + // struct ifmap ifr_map; + // char ifr_slave[IFNAMSIZ]; + // char ifr_newname[IFNAMSIZ]; + // char *ifr_data; + Data [24]byte +} + +// Name returns the name. +func (ifr *IFReq) Name() string { + for c := 0; c < len(ifr.IFName); c++ { + if ifr.IFName[c] == 0 { + return string(ifr.IFName[:c]) + } + } + return string(ifr.IFName[:]) +} + +// SetName sets the name. +func (ifr *IFReq) SetName(name string) { + n := copy(ifr.IFName[:], []byte(name)) + for i := n; i < len(ifr.IFName); i++ { + ifr.IFName[i] = 0 + } +} + +// SizeOfIFReq is the binary size of an IFReq struct (40 bytes). +var SizeOfIFReq = binary.Size(IFReq{}) + +// IFMap contains interface hardware parameters. +type IFMap struct { + MemStart uint64 + MemEnd uint64 + BaseAddr int16 + IRQ byte + DMA byte + Port byte + _ [3]byte // Pad to sizeof(struct ifmap). +} + +// IFConf is used to return a list of interfaces and their addresses. See +// netdevice(7) and struct ifconf for more detail on its use. +type IFConf struct { + Len int32 + _ [4]byte // Pad to sizeof(struct ifconf). + Ptr uint64 +} diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go new file mode 100644 index 000000000..e823ffa7e --- /dev/null +++ b/pkg/abi/linux/netlink.go @@ -0,0 +1,110 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Netlink protocols, from uapi/linux/netlink.h. +const ( + NETLINK_ROUTE = 0 + NETLINK_UNUSED = 1 + NETLINK_USERSOCK = 2 + NETLINK_FIREWALL = 3 + NETLINK_SOCK_DIAG = 4 + NETLINK_NFLOG = 5 + NETLINK_XFRM = 6 + NETLINK_SELINUX = 7 + NETLINK_ISCSI = 8 + NETLINK_AUDIT = 9 + NETLINK_FIB_LOOKUP = 10 + NETLINK_CONNECTOR = 11 + NETLINK_NETFILTER = 12 + NETLINK_IP6_FW = 13 + NETLINK_DNRTMSG = 14 + NETLINK_KOBJECT_UEVENT = 15 + NETLINK_GENERIC = 16 + NETLINK_SCSITRANSPORT = 18 + NETLINK_ECRYPTFS = 19 + NETLINK_RDMA = 20 + NETLINK_CRYPTO = 21 +) + +// SockAddrNetlink is struct sockaddr_nl, from uapi/linux/netlink.h. +type SockAddrNetlink struct { + Family uint16 + Padding uint16 + PortID uint32 + Groups uint32 +} + +// SockAddrNetlinkSize is the size of SockAddrNetlink. +const SockAddrNetlinkSize = 12 + +// NetlinkMessageHeader is struct nlmsghdr, from uapi/linux/netlink.h. +type NetlinkMessageHeader struct { + Length uint32 + Type uint16 + Flags uint16 + Seq uint32 + PortID uint32 +} + +// NetlinkMessageHeaderSize is the size of NetlinkMessageHeader. +const NetlinkMessageHeaderSize = 16 + +// Netlink message header flags, from uapi/linux/netlink.h. +const ( + NLM_F_REQUEST = 0x1 + NLM_F_MULTI = 0x2 + NLM_F_ACK = 0x4 + NLM_F_ECHO = 0x8 + NLM_F_DUMP_INTR = 0x10 + NLM_F_ROOT = 0x100 + NLM_F_MATCH = 0x200 + NLM_F_ATOMIC = 0x400 + NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH + NLM_F_REPLACE = 0x100 + NLM_F_EXCL = 0x200 + NLM_F_CREATE = 0x400 + NLM_F_APPEND = 0x800 +) + +// Standard netlink message types, from uapi/linux/netlink.h. +const ( + NLMSG_NOOP = 0x1 + NLMSG_ERROR = 0x2 + NLMSG_DONE = 0x3 + NLMSG_OVERRUN = 0x4 + + // NLMSG_MIN_TYPE is the first value for protocol-level types. + NLMSG_MIN_TYPE = 0x10 +) + +// NLMSG_ALIGNTO is the alignment of netlink messages, from +// uapi/linux/netlink.h. +const NLMSG_ALIGNTO = 4 + +// NetlinkAttrHeader is the header of a netlink attribute, followed by payload. +// +// This is struct nlattr, from uapi/linux/netlink.h. +type NetlinkAttrHeader struct { + Length uint16 + Type uint16 +} + +// NetlinkAttrHeaderSize is the size of NetlinkAttrHeader. +const NetlinkAttrHeaderSize = 4 + +// NLA_ALIGNTO is the alignment of netlink attributes, from +// uapi/linux/netlink.h. +const NLA_ALIGNTO = 4 diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go new file mode 100644 index 000000000..0d88bc5c5 --- /dev/null +++ b/pkg/abi/linux/netlink_route.go @@ -0,0 +1,186 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Netlink message types for NETLINK_ROUTE sockets, from uapi/linux/rtnetlink.h. +const ( + RTM_NEWLINK = 16 + RTM_DELLINK = 17 + RTM_GETLINK = 18 + RTM_SETLINK = 19 + + RTM_NEWADDR = 20 + RTM_DELADDR = 21 + RTM_GETADDR = 22 + + RTM_NEWROUTE = 24 + RTM_DELROUTE = 25 + RTM_GETROUTE = 26 + + RTM_NEWNEIGH = 28 + RTM_DELNEIGH = 29 + RTM_GETNEIGH = 30 + + RTM_NEWRULE = 32 + RTM_DELRULE = 33 + RTM_GETRULE = 34 + + RTM_NEWQDISC = 36 + RTM_DELQDISC = 37 + RTM_GETQDISC = 38 + + RTM_NEWTCLASS = 40 + RTM_DELTCLASS = 41 + RTM_GETTCLASS = 42 + + RTM_NEWTFILTER = 44 + RTM_DELTFILTER = 45 + RTM_GETTFILTER = 46 + + RTM_NEWACTION = 48 + RTM_DELACTION = 49 + RTM_GETACTION = 50 + + RTM_NEWPREFIX = 52 + + RTM_GETMULTICAST = 58 + + RTM_GETANYCAST = 62 + + RTM_NEWNEIGHTBL = 64 + RTM_GETNEIGHTBL = 66 + RTM_SETNEIGHTBL = 67 + + RTM_NEWNDUSEROPT = 68 + + RTM_NEWADDRLABEL = 72 + RTM_DELADDRLABEL = 73 + RTM_GETADDRLABEL = 74 + + RTM_GETDCB = 78 + RTM_SETDCB = 79 + + RTM_NEWNETCONF = 80 + RTM_GETNETCONF = 82 + + RTM_NEWMDB = 84 + RTM_DELMDB = 85 + RTM_GETMDB = 86 + + RTM_NEWNSID = 88 + RTM_DELNSID = 89 + RTM_GETNSID = 90 +) + +// InterfaceInfoMessage is struct ifinfomsg, from uapi/linux/rtnetlink.h. +type InterfaceInfoMessage struct { + Family uint8 + Padding uint8 + Type uint16 + Index int32 + Flags uint32 + Change uint32 +} + +// Interface flags, from uapi/linux/if.h. +const ( + IFF_UP = 1 << 0 + IFF_BROADCAST = 1 << 1 + IFF_DEBUG = 1 << 2 + IFF_LOOPBACK = 1 << 3 + IFF_POINTOPOINT = 1 << 4 + IFF_NOTRAILERS = 1 << 5 + IFF_RUNNING = 1 << 6 + IFF_NOARP = 1 << 7 + IFF_PROMISC = 1 << 8 + IFF_ALLMULTI = 1 << 9 + IFF_MASTER = 1 << 10 + IFF_SLAVE = 1 << 11 + IFF_MULTICAST = 1 << 12 + IFF_PORTSEL = 1 << 13 + IFF_AUTOMEDIA = 1 << 14 + IFF_DYNAMIC = 1 << 15 + IFF_LOWER_UP = 1 << 16 + IFF_DORMANT = 1 << 17 + IFF_ECHO = 1 << 18 +) + +// Interface link attributes, from uapi/linux/if_link.h. +const ( + IFLA_UNSPEC = 0 + IFLA_ADDRESS = 1 + IFLA_BROADCAST = 2 + IFLA_IFNAME = 3 + IFLA_MTU = 4 + IFLA_LINK = 5 + IFLA_QDISC = 6 + IFLA_STATS = 7 + IFLA_COST = 8 + IFLA_PRIORITY = 9 + IFLA_MASTER = 10 + IFLA_WIRELESS = 11 + IFLA_PROTINFO = 12 + IFLA_TXQLEN = 13 + IFLA_MAP = 14 + IFLA_WEIGHT = 15 + IFLA_OPERSTATE = 16 + IFLA_LINKMODE = 17 + IFLA_LINKINFO = 18 + IFLA_NET_NS_PID = 19 + IFLA_IFALIAS = 20 + IFLA_NUM_VF = 21 + IFLA_VFINFO_LIST = 22 + IFLA_STATS64 = 23 + IFLA_VF_PORTS = 24 + IFLA_PORT_SELF = 25 + IFLA_AF_SPEC = 26 + IFLA_GROUP = 27 + IFLA_NET_NS_FD = 28 + IFLA_EXT_MASK = 29 + IFLA_PROMISCUITY = 30 + IFLA_NUM_TX_QUEUES = 31 + IFLA_NUM_RX_QUEUES = 32 + IFLA_CARRIER = 33 + IFLA_PHYS_PORT_ID = 34 + IFLA_CARRIER_CHANGES = 35 + IFLA_PHYS_SWITCH_ID = 36 + IFLA_LINK_NETNSID = 37 + IFLA_PHYS_PORT_NAME = 38 + IFLA_PROTO_DOWN = 39 + IFLA_GSO_MAX_SEGS = 40 + IFLA_GSO_MAX_SIZE = 41 +) + +// InterfaceAddrMessage is struct ifaddrmsg, from uapi/linux/if_addr.h. +type InterfaceAddrMessage struct { + Family uint8 + PrefixLen uint8 + Flags uint8 + Scope uint8 + Index uint32 +} + +// Interface attributes, from uapi/linux/if_addr.h. +const ( + IFA_UNSPEC = 0 + IFA_ADDRESS = 1 + IFA_LOCAL = 2 + IFA_LABEL = 3 + IFA_BROADCAST = 4 + IFA_ANYCAST = 5 + IFA_CACHEINFO = 6 + IFA_MULTICAST = 7 + IFA_FLAGS = 8 +) diff --git a/pkg/abi/linux/poll.go b/pkg/abi/linux/poll.go new file mode 100644 index 000000000..f373cfca1 --- /dev/null +++ b/pkg/abi/linux/poll.go @@ -0,0 +1,42 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// PollFD is struct pollfd, used by poll(2)/ppoll(2), from uapi/asm-generic/poll.h. +type PollFD struct { + FD int32 + Events int16 + REvents int16 +} + +// Poll event flags, used by poll(2)/ppoll(2) and/or +// epoll_ctl(2)/epoll_wait(2), from uapi/asm-generic/poll.h. +const ( + POLLIN = 0x0001 + POLLPRI = 0x0002 + POLLOUT = 0x0004 + POLLERR = 0x0008 + POLLHUP = 0x0010 + POLLNVAL = 0x0020 + POLLRDNORM = 0x0040 + POLLRDBAND = 0x0080 + POLLWRNORM = 0x0100 + POLLWRBAND = 0x0200 + POLLMSG = 0x0400 + POLLREMOVE = 0x1000 + POLLRDHUP = 0x2000 + POLLFREE = 0x4000 + POLL_BUSY_LOOP = 0x8000 +) diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go new file mode 100644 index 000000000..6c93601de --- /dev/null +++ b/pkg/abi/linux/prctl.go @@ -0,0 +1,72 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// PR_* flags, from for prctl(2). +const ( + // PR_SET_PDEATHSIG will set the process' death signal. + PR_SET_PDEATHSIG = 1 + + // PR_GET_PDEATHSIG will get the process' death signal. + PR_GET_PDEATHSIG = 2 + + // PR_GET_KEEPCAPS will get the value of the keep capabilities flag. + PR_GET_KEEPCAPS = 7 + + // PR_SET_KEEPCAPS will set the value of the keep capabilities flag. + PR_SET_KEEPCAPS = 8 + + // PR_SET_NAME will set the process' name. + PR_SET_NAME = 15 + + // PR_GET_NAME will get the process' name. + PR_GET_NAME = 16 + + // PR_SET_MM will modify certain kernel memory map descriptor fields of the + // calling process. See prctl(2) for more information. + PR_SET_MM = 35 + + // PR_SET_MM_EXE_FILE will supersede the /proc/pid/exe symbolic link with a + // new one pointing to a new executable file identified by the file descriptor + // provided in arg3 argument. See prctl(2) for more information. + PR_SET_MM_EXE_FILE = 13 + + // PR_SET_NO_NEW_PRIVS will set the calling thread's no_new_privs bit. + PR_SET_NO_NEW_PRIVS = 38 + + // PR_GET_NO_NEW_PRIVS will get the calling thread's no_new_privs bit. + PR_GET_NO_NEW_PRIVS = 39 + + // PR_SET_SECCOMP will set a process' seccomp mode. + PR_SET_SECCOMP = 22 + + // PR_GET_SECCOMP will get a process' seccomp mode. + PR_GET_SECCOMP = 21 + + // PR_CAPBSET_READ will get the capability bounding set. + PR_CAPBSET_READ = 23 + + // PR_CAPBSET_DROP will set the capability bounding set. + PR_CAPBSET_DROP = 24 +) + +// From +// Flags are used in syscall arch_prctl(2). +const ( + ARCH_SET_GS = 0x1001 + ARCH_SET_FS = 0x1002 + ARCH_GET_FS = 0x1003 + ARCH_GET_GS = 0x1004 +) diff --git a/pkg/abi/linux/rusage.go b/pkg/abi/linux/rusage.go new file mode 100644 index 000000000..a4a89abda --- /dev/null +++ b/pkg/abi/linux/rusage.go @@ -0,0 +1,46 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Flags that may be used with wait4(2) and getrusage(2). +const ( + // wait4(2) uses this to aggregate RUSAGE_SELF and RUSAGE_CHILDREN. + RUSAGE_BOTH = -0x2 + + // getrusage(2) flags. + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + RUSAGE_THREAD = 0x1 +) + +// Rusage represents the Linux struct rusage. +type Rusage struct { + UTime Timeval + STime Timeval + MaxRSS int64 + IXRSS int64 + IDRSS int64 + ISRSS int64 + MinFlt int64 + MajFlt int64 + NSwap int64 + InBlock int64 + OuBlock int64 + MsgSnd int64 + MsgRcv int64 + NSignals int64 + NVCSw int64 + NIvCSw int64 +} diff --git a/pkg/abi/linux/sched.go b/pkg/abi/linux/sched.go new file mode 100644 index 000000000..05fda1604 --- /dev/null +++ b/pkg/abi/linux/sched.go @@ -0,0 +1,30 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Scheduling policies, exposed by sched_getscheduler(2)/sched_setscheduler(2). +const ( + SCHED_NORMAL = 0 + SCHED_FIFO = 1 + SCHED_RR = 2 + SCHED_BATCH = 3 + SCHED_IDLE = 5 + SCHED_DEADLINE = 6 + SCHED_MICROQ = 16 + + // SCHED_RESET_ON_FORK is a flag that indicates that the process is + // reverted back to SCHED_NORMAL on fork. + SCHED_RESET_ON_FORK = 0x40000000 +) diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go new file mode 100644 index 000000000..a8de9d3d0 --- /dev/null +++ b/pkg/abi/linux/seccomp.go @@ -0,0 +1,38 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Seccomp constants taken from . +const ( + SECCOMP_MODE_NONE = 0 + SECCOMP_MODE_FILTER = 2 + + SECCOMP_RET_KILL = 0x00000000 + SECCOMP_RET_TRAP = 0x00030000 + SECCOMP_RET_ERRNO = 0x00050000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_ALLOW = 0x7fff0000 + + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_DATA = 0x0000ffff + + SECCOMP_SET_MODE_FILTER = 1 + SECCOMP_FILTER_FLAG_TSYNC = 1 +) + +const ( + // AUDIT_ARCH_X86_64 is taken from . + AUDIT_ARCH_X86_64 = 0xc000003e +) diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go new file mode 100644 index 000000000..f8d8debf1 --- /dev/null +++ b/pkg/abi/linux/sem.go @@ -0,0 +1,53 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// semctl Command Definitions. Source: //include/uapi/linux/sem.h +const ( + GETPID = 11 + GETVAL = 12 + GETALL = 13 + GETNCNT = 14 + GETZCNT = 15 + SETVAL = 16 + SETALL = 17 +) + +// ipcs ctl cmds. Source: //include/uapi/linux/sem.h +const ( + SEM_STAT = 18 + SEM_INFO = 19 +) + +const SEM_UNDO = 0x1000 + +// SemidDS is equivalent to struct semid_ds. +type SemidDS struct { + SemPerm IPCPerm + SemOTime TimeT + reserved1 uint32 + SemCTime TimeT + reserved2 uint32 + SemNSems uint32 + reserved3 uint32 + reserved4 uint32 +} + +// Sembuf is equivalent to struct sembuf. +type Sembuf struct { + SemNum uint16 + SemOp int16 + SemFlg int16 +} diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go new file mode 100644 index 000000000..cd09008b5 --- /dev/null +++ b/pkg/abi/linux/signal.go @@ -0,0 +1,177 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import ( + "gvisor.googlesource.com/gvisor/pkg/bits" +) + +const ( + // SignalMaximum is the highest valid signal number. + SignalMaximum = 64 + + // FirstStdSignal is the lowest standard signal number. + FirstStdSignal = 1 + + // LastStdSignal is the highest standard signal number. + LastStdSignal = 31 + + // FirstRTSignal is the lowest real-time signal number. + // + // 32 (SIGCANCEL) and 33 (SIGSETXID) are used internally by glibc. + FirstRTSignal = 32 + + // LastRTSignal is the highest real-time signal number. + LastRTSignal = 64 + + // NumStdSignals is the number of standard signals. + NumStdSignals = LastStdSignal - FirstStdSignal + 1 + + // NumRTSignals is the number of realtime signals. + NumRTSignals = LastRTSignal - FirstRTSignal + 1 +) + +// Signal is a signal number. +type Signal int + +// IsValid returns true if s is a valid standard or realtime signal. (0 is not +// considered valid; interfaces special-casing signal number 0 should check for +// 0 first before asserting validity.) +func (s Signal) IsValid() bool { + return s > 0 && s <= SignalMaximum +} + +// IsStandard returns true if s is a standard signal. +// +// Preconditions: s.IsValid(). +func (s Signal) IsStandard() bool { + return s <= LastStdSignal +} + +// IsRealtime returns true if s is a realtime signal. +// +// Preconditions: s.IsValid(). +func (s Signal) IsRealtime() bool { + return s >= FirstRTSignal +} + +// Index returns the index for signal s into arrays of both standard and +// realtime signals (e.g. signal masks). +// +// Preconditions: s.IsValid(). +func (s Signal) Index() int { + return int(s - 1) +} + +// Signals. +const ( + SIGABRT = Signal(6) + SIGALRM = Signal(14) + SIGBUS = Signal(7) + SIGCHLD = Signal(17) + SIGCLD = Signal(17) + SIGCONT = Signal(18) + SIGFPE = Signal(8) + SIGHUP = Signal(1) + SIGILL = Signal(4) + SIGINT = Signal(2) + SIGIO = Signal(29) + SIGIOT = Signal(6) + SIGKILL = Signal(9) + SIGPIPE = Signal(13) + SIGPOLL = Signal(29) + SIGPROF = Signal(27) + SIGPWR = Signal(30) + SIGQUIT = Signal(3) + SIGSEGV = Signal(11) + SIGSTKFLT = Signal(16) + SIGSTOP = Signal(19) + SIGSYS = Signal(31) + SIGTERM = Signal(15) + SIGTRAP = Signal(5) + SIGTSTP = Signal(20) + SIGTTIN = Signal(21) + SIGTTOU = Signal(22) + SIGUNUSED = Signal(31) + SIGURG = Signal(23) + SIGUSR1 = Signal(10) + SIGUSR2 = Signal(12) + SIGVTALRM = Signal(26) + SIGWINCH = Signal(28) + SIGXCPU = Signal(24) + SIGXFSZ = Signal(25) +) + +// SignalSet is a signal mask with a bit corresponding to each signal. +type SignalSet uint64 + +// SignalSetSize is the size in bytes of a SignalSet. +const SignalSetSize = 8 + +// MakeSignalSet returns SignalSet with the bit corresponding to each of the +// given signals set. +func MakeSignalSet(sigs ...Signal) SignalSet { + indices := make([]int, len(sigs)) + for i, sig := range sigs { + indices[i] = sig.Index() + } + return SignalSet(bits.Mask64(indices...)) +} + +// SignalSetOf returns a SignalSet with a single signal set. +func SignalSetOf(sig Signal) SignalSet { + return SignalSet(bits.MaskOf64(sig.Index())) +} + +// ForEachSignal invokes f for each signal set in the given mask. +func ForEachSignal(mask SignalSet, f func(sig Signal)) { + bits.ForEachSetBit64(uint64(mask), func(i int) { + f(Signal(i + 1)) + }) +} + +// 'how' values for rt_sigprocmask(2). +const ( + // SIG_BLOCK blocks the signals in the set. + SIG_BLOCK = 0 + + // SIG_UNBLOCK blocks the signals in the set. + SIG_UNBLOCK = 1 + + // SIG_SETMASK sets the signal mask to set. + SIG_SETMASK = 2 +) + +// Signal actions for rt_sigaction(2), from uapi/asm-generic/signal-defs.h. +const ( + // SIG_DFL performs the default action. + SIG_DFL = 0 + + // SIG_IGN ignores the signal. + SIG_IGN = 1 +) + +// Signal action flags for rt_sigaction(2), from uapi/asm-generic/signal.h +const ( + SA_NOCLDSTOP = 0x00000001 + SA_NOCLDWAIT = 0x00000002 + SA_SIGINFO = 0x00000004 + SA_ONSTACK = 0x08000000 + SA_RESTART = 0x10000000 + SA_NODEFER = 0x40000000 + SA_RESTARTHAND = 0x80000000 + SA_NOMASK = SA_NODEFER + SA_ONESHOT = SA_RESTARTHAND +) diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go new file mode 100644 index 000000000..9a78cc131 --- /dev/null +++ b/pkg/abi/linux/socket.go @@ -0,0 +1,290 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import "gvisor.googlesource.com/gvisor/pkg/binary" + +// Address families, from linux/socket.h. +const ( + AF_UNSPEC = 0 + AF_UNIX = 1 + AF_INET = 2 + AF_AX25 = 3 + AF_IPX = 4 + AF_APPLETALK = 5 + AF_NETROM = 6 + AF_BRIDGE = 7 + AF_ATMPVC = 8 + AF_X25 = 9 + AF_INET6 = 10 + AF_ROSE = 11 + AF_DECnet = 12 + AF_NETBEUI = 13 + AF_SECURITY = 14 + AF_KEY = 15 + AF_NETLINK = 16 + AF_PACKET = 17 + AF_ASH = 18 + AF_ECONET = 19 + AF_ATMSVC = 20 + AF_RDS = 21 + AF_SNA = 22 + AF_IRDA = 23 + AF_PPPOX = 24 + AF_WANPIPE = 25 + AF_LLC = 26 + AF_IB = 27 + AF_MPLS = 28 + AF_CAN = 29 + AF_TIPC = 30 + AF_BLUETOOTH = 31 + AF_IUCV = 32 + AF_RXRPC = 33 + AF_ISDN = 34 + AF_PHONET = 35 + AF_IEEE802154 = 36 + AF_CAIF = 37 + AF_ALG = 38 + AF_NFC = 39 + AF_VSOCK = 40 +) + +// sendmsg(2)/recvmsg(2) flags, from linux/socket.h. +const ( + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_DONTROUTE = 0x4 + MSG_TRYHARD = 0x4 + MSG_CTRUNC = 0x8 + MSG_PROBE = 0x10 + MSG_TRUNC = 0x20 + MSG_DONTWAIT = 0x40 + MSG_EOR = 0x80 + MSG_WAITALL = 0x100 + MSG_FIN = 0x200 + MSG_EOF = MSG_FIN + MSG_SYN = 0x400 + MSG_CONFIRM = 0x800 + MSG_RST = 0x1000 + MSG_ERRQUEUE = 0x2000 + MSG_NOSIGNAL = 0x4000 + MSG_MORE = 0x8000 + MSG_WAITFORONE = 0x10000 + MSG_SENDPAGE_NOTLAST = 0x20000 + MSG_REINJECT = 0x8000000 + MSG_ZEROCOPY = 0x4000000 + MSG_FASTOPEN = 0x20000000 + MSG_CMSG_CLOEXEC = 0x40000000 +) + +// SOL_SOCKET is from socket.h +const SOL_SOCKET = 1 + +// Socket types, from linux/net.h. +const ( + SOCK_STREAM = 1 + SOCK_DGRAM = 2 + SOCK_RAW = 3 + SOCK_RDM = 4 + SOCK_SEQPACKET = 5 + SOCK_DCCP = 6 + SOCK_PACKET = 10 +) + +// SOCK_TYPE_MASK covers all of the above socket types. The remaining bits are +// flags. From linux/net.h. +const SOCK_TYPE_MASK = 0xf + +// socket(2)/socketpair(2)/accept4(2) flags, from linux/net.h. +const ( + SOCK_CLOEXEC = O_CLOEXEC + SOCK_NONBLOCK = O_NONBLOCK +) + +// shutdown(2) how commands, from . +const ( + SHUT_RD = 0 + SHUT_WR = 1 + SHUT_RDWR = 2 +) + +// Socket options from socket.h. +const ( + SO_ERROR = 4 + SO_KEEPALIVE = 9 + SO_LINGER = 13 + SO_MARK = 36 + SO_PASSCRED = 16 + SO_PEERCRED = 17 + SO_PEERNAME = 28 + SO_PROTOCOL = 38 + SO_RCVBUF = 8 + SO_RCVTIMEO = 20 + SO_REUSEADDR = 2 + SO_SNDBUF = 7 + SO_SNDTIMEO = 21 + SO_TIMESTAMP = 29 + SO_TIMESTAMPNS = 35 + SO_TYPE = 3 +) + +// SockAddrInt is struct sockaddr_in, from uapi/linux/in.h. +type SockAddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte + Zero [8]uint8 // pad to sizeof(struct sockaddr). +} + +// SockAddrInt6 is struct sockaddr_in6, from uapi/linux/in6.h. +type SockAddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte + Scope_id uint32 +} + +// UnixPathMax is the maximum length of the path in an AF_UNIX socket. +// +// From uapi/linux/un.h. +const UnixPathMax = 108 + +// SockAddrUnix is struct sockaddr_un, from uapi/linux/un.h. +type SockAddrUnix struct { + Family uint16 + Path [UnixPathMax]int8 +} + +// TCPInfo is a collection of TCP statistics. +// +// From uapi/linux/tcp.h. +type TCPInfo struct { + State uint8 + CaState uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + // WindowScale is the combination of snd_wscale (first 4 bits) and rcv_wscale (second 4 bits) + WindowScale uint8 + // DeliveryRateAppLimited is a boolean and only the first bit is meaningful. + DeliveryRateAppLimited uint8 + + RTO uint32 + ATO uint32 + SndMss uint32 + RcvMss uint32 + + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + + // Times. + LastDataSent uint32 + LastAckSent uint32 + LastDataRecv uint32 + LastAckRecv uint32 + + // Metrics. + PMTU uint32 + RcvSsthresh uint32 + RTT uint32 + RTTVar uint32 + SndSsthresh uint32 + SndCwnd uint32 + Advmss uint32 + Reordering uint32 + + RcvRTT uint32 + RcvSpace uint32 + + TotalRetrans uint32 + + PacingRate uint64 + MaxPacingRate uint64 + // BytesAcked is RFC4898 tcpEStatsAppHCThruOctetsAcked. + BytesAcked uint64 + // BytesReceived is RFC4898 tcpEStatsAppHCThruOctetsReceived. + BytesReceived uint64 + // SegsOut is RFC4898 tcpEStatsPerfSegsOut. + SegsOut uint32 + // SegsIn is RFC4898 tcpEStatsPerfSegsIn. + SegsIn uint32 + + NotSentBytes uint32 + MinRTT uint32 + // DataSegsIn is RFC4898 tcpEStatsDataSegsIn. + DataSegsIn uint32 + // DataSegsOut is RFC4898 tcpEStatsDataSegsOut. + DataSegsOut uint32 + + DeliveryRate uint64 + + // BusyTime is the time in microseconds busy sending data. + BusyTime uint64 + // RwndLimited is the time in microseconds limited by receive window. + RwndLimited uint64 + // SndBufLimited is the time in microseconds limited by send buffer. + SndBufLimited uint64 +} + +// SizeOfTCPInfo is the binary size of a TCPInfo struct (104 bytes). +var SizeOfTCPInfo = binary.Size(TCPInfo{}) + +// Control message types, from linux/socket.h. +const ( + SCM_CREDENTIALS = 0x2 + SCM_RIGHTS = 0x1 +) + +// A ControlMessageHeader is the header for a socket control message. +// +// ControlMessageHeader represents struct cmsghdr from linux/socket.h. +type ControlMessageHeader struct { + Length uint64 + Level int32 + Type int32 +} + +// SizeOfControlMessageHeader is the binary size of a ControlMessageHeader +// struct. +var SizeOfControlMessageHeader = int(binary.Size(ControlMessageHeader{})) + +// A ControlMessageCredentials is an SCM_CREDENTIALS socket control message. +// +// ControlMessageCredentials represents struct ucred from linux/socket.h. +type ControlMessageCredentials struct { + PID int32 + UID uint32 + GID uint32 +} + +// SizeOfControlMessageCredentials is the binary size of a +// ControlMessageCredentials struct. +var SizeOfControlMessageCredentials = int(binary.Size(ControlMessageCredentials{})) + +// A ControlMessageRights is an SCM_RIGHTS socket control message. +type ControlMessageRights []int32 + +// SizeOfControlMessageRight is the size of a single element in +// ControlMessageRights. +const SizeOfControlMessageRight = 4 + +// SCM_MAX_FD is the maximum number of FDs accepted in a single sendmsg call. +// From net/scm.h. +const SCM_MAX_FD = 253 diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go new file mode 100644 index 000000000..9109a2848 --- /dev/null +++ b/pkg/abi/linux/time.go @@ -0,0 +1,224 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import ( + "math" + "time" +) + +const ( + // ClockTick is the length of time represented by a single clock tick, as + // used by times(2) and /proc/[pid]/stat. + ClockTick = time.Second / CLOCKS_PER_SEC + + // CLOCKS_PER_SEC is the number of ClockTicks per second. + // + // Linux defines this to be 100 on most architectures, irrespective of + // CONFIG_HZ. Userspace obtains the value through sysconf(_SC_CLK_TCK), + // which uses the AT_CLKTCK entry in the auxiliary vector if one is + // provided, and assumes 100 otherwise (glibc: + // sysdeps/posix/sysconf.c:__sysconf() => + // sysdeps/unix/sysv/linux/getclktck.c, elf/dl-support.c:_dl_aux_init()). + // + // Not to be confused with POSIX CLOCKS_PER_SEC, as used by clock(3); "XSI + // requires that [POSIX] CLOCKS_PER_SEC equals 1000000 independent of the + // actual resolution" - clock(3). + CLOCKS_PER_SEC = 100 +) + +// CPU clock types for use with clock_gettime(2) et al. +// +// The 29 most significant bits of a 32 bit clock ID are either a PID or a FD. +// +// Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3. +// +// Bit 2 indicates whether a cpu clock refers to a thread or a process. +const ( + CPUCLOCK_PROF = 0 + CPUCLOCK_VIRT = 1 + CPUCLOCK_SCHED = 2 + CPUCLOCK_MAX = 3 + CLOCKFD = CPUCLOCK_MAX + + CPUCLOCK_CLOCK_MASK = 3 + CPUCLOCK_PERTHREAD_MASK = 4 +) + +// Clock identifiers for use with clock_gettime(2), clock_getres(2), +// clock_nanosleep(2). +const ( + CLOCK_REALTIME = 0 + CLOCK_MONOTONIC = 1 + CLOCK_PROCESS_CPUTIME_ID = 2 + CLOCK_THREAD_CPUTIME_ID = 3 + CLOCK_MONOTONIC_RAW = 4 + CLOCK_REALTIME_COARSE = 5 + CLOCK_MONOTONIC_COARSE = 6 + CLOCK_BOOTTIME = 7 + CLOCK_REALTIME_ALARM = 8 + CLOCK_BOOTTIME_ALARM = 9 +) + +// Flags for clock_nanosleep(2). +const ( + TIMER_ABSTIME = 1 +) + +// Flags for timerfd syscalls (timerfd_create(2), timerfd_settime(2)). +const ( + // TFD_CLOEXEC is a timerfd_create flag. + TFD_CLOEXEC = O_CLOEXEC + + // TFD_NONBLOCK is a timerfd_create flag. + TFD_NONBLOCK = O_NONBLOCK + + // TFD_TIMER_ABSTIME is a timerfd_settime flag. + TFD_TIMER_ABSTIME = 1 +) + +// The safe number of seconds you can represent by int64. +const maxSecInDuration = math.MaxInt64 / int64(time.Second) + +// TimeT represents time_t in . It represents time in seconds. +type TimeT int64 + +// NsecToTimeT translates nanoseconds to TimeT (seconds). +func NsecToTimeT(nsec int64) TimeT { + return TimeT(nsec / 1e9) +} + +// Timespec represents struct timespec in . +type Timespec struct { + Sec int64 + Nsec int64 +} + +// Unix returns the second and nanosecond. +func (ts Timespec) Unix() (sec int64, nsec int64) { + return int64(ts.Sec), int64(ts.Nsec) +} + +// ToTime returns the Go time.Time representation. +func (ts Timespec) ToTime() time.Time { + return time.Unix(ts.Sec, ts.Nsec) +} + +// ToNsec returns the nanosecond representation. +func (ts Timespec) ToNsec() int64 { + return int64(ts.Sec)*1e9 + int64(ts.Nsec) +} + +// ToNsecCapped returns the safe nanosecond representation. +func (ts Timespec) ToNsecCapped() int64 { + if ts.Sec > maxSecInDuration { + return math.MaxInt64 + } + return ts.ToNsec() +} + +// ToDuration returns the safe nanosecond representation as time.Duration. +func (ts Timespec) ToDuration() time.Duration { + return time.Duration(ts.ToNsecCapped()) +} + +// Valid returns whether the timespec contains valid values. +func (ts Timespec) Valid() bool { + return !(ts.Sec < 0 || ts.Nsec < 0 || ts.Nsec >= int64(time.Second)) +} + +// NsecToTimespec translates nanoseconds to Timespec. +func NsecToTimespec(nsec int64) (ts Timespec) { + ts.Sec = nsec / 1e9 + ts.Nsec = nsec % 1e9 + return +} + +// DurationToTimespec translates time.Duration to Timespec. +func DurationToTimespec(dur time.Duration) Timespec { + return NsecToTimespec(dur.Nanoseconds()) +} + +// SizeOfTimeval is the size of a Timeval struct in bytes. +const SizeOfTimeval = 16 + +// Timeval represents struct timeval in . +type Timeval struct { + Sec int64 + Usec int64 +} + +// ToNsecCapped returns the safe nanosecond representation. +func (tv Timeval) ToNsecCapped() int64 { + if tv.Sec > maxSecInDuration { + return math.MaxInt64 + } + return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 +} + +// ToDuration returns the safe nanosecond representation as a time.Duration. +func (tv Timeval) ToDuration() time.Duration { + return time.Duration(tv.ToNsecCapped()) +} + +// ToTime returns the Go time.Time representation. +func (tv Timeval) ToTime() time.Time { + return time.Unix(tv.Sec, tv.Usec*1e3) +} + +// NsecToTimeval translates nanosecond to Timeval. +func NsecToTimeval(nsec int64) (tv Timeval) { + nsec += 999 // round up to microsecond + tv.Sec = nsec / 1e9 + tv.Usec = nsec % 1e9 / 1e3 + return +} + +// DurationToTimeval translates time.Duration to Timeval. +func DurationToTimeval(dur time.Duration) Timeval { + return NsecToTimeval(dur.Nanoseconds()) +} + +// Itimerspec represents struct itimerspec in . +type Itimerspec struct { + Interval Timespec + Value Timespec +} + +// ItimerVal mimics the following struct in +// struct itimerval { +// struct timeval it_interval; /* next value */ +// struct timeval it_value; /* current value */ +// }; +type ItimerVal struct { + Interval Timeval + Value Timeval +} + +// ClockT represents type clock_t. +type ClockT int64 + +// ClockTFromDuration converts time.Duration to clock_t. +func ClockTFromDuration(d time.Duration) ClockT { + return ClockT(d / ClockTick) +} + +// Tms represents struct tms, used by times(2). +type Tms struct { + UTime ClockT + STime ClockT + CUTime ClockT + CSTime ClockT +} diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go new file mode 100644 index 000000000..f9e641af9 --- /dev/null +++ b/pkg/abi/linux/tty.go @@ -0,0 +1,292 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +const ( + // NumControlCharacters is the number of control characters in Termios. + NumControlCharacters = 19 +) + +// Termios is struct termios, defined in uapi/asm-generic/termbits.h. +type Termios struct { + InputFlags uint32 + OutputFlags uint32 + ControlFlags uint32 + LocalFlags uint32 + LineDiscipline uint8 + ControlCharacters [NumControlCharacters]uint8 +} + +// KernelTermios is struct ktermios/struct termios2, defined in +// uapi/asm-generic/termbits.h. +type KernelTermios struct { + InputFlags uint32 + OutputFlags uint32 + ControlFlags uint32 + LocalFlags uint32 + LineDiscipline uint8 + ControlCharacters [NumControlCharacters]uint8 + InputSpeed uint32 + OutputSpeed uint32 +} + +// IEnabled returns whether flag is enabled in termios input flags. +func (t *KernelTermios) IEnabled(flag uint32) bool { + return t.InputFlags&flag == flag +} + +// OEnabled returns whether flag is enabled in termios output flags. +func (t *KernelTermios) OEnabled(flag uint32) bool { + return t.OutputFlags&flag == flag +} + +// CEnabled returns whether flag is enabled in termios control flags. +func (t *KernelTermios) CEnabled(flag uint32) bool { + return t.ControlFlags&flag == flag +} + +// LEnabled returns whether flag is enabled in termios local flags. +func (t *KernelTermios) LEnabled(flag uint32) bool { + return t.LocalFlags&flag == flag +} + +// ToTermios copies fields that are shared with Termios into a new Termios +// struct. +func (t *KernelTermios) ToTermios() Termios { + return Termios{ + InputFlags: t.InputFlags, + OutputFlags: t.OutputFlags, + ControlFlags: t.ControlFlags, + LocalFlags: t.LocalFlags, + LineDiscipline: t.LineDiscipline, + ControlCharacters: t.ControlCharacters, + } +} + +// FromTermios copies fields that are shared with Termios into this +// KernelTermios struct. +func (t *KernelTermios) FromTermios(term Termios) { + t.InputFlags = term.InputFlags + t.OutputFlags = term.OutputFlags + t.ControlFlags = term.ControlFlags + t.LocalFlags = term.LocalFlags + t.LineDiscipline = term.LineDiscipline + t.ControlCharacters = term.ControlCharacters +} + +// Input flags. +const ( + IGNBRK = 0000001 + BRKINT = 0000002 + IGNPAR = 0000004 + PARMRK = 0000010 + INPCK = 0000020 + ISTRIP = 0000040 + INLCR = 0000100 + IGNCR = 0000200 + ICRNL = 0000400 + IUCLC = 0001000 + IXON = 0002000 + IXANY = 0004000 + IXOFF = 0010000 + IMAXBEL = 0020000 + IUTF8 = 0040000 +) + +// Output flags. +const ( + OPOST = 0000001 + OLCUC = 0000002 + ONLCR = 0000004 + OCRNL = 0000010 + ONOCR = 0000020 + ONLRET = 0000040 + OFILL = 0000100 + OFDEL = 0000200 + NLDLY = 0000400 + NL0 = 0000000 + NL1 = 0000400 + CRDLY = 0003000 + CR0 = 0000000 + CR1 = 0001000 + CR2 = 0002000 + CR3 = 0003000 + TABDLY = 0014000 + TAB0 = 0000000 + TAB1 = 0004000 + TAB2 = 0010000 + TAB3 = 0014000 + XTABS = 0014000 + BSDLY = 0020000 + BS0 = 0000000 + BS1 = 0020000 + VTDLY = 0040000 + VT0 = 0000000 + VT1 = 0040000 + FFDLY = 0100000 + FF0 = 0000000 + FF1 = 0100000 +) + +// Control flags. +const ( + CBAUD = 0010017 + B0 = 0000000 + B50 = 0000001 + B75 = 0000002 + B110 = 0000003 + B134 = 0000004 + B150 = 0000005 + B200 = 0000006 + B300 = 0000007 + B600 = 0000010 + B1200 = 0000011 + B1800 = 0000012 + B2400 = 0000013 + B4800 = 0000014 + B9600 = 0000015 + B19200 = 0000016 + B38400 = 0000017 + EXTA = B19200 + EXTB = B38400 + CSIZE = 0000060 + CS5 = 0000000 + CS6 = 0000020 + CS7 = 0000040 + CS8 = 0000060 + CSTOPB = 0000100 + CREAD = 0000200 + PARENB = 0000400 + PARODD = 0001000 + HUPCL = 0002000 + CLOCAL = 0004000 + CBAUDEX = 0010000 + BOTHER = 0010000 + B57600 = 0010001 + B115200 = 0010002 + B230400 = 0010003 + B460800 = 0010004 + B500000 = 0010005 + B576000 = 0010006 + B921600 = 0010007 + B1000000 = 0010010 + B1152000 = 0010011 + B1500000 = 0010012 + B2000000 = 0010013 + B2500000 = 0010014 + B3000000 = 0010015 + B3500000 = 0010016 + B4000000 = 0010017 + CIBAUD = 002003600000 + CMSPAR = 010000000000 + CRTSCTS = 020000000000 + + // IBSHIFT is the shift from CBAUD to CIBAUD. + IBSHIFT = 16 +) + +// Local flags. +const ( + ISIG = 0000001 + ICANON = 0000002 + XCASE = 0000004 + ECHO = 0000010 + ECHOE = 0000020 + ECHOK = 0000040 + ECHONL = 0000100 + NOFLSH = 0000200 + TOSTOP = 0000400 + ECHOCTL = 0001000 + ECHOPRT = 0002000 + ECHOKE = 0004000 + FLUSHO = 0010000 + PENDIN = 0040000 + IEXTEN = 0100000 + EXTPROC = 0200000 +) + +// Control Character indices. +const ( + VINTR = 0 + VQUIT = 1 + VERASE = 2 + VKILL = 3 + VEOF = 4 + VTIME = 5 + VMIN = 6 + VSWTC = 7 + VSTART = 8 + VSTOP = 9 + VSUSP = 10 + VEOL = 11 + VREPRINT = 12 + VDISCARD = 13 + VWERASE = 14 + VLNEXT = 15 + VEOL2 = 16 +) + +// ControlCharacter returns the termios-style control character for the passed +// character. +// +// e.g., for Ctrl-C, i.e., ^C, call ControlCharacter('C'). +// +// Standard control characters are ASCII bytes 0 through 31. +func ControlCharacter(c byte) uint8 { + // A is 1, B is 2, etc. + return uint8(c - 'A' + 1) +} + +// DefaultControlCharacters is the default set of Termios control characters. +var DefaultControlCharacters = [NumControlCharacters]uint8{ + ControlCharacter('C'), // VINTR = ^C + ControlCharacter('\\'), // VQUIT = ^\ + '\x7f', // VERASE = DEL + ControlCharacter('U'), // VKILL = ^U + ControlCharacter('D'), // VEOF = ^D + 0, // VTIME + 1, // VMIN + 0, // VSWTC + ControlCharacter('Q'), // VSTART = ^Q + ControlCharacter('S'), // VSTOP = ^S + ControlCharacter('Z'), // VSUSP = ^Z + 0, // VEOL + ControlCharacter('R'), // VREPRINT = ^R + ControlCharacter('O'), // VDISCARD = ^O + ControlCharacter('W'), // VWERASE = ^W + ControlCharacter('V'), // VLNEXT = ^V + 0, // VEOL2 +} + +// MasterTermios is the terminal configuration of the master end of a Unix98 +// pseudoterminal. +var MasterTermios = KernelTermios{ + ControlFlags: B38400 | CS8 | CREAD, + ControlCharacters: DefaultControlCharacters, + InputSpeed: 38400, + OutputSpeed: 38400, +} + +// DefaultSlaveTermios is the default terminal configuration of the slave end +// of a Unix98 pseudoterminal. +var DefaultSlaveTermios = KernelTermios{ + InputFlags: ICRNL | IXON, + OutputFlags: OPOST | ONLCR, + ControlFlags: B38400 | CS8 | CREAD, + LocalFlags: ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN, + ControlCharacters: DefaultControlCharacters, + InputSpeed: 38400, + OutputSpeed: 38400, +} diff --git a/pkg/abi/linux/uio.go b/pkg/abi/linux/uio.go new file mode 100644 index 000000000..93c972774 --- /dev/null +++ b/pkg/abi/linux/uio.go @@ -0,0 +1,18 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// UIO_MAXIOV is the maximum number of struct iovecs in a struct iovec array. +const UIO_MAXIOV = 1024 diff --git a/pkg/abi/linux/utsname.go b/pkg/abi/linux/utsname.go new file mode 100644 index 000000000..7d33d20de --- /dev/null +++ b/pkg/abi/linux/utsname.go @@ -0,0 +1,49 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import ( + "bytes" + "fmt" +) + +const ( + // UTSLen is the maximum length of strings contained in fields of + // UtsName. + UTSLen = 64 +) + +// UtsName represents struct utsname, the struct returned by uname(2). +type UtsName struct { + Sysname [UTSLen + 1]byte + Nodename [UTSLen + 1]byte + Release [UTSLen + 1]byte + Version [UTSLen + 1]byte + Machine [UTSLen + 1]byte + Domainname [UTSLen + 1]byte +} + +// utsNameString converts a UtsName entry to a string without NULs. +func utsNameString(s [UTSLen + 1]byte) string { + // The NUL bytes will remain even in a cast to string. We must + // explicitly strip them. + return string(bytes.TrimRight(s[:], "\x00")) +} + +func (u UtsName) String() string { + return fmt.Sprintf("{Sysname: %s, Nodename: %s, Release: %s, Version: %s, Machine: %s, Domainname: %s}", + utsNameString(u.Sysname), utsNameString(u.Nodename), utsNameString(u.Release), + utsNameString(u.Version), utsNameString(u.Machine), utsNameString(u.Domainname)) +} -- cgit v1.2.3 From c90fefc1161c58af34856aff7b7012f19f5d1f1b Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Fri, 4 May 2018 09:38:35 -0700 Subject: Fix runsc capabilities There was a typo and one new capability missing from the list PiperOrigin-RevId: 195427713 Change-Id: I6d9e1c6e77b48fe85ef10d9f54c70c8a7271f6e7 --- pkg/abi/linux/capability.go | 5 +++-- runsc/boot/capability.go | 3 ++- runsc/specutils/specutils.go | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go index 1a1bd0ce3..b470ce0a5 100644 --- a/pkg/abi/linux/capability.go +++ b/pkg/abi/linux/capability.go @@ -32,7 +32,7 @@ const ( CAP_SETPCAP = Capability(8) CAP_LINUX_IMMUTABLE = Capability(9) CAP_NET_BIND_SERVICE = Capability(10) - CAP_NET_BROAD_CAST = Capability(11) + CAP_NET_BROADCAST = Capability(11) CAP_NET_ADMIN = Capability(12) CAP_NET_RAW = Capability(13) CAP_IPC_LOCK = Capability(14) @@ -58,9 +58,10 @@ const ( CAP_SYSLOG = Capability(34) CAP_WAKE_ALARM = Capability(35) CAP_BLOCK_SUSPEND = Capability(36) + CAP_AUDIT_READ = Capability(37) // MaxCapability is the highest-numbered capability. - MaxCapability = Capability(36) // CAP_BLOCK_SUSPEND as of 3.11 + MaxCapability = CAP_AUDIT_READ ) // Ok returns true if cp is a supported capability. diff --git a/runsc/boot/capability.go b/runsc/boot/capability.go index 4c6a59245..efa28fb97 100644 --- a/runsc/boot/capability.go +++ b/runsc/boot/capability.go @@ -91,7 +91,7 @@ var capFromName = map[string]capability.Cap{ "CAP_SETPCAP": capability.CAP_SETPCAP, "CAP_LINUX_IMMUTABLE": capability.CAP_LINUX_IMMUTABLE, "CAP_NET_BIND_SERVICE": capability.CAP_NET_BIND_SERVICE, - "CAP_NET_BROAD_CAST": capability.CAP_NET_BROADCAST, + "CAP_NET_BROADCAST": capability.CAP_NET_BROADCAST, "CAP_NET_ADMIN": capability.CAP_NET_ADMIN, "CAP_NET_RAW": capability.CAP_NET_RAW, "CAP_IPC_LOCK": capability.CAP_IPC_LOCK, @@ -117,4 +117,5 @@ var capFromName = map[string]capability.Cap{ "CAP_SYSLOG": capability.CAP_SYSLOG, "CAP_WAKE_ALARM": capability.CAP_WAKE_ALARM, "CAP_BLOCK_SUSPEND": capability.CAP_BLOCK_SUSPEND, + "CAP_AUDIT_READ": capability.CAP_AUDIT_READ, } diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index 04ecb6ae3..dcb4b20db 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -129,7 +129,7 @@ var capFromName = map[string]linux.Capability{ "CAP_SETPCAP": linux.CAP_SETPCAP, "CAP_LINUX_IMMUTABLE": linux.CAP_LINUX_IMMUTABLE, "CAP_NET_BIND_SERVICE": linux.CAP_NET_BIND_SERVICE, - "CAP_NET_BROAD_CAST": linux.CAP_NET_BROAD_CAST, + "CAP_NET_BROADCAST": linux.CAP_NET_BROADCAST, "CAP_NET_ADMIN": linux.CAP_NET_ADMIN, "CAP_NET_RAW": linux.CAP_NET_RAW, "CAP_IPC_LOCK": linux.CAP_IPC_LOCK, @@ -155,6 +155,7 @@ var capFromName = map[string]linux.Capability{ "CAP_SYSLOG": linux.CAP_SYSLOG, "CAP_WAKE_ALARM": linux.CAP_WAKE_ALARM, "CAP_BLOCK_SUSPEND": linux.CAP_BLOCK_SUSPEND, + "CAP_AUDIT_READ": linux.CAP_AUDIT_READ, } func capsFromNames(names []string) (auth.CapabilitySet, error) { -- cgit v1.2.3 From 3ac3ea1d6afea0b128112e6a46b8bf47b4b0e02a Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Tue, 8 May 2018 11:25:40 -0700 Subject: Correct definition of SysV IPC structures. PiperOrigin-RevId: 195849066 Change-Id: If2146c7ce649522f86e661c5e52a9983345d6967 --- pkg/abi/linux/ipc.go | 34 ++++++++++++++++++++-------------- pkg/abi/linux/sem.go | 20 +++++++++----------- 2 files changed, 29 insertions(+), 25 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go index 5441492e7..81e9904dd 100644 --- a/pkg/abi/linux/ipc.go +++ b/pkg/abi/linux/ipc.go @@ -14,7 +14,8 @@ package linux -// Control commands used with semctl. Source: //include/uapi/linux/ipc.h. +// Control commands used with semctl, shmctl, and msgctl. Source: +// include/uapi/linux/ipc.h. const ( IPC_RMID = 0 IPC_SET = 1 @@ -22,7 +23,7 @@ const ( IPC_INFO = 3 ) -// resource get request flags. Source: //include/uapi/linux/ipc.h +// resource get request flags. Source: include/uapi/linux/ipc.h const ( IPC_CREAT = 00001000 IPC_EXCL = 00002000 @@ -31,17 +32,22 @@ const ( const IPC_PRIVATE = 0 -// IPCPerm is equivalent to struct ipc_perm. +// In Linux, amd64 does not enable CONFIG_ARCH_WANT_IPC_PARSE_VERSION, so SysV +// IPC unconditionally uses the "new" 64-bit structures that are needed for +// features like 32-bit UIDs. + +// IPCPerm is equivalent to struct ipc64_perm. type IPCPerm struct { - Key uint32 - UID uint32 - GID uint32 - CUID uint32 - CGID uint32 - Mode uint16 - pad1 uint16 - Seq uint16 - pad2 uint16 - reserved1 uint32 - reserved2 uint32 + Key uint32 + UID uint32 + GID uint32 + CUID uint32 + CGID uint32 + Mode uint16 + pad1 uint16 + Seq uint16 + pad2 uint16 + pad3 uint32 + unused1 uint64 + unused2 uint64 } diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go index f8d8debf1..3495f5cd0 100644 --- a/pkg/abi/linux/sem.go +++ b/pkg/abi/linux/sem.go @@ -14,7 +14,7 @@ package linux -// semctl Command Definitions. Source: //include/uapi/linux/sem.h +// semctl Command Definitions. Source: include/uapi/linux/sem.h const ( GETPID = 11 GETVAL = 12 @@ -25,7 +25,7 @@ const ( SETALL = 17 ) -// ipcs ctl cmds. Source: //include/uapi/linux/sem.h +// ipcs ctl cmds. Source: include/uapi/linux/sem.h const ( SEM_STAT = 18 SEM_INFO = 19 @@ -33,16 +33,14 @@ const ( const SEM_UNDO = 0x1000 -// SemidDS is equivalent to struct semid_ds. +// SemidDS is equivalent to struct semid64_ds. type SemidDS struct { - SemPerm IPCPerm - SemOTime TimeT - reserved1 uint32 - SemCTime TimeT - reserved2 uint32 - SemNSems uint32 - reserved3 uint32 - reserved4 uint32 + SemPerm IPCPerm + SemOTime TimeT + SemCTime TimeT + SemNSems uint64 + unused3 uint64 + unused4 uint64 } // Sembuf is equivalent to struct sembuf. -- cgit v1.2.3 From 12c161f27865d0e389cd593c669bd740d7f24692 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Fri, 11 May 2018 11:16:57 -0700 Subject: Implement MAP_32BIT. PiperOrigin-RevId: 196281052 Change-Id: Ie620a0f983a1bf2570d0003d4754611879335c1c --- pkg/abi/linux/mm.go | 1 + pkg/sentry/memmap/memmap.go | 6 +++++ pkg/sentry/mm/vma.go | 46 +++++++++++++++++++++++++---------- pkg/sentry/syscalls/linux/sys_mmap.go | 14 ++++++----- 4 files changed, 48 insertions(+), 19 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index 2263653cc..b48e1d18a 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -31,6 +31,7 @@ const ( MAP_PRIVATE = 1 << 1 MAP_FIXED = 1 << 4 MAP_ANONYMOUS = 1 << 5 + MAP_32BIT = 1 << 6 // arch/x86/include/uapi/asm/mman.h MAP_GROWSDOWN = 1 << 8 MAP_DENYWRITE = 1 << 11 MAP_EXECUTABLE = 1 << 12 diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index 14fed55bc..72986cbb9 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -266,6 +266,12 @@ type MMapOpts struct { // be replaced. If Unmap is true, Fixed must be true. Unmap bool + // If Map32Bit is true, all addresses in the created mapping must fit in a + // 32-bit integer. (Note that the "end address" of the mapping, i.e. the + // address of the first byte *after* the mapping, need not fit in a 32-bit + // integer.) Map32Bit is ignored if Fixed is true. + Map32Bit bool + // Perms is the set of permissions to the applied to this mapping. Perms usermem.AccessType diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index 61aaa3195..b81e861f1 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -34,9 +34,10 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp // Find a useable range. addr, err := mm.findAvailableLocked(opts.Length, findAvailableOpts{ - Addr: opts.Addr, - Fixed: opts.Fixed, - Unmap: opts.Unmap, + Addr: opts.Addr, + Fixed: opts.Fixed, + Unmap: opts.Unmap, + Map32Bit: opts.Map32Bit, }) if err != nil { return vmaIterator{}, usermem.AddrRange{}, err @@ -93,24 +94,40 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp } type findAvailableOpts struct { - // Addr is a suggested address. Addr must be page-aligned. - Addr usermem.Addr - - // Fixed is true if only the suggested address is acceptable. - Fixed bool - - // Unmap is true if existing vmas and guard pages may exist in the returned - // range. - Unmap bool + // These fields are equivalent to those in memmap.MMapOpts, except that: + // + // - Addr must be page-aligned. + // + // - Unmap allows existing guard pages in the returned range. + + Addr usermem.Addr + Fixed bool + Unmap bool + Map32Bit bool } +// map32Start/End are the bounds to which MAP_32BIT mappings are constrained, +// and are equivalent to Linux's MAP32_BASE and MAP32_MAX respectively. +const ( + map32Start = 0x40000000 + map32End = 0x80000000 +) + // findAvailableLocked finds an allocatable range. // // Preconditions: mm.mappingMu must be locked. func (mm *MemoryManager) findAvailableLocked(length uint64, opts findAvailableOpts) (usermem.Addr, error) { + if opts.Fixed { + opts.Map32Bit = false + } + allowedAR := mm.applicationAddrRange() + if opts.Map32Bit { + allowedAR = allowedAR.Intersect(usermem.AddrRange{map32Start, map32End}) + } + // Does the provided suggestion work? if ar, ok := opts.Addr.ToRange(length); ok { - if mm.applicationAddrRange().IsSupersetOf(ar) { + if allowedAR.IsSupersetOf(ar) { if opts.Unmap { return ar.Start, nil } @@ -132,6 +149,9 @@ func (mm *MemoryManager) findAvailableLocked(length uint64, opts findAvailableOp alignment = usermem.HugePageSize } + if opts.Map32Bit { + return mm.findLowestAvailableLocked(length, alignment, allowedAR) + } if mm.layout.DefaultDirection == arch.MmapBottomUp { return mm.findLowestAvailableLocked(length, alignment, usermem.AddrRange{mm.layout.BottomUpBase, mm.layout.MaxAddr}) } diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 2c7d41de0..bfa23f6a8 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -45,6 +45,7 @@ func Mmap(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC private := flags&linux.MAP_PRIVATE != 0 shared := flags&linux.MAP_SHARED != 0 anon := flags&linux.MAP_ANONYMOUS != 0 + map32bit := flags&linux.MAP_32BIT != 0 // Require exactly one of MAP_PRIVATE and MAP_SHARED. if private == shared { @@ -52,12 +53,13 @@ func Mmap(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC } opts := memmap.MMapOpts{ - Length: args[1].Uint64(), - Offset: args[5].Uint64(), - Addr: args[0].Pointer(), - Fixed: fixed, - Unmap: fixed, - Private: private, + Length: args[1].Uint64(), + Offset: args[5].Uint64(), + Addr: args[0].Pointer(), + Fixed: fixed, + Unmap: fixed, + Map32Bit: map32bit, + Private: private, Perms: usermem.AccessType{ Read: linux.PROT_READ&prot != 0, Write: linux.PROT_WRITE&prot != 0, -- cgit v1.2.3 From 08879266fef3a67fac1a77f1ea133c3ac75759dd Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Fri, 11 May 2018 17:18:56 -0700 Subject: sentry: Adds canonical mode support. PiperOrigin-RevId: 196331627 Change-Id: Ifef4485f8202c52481af317cedd52d2ef48cea6a --- pkg/abi/linux/tty.go | 28 +++ pkg/sentry/fs/tty/line_discipline.go | 354 ++++++++++++++++++++++++++--------- pkg/sentry/fs/tty/master.go | 3 + pkg/sentry/fs/tty/slave.go | 3 + 4 files changed, 298 insertions(+), 90 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index f9e641af9..84b6ccc87 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -14,9 +14,16 @@ package linux +import ( + "unicode/utf8" +) + const ( // NumControlCharacters is the number of control characters in Termios. NumControlCharacters = 19 + // disabledChar is used to indicate that a control character is + // disabled. + disabledChar = 0 ) // Termios is struct termios, defined in uapi/asm-generic/termbits.h. @@ -86,6 +93,27 @@ func (t *KernelTermios) FromTermios(term Termios) { t.ControlCharacters = term.ControlCharacters } +// IsTerminating returns whether c is a line terminating character. +func (t *KernelTermios) IsTerminating(c rune) bool { + if t.IsEOF(c) { + return true + } + switch byte(c) { + case disabledChar: + return false + case '\n', t.ControlCharacters[VEOL]: + return true + case t.ControlCharacters[VEOL2]: + return t.LEnabled(IEXTEN) + } + return false +} + +// IsEOF returns whether c is the EOF character. +func (t *KernelTermios) IsEOF(c rune) bool { + return utf8.RuneLen(c) == 1 && byte(c) == t.ControlCharacters[VEOF] && t.ControlCharacters[VEOF] != disabledChar +} + // Input flags. const ( IGNBRK = 0000001 diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index a3aa95ece..bdc4f5b92 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -28,9 +28,90 @@ import ( ) const ( + // canonMaxBytes is the number of bytes that fit into a single line of + // terminal input in canonical mode. This corresponds to N_TTY_BUF_SIZE + // in include/linux/tty.h. + canonMaxBytes = 4096 + + // nonCanonMaxBytes is the maximum number of bytes that can be read at + // a time in noncanonical mode. + nonCanonMaxBytes = canonMaxBytes - 1 + spacesPerTab = 8 ) +// queue represents one of the input or output queues between a pty master and +// slave. Bytes written to a queue are added to the read buffer until it is +// full, at which point they are written to the wait buffer. Bytes are +// processed (i.e. undergo termios transformations) as they are added to the +// read buffer. The read buffer is readable when its length is nonzero and +// readable is true. +type queue struct { + waiter.Queue `state:"nosave"` + + // readBuf is buffer of data ready to be read when readable is true. + // This data has been processed. + readBuf bytes.Buffer `state:".([]byte)"` + + // waitBuf contains data that can't fit into readBuf. It is put here + // until it can be loaded into the read buffer. waitBuf contains data + // that hasn't been processed. + waitBuf bytes.Buffer `state:".([]byte)"` + + // readable indicates whether the read buffer can be read from. In + // canonical mode, there can be an unterminated line in the read buffer, + // so readable must be checked. + readable bool +} + +// saveReadBuf is invoked by stateify. +func (q *queue) saveReadBuf() []byte { + return append([]byte(nil), q.readBuf.Bytes()...) +} + +// loadReadBuf is invoked by stateify. +func (q *queue) loadReadBuf(b []byte) { + q.readBuf.Write(b) +} + +// saveWaitBuf is invoked by stateify. +func (q *queue) saveWaitBuf() []byte { + return append([]byte(nil), q.waitBuf.Bytes()...) +} + +// loadWaitBuf is invoked by stateify. +func (q *queue) loadWaitBuf(b []byte) { + q.waitBuf.Write(b) +} + +// readReadiness returns whether q is ready to be read from. +func (q *queue) readReadiness(t *linux.KernelTermios) waiter.EventMask { + if q.readBuf.Len() > 0 && q.readable { + return waiter.EventIn + } + return waiter.EventMask(0) +} + +// writeReadiness returns whether q is ready to be written to. +func (q *queue) writeReadiness(t *linux.KernelTermios) waiter.EventMask { + // Like Linux, we don't impose a maximum size on what can be enqueued. + return waiter.EventOut +} + +// readableSize writes the number of readable bytes to userspace. +func (q *queue) readableSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error { + var size int32 + if q.readable { + size = int32(q.readBuf.Len()) + } + + _, err := usermem.CopyObjectOut(ctx, io, args[2].Pointer(), size, usermem.IOOpts{ + AddressSpaceActive: true, + }) + return err + +} + // lineDiscipline dictates how input and output are handled between the // pseudoterminal (pty) master and slave. It can be configured to alter I/O, // modify control characters (e.g. Ctrl-C for SIGINT), etc. The following man @@ -50,7 +131,7 @@ const ( // // input from terminal +-------------+ input to process (e.g. bash) // +------------------------>| input queue |---------------------------+ -// | +-------------+ | +// | (inputQueueWrite) +-------------+ (inputQueueRead) | // | | // | v // masterFD slaveFD @@ -58,7 +139,7 @@ const ( // | | // | output to terminal +--------------+ output from process | // +------------------------| output queue |<--------------------------+ -// +--------------+ +// (outputQueueRead) +--------------+ (outputQueueWrite) // // Lock order: // inMu @@ -102,14 +183,25 @@ func (l *lineDiscipline) getTermios(ctx context.Context, io usermem.IO, args arc // setTermios sets a linux.Termios for the tty. func (l *lineDiscipline) setTermios(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { + l.inMu.Lock() + defer l.inMu.Unlock() l.termiosMu.Lock() defer l.termiosMu.Unlock() + oldCanonEnabled := l.termios.LEnabled(linux.ICANON) // We must copy a Termios struct, not KernelTermios. var t linux.Termios _, err := usermem.CopyObjectIn(ctx, io, args[2].Pointer(), &t, usermem.IOOpts{ AddressSpaceActive: true, }) l.termios.FromTermios(t) + + // If canonical mode is turned off, move bytes from inQueue's wait + // buffer to its read buffer. Anything already in the read buffer is + // now readable. + if oldCanonEnabled && !l.termios.LEnabled(linux.ICANON) { + l.pushWaitBuf(&l.inQueue, transformInput) + } + return 0, err } @@ -118,7 +210,9 @@ func (l *lineDiscipline) masterReadiness() waiter.EventMask { defer l.inMu.Unlock() l.outMu.Lock() defer l.outMu.Unlock() - return l.inQueue.writeReadiness() | l.outQueue.readReadiness() + // We don't have to lock a termios because the default master termios + // is immutable. + return l.inQueue.writeReadiness(&linux.MasterTermios) | l.outQueue.readReadiness(&linux.MasterTermios) } func (l *lineDiscipline) slaveReadiness() waiter.EventMask { @@ -126,93 +220,97 @@ func (l *lineDiscipline) slaveReadiness() waiter.EventMask { defer l.inMu.Unlock() l.outMu.Lock() defer l.outMu.Unlock() - return l.outQueue.writeReadiness() | l.inQueue.readReadiness() -} - -// queue represents one of the input or output queues between a pty master and -// slave. -type queue struct { - waiter.Queue `state:"nosave"` - buf bytes.Buffer `state:".([]byte)"` -} - -// saveBuf is invoked by stateify. -func (q *queue) saveBuf() []byte { - return append([]byte(nil), q.buf.Bytes()...) -} - -// loadBuf is invoked by stateify. -func (q *queue) loadBuf(b []byte) { - q.buf.Write(b) -} - -// readReadiness returns whether q is ready to be read from. -// -// Preconditions: q's mutex must be held. -func (q *queue) readReadiness() waiter.EventMask { - ready := waiter.EventMask(0) - if q.buf.Len() > 0 { - ready |= waiter.EventIn - } - return ready + l.termiosMu.Lock() + defer l.termiosMu.Unlock() + return l.outQueue.writeReadiness(&l.termios) | l.inQueue.readReadiness(&l.termios) } -// writeReadiness returns whether q is ready to be written to. -func (q *queue) writeReadiness() waiter.EventMask { - return waiter.EventOut +func (l *lineDiscipline) inputQueueReadSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error { + l.inMu.Lock() + defer l.inMu.Unlock() + return l.inQueue.readableSize(ctx, io, args) } func (l *lineDiscipline) inputQueueRead(ctx context.Context, dst usermem.IOSequence) (int64, error) { l.inMu.Lock() defer l.inMu.Unlock() - return l.queueRead(ctx, dst, &l.inQueue) + return l.queueRead(ctx, dst, &l.inQueue, transformInput) } func (l *lineDiscipline) inputQueueWrite(ctx context.Context, src usermem.IOSequence) (int64, error) { l.inMu.Lock() defer l.inMu.Unlock() - return l.queueWrite(ctx, src, &l.inQueue, false) + return l.queueWrite(ctx, src, &l.inQueue, transformInput) +} + +func (l *lineDiscipline) outputQueueReadSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error { + l.outMu.Lock() + defer l.outMu.Unlock() + return l.outQueue.readableSize(ctx, io, args) } func (l *lineDiscipline) outputQueueRead(ctx context.Context, dst usermem.IOSequence) (int64, error) { l.outMu.Lock() defer l.outMu.Unlock() - return l.queueRead(ctx, dst, &l.outQueue) + return l.queueRead(ctx, dst, &l.outQueue, transformOutput) } func (l *lineDiscipline) outputQueueWrite(ctx context.Context, src usermem.IOSequence) (int64, error) { l.outMu.Lock() defer l.outMu.Unlock() - return l.queueWrite(ctx, src, &l.outQueue, true) + return l.queueWrite(ctx, src, &l.outQueue, transformOutput) } // queueRead reads from q to userspace. // // Preconditions: q's lock must be held. -func (l *lineDiscipline) queueRead(ctx context.Context, dst usermem.IOSequence, q *queue) (int64, error) { - // Copy bytes out to user-space. queueRead doesn't have to do any - // processing or other extra work -- that's all taken care of when - // writing to a queue. - n, err := q.buf.WriteTo(dst.Writer(ctx)) +func (l *lineDiscipline) queueRead(ctx context.Context, dst usermem.IOSequence, q *queue, f transform) (int64, error) { + if !q.readable { + return 0, syserror.ErrWouldBlock + } + + // Read out from the read buffer. + n := canonMaxBytes + if n > int(dst.NumBytes()) { + n = int(dst.NumBytes()) + } + if n > q.readBuf.Len() { + n = q.readBuf.Len() + } + n, err := dst.Writer(ctx).Write(q.readBuf.Bytes()[:n]) + if err != nil { + return 0, err + } + // Discard bytes read out. + q.readBuf.Next(n) + + // If we read everything, this queue is no longer readable. + if q.readBuf.Len() == 0 { + q.readable = false + } + + // Move data from the queue's wait buffer to its read buffer. + l.termiosMu.Lock() + defer l.termiosMu.Unlock() + l.pushWaitBuf(q, f) // If state changed, notify any waiters. If nothing was available to // read, let the caller know we could block. if n > 0 { q.Notify(waiter.EventOut) - } else if err == nil { + } else { return 0, syserror.ErrWouldBlock } - return int64(n), err + return int64(n), nil } -// queueWrite writes to q from userspace. `output` is whether the queue being -// written to should be subject to output processing (i.e. whether it is the -// output queue). +// queueWrite writes to q from userspace. f is the function used to perform +// processing on data being written and write it to the read buffer. // // Precondition: q's lock must be held. -func (l *lineDiscipline) queueWrite(ctx context.Context, src usermem.IOSequence, q *queue, output bool) (int64, error) { +func (l *lineDiscipline) queueWrite(ctx context.Context, src usermem.IOSequence, q *queue, f transform) (int64, error) { // TODO: Use CopyInTo/safemem to avoid extra copying. - // Get the bytes to write from user-space. + // Copy in the bytes to write from user-space. b := make([]byte, src.NumBytes()) n, err := src.CopyIn(ctx, b) if err != nil { @@ -220,49 +318,69 @@ func (l *lineDiscipline) queueWrite(ctx context.Context, src usermem.IOSequence, } b = b[:n] + // Write as much as possible to the read buffer. + l.termiosMu.Lock() + defer l.termiosMu.Unlock() + n = f(l, q, b) + + // Write remaining data to the wait buffer. + nWaiting, _ := q.waitBuf.Write(b[n:]) + // If state changed, notify any waiters. If we were unable to write // anything, let the caller know we could block. if n > 0 { q.Notify(waiter.EventIn) - } else { + } else if nWaiting == 0 { return 0, syserror.ErrWouldBlock } + return int64(n + nWaiting), nil +} - // Optionally perform line discipline transformations depending on - // whether we're writing to the input queue or output queue. - var buf *bytes.Buffer - l.termiosMu.Lock() - if output { - buf = l.transformOutput(b) - } else { - buf = l.transformInput(b) - } - l.termiosMu.Unlock() +// pushWaitBuf fills the queue's read buffer with data from the wait buffer. +// +// Precondition: l.inMu and l.termiosMu must be held. +func (l *lineDiscipline) pushWaitBuf(q *queue, f transform) { + // Remove bytes from the wait buffer and move them to the read buffer. + n := f(l, q, q.waitBuf.Bytes()) + q.waitBuf.Next(n) - // Enqueue buf at the end of the queue. - buf.WriteTo(&q.buf) - return int64(n), err + // If state changed, notify any waiters. + if n > 0 { + q.Notify(waiter.EventIn) + } } +// transform functions require the passed in lineDiscipline's mutex to be held. +type transform func(*lineDiscipline, *queue, []byte) int + // transformOutput does output processing for one end of the pty. See // drivers/tty/n_tty.c:do_output_char for an analogous kernel function. // -// Precondition: l.termiosMu must be held. -func (l *lineDiscipline) transformOutput(buf []byte) *bytes.Buffer { +// Precondition: l.termiosMu and q's mutex must be held. +func transformOutput(l *lineDiscipline, q *queue, buf []byte) int { + // transformOutput is effectively always in noncanonical mode, as the + // master termios never has ICANON set. + if !l.termios.OEnabled(linux.OPOST) { - return bytes.NewBuffer(buf) + n, _ := q.readBuf.Write(buf) + if q.readBuf.Len() > 0 { + q.readable = true + } + return n } - var ret bytes.Buffer + var ret int for len(buf) > 0 { - c := l.removeRune(&buf) + c, size := l.peekRune(buf) + ret += size + buf = buf[size:] switch c { case '\n': if l.termios.OEnabled(linux.ONLRET) { l.column = 0 } if l.termios.OEnabled(linux.ONLCR) { - ret.Write([]byte{'\r', '\n'}) + q.readBuf.Write([]byte{'\r', '\n'}) continue } case '\r': @@ -281,7 +399,7 @@ func (l *lineDiscipline) transformOutput(buf []byte) *bytes.Buffer { spaces := spacesPerTab - l.column%spacesPerTab if l.termios.OutputFlags&linux.TABDLY == linux.XTABS { l.column += spaces - ret.Write(bytes.Repeat([]byte{' '}, 8)) + q.readBuf.Write(bytes.Repeat([]byte{' '}, spacesPerTab)) continue } l.column += spaces @@ -292,24 +410,40 @@ func (l *lineDiscipline) transformOutput(buf []byte) *bytes.Buffer { default: l.column++ } - ret.WriteRune(c) + q.readBuf.WriteRune(c) + } + if q.readBuf.Len() > 0 { + q.readable = true } - return &ret + return ret } -// transformInput does input processing for one end of the pty. Characters -// read are transformed according to flags set in the termios struct. See +// transformInput does input processing for one end of the pty. Characters read +// are transformed according to flags set in the termios struct. See // drivers/tty/n_tty.c:n_tty_receive_char_special for an analogous kernel // function. // -// Precondition: l.termiosMu must be held. -func (l *lineDiscipline) transformInput(buf []byte) *bytes.Buffer { - var ret bytes.Buffer - for len(buf) > 0 { - c := l.removeRune(&buf) +// Precondition: l.termiosMu and q's mutex must be held. +func transformInput(l *lineDiscipline, q *queue, buf []byte) int { + // If there's a line waiting to be read in canonical mode, don't write + // anything else to the read buffer. + if l.termios.LEnabled(linux.ICANON) && q.readable { + return 0 + } + + maxBytes := nonCanonMaxBytes + if l.termios.LEnabled(linux.ICANON) { + maxBytes = canonMaxBytes + } + + var ret int + for len(buf) > 0 && q.readBuf.Len() < canonMaxBytes { + c, size := l.peekRune(buf) switch c { case '\r': if l.termios.IEnabled(linux.IGNCR) { + buf = buf[size:] + ret += size continue } if l.termios.IEnabled(linux.ICRNL) { @@ -320,23 +454,63 @@ func (l *lineDiscipline) transformInput(buf []byte) *bytes.Buffer { c = '\r' } } - ret.WriteRune(c) + + // In canonical mode, we discard non-terminating characters + // after the first 4095. + if l.shouldDiscard(q, c) { + buf = buf[size:] + ret += size + continue + } + + // Stop if the buffer would be overfilled. + if q.readBuf.Len()+size > maxBytes { + break + } + buf = buf[size:] + ret += size + + // If we get EOF, make the buffer available for reading. + if l.termios.LEnabled(linux.ICANON) && l.termios.IsEOF(c) { + q.readable = true + break + } + + q.readBuf.WriteRune(c) + + // If we finish a line, make it available for reading. + if l.termios.LEnabled(linux.ICANON) && l.termios.IsTerminating(c) { + q.readable = true + break + } + } + + // In noncanonical mode, everything is readable. + if !l.termios.LEnabled(linux.ICANON) && q.readBuf.Len() > 0 { + q.readable = true } - return &ret + + return ret +} + +// shouldDiscard returns whether c should be discarded. In canonical mode, if +// too many bytes are enqueued, we keep reading input and discarding it until +// we find a terminating character. Signal/echo processing still occurs. +func (l *lineDiscipline) shouldDiscard(q *queue, c rune) bool { + return l.termios.LEnabled(linux.ICANON) && q.readBuf.Len()+utf8.RuneLen(c) >= canonMaxBytes && !l.termios.IsTerminating(c) } -// removeRune removes and returns the first rune from the byte array. The -// buffer's length is updated accordingly. -func (l *lineDiscipline) removeRune(b *[]byte) rune { +// peekRune returns the first rune from the byte array depending on whether +// UTF8 is enabled. +func (l *lineDiscipline) peekRune(b []byte) (rune, int) { var c rune var size int // If UTF-8 support is enabled, runes might be multiple bytes. if l.termios.IEnabled(linux.IUTF8) { - c, size = utf8.DecodeRune(*b) + c, size = utf8.DecodeRune(b) } else { - c = rune((*b)[0]) + c = rune(b[0]) size = 1 } - *b = (*b)[size:] - return c + return c, size } diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index 3c47ee517..74cdbe874 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -148,6 +148,9 @@ func (mf *masterFileOperations) Write(ctx context.Context, _ *fs.File, src userm // Ioctl implements fs.FileOperations.Ioctl. func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { switch args[1].Uint() { + case linux.FIONREAD: // linux.FIONREAD == linux.TIOCINQ + // Get the number of bytes in the output queue read buffer. + return 0, mf.t.ld.outputQueueReadSize(ctx, io, args) case linux.TCGETS: // N.B. TCGETS on the master actually returns the configuration // of the slave end. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 9178071a4..f5eec726e 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -133,6 +133,9 @@ func (sf *slaveFileOperations) Write(ctx context.Context, _ *fs.File, src userme // Ioctl implements fs.FileOperations.Ioctl. func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { switch args[1].Uint() { + case linux.FIONREAD: // linux.FIONREAD == linux.TIOCINQ + // Get the number of bytes in the input queue read buffer. + return 0, sf.si.t.ld.inputQueueReadSize(ctx, io, args) case linux.TCGETS: return sf.si.t.ld.getTermios(ctx, io, args) case linux.TCSETS: -- cgit v1.2.3 From 8878a66a565733493e702199b284cd7855f80bf0 Mon Sep 17 00:00:00 2001 From: Rahat Mahmood Date: Thu, 17 May 2018 15:05:15 -0700 Subject: Implement sysv shm. PiperOrigin-RevId: 197058289 Change-Id: I3946c25028b7e032be4894d61acb48ac0c24d574 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/shm.go | 75 +++++ pkg/refs/refcounter.go | 8 +- pkg/sentry/context/context.go | 20 ++ pkg/sentry/fs/dirent_refs_test.go | 62 ++-- pkg/sentry/kernel/BUILD | 1 + pkg/sentry/kernel/ipc_namespace.go | 15 +- pkg/sentry/kernel/shm/BUILD | 40 +++ pkg/sentry/kernel/shm/device.go | 20 ++ pkg/sentry/kernel/shm/shm.go | 630 +++++++++++++++++++++++++++++++++++ pkg/sentry/kernel/task.go | 3 + pkg/sentry/kernel/task_clone.go | 4 +- pkg/sentry/mm/BUILD | 2 + pkg/sentry/mm/shm.go | 66 ++++ pkg/sentry/syscalls/linux/BUILD | 2 + pkg/sentry/syscalls/linux/linux64.go | 8 +- pkg/sentry/syscalls/linux/sys_shm.go | 155 +++++++++ runsc/boot/loader.go | 2 +- 18 files changed, 1072 insertions(+), 42 deletions(-) create mode 100644 pkg/abi/linux/shm.go create mode 100644 pkg/sentry/kernel/shm/BUILD create mode 100644 pkg/sentry/kernel/shm/device.go create mode 100644 pkg/sentry/kernel/shm/shm.go create mode 100644 pkg/sentry/mm/shm.go create mode 100644 pkg/sentry/syscalls/linux/sys_shm.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index a428e61a3..693ce0fdd 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -51,6 +51,7 @@ go_library( "sched.go", "seccomp.go", "sem.go", + "shm.go", "signal.go", "socket.go", "time.go", diff --git a/pkg/abi/linux/shm.go b/pkg/abi/linux/shm.go new file mode 100644 index 000000000..9149ed094 --- /dev/null +++ b/pkg/abi/linux/shm.go @@ -0,0 +1,75 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// shmat(2) flags. Source: include/uapi/linux/shm.h +const ( + SHM_RDONLY = 010000 // Read-only access. + SHM_RND = 020000 // Round attach address to SHMLBA boundary. + SHM_REMAP = 040000 // Take-over region on attach. + SHM_EXEC = 0100000 // Execution access. +) + +// IPCPerm.Mode upper byte flags. Source: include/linux/shm.h +const ( + SHM_DEST = 01000 // Segment will be destroyed on last detach. + SHM_LOCKED = 02000 // Segment will not be swapped. + SHM_HUGETLB = 04000 // Segment will use huge TLB pages. + SHM_NORESERVE = 010000 // Don't check for reservations. +) + +// Additional Linux-only flags for shmctl(2). Source: include/uapi/linux/shm.h +const ( + SHM_LOCK = 11 + SHM_UNLOCK = 12 + SHM_STAT = 13 + SHM_INFO = 14 +) + +// ShmidDS is equivalent to struct shmid64_ds. Source: +// include/uapi/asm-generic/shmbuf.h +type ShmidDS struct { + ShmPerm IPCPerm + ShmSegsz uint64 + ShmAtime TimeT + ShmDtime TimeT + ShmCtime TimeT + ShmCpid int32 + ShmLpid int32 + ShmNattach uint64 + + Unused4 uint64 + Unused5 uint64 +} + +// ShmParams is equivalent to struct shminfo. Source: include/uapi/linux/shm.h +type ShmParams struct { + ShmMax uint64 + ShmMin uint64 + ShmMni uint64 + ShmSeg uint64 + ShmAll uint64 +} + +// ShmInfo is equivalent to struct shm_info. Source: include/uapi/linux/shm.h +type ShmInfo struct { + UsedIDs int32 // Number of currently existing segments. + _ [4]byte + ShmTot uint64 // Total number of shared memory pages. + ShmRss uint64 // Number of resident shared memory pages. + ShmSwp uint64 // Number of swapped shared memory pages. + SwapAttempts uint64 // Unused since Linux 2.4. + SwapSuccesses uint64 // Unused since Linux 2.4. +} diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 1036553c7..3162001e1 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -194,9 +194,11 @@ type AtomicRefCount struct { weakRefs ilist.List `state:"nosave"` } -// TestReadRefs returns the current reference count of r. Use only for tests. -func (r *AtomicRefCount) TestReadRefs() int64 { - return atomic.LoadInt64(&r.refCount) +// ReadRefs returns the current number of references. The returned count is +// inherently racy and is unsafe to use without external synchronization. +func (r *AtomicRefCount) ReadRefs() int64 { + // Account for the internal -1 offset on refcounts. + return atomic.LoadInt64(&r.refCount) + 1 } // IncRef increments this object's reference count. While the count is kept diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go index e0dffafba..598c5b4ff 100644 --- a/pkg/sentry/context/context.go +++ b/pkg/sentry/context/context.go @@ -20,6 +20,26 @@ import ( "gvisor.googlesource.com/gvisor/pkg/log" ) +type contextID int + +// Globally accessible values from a context. These keys are defined in the +// context package to resolve dependency cycles by not requiring the caller to +// import packages usually required to get these information. +const ( + // CtxThreadGroupID is the current thread group ID when a context represents + // a task context. The value is represented as an int32. + CtxThreadGroupID contextID = iota +) + +// ThreadGroupIDFromContext returns the current thread group ID when ctx +// represents a task context. +func ThreadGroupIDFromContext(ctx Context) (tgid int32, ok bool) { + if tgid := ctx.Value(CtxThreadGroupID); tgid != nil { + return tgid.(int32), true + } + return 0, false +} + // A Context represents a thread of execution (hereafter "goroutine" to reflect // Go idiosyncrasy). It carries state associated with the goroutine across API // boundaries. diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go index 8ce9ba02d..f9dcba316 100644 --- a/pkg/sentry/fs/dirent_refs_test.go +++ b/pkg/sentry/fs/dirent_refs_test.go @@ -33,8 +33,8 @@ func TestWalkPositive(t *testing.T) { ctx := contexttest.Context(t) root := NewDirent(newMockDirInode(ctx, nil), "root") - if got := root.TestReadRefs(); got != 0 { - t.Fatalf("root has a ref count of %d, want %d", got, 0) + if got := root.ReadRefs(); got != 1 { + t.Fatalf("root has a ref count of %d, want %d", got, 1) } name := "d" @@ -43,22 +43,22 @@ func TestWalkPositive(t *testing.T) { t.Fatalf("root.walk(root, %q) got %v, want nil", name, err) } - if got := root.TestReadRefs(); got != 1 { - t.Fatalf("root has a ref count of %d, want %d", got, 1) + if got := root.ReadRefs(); got != 2 { + t.Fatalf("root has a ref count of %d, want %d", got, 2) } - if got := d.TestReadRefs(); got != 0 { - t.Fatalf("child name = %q has a ref count of %d, want %d", d.name, got, 0) + if got := d.ReadRefs(); got != 1 { + t.Fatalf("child name = %q has a ref count of %d, want %d", d.name, got, 1) } d.DecRef() - if got := root.TestReadRefs(); got != 0 { - t.Fatalf("root has a ref count of %d, want %d", got, 0) + if got := root.ReadRefs(); got != 1 { + t.Fatalf("root has a ref count of %d, want %d", got, 1) } - if got := d.TestReadRefs(); got != -1 { - t.Fatalf("child name = %q has a ref count of %d, want %d", d.name, got, -1) + if got := d.ReadRefs(); got != 0 { + t.Fatalf("child name = %q has a ref count of %d, want %d", d.name, got, 0) } root.flush() @@ -76,8 +76,8 @@ func TestWalkNegative(t *testing.T) { root := NewDirent(NewEmptyDir(ctx, nil), "root") mn := root.Inode.InodeOperations.(*mockInodeOperationsLookupNegative) - if got := root.TestReadRefs(); got != 0 { - t.Fatalf("root has a ref count of %d, want %d", got, 0) + if got := root.ReadRefs(); got != 1 { + t.Fatalf("root has a ref count of %d, want %d", got, 1) } name := "d" @@ -88,7 +88,7 @@ func TestWalkNegative(t *testing.T) { } } - if got := root.TestReadRefs(); got != 0 { + if got := root.ReadRefs(); got != 1 { t.Fatalf("root has a ref count of %d, want %d", got, 1) } @@ -110,14 +110,14 @@ func TestWalkNegative(t *testing.T) { t.Fatalf("root found positive child at %q, want negative", name) } - if got := child.(*Dirent).TestReadRefs(); got != 1 { - t.Fatalf("child has a ref count of %d, want %d", got, 1) + if got := child.(*Dirent).ReadRefs(); got != 2 { + t.Fatalf("child has a ref count of %d, want %d", got, 2) } child.DecRef() - if got := child.(*Dirent).TestReadRefs(); got != 0 { - t.Fatalf("child has a ref count of %d, want %d", got, 0) + if got := child.(*Dirent).ReadRefs(); got != 1 { + t.Fatalf("child has a ref count of %d, want %d", got, 1) } if got := len(root.children); got != 1 { @@ -126,7 +126,7 @@ func TestWalkNegative(t *testing.T) { root.DecRef() - if got := root.TestReadRefs(); got != -1 { + if got := root.ReadRefs(); got != 0 { t.Fatalf("root has a ref count of %d, want %d", got, 0) } @@ -184,12 +184,12 @@ func TestHashNegativeToPositive(t *testing.T) { t.Fatalf("got negative Dirent, want positive") } - if got := d.TestReadRefs(); got != 0 { - t.Fatalf("child %q has a ref count of %d, want %d", name, got, 0) + if got := d.ReadRefs(); got != 1 { + t.Fatalf("child %q has a ref count of %d, want %d", name, got, 1) } - if got := root.TestReadRefs(); got != 1 { - t.Fatalf("root has a ref count of %d, want %d", got, 1) + if got := root.ReadRefs(); got != 2 { + t.Fatalf("root has a ref count of %d, want %d", got, 2) } if got := len(root.children); got != 1 { @@ -291,12 +291,12 @@ func TestCreateExtraRefs(t *testing.T) { { desc: "Create caching", root: NewDirent(NewEmptyDir(ctx, NewDirentCache(1)), "root"), - refs: 1, + refs: 2, }, { desc: "Create not caching", root: NewDirent(NewEmptyDir(ctx, nil), "root"), - refs: 0, + refs: 1, }, } { t.Run(test.desc, func(t *testing.T) { @@ -307,7 +307,7 @@ func TestCreateExtraRefs(t *testing.T) { } d := f.Dirent - if got := d.TestReadRefs(); got != test.refs { + if got := d.ReadRefs(); got != test.refs { t.Errorf("dirent has a ref count of %d, want %d", got, test.refs) } }) @@ -347,8 +347,8 @@ func TestRemoveExtraRefs(t *testing.T) { t.Fatalf("root.Remove(root, %q) failed: %v", name, err) } - if got := d.TestReadRefs(); got != 0 { - t.Fatalf("dirent has a ref count of %d, want %d", got, 0) + if got := d.ReadRefs(); got != 1 { + t.Fatalf("dirent has a ref count of %d, want %d", got, 1) } d.DecRef() @@ -406,11 +406,11 @@ func TestRenameExtraRefs(t *testing.T) { newParent.flush() // Expect to have only active references. - if got := renamed.TestReadRefs(); got != 0 { - t.Errorf("renamed has ref count %d, want only active references %d", got, 0) + if got := renamed.ReadRefs(); got != 1 { + t.Errorf("renamed has ref count %d, want only active references %d", got, 1) } - if got := replaced.TestReadRefs(); got != 0 { - t.Errorf("replaced has ref count %d, want only active references %d", got, 0) + if got := replaced.ReadRefs(); got != 1 { + t.Errorf("replaced has ref count %d, want only active references %d", got, 1) } }) } diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 62794cff5..377c94e4c 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -184,6 +184,7 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/sched", "//pkg/sentry/kernel/semaphore", + "//pkg/sentry/kernel/shm", "//pkg/sentry/kernel/time", "//pkg/sentry/limits", "//pkg/sentry/loader", diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 78737f58f..3049fead4 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -15,18 +15,26 @@ package kernel import ( + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/semaphore" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm" ) // IPCNamespace represents an IPC namespace. type IPCNamespace struct { + // User namespace which owns this IPC namespace. Immutable. + userNS *auth.UserNamespace + semaphores *semaphore.Registry + shms *shm.Registry } // NewIPCNamespace creates a new IPC namespace. -func NewIPCNamespace() *IPCNamespace { +func NewIPCNamespace(userNS *auth.UserNamespace) *IPCNamespace { return &IPCNamespace{ + userNS: userNS, semaphores: semaphore.NewRegistry(), + shms: shm.NewRegistry(userNS), } } @@ -35,6 +43,11 @@ func (i *IPCNamespace) SemaphoreRegistry() *semaphore.Registry { return i.semaphores } +// ShmRegistry returns the shm segment registry for this namespace. +func (i *IPCNamespace) ShmRegistry() *shm.Registry { + return i.shms +} + // IPCNamespace returns the task's IPC namespace. func (t *Task) IPCNamespace() *IPCNamespace { t.mu.Lock() diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD new file mode 100644 index 000000000..182cc1c76 --- /dev/null +++ b/pkg/sentry/kernel/shm/BUILD @@ -0,0 +1,40 @@ +package(licenses = ["notice"]) # Apache 2.0 + +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_stateify") + +go_stateify( + name = "shm_state", + srcs = [ + "shm.go", + ], + out = "shm_autogen_state.go", + package = "shm", +) + +go_library( + name = "shm", + srcs = [ + "device.go", + "shm.go", + "shm_autogen_state.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm", + visibility = ["//pkg/sentry:internal"], + deps = [ + "//pkg/abi/linux", + "//pkg/log", + "//pkg/refs", + "//pkg/sentry/context", + "//pkg/sentry/device", + "//pkg/sentry/fs", + "//pkg/sentry/kernel/auth", + "//pkg/sentry/kernel/time", + "//pkg/sentry/memmap", + "//pkg/sentry/platform", + "//pkg/sentry/usage", + "//pkg/sentry/usermem", + "//pkg/state", + "//pkg/syserror", + ], +) diff --git a/pkg/sentry/kernel/shm/device.go b/pkg/sentry/kernel/shm/device.go new file mode 100644 index 000000000..b0dacdbe0 --- /dev/null +++ b/pkg/sentry/kernel/shm/device.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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 shm + +import "gvisor.googlesource.com/gvisor/pkg/sentry/device" + +// shmDevice is the kernel shm device. +var shmDevice = device.NewAnonDevice() diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go new file mode 100644 index 000000000..7217e8103 --- /dev/null +++ b/pkg/sentry/kernel/shm/shm.go @@ -0,0 +1,630 @@ +// Copyright 2018 Google Inc. +// +// 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 shm implements sysv shared memory segments. +// +// Known missing features: +// +// - SHM_LOCK/SHM_UNLOCK are no-ops. The sentry currently doesn't implement +// memory locking in general. +// +// - SHM_HUGETLB and related flags for shmget(2) are ignored. There's no easy +// way to implement hugetlb support on a per-map basis, and it has no impact +// on correctness. +// +// - SHM_NORESERVE for shmget(2) is ignored, the sentry doesn't implement swap +// so it's meaningless to reserve space for swap. +// +// - No per-process segment size enforcement. This feature probably isn't used +// much anyways, since Linux sets the per-process limits to the system-wide +// limits by default. +// +// Lock ordering: mm.mappingMu -> shm registry lock -> shm lock +package shm + +import ( + "fmt" + "math" + "sync" + + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/log" + "gvisor.googlesource.com/gvisor/pkg/refs" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" + "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" + "gvisor.googlesource.com/gvisor/pkg/sentry/platform" + "gvisor.googlesource.com/gvisor/pkg/sentry/usage" + "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +// Various limits for shared memory segments. +const ( + // shmsTotalMaxPages is the system-wide limit on all shared memory segments, measured + // in number of pages. + shmsTotalMaxPages = math.MaxInt64 // SHMALL + + // shmMaxSize is the maximum size of a single segment, in bytes. + shmMaxSize = math.MaxInt64 // SHMMAX + + // shmMinSize is the minimum specifiable size of a segment, effectively + // yielding a size rounded up to the next page size. Measured in bytes. + shmMinSize = 1 // SHMMIN + + // shmsTotalMax is the maximum number of segments on the system. + shmsTotalMax = 4096 // SHMMNI +) + +// Registry tracks all shared memory segments in an IPC namespace. The registry +// provides the mechanisms for creating and finding segments, and reporting +// global shm parameters. +type Registry struct { + // userNS owns the IPC namespace this registry belong to. Immutable. + userNS *auth.UserNamespace + + mu sync.Mutex `state:"nosave"` + + // shms maps segment ids to segments. Protected by mu. + shms map[int32]*Shm + + // Sum of the sizes of all existing segments rounded up to page size, in + // units of page size. Protected by mu. + totalPages uint64 + + // lastIDUsed is protected by mu. + lastIDUsed int32 +} + +// NewRegistry creates a new shm registry. +func NewRegistry(userNS *auth.UserNamespace) *Registry { + return &Registry{ + userNS: userNS, + shms: make(map[int32]*Shm), + } +} + +// FindByID looks up a segment given an ID. +func (r *Registry) FindByID(id int32) *Shm { + r.mu.Lock() + defer r.mu.Unlock() + return r.shms[id] +} + +// Precondition: Caller must hold r.mu. +func (r *Registry) findByKey(key int32) *Shm { + for _, v := range r.shms { + if v.key == key { + return v + } + } + return nil +} + +// FindOrCreate looks up or creates a segment in the registry. It's functionally +// analogous to open(2). +func (r *Registry) FindOrCreate(ctx context.Context, pid, key int32, size uint64, mode linux.FileMode, private, create, exclusive bool) (*Shm, error) { + if create && (size < shmMinSize || size > shmMaxSize) { + // "A new segment was to be created and size is less than SHMMIN or + // greater than SHMMAX." - man shmget(2) + return nil, syserror.EINVAL + } + + r.mu.Lock() + defer r.mu.Unlock() + + if len(r.shms) >= shmsTotalMax { + // "All possible shared memory IDs have been taken (SHMMNI) ..." + // - man shmget(2) + return nil, syserror.ENOSPC + } + + if !private { + // Look up an existing segment. + if shm := r.findByKey(key); shm != nil { + shm.mu.Lock() + defer shm.mu.Unlock() + + // Check that caller can access the segment. + if !shm.checkPermissions(ctx, fs.PermsFromMode(mode)) { + // "The user does not have permission to access the shared + // memory segment, and does not have the CAP_IPC_OWNER + // capability in the user namespace that governs its IPC + // namespace." - man shmget(2) + return nil, syserror.EACCES + } + + if size > shm.size { + // "A segment for the given key exists, but size is greater than + // the size of that segment." - man shmget(2) + return nil, syserror.EINVAL + } + + if create && exclusive { + // "IPC_CREAT and IPC_EXCL were specified in shmflg, but a + // shared memory segment already exists for key." + // - man shmget(2) + return nil, syserror.EEXIST + } + + return shm, nil + } + + if !create { + // "No segment exists for the given key, and IPC_CREAT was not + // specified." - man shmget(2) + return nil, syserror.ENOENT + } + } + + var sizeAligned uint64 + if val, ok := usermem.Addr(size).RoundUp(); ok { + sizeAligned = uint64(val) + } else { + return nil, syserror.EINVAL + } + + if numPages := sizeAligned / usermem.PageSize; r.totalPages+numPages > shmsTotalMaxPages { + // "... allocating a segment of the requested size would cause the + // system to exceed the system-wide limit on shared memory (SHMALL)." + // - man shmget(2) + return nil, syserror.ENOSPC + } + + // Need to create a new segment. + creator := fs.FileOwnerFromContext(ctx) + perms := fs.FilePermsFromMode(mode) + return r.newShm(ctx, pid, key, creator, perms, size) +} + +// newShm creates a new segment in the registry. +func (r *Registry) newShm(ctx context.Context, pid, key int32, creator fs.FileOwner, perms fs.FilePermissions, size uint64) (*Shm, error) { + p := platform.FromContext(ctx) + if p == nil { + panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, platform.CtxPlatform)) + } + + effectiveSize := uint64(usermem.Addr(size).MustRoundUp()) + fr, err := p.Memory().Allocate(effectiveSize, usage.Anonymous) + if err != nil { + return nil, err + } + + shm := &Shm{ + p: p, + registry: r, + creator: creator, + size: size, + effectiveSize: effectiveSize, + fr: fr, + key: key, + perms: perms, + owner: creator, + creatorPID: pid, + changeTime: ktime.NowFromContext(ctx), + } + + // Find the next available ID. + for id := r.lastIDUsed + 1; id != r.lastIDUsed; id++ { + // Handle wrap around. + if id < 0 { + id = 0 + continue + } + if r.shms[id] == nil { + r.lastIDUsed = id + r.shms[id] = shm + shm.ID = id + + r.totalPages += effectiveSize / usermem.PageSize + + return shm, nil + } + } + + log.Warningf("Shm ids exhuasted, they may be leaking") + return nil, syserror.ENOSPC +} + +// IPCInfo reports global parameters for sysv shared memory segments on this +// system. See shmctl(IPC_INFO). +func (r *Registry) IPCInfo() *linux.ShmParams { + return &linux.ShmParams{ + ShmMax: shmMaxSize, + ShmMin: shmMinSize, + ShmMni: shmsTotalMax, + ShmSeg: shmsTotalMax, // Linux also sets this to SHMMNI. + ShmAll: shmsTotalMaxPages, + } +} + +// ShmInfo reports linux-specific global parameters for sysv shared memory +// segments on this system. See shmctl(SHM_INFO). +func (r *Registry) ShmInfo() *linux.ShmInfo { + r.mu.Lock() + defer r.mu.Unlock() + + return &linux.ShmInfo{ + UsedIDs: int32(r.lastIDUsed), + ShmTot: r.totalPages, + ShmRss: r.totalPages, // We could probably get a better estimate from memory accounting. + ShmSwp: 0, // No reclaim at the moment. + } +} + +// remove unregisters a segment from this registry, preventing it from being +// discovered in the future. Caller is responsible for ensuring s is destroyed. +// +// Precondition: To preserve lock ordering, caller must not hold s.mu. +func (r *Registry) remove(s *Shm) { + r.mu.Lock() + defer r.mu.Unlock() + delete(r.shms, s.ID) + r.totalPages -= s.effectiveSize / usermem.PageSize +} + +// Shm represents a single shared memory segment. +// +// Shm segment are backed directly by an allocation from platform +// memory. Segments are always mapped as a whole, greatly simplifying how +// mappings are tracked. However note that mremap and munmap calls may cause the +// vma for a segment to become fragmented; which requires special care when +// unmapping a segment. See mm/shm.go. +// +// Segments persist until they are explicitly marked for destruction via +// shmctl(SHM_RMID). +// +// Shm implements memmap.Mappable and memmap.MappingIdentity. +type Shm struct { + // AtomicRefCount tracks the number of references to this segment from + // maps. A segment always holds a reference to itself, until it's marked for + // destruction. + refs.AtomicRefCount + + p platform.Platform + + // registry points to the shm registry containing this segment. Immutable. + registry *Registry + + // ID is the kernel identifier for this segment. Immutable. + ID int32 + + // creator is the user that created the segment. Immutable. + creator fs.FileOwner + + // size is the requested size of the segment at creation, in + // bytes. Immutable. + size uint64 + + // effectiveSize of the segment, rounding up to the next page + // boundary. Immutable. + // + // Invariant: effectiveSize must be a multiple of usermem.PageSize. + effectiveSize uint64 + + // fr is the offset into platform.Memory() that backs this contents of this + // segment. Immutable. + fr platform.FileRange + + // key is the public identifier for this segment. + key int32 + + // mu protects all fields below. + mu sync.Mutex `state:"nosave"` + + // perms is the access permissions for the segment. + perms fs.FilePermissions + + // owner of this segment. + owner fs.FileOwner + // attachTime is updated on every successful shmat. + attachTime ktime.Time + // detachTime is updated on every successful shmdt. + detachTime ktime.Time + // changeTime is updated on every successful changes to the segment via + // shmctl(IPC_SET). + changeTime ktime.Time + + // creatorPID is the PID of the process that created the segment. + creatorPID int32 + // lastAttachDetachPID is the pid of the process that issued the last shmat + // or shmdt syscall. + lastAttachDetachPID int32 + + // pendingDestruction indicates the segment was marked as destroyed through + // shmctl(IPC_RMID). When marked as destroyed, the segment will not be found + // in the registry and can no longer be attached. When the last user + // detaches from the segment, it is destroyed. Protected by mu. + pendingDestruction bool +} + +// MappedName implements memmap.MappingIdentity.MappedName. +func (s *Shm) MappedName(ctx context.Context) string { + return fmt.Sprintf("SYSV%08d", s.key) +} + +// DeviceID implements memmap.MappingIdentity.DeviceID. +func (s *Shm) DeviceID() uint64 { + return shmDevice.DeviceID() +} + +// InodeID implements memmap.MappingIdentity.InodeID. +func (s *Shm) InodeID() uint64 { + // "shmid gets reported as "inode#" in /proc/pid/maps. proc-ps tools use + // this. Changing this will break them." -- Linux, ipc/shm.c:newseg() + return uint64(s.ID) +} + +// DecRef overrides refs.RefCount.DecRef with a destructor. +func (s *Shm) DecRef() { + s.DecRefWithDestructor(s.destroy) +} + +// Msync implements memmap.MappingIdentity.Msync. Msync is a no-op for shm +// segments. +func (s *Shm) Msync(context.Context, memmap.MappableRange) error { + return nil +} + +// AddMapping implements memmap.Mappable.AddMapping. +func (s *Shm) AddMapping(ctx context.Context, ms memmap.MappingSpace, ar usermem.AddrRange, offset uint64) error { + s.mu.Lock() + defer s.mu.Unlock() + s.attachTime = ktime.NowFromContext(ctx) + if pid, ok := context.ThreadGroupIDFromContext(ctx); ok { + s.lastAttachDetachPID = pid + } else { + // AddMapping is called during a syscall, so ctx should always be a task + // context. + log.Warningf("Adding mapping to shm %+v but couldn't get the current pid; not updating the last attach pid", s) + } + return nil +} + +// RemoveMapping implements memmap.Mappable.RemoveMapping. +func (s *Shm) RemoveMapping(ctx context.Context, ms memmap.MappingSpace, ar usermem.AddrRange, offset uint64) { + s.mu.Lock() + defer s.mu.Unlock() + // TODO: RemoveMapping may be called during task exit, when ctx + // is context.Background. Gracefully handle missing clocks. Failing to + // update the detach time in these cases is ok, since no one can observe the + // omission. + if clock := ktime.RealtimeClockFromContext(ctx); clock != nil { + s.detachTime = clock.Now() + } + + // If called from a non-task context we also won't have a threadgroup + // id. Silently skip updating the lastAttachDetachPid in that case. + if pid, ok := context.ThreadGroupIDFromContext(ctx); ok { + s.lastAttachDetachPID = pid + } else { + log.Debugf("Couldn't obtain pid when removing mapping to shm %+v, not updating the last detach pid.", s) + } +} + +// CopyMapping implements memmap.Mappable.CopyMapping. +func (s *Shm) CopyMapping(ctx context.Context, ms memmap.MappingSpace, srcAR, dstAR usermem.AddrRange, offset uint64) error { + return nil +} + +// Translate implements memmap.Mappable.Translate. +func (s *Shm) Translate(ctx context.Context, required, optional memmap.MappableRange, at usermem.AccessType) ([]memmap.Translation, error) { + var err error + if required.End > s.fr.Length() { + err = &memmap.BusError{syserror.EFAULT} + } + if source := optional.Intersect(memmap.MappableRange{0, s.fr.Length()}); source.Length() != 0 { + return []memmap.Translation{ + { + Source: source, + File: s.p.Memory(), + Offset: s.fr.Start + source.Start, + }, + }, err + } + return nil, err +} + +// InvalidateUnsavable implements memmap.Mappable.InvalidateUnsavable. +func (s *Shm) InvalidateUnsavable(ctx context.Context) error { + return nil +} + +// AttachOpts describes various flags passed to shmat(2). +type AttachOpts struct { + Execute bool + Readonly bool + Remap bool +} + +// ConfigureAttach creates an mmap configuration for the segment with the +// requested attach options. +// +// ConfigureAttach returns with a ref on s on success. The caller should drop +// this once the map is installed. This reference prevents s from being +// destroyed before the returned configuration is used. +func (s *Shm) ConfigureAttach(ctx context.Context, addr usermem.Addr, opts AttachOpts) (memmap.MMapOpts, error) { + s.mu.Lock() + defer s.mu.Unlock() + if s.pendingDestruction && s.ReadRefs() == 0 { + return memmap.MMapOpts{}, syserror.EIDRM + } + + if !s.checkPermissions(ctx, fs.PermMask{ + Read: true, + Write: !opts.Readonly, + Execute: opts.Execute, + }) { + // "The calling process does not have the required permissions for the + // requested attach type, and does not have the CAP_IPC_OWNER capability + // in the user namespace that governs its IPC namespace." - man shmat(2) + return memmap.MMapOpts{}, syserror.EACCES + } + s.IncRef() + return memmap.MMapOpts{ + Length: s.size, + Offset: 0, + Addr: addr, + Fixed: opts.Remap, + Perms: usermem.AccessType{ + Read: true, + Write: !opts.Readonly, + Execute: opts.Execute, + }, + MaxPerms: usermem.AnyAccess, + Mappable: s, + MappingIdentity: s, + }, nil +} + +// EffectiveSize returns the size of the underlying shared memory segment. This +// may be larger than the requested size at creation, due to rounding to page +// boundaries. +func (s *Shm) EffectiveSize() uint64 { + return s.effectiveSize +} + +// IPCStat returns information about a shm. See shmctl(IPC_STAT). +func (s *Shm) IPCStat(ctx context.Context) (*linux.ShmidDS, error) { + s.mu.Lock() + defer s.mu.Unlock() + + // "The caller must have read permission on the shared memory segment." + // - man shmctl(2) + if !s.checkPermissions(ctx, fs.PermMask{Read: true}) { + // "IPC_STAT or SHM_STAT is requested and shm_perm.mode does not allow + // read access for shmid, and the calling process does not have the + // CAP_IPC_OWNER capability in the user namespace that governs its IPC + // namespace." - man shmctl(2) + return nil, syserror.EACCES + } + + var mode uint16 + if s.pendingDestruction { + mode |= linux.SHM_DEST + } + creds := auth.CredentialsFromContext(ctx) + + nattach := uint64(s.ReadRefs()) + // Don't report the self-reference we keep prior to being marked for + // destruction. However, also don't report a count of -1 for segments marked + // as destroyed, with no mappings. + if !s.pendingDestruction { + nattach-- + } + + ds := &linux.ShmidDS{ + ShmPerm: linux.IPCPerm{ + Key: uint32(s.key), + UID: uint32(creds.UserNamespace.MapFromKUID(s.owner.UID)), + GID: uint32(creds.UserNamespace.MapFromKGID(s.owner.GID)), + CUID: uint32(creds.UserNamespace.MapFromKUID(s.creator.UID)), + CGID: uint32(creds.UserNamespace.MapFromKGID(s.creator.GID)), + Mode: mode | uint16(s.perms.LinuxMode()), + Seq: 0, // IPC sequences not supported. + }, + ShmSegsz: s.size, + ShmAtime: s.attachTime.TimeT(), + ShmDtime: s.detachTime.TimeT(), + ShmCtime: s.changeTime.TimeT(), + ShmCpid: s.creatorPID, + ShmLpid: s.lastAttachDetachPID, + ShmNattach: nattach, + } + + return ds, nil +} + +// Set modifies attributes for a segment. See shmctl(IPC_SET). +func (s *Shm) Set(ctx context.Context, ds *linux.ShmidDS) error { + s.mu.Lock() + defer s.mu.Unlock() + + if !s.checkOwnership(ctx) { + return syserror.EPERM + } + + creds := auth.CredentialsFromContext(ctx) + uid := creds.UserNamespace.MapToKUID(auth.UID(ds.ShmPerm.UID)) + gid := creds.UserNamespace.MapToKGID(auth.GID(ds.ShmPerm.GID)) + if !uid.Ok() || !gid.Ok() { + return syserror.EINVAL + } + + // User may only modify the lower 9 bits of the mode. All the other bits are + // always 0 for the underlying inode. + mode := linux.FileMode(ds.ShmPerm.Mode & 0x1ff) + s.perms = fs.FilePermsFromMode(mode) + + s.owner.UID = uid + s.owner.GID = gid + + s.changeTime = ktime.NowFromContext(ctx) + return nil +} + +func (s *Shm) destroy() { + s.registry.remove(s) + s.p.Memory().DecRef(s.fr) +} + +// MarkDestroyed marks a shm for destruction. The shm is actually destroyed once +// it has no references. See shmctl(IPC_RMID). +func (s *Shm) MarkDestroyed() { + s.mu.Lock() + defer s.mu.Unlock() + // Prevent the segment from being found in the registry. + s.key = linux.IPC_PRIVATE + s.pendingDestruction = true + s.DecRef() +} + +// checkOwnership verifies whether a segment may be accessed by ctx as an +// owner. See ipc/util.c:ipcctl_pre_down_nolock() in Linux. +// +// Precondition: Caller must hold s.mu. +func (s *Shm) checkOwnership(ctx context.Context) bool { + creds := auth.CredentialsFromContext(ctx) + if s.owner.UID == creds.EffectiveKUID || s.creator.UID == creds.EffectiveKUID { + return true + } + + // Tasks with CAP_SYS_ADMIN may bypass ownership checks. Strangely, Linux + // doesn't use CAP_IPC_OWNER for this despite CAP_IPC_OWNER being documented + // for use to "override IPC ownership checks". + return creds.HasCapabilityIn(linux.CAP_SYS_ADMIN, s.registry.userNS) +} + +// checkPermissions verifies whether a segment is accessible by ctx for access +// described by req. See ipc/util.c:ipcperms() in Linux. +// +// Precondition: Caller must hold s.mu. +func (s *Shm) checkPermissions(ctx context.Context, req fs.PermMask) bool { + creds := auth.CredentialsFromContext(ctx) + + p := s.perms.Other + if s.owner.UID == creds.EffectiveKUID { + p = s.perms.User + } else if creds.InGroup(s.owner.GID) { + p = s.perms.Group + } + if p.SupersetOf(req) { + return true + } + + // Tasks with CAP_IPC_OWNER may bypass permission checks. + return creds.HasCapabilityIn(linux.CAP_IPC_OWNER, s.registry.userNS) +} diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index 490f795c2..7763050a5 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -21,6 +21,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/bpf" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/inet" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" @@ -559,6 +560,8 @@ func (t *Task) Value(key interface{}) interface{} { return t case auth.CtxCredentials: return t.creds + case context.CtxThreadGroupID: + return int32(t.ThreadGroup().ID()) case fs.CtxRoot: return t.FSContext().RootDirectory() case inet.CtxStack: diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index 3a74abdfb..0c2427952 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -197,7 +197,7 @@ func (t *Task) Clone(opts *CloneOptions) (ThreadID, *SyscallControl, error) { if opts.NewIPCNamespace { // Note that "If CLONE_NEWIPC is set, then create the process in a new IPC // namespace" - ipcns = NewIPCNamespace() + ipcns = NewIPCNamespace(userns) } tc, err := t.tc.Fork(t, !opts.NewAddressSpace) @@ -449,7 +449,7 @@ func (t *Task) Unshare(opts *SharingOptions) error { } // Note that "If CLONE_NEWIPC is set, then create the process in a new IPC // namespace" - t.ipcns = NewIPCNamespace() + t.ipcns = NewIPCNamespace(t.creds.UserNamespace) } if opts.NewFiles { oldFDMap := t.tr.FDMap diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 39bde2be3..258389bb2 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -107,6 +107,7 @@ go_library( "pma_set.go", "proc_pid_maps.go", "save_restore.go", + "shm.go", "special_mappable.go", "syscalls.go", "vma.go", @@ -123,6 +124,7 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/seqfile", + "//pkg/sentry/kernel/shm", "//pkg/sentry/limits", "//pkg/sentry/memmap", "//pkg/sentry/platform", diff --git a/pkg/sentry/mm/shm.go b/pkg/sentry/mm/shm.go new file mode 100644 index 000000000..bab137a5a --- /dev/null +++ b/pkg/sentry/mm/shm.go @@ -0,0 +1,66 @@ +// Copyright 2018 Google Inc. +// +// 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 mm + +import ( + "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm" + "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +// DetachShm unmaps a sysv shared memory segment. +func (mm *MemoryManager) DetachShm(ctx context.Context, addr usermem.Addr) error { + if addr != addr.RoundDown() { + // "... shmaddr is not aligned on a page boundary." - man shmdt(2) + return syserror.EINVAL + } + + var detached *shm.Shm + mm.mappingMu.Lock() + defer mm.mappingMu.Unlock() + + // Find and remove the first vma containing an address >= addr that maps a + // segment originally attached at addr. + vseg := mm.vmas.LowerBoundSegment(addr) + for vseg.Ok() { + vma := vseg.ValuePtr() + if shm, ok := vma.mappable.(*shm.Shm); ok && vseg.Start() >= addr && uint64(vseg.Start()-addr) == vma.off { + detached = shm + vseg = mm.unmapLocked(ctx, vseg.Range()).NextSegment() + break + } else { + vseg = vseg.NextSegment() + } + } + + if detached == nil { + // There is no shared memory segment attached at addr. + return syserror.EINVAL + } + + // Remove all vmas that could have been created by the same attach. + end := addr + usermem.Addr(detached.EffectiveSize()) + for vseg.Ok() && vseg.End() <= end { + vma := vseg.ValuePtr() + if vma.mappable == detached && uint64(vseg.Start()-addr) == vma.off { + vseg = mm.unmapLocked(ctx, vseg.Range()).NextSegment() + } else { + vseg = vseg.NextSegment() + } + } + + return nil +} diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index bc67ebf30..f9e0a4be3 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -44,6 +44,7 @@ go_library( "sys_rusage.go", "sys_sched.go", "sys_sem.go", + "sys_shm.go", "sys_signal.go", "sys_socket.go", "sys_stat.go", @@ -84,6 +85,7 @@ go_library( "//pkg/sentry/kernel/pipe", "//pkg/sentry/kernel/sched", "//pkg/sentry/kernel/semaphore", + "//pkg/sentry/kernel/shm", "//pkg/sentry/kernel/time", "//pkg/sentry/limits", "//pkg/sentry/memmap", diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 44db2d582..237c61007 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -75,9 +75,9 @@ var AMD64 = &kernel.SyscallTable{ 26: Msync, 27: Mincore, 28: Madvise, - // 29: Shmget, TODO - // 30: Shmat, TODO - // 31: Shmctl, TODO + 29: Shmget, + 30: Shmat, + 31: Shmctl, 32: Dup, 33: Dup2, 34: Pause, @@ -113,7 +113,7 @@ var AMD64 = &kernel.SyscallTable{ 64: Semget, 65: Semop, 66: Semctl, - // 67: Shmdt, TODO + 67: Shmdt, // 68: Msgget, TODO // 69: Msgsnd, TODO // 70: Msgrcv, TODO diff --git a/pkg/sentry/syscalls/linux/sys_shm.go b/pkg/sentry/syscalls/linux/sys_shm.go new file mode 100644 index 000000000..48ff1d5f0 --- /dev/null +++ b/pkg/sentry/syscalls/linux/sys_shm.go @@ -0,0 +1,155 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import ( + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +// Shmget implements shmget(2). +func Shmget(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + key := args[0].Int() + size := uint64(args[1].SizeT()) + flag := args[2].Int() + + private := key == linux.IPC_PRIVATE + create := flag&linux.IPC_CREAT == linux.IPC_CREAT + exclusive := flag&linux.IPC_EXCL == linux.IPC_EXCL + mode := linux.FileMode(flag & 0777) + + pid := int32(t.ThreadGroup().ID()) + r := t.IPCNamespace().ShmRegistry() + segment, err := r.FindOrCreate(t, pid, key, size, mode, private, create, exclusive) + if err != nil { + return 0, nil, err + } + return uintptr(segment.ID), nil, nil +} + +// findSegment retrives a shm segment by the given id. +func findSegment(t *kernel.Task, id int32) (*shm.Shm, error) { + r := t.IPCNamespace().ShmRegistry() + segment := r.FindByID(id) + if segment == nil { + // No segment with provided id. + return nil, syserror.EINVAL + } + return segment, nil +} + +// Shmat implements shmat(2). +func Shmat(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + id := args[0].Int() + addr := args[1].Pointer() + flag := args[2].Int() + + segment, err := findSegment(t, id) + if err != nil { + return 0, nil, syserror.EINVAL + } + + opts, err := segment.ConfigureAttach(t, addr, shm.AttachOpts{ + Execute: flag&linux.SHM_EXEC == linux.SHM_EXEC, + Readonly: flag&linux.SHM_RDONLY == linux.SHM_RDONLY, + Remap: flag&linux.SHM_REMAP == linux.SHM_REMAP, + }) + if err != nil { + return 0, nil, err + } + defer segment.DecRef() + addr, err = t.MemoryManager().MMap(t, opts) + return uintptr(addr), nil, err +} + +// Shmdt implements shmdt(2). +func Shmdt(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + err := t.MemoryManager().DetachShm(t, addr) + return 0, nil, err +} + +// Shmctl implements shmctl(2). +func Shmctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + id := args[0].Int() + cmd := args[1].Int() + buf := args[2].Pointer() + + r := t.IPCNamespace().ShmRegistry() + + switch cmd { + case linux.SHM_STAT: + // Technically, we should be treating id as "an index into the kernel's + // internal array that maintains information about all shared memory + // segments on the system". Since we don't track segments in an array, + // we'll just pretend the shmid is the index and do the same thing as + // IPC_STAT. Linux also uses the index as the shmid. + fallthrough + case linux.IPC_STAT: + segment, err := findSegment(t, id) + if err != nil { + return 0, nil, syserror.EINVAL + } + + stat, err := segment.IPCStat(t) + if err == nil { + _, err = t.CopyOut(buf, stat) + } + return 0, nil, err + + case linux.IPC_INFO: + params := r.IPCInfo() + _, err := t.CopyOut(buf, params) + return 0, nil, err + + case linux.SHM_INFO: + info := r.ShmInfo() + _, err := t.CopyOut(buf, info) + return 0, nil, err + } + + // Remaining commands refer to a specific segment. + segment, err := findSegment(t, id) + if err != nil { + return 0, nil, syserror.EINVAL + } + + switch cmd { + case linux.IPC_SET: + var ds linux.ShmidDS + _, err = t.CopyIn(buf, &ds) + if err != nil { + return 0, nil, err + } + err = segment.Set(t, &ds) + return 0, nil, err + + case linux.IPC_RMID: + segment.MarkDestroyed() + return 0, nil, nil + + case linux.SHM_LOCK, linux.SHM_UNLOCK: + // We currently do not support memmory locking anywhere. + // mlock(2)/munlock(2) are currently stubbed out as no-ops so do the + // same here. + return 0, nil, nil + + default: + return 0, nil, syserror.EINVAL + } +} diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 0ff54d349..566f2eb46 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -146,7 +146,7 @@ func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console // not configurable from runtime spec. utsns := kernel.NewUTSNamespace(spec.Hostname, "", creds.UserNamespace) - ipcns := kernel.NewIPCNamespace() + ipcns := kernel.NewIPCNamespace(creds.UserNamespace) if err := enableStrace(conf); err != nil { return nil, fmt.Errorf("failed to enable strace: %v", err) -- cgit v1.2.3 From d571a4359cebbcf8a9b201bb125f1cdc9fb126e4 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 21 Jun 2018 10:52:33 -0700 Subject: Implement ioctl(FIOASYNC) FIOASYNC and friends are used to send signals when a file is ready for IO. This may or may not be needed by Nginx. While Nginx does use it, it is unclear if the code that uses it has any effect. PiperOrigin-RevId: 201550828 Change-Id: I7ba05a7db4eb2dfffde11e9bd9a35b65b98d7f50 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/fcntl.go | 29 +++++++ pkg/abi/linux/ioctl.go | 5 ++ pkg/abi/linux/signal.go | 34 ++++++++ pkg/sentry/fs/file.go | 62 +++++++++++++-- pkg/sentry/fs/file_state.go | 10 --- pkg/sentry/fs/flags.go | 7 ++ pkg/sentry/kernel/fasync/BUILD | 18 +++++ pkg/sentry/kernel/fasync/fasync.go | 145 ++++++++++++++++++++++++++++++++++ pkg/sentry/kernel/sessions.go | 5 ++ pkg/sentry/syscalls/linux/BUILD | 1 + pkg/sentry/syscalls/linux/flags.go | 5 ++ pkg/sentry/syscalls/linux/sys_file.go | 78 ++++++++++++++++-- 13 files changed, 376 insertions(+), 24 deletions(-) create mode 100644 pkg/abi/linux/fcntl.go create mode 100644 pkg/sentry/kernel/fasync/BUILD create mode 100644 pkg/sentry/kernel/fasync/fasync.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 693ce0fdd..5d00b66cc 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -31,6 +31,7 @@ go_library( "elf.go", "errors.go", "exec.go", + "fcntl.go", "file.go", "fs.go", "futex.go", diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go new file mode 100644 index 000000000..f5dbe5199 --- /dev/null +++ b/pkg/abi/linux/fcntl.go @@ -0,0 +1,29 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Comands from linux/fcntl.h. +const ( + F_DUPFD = 0 + F_DUPFD_CLOEXEC = 1030 + F_GETFD = 1 + F_GETFL = 3 + F_GETOWN = 9 + F_SETFD = 2 + F_SETFL = 4 + F_SETLK = 6 + F_SETLKW = 7 + F_SETOWN = 8 +) diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 35cefbdfc..3ef046562 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -29,6 +29,11 @@ const ( TIOCSPTLCK = 0x40045431 FIONCLEX = 0x00005450 FIOCLEX = 0x00005451 + FIOASYNC = 0x00005452 + FIOSETOWN = 0x00008901 + SIOCSPGRP = 0x00008902 + FIOGETOWN = 0x00008903 + SIOCGPGRP = 0x00008904 ) // ioctl(2) requests provided by uapi/linux/android/binder.h diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index cd09008b5..fed2a159f 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -175,3 +175,37 @@ const ( SA_NOMASK = SA_NODEFER SA_ONESHOT = SA_RESTARTHAND ) + +// Signal info types. +const ( + SI_MASK = 0xffff0000 + SI_KILL = 0 << 16 + SI_TIMER = 1 << 16 + SI_POLL = 2 << 16 + SI_FAULT = 3 << 16 + SI_CHLD = 4 << 16 + SI_RT = 5 << 16 + SI_MESGQ = 6 << 16 + SI_SYS = 7 << 16 +) + +// SIGPOLL si_codes. +const ( + // POLL_IN indicates that data input available. + POLL_IN = SI_POLL | 1 + + // POLL_OUT indicates that output buffers available. + POLL_OUT = SI_POLL | 2 + + // POLL_MSG indicates that an input message available. + POLL_MSG = SI_POLL | 3 + + // POLL_ERR indicates that there was an i/o error. + POLL_ERR = SI_POLL | 4 + + // POLL_PRI indicates that a high priority input available. + POLL_PRI = SI_POLL | 5 + + // POLL_HUP indicates that a device disconnected. + POLL_HUP = SI_POLL | 6 +) diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index f2683bbd2..6d93ef760 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -16,6 +16,7 @@ package fs import ( "math" + "sync" "sync/atomic" "gvisor.googlesource.com/gvisor/pkg/amutex" @@ -72,9 +73,15 @@ type File struct { // other files via the Dirent cache. Dirent *Dirent + // flagsMu protects flags and async below. + flagsMu sync.Mutex `state:"nosave"` + // flags are the File's flags. Setting or getting flags is fully atomic // and is not protected by mu (below). - flags atomic.Value `state:".(FileFlags)"` + flags FileFlags + + // async handles O_ASYNC notifications. + async FileAsync // mu is dual-purpose: first, to make read(2) and write(2) thread-safe // in conformity with POSIX, and second, to cancel operations before they @@ -99,8 +106,8 @@ func NewFile(ctx context.Context, dirent *Dirent, flags FileFlags, fops FileOper UniqueID: uniqueid.GlobalFromContext(ctx), Dirent: dirent, FileOperations: fops, + flags: flags, } - f.flags.Store(flags) f.mu.Init() return f } @@ -117,22 +124,40 @@ func (f *File) DecRef() { // Release a reference on the Dirent. f.Dirent.DecRef() + + f.flagsMu.Lock() + if f.flags.Async && f.async != nil { + f.async.Unregister(f) + } + f.flagsMu.Unlock() }) } // Flags atomically loads the File's flags. func (f *File) Flags() FileFlags { - return f.flags.Load().(FileFlags) + f.flagsMu.Lock() + flags := f.flags + f.flagsMu.Unlock() + return flags } // SetFlags atomically changes the File's flags to the values contained // in newFlags. See SettableFileFlags for values that can be set. func (f *File) SetFlags(newFlags SettableFileFlags) { - flags := f.flags.Load().(FileFlags) - flags.Direct = newFlags.Direct - flags.NonBlocking = newFlags.NonBlocking - flags.Append = newFlags.Append - f.flags.Store(flags) + f.flagsMu.Lock() + f.flags.Direct = newFlags.Direct + f.flags.NonBlocking = newFlags.NonBlocking + f.flags.Append = newFlags.Append + if f.async != nil { + if newFlags.Async && !f.flags.Async { + f.async.Register(f) + } + if !newFlags.Async && f.flags.Async { + f.async.Unregister(f) + } + } + f.flags.Async = newFlags.Async + f.flagsMu.Unlock() } // Offset atomically loads the File's offset. @@ -361,6 +386,27 @@ func (f *File) Msync(ctx context.Context, mr memmap.MappableRange) error { return f.Fsync(ctx, int64(mr.Start), int64(mr.End-1), SyncData) } +// A FileAsync sends signals to its owner when w is ready for IO. +type FileAsync interface { + Register(w waiter.Waitable) + Unregister(w waiter.Waitable) +} + +// Async gets the stored FileAsync or creates a new one with the supplied +// function. If the supplied function is nil, no FileAsync is created and the +// current value is returned. +func (f *File) Async(newAsync func() FileAsync) FileAsync { + f.flagsMu.Lock() + defer f.flagsMu.Unlock() + if f.async == nil && newAsync != nil { + f.async = newAsync() + if f.flags.Async { + f.async.Register(f) + } + } + return f.async +} + // FileReader implements io.Reader and io.ReaderAt. type FileReader struct { // Ctx is the context for the file reader. diff --git a/pkg/sentry/fs/file_state.go b/pkg/sentry/fs/file_state.go index 341cbda0b..3384737ab 100644 --- a/pkg/sentry/fs/file_state.go +++ b/pkg/sentry/fs/file_state.go @@ -18,13 +18,3 @@ package fs func (f *File) afterLoad() { f.mu.Init() } - -// saveFlags is invoked by stateify. -func (f *File) saveFlags() FileFlags { - return f.flags.Load().(FileFlags) -} - -// loadFlags is invoked by stateify. -func (f *File) loadFlags(flags FileFlags) { - f.flags.Store(flags) -} diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index dfa6a3d62..7a8eefd02 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -42,6 +42,9 @@ type FileFlags struct { // Directory indicates that this file must be a directory. Directory bool + + // Async indicates that this file sends signals on IO events. + Async bool } // SettableFileFlags is a subset of FileFlags above that can be changed @@ -55,6 +58,9 @@ type SettableFileFlags struct { // Append indicates this file is append only. Append bool + + // Async indicates that this file sends signals on IO events. + Async bool } // Settable returns the subset of f that are settable. @@ -63,5 +69,6 @@ func (f FileFlags) Settable() SettableFileFlags { Direct: f.Direct, NonBlocking: f.NonBlocking, Append: f.Append, + Async: f.Async, } } diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD new file mode 100644 index 000000000..8d06e1182 --- /dev/null +++ b/pkg/sentry/kernel/fasync/BUILD @@ -0,0 +1,18 @@ +package(licenses = ["notice"]) # Apache 2.0 + +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "fasync", + srcs = ["fasync.go"], + importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/fasync", + visibility = ["//:sandbox"], + deps = [ + "//pkg/abi/linux", + "//pkg/sentry/arch", + "//pkg/sentry/fs", + "//pkg/sentry/kernel", + "//pkg/sentry/kernel/auth", + "//pkg/waiter", + ], +) diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go new file mode 100644 index 000000000..028d6766f --- /dev/null +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -0,0 +1,145 @@ +// Copyright 2018 Google Inc. +// +// 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 fasync provides FIOASYNC related functionality. +package fasync + +import ( + "sync" + + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +// New creates a new FileAsync. +func New() fs.FileAsync { + return &FileAsync{} +} + +// FileAsync sends signals when the registered file is ready for IO. +type FileAsync struct { + mu sync.Mutex + e waiter.Entry + requester auth.Credentials + + // Only one of the following is allowed to be non-nil. + recipientPG *kernel.ProcessGroup + recipientTG *kernel.ThreadGroup + recipientT *kernel.Task +} + +// Callback sends a signal. +func (a *FileAsync) Callback(e *waiter.Entry) { + a.mu.Lock() + if a.e.Callback == nil { + return + } + t := a.recipientT + tg := a.recipientTG + if a.recipientPG != nil { + tg = a.recipientPG.Originator() + } + if tg != nil { + t = tg.Leader() + } + c := t.Credentials() + // Logic from sigio_perm in fs/fcntl.c. + if a.requester.EffectiveKUID == 0 || + a.requester.EffectiveKUID == c.SavedKUID || + a.requester.EffectiveKUID == c.RealKUID || + a.requester.RealKUID == c.SavedKUID || + a.requester.RealKUID == c.RealKUID { + t.SendSignal(&arch.SignalInfo{ + Signo: int32(linux.SIGIO), + // SEND_SIG_PRIV + Code: arch.SignalInfoKernel, + }) + } + a.mu.Unlock() +} + +// Register sets the file which will be monitored for IO events. +// +// The file must not be currently registered. +func (a *FileAsync) Register(w waiter.Waitable) { + a.mu.Lock() + defer a.mu.Unlock() + + if a.e.Callback != nil { + panic("registering already registered file") + } + + a.e.Callback = a + w.EventRegister(&a.e, waiter.EventIn|waiter.EventOut|waiter.EventErr|waiter.EventHUp) +} + +// Unregister stops monitoring a file. +// +// The file must be currently registered. +func (a *FileAsync) Unregister(w waiter.Waitable) { + a.mu.Lock() + defer a.mu.Unlock() + + if a.e.Callback == nil { + panic("unregistering unregistered file") + } + + w.EventUnregister(&a.e) + a.e.Callback = nil +} + +// Owner returns who is currently getting signals. All return values will be +// nil if no one is set to receive signals. +func (a *FileAsync) Owner() (*kernel.Task, *kernel.ThreadGroup, *kernel.ProcessGroup) { + a.mu.Lock() + defer a.mu.Unlock() + return a.recipientT, a.recipientTG, a.recipientPG +} + +// SetOwnerTask sets the owner (who will receive signals) to a specified task. +// Only this owner will receive signals. +func (a *FileAsync) SetOwnerTask(requester *kernel.Task, recipient *kernel.Task) { + a.mu.Lock() + defer a.mu.Unlock() + a.requester = requester.Credentials() + a.recipientT = recipient + a.recipientTG = nil + a.recipientPG = nil +} + +// SetOwnerThreadGroup sets the owner (who will receive signals) to a specified +// thread group. Only this owner will receive signals. +func (a *FileAsync) SetOwnerThreadGroup(requester *kernel.Task, recipient *kernel.ThreadGroup) { + a.mu.Lock() + defer a.mu.Unlock() + a.requester = requester.Credentials() + a.recipientT = nil + a.recipientTG = recipient + a.recipientPG = nil +} + +// SetOwnerProcessGroup sets the owner (who will receive signals) to a +// specified process group. Only this owner will receive signals. +func (a *FileAsync) SetOwnerProcessGroup(requester *kernel.Task, recipient *kernel.ProcessGroup) { + a.mu.Lock() + defer a.mu.Unlock() + a.requester = requester.Credentials() + a.recipientT = nil + a.recipientTG = nil + a.recipientPG = recipient +} diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index 53d8fb844..fa4c7b8f6 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -110,6 +110,11 @@ type ProcessGroup struct { processGroupEntry } +// Originator retuns the originator of the process group. +func (pg *ProcessGroup) Originator() *ThreadGroup { + return pg.originator +} + // incRefWithParent grabs a reference. // // This function is called when this ProcessGroup is being associated with some diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 7cfd37fb1..d3f3cc459 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -82,6 +82,7 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/epoll", "//pkg/sentry/kernel/eventfd", + "//pkg/sentry/kernel/fasync", "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/pipe", "//pkg/sentry/kernel/sched", diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index 82bfd7c2a..3d39a20f4 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -61,6 +61,9 @@ func flagsToLinux(flags fs.FileFlags) (mask uint) { if flags.Directory { mask |= syscall.O_DIRECTORY } + if flags.Async { + mask |= syscall.O_ASYNC + } switch { case flags.Read && flags.Write: mask |= syscall.O_RDWR @@ -82,6 +85,7 @@ func linuxToFlags(mask uint) (flags fs.FileFlags) { Write: (mask & syscall.O_ACCMODE) != syscall.O_RDONLY, Append: mask&syscall.O_APPEND != 0, Directory: mask&syscall.O_DIRECTORY != 0, + Async: mask&syscall.O_ASYNC != 0, } } @@ -91,5 +95,6 @@ func linuxToSettableFlags(mask uint) fs.SettableFileFlags { Direct: mask&syscall.O_DIRECT != 0, NonBlocking: mask&syscall.O_NONBLOCK != 0, Append: mask&syscall.O_APPEND != 0, + Async: mask&syscall.O_ASYNC != 0, } } diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index e2980842f..490649f87 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -25,6 +25,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/fs/lock" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/fasync" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" @@ -528,6 +529,33 @@ func Ioctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall file.SetFlags(flags.Settable()) return 0, nil, nil + case linux.FIOASYNC: + var set int32 + if _, err := t.CopyIn(args[2].Pointer(), &set); err != nil { + return 0, nil, err + } + flags := file.Flags() + if set != 0 { + flags.Async = true + } else { + flags.Async = false + } + file.SetFlags(flags.Settable()) + return 0, nil, nil + + case linux.FIOSETOWN, linux.SIOCSPGRP: + var set int32 + if _, err := t.CopyIn(args[2].Pointer(), &set); err != nil { + return 0, nil, err + } + fSetOwn(t, file, set) + return 0, nil, nil + + case linux.FIOGETOWN, linux.SIOCGPGRP: + who := fGetOwn(t, file) + _, err := t.CopyOut(args[2].Pointer(), &who) + return 0, nil, err + default: ret, err := file.FileOperations.Ioctl(t, t.MemoryManager(), args) if err != nil { @@ -725,6 +753,39 @@ func Dup3(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC return uintptr(newfd), nil, nil } +func fGetOwn(t *kernel.Task, file *fs.File) int32 { + ma := file.Async(nil) + if ma == nil { + return 0 + } + a := ma.(*fasync.FileAsync) + ot, otg, opg := a.Owner() + switch { + case ot != nil: + return int32(t.PIDNamespace().IDOfTask(ot)) + case otg != nil: + return int32(t.PIDNamespace().IDOfThreadGroup(otg)) + case opg != nil: + return int32(-t.PIDNamespace().IDOfProcessGroup(opg)) + default: + return 0 + } +} + +// fSetOwn sets the file's owner with the semantics of F_SETOWN in Linux. +// +// If who is positive, it represents a PID. If negative, it represents a PGID. +// If the PID or PGID is invalid, the owner is silently unset. +func fSetOwn(t *kernel.Task, file *fs.File, who int32) { + a := file.Async(fasync.New).(*fasync.FileAsync) + if who < 0 { + pg := t.PIDNamespace().ProcessGroupWithID(kernel.ProcessGroupID(-who)) + a.SetOwnerProcessGroup(t, pg) + } + tg := t.PIDNamespace().ThreadGroupWithID(kernel.ThreadID(who)) + a.SetOwnerThreadGroup(t, tg) +} + // Fcntl implements linux syscall fcntl(2). func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { fd := kdefs.FD(args[0].Int()) @@ -737,7 +798,7 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall defer file.DecRef() switch cmd { - case syscall.F_DUPFD, syscall.F_DUPFD_CLOEXEC: + case linux.F_DUPFD, linux.F_DUPFD_CLOEXEC: from := kdefs.FD(args[2].Int()) fdFlags := kernel.FDFlags{CloseOnExec: cmd == syscall.F_DUPFD_CLOEXEC} fd, err := t.FDMap().NewFDFrom(from, file, fdFlags, t.ThreadGroup().Limits()) @@ -745,19 +806,19 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall return 0, nil, err } return uintptr(fd), nil, nil - case syscall.F_GETFD: + case linux.F_GETFD: return uintptr(fdFlagsToLinux(flags)), nil, nil - case syscall.F_SETFD: + case linux.F_SETFD: flags := args[2].Uint() t.FDMap().SetFlags(fd, kernel.FDFlags{ CloseOnExec: flags&syscall.FD_CLOEXEC != 0, }) - case syscall.F_GETFL: + case linux.F_GETFL: return uintptr(flagsToLinux(file.Flags())), nil, nil - case syscall.F_SETFL: + case linux.F_SETFL: flags := uint(args[2].Uint()) file.SetFlags(linuxToSettableFlags(flags)) - case syscall.F_SETLK, syscall.F_SETLKW: + case linux.F_SETLK, linux.F_SETLKW: // In Linux the file system can choose to provide lock operations for an inode. // Normally pipe and socket types lack lock operations. We diverge and use a heavy // hammer by only allowing locks on files and directories. @@ -854,6 +915,11 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall default: return 0, nil, syserror.EINVAL } + case linux.F_GETOWN: + return uintptr(fGetOwn(t, file)), nil, nil + case linux.F_SETOWN: + fSetOwn(t, file, args[2].Int()) + return 0, nil, nil default: // Everything else is not yet supported. return 0, nil, syserror.EINVAL -- cgit v1.2.3 From b9c469f37282129031a6036cfe43028faaeb1a96 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Wed, 11 Jul 2018 14:23:17 -0700 Subject: Move ptrace constants to abi/linux. PiperOrigin-RevId: 204188763 Change-Id: I5596ab7abb3ec9e210a7f57b3fc420e836fa43f3 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/ptrace.go | 89 ++++++++++++++++++++++++++++++++++++ pkg/sentry/kernel/ptrace.go | 108 ++++++++++++++++++++------------------------ pkg/sentry/strace/ptrace.go | 80 ++++++++++++++++---------------- 4 files changed, 179 insertions(+), 99 deletions(-) create mode 100644 pkg/abi/linux/ptrace.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 5d00b66cc..e164945cf 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -48,6 +48,7 @@ go_library( "netlink_route.go", "poll.go", "prctl.go", + "ptrace.go", "rusage.go", "sched.go", "seccomp.go", diff --git a/pkg/abi/linux/ptrace.go b/pkg/abi/linux/ptrace.go new file mode 100644 index 000000000..ba48d4d6d --- /dev/null +++ b/pkg/abi/linux/ptrace.go @@ -0,0 +1,89 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// ptrace commands from include/uapi/linux/ptrace.h. +const ( + PTRACE_TRACEME = 0 + PTRACE_PEEKTEXT = 1 + PTRACE_PEEKDATA = 2 + PTRACE_PEEKUSR = 3 + PTRACE_POKETEXT = 4 + PTRACE_POKEDATA = 5 + PTRACE_POKEUSR = 6 + PTRACE_CONT = 7 + PTRACE_KILL = 8 + PTRACE_SINGLESTEP = 9 + PTRACE_ATTACH = 16 + PTRACE_DETACH = 17 + PTRACE_SYSCALL = 24 + PTRACE_SETOPTIONS = 0x4200 + PTRACE_GETEVENTMSG = 0x4201 + PTRACE_GETSIGINFO = 0x4202 + PTRACE_SETSIGINFO = 0x4203 + PTRACE_GETREGSET = 0x4204 + PTRACE_SETREGSET = 0x4205 + PTRACE_SEIZE = 0x4206 + PTRACE_INTERRUPT = 0x4207 + PTRACE_LISTEN = 0x4208 + PTRACE_PEEKSIGINFO = 0x4209 + PTRACE_GETSIGMASK = 0x420a + PTRACE_SETSIGMASK = 0x420b + PTRACE_SECCOMP_GET_FILTER = 0x420c + PTRACE_SECCOMP_GET_METADATA = 0x420d +) + +// ptrace commands from arch/x86/include/uapi/asm/ptrace-abi.h. +const ( + PTRACE_GETREGS = 12 + PTRACE_SETREGS = 13 + PTRACE_GETFPREGS = 14 + PTRACE_SETFPREGS = 15 + PTRACE_GETFPXREGS = 18 + PTRACE_SETFPXREGS = 19 + PTRACE_OLDSETOPTIONS = 21 + PTRACE_GET_THREAD_AREA = 25 + PTRACE_SET_THREAD_AREA = 26 + PTRACE_ARCH_PRCTL = 30 + PTRACE_SYSEMU = 31 + PTRACE_SYSEMU_SINGLESTEP = 32 + PTRACE_SINGLEBLOCK = 33 +) + +// ptrace event codes from include/uapi/linux/ptrace.h. +const ( + PTRACE_EVENT_FORK = 1 + PTRACE_EVENT_VFORK = 2 + PTRACE_EVENT_CLONE = 3 + PTRACE_EVENT_EXEC = 4 + PTRACE_EVENT_VFORK_DONE = 5 + PTRACE_EVENT_EXIT = 6 + PTRACE_EVENT_SECCOMP = 7 + PTRACE_EVENT_STOP = 128 +) + +// PTRACE_SETOPTIONS options from include/uapi/linux/ptrace.h. +const ( + PTRACE_O_TRACESYSGOOD = 1 + PTRACE_O_TRACEFORK = 1 << PTRACE_EVENT_FORK + PTRACE_O_TRACEVFORK = 1 << PTRACE_EVENT_VFORK + PTRACE_O_TRACECLONE = 1 << PTRACE_EVENT_CLONE + PTRACE_O_TRACEEXEC = 1 << PTRACE_EVENT_EXEC + PTRACE_O_TRACEVFORKDONE = 1 << PTRACE_EVENT_VFORK_DONE + PTRACE_O_TRACEEXIT = 1 << PTRACE_EVENT_EXIT + PTRACE_O_TRACESECCOMP = 1 << PTRACE_EVENT_SECCOMP + PTRACE_O_EXITKILL = 1 << 20 + PTRACE_O_SUSPEND_SECCOMP = 1 << 21 +) diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 20b1c4cd4..f1c2c4bf0 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -16,7 +16,6 @@ package kernel import ( "fmt" - "syscall" "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" @@ -24,19 +23,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/syserror" ) -// ptrace constants from Linux's include/uapi/linux/ptrace.h. -const ( - _PTRACE_EVENT_SECCOMP = 7 - PTRACE_SEIZE = 0x4206 - PTRACE_INTERRUPT = 0x4207 - PTRACE_LISTEN = 0x4208 - PTRACE_PEEKSIGINFO = 0x4209 - PTRACE_GETSIGMASK = 0x420a - PTRACE_SETSIGMASK = 0x420b - _PTRACE_O_EXITKILL = 1 << 20 - _PTRACE_O_TRACESECCOMP = 1 << _PTRACE_EVENT_SECCOMP -) - // ptraceOptions are the subset of options controlling a task's ptrace behavior // that are set by ptrace(PTRACE_SETOPTIONS). type ptraceOptions struct { @@ -505,7 +491,7 @@ func (t *Task) ptraceSeccomp(data uint16) bool { return false } t.Debugf("Entering PTRACE_EVENT_SECCOMP stop") - t.ptraceEventLocked(_PTRACE_EVENT_SECCOMP, uint64(data)) + t.ptraceEventLocked(linux.PTRACE_EVENT_SECCOMP, uint64(data)) return true } @@ -587,19 +573,19 @@ func (t *Task) ptraceClone(kind ptraceCloneKind, child *Task, opts *CloneOptions case ptraceCloneKindClone: if t.ptraceOpts.TraceClone { t.Debugf("Entering PTRACE_EVENT_CLONE stop") - t.ptraceEventLocked(syscall.PTRACE_EVENT_CLONE, uint64(t.tg.pidns.tids[child])) + t.ptraceEventLocked(linux.PTRACE_EVENT_CLONE, uint64(t.tg.pidns.tids[child])) event = true } case ptraceCloneKindFork: if t.ptraceOpts.TraceFork { t.Debugf("Entering PTRACE_EVENT_FORK stop") - t.ptraceEventLocked(syscall.PTRACE_EVENT_FORK, uint64(t.tg.pidns.tids[child])) + t.ptraceEventLocked(linux.PTRACE_EVENT_FORK, uint64(t.tg.pidns.tids[child])) event = true } case ptraceCloneKindVfork: if t.ptraceOpts.TraceVfork { t.Debugf("Entering PTRACE_EVENT_VFORK stop") - t.ptraceEventLocked(syscall.PTRACE_EVENT_VFORK, uint64(t.tg.pidns.tids[child])) + t.ptraceEventLocked(linux.PTRACE_EVENT_VFORK, uint64(t.tg.pidns.tids[child])) event = true } default: @@ -657,7 +643,7 @@ func (t *Task) ptraceVforkDone(child ThreadID) bool { return false } t.Debugf("Entering PTRACE_EVENT_VFORK_DONE stop") - t.ptraceEventLocked(syscall.PTRACE_EVENT_VFORK_DONE, uint64(child)) + t.ptraceEventLocked(linux.PTRACE_EVENT_VFORK_DONE, uint64(child)) return true } @@ -680,7 +666,7 @@ func (t *Task) ptraceExec(oldTID ThreadID) { } if t.ptraceOpts.TraceExec { t.Debugf("Entering PTRACE_EVENT_EXEC stop") - t.ptraceEventLocked(syscall.PTRACE_EVENT_EXEC, uint64(oldTID)) + t.ptraceEventLocked(linux.PTRACE_EVENT_EXEC, uint64(oldTID)) return } // "If the PTRACE_O_TRACEEXEC option is not in effect for the execing @@ -714,7 +700,7 @@ func (t *Task) ptraceExit() { status := t.exitStatus.Status() t.tg.signalHandlers.mu.Unlock() t.Debugf("Entering PTRACE_EVENT_EXIT stop") - t.ptraceEventLocked(syscall.PTRACE_EVENT_EXIT, uint64(status)) + t.ptraceEventLocked(linux.PTRACE_EVENT_EXIT, uint64(status)) } // Preconditions: The TaskSet mutex must be locked. @@ -762,7 +748,7 @@ func (t *Task) ptraceKill(target *Task) error { // Ptrace implements the ptrace system call. func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { // PTRACE_TRACEME ignores all other arguments. - if req == syscall.PTRACE_TRACEME { + if req == linux.PTRACE_TRACEME { return t.ptraceTraceme() } // All other ptrace requests operate on a current or future tracee @@ -774,12 +760,12 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { // PTRACE_ATTACH (and PTRACE_SEIZE, which is unimplemented) do not require // that target is not already a tracee. - if req == syscall.PTRACE_ATTACH { + if req == linux.PTRACE_ATTACH { return t.ptraceAttach(target) } // PTRACE_KILL (and PTRACE_INTERRUPT, which is unimplemented) require that // the target is a tracee, but does not require that it is ptrace-stopped. - if req == syscall.PTRACE_KILL { + if req == linux.PTRACE_KILL { return t.ptraceKill(target) } // All other ptrace requests require that the target is a ptrace-stopped @@ -812,37 +798,37 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { // Resuming commands end the ptrace stop, but only if successful. switch req { - case syscall.PTRACE_DETACH: + case linux.PTRACE_DETACH: if err := t.ptraceDetach(target, linux.Signal(data)); err != nil { target.ptraceUnfreeze() return err } return nil - case syscall.PTRACE_CONT: + case linux.PTRACE_CONT: if err := target.ptraceUnstop(ptraceSyscallNone, false, linux.Signal(data)); err != nil { target.ptraceUnfreeze() return err } return nil - case syscall.PTRACE_SYSCALL: + case linux.PTRACE_SYSCALL: if err := target.ptraceUnstop(ptraceSyscallIntercept, false, linux.Signal(data)); err != nil { target.ptraceUnfreeze() return err } return nil - case syscall.PTRACE_SINGLESTEP: + case linux.PTRACE_SINGLESTEP: if err := target.ptraceUnstop(ptraceSyscallNone, true, linux.Signal(data)); err != nil { target.ptraceUnfreeze() return err } return nil - case syscall.PTRACE_SYSEMU: + case linux.PTRACE_SYSEMU: if err := target.ptraceUnstop(ptraceSyscallEmu, false, linux.Signal(data)); err != nil { target.ptraceUnfreeze() return err } return nil - case syscall.PTRACE_SYSEMU_SINGLESTEP: + case linux.PTRACE_SYSEMU_SINGLESTEP: if err := target.ptraceUnstop(ptraceSyscallEmu, true, linux.Signal(data)); err != nil { target.ptraceUnfreeze() return err @@ -853,7 +839,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { defer target.ptraceUnfreeze() switch req { - case syscall.PTRACE_PEEKTEXT, syscall.PTRACE_PEEKDATA: + case linux.PTRACE_PEEKTEXT, linux.PTRACE_PEEKDATA: // "At the system call level, the PTRACE_PEEKTEXT, PTRACE_PEEKDATA, and // PTRACE_PEEKUSER requests have a different API: they store the result // at the address specified by the data parameter, and the return value @@ -867,13 +853,13 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { _, err := t.CopyOut(data, word) return err - case syscall.PTRACE_POKETEXT, syscall.PTRACE_POKEDATA: + case linux.PTRACE_POKETEXT, linux.PTRACE_POKEDATA: _, err := usermem.CopyObjectOut(t, target.MemoryManager(), addr, t.Arch().Native(uintptr(data)), usermem.IOOpts{ IgnorePermissions: true, }) return err - case syscall.PTRACE_PEEKUSR: // aka PTRACE_PEEKUSER + case linux.PTRACE_PEEKUSR: // aka PTRACE_PEEKUSER n, err := target.Arch().PtracePeekUser(uintptr(addr)) if err != nil { return err @@ -881,10 +867,10 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { _, err = t.CopyOut(data, n) return err - case syscall.PTRACE_POKEUSR: // aka PTRACE_POKEUSER + case linux.PTRACE_POKEUSR: // aka PTRACE_POKEUSER return target.Arch().PtracePokeUser(uintptr(addr), uintptr(data)) - case syscall.PTRACE_GETREGS: + case linux.PTRACE_GETREGS: // "Copy the tracee's general-purpose ... registers ... to the address // data in the tracer. ... (addr is ignored.) Note that SPARC systems // have the meaning of data and addr reversed ..." @@ -898,7 +884,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { }) return err - case syscall.PTRACE_GETFPREGS: + case linux.PTRACE_GETFPREGS: _, err := target.Arch().PtraceGetFPRegs(&usermem.IOReadWriter{ Ctx: t, IO: t.MemoryManager(), @@ -909,7 +895,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { }) return err - case syscall.PTRACE_GETREGSET: + case linux.PTRACE_GETREGSET: // "Read the tracee's registers. addr specifies, in an // architecture-dependent way, the type of registers to be read. ... // data points to a struct iovec, which describes the destination @@ -934,7 +920,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { ar.End -= usermem.Addr(n) return t.CopyOutIovecs(data, usermem.AddrRangeSeqOf(ar)) - case syscall.PTRACE_SETREGS: + case linux.PTRACE_SETREGS: _, err := target.Arch().PtraceSetRegs(&usermem.IOReadWriter{ Ctx: t, IO: t.MemoryManager(), @@ -945,7 +931,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { }) return err - case syscall.PTRACE_SETFPREGS: + case linux.PTRACE_SETFPREGS: _, err := target.Arch().PtraceSetFPRegs(&usermem.IOReadWriter{ Ctx: t, IO: t.MemoryManager(), @@ -956,7 +942,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { }) return err - case syscall.PTRACE_SETREGSET: + case linux.PTRACE_SETREGSET: ars, err := t.CopyInIovecs(data, 1) if err != nil { return err @@ -976,7 +962,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { ar.End -= usermem.Addr(n) return t.CopyOutIovecs(data, usermem.AddrRangeSeqOf(ar)) - case syscall.PTRACE_GETSIGINFO: + case linux.PTRACE_GETSIGINFO: t.tg.pidns.owner.mu.RLock() defer t.tg.pidns.owner.mu.RUnlock() if target.ptraceSiginfo == nil { @@ -985,7 +971,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { _, err := t.CopyOut(data, target.ptraceSiginfo) return err - case syscall.PTRACE_SETSIGINFO: + case linux.PTRACE_SETSIGINFO: var info arch.SignalInfo if _, err := t.CopyIn(data, &info); err != nil { return err @@ -998,7 +984,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { target.ptraceSiginfo = &info return nil - case PTRACE_GETSIGMASK: + case linux.PTRACE_GETSIGMASK: if addr != linux.SignalSetSize { return syserror.EINVAL } @@ -1007,7 +993,7 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { _, err := t.CopyOut(data, target.tr.SignalMask) return err - case PTRACE_SETSIGMASK: + case linux.PTRACE_SETSIGMASK: if addr != linux.SignalSetSize { return syserror.EINVAL } @@ -1019,29 +1005,35 @@ func (t *Task) Ptrace(req int64, pid ThreadID, addr, data usermem.Addr) error { target.SetSignalMask(mask &^ UnblockableSignals) return nil - case syscall.PTRACE_SETOPTIONS: + case linux.PTRACE_SETOPTIONS: t.tg.pidns.owner.mu.Lock() defer t.tg.pidns.owner.mu.Unlock() - validOpts := uintptr(_PTRACE_O_EXITKILL | syscall.PTRACE_O_TRACESYSGOOD | syscall.PTRACE_O_TRACECLONE | - syscall.PTRACE_O_TRACEEXEC | syscall.PTRACE_O_TRACEEXIT | syscall.PTRACE_O_TRACEFORK | - _PTRACE_O_TRACESECCOMP | syscall.PTRACE_O_TRACEVFORK | syscall.PTRACE_O_TRACEVFORKDONE) + validOpts := uintptr(linux.PTRACE_O_EXITKILL | + linux.PTRACE_O_TRACESYSGOOD | + linux.PTRACE_O_TRACECLONE | + linux.PTRACE_O_TRACEEXEC | + linux.PTRACE_O_TRACEEXIT | + linux.PTRACE_O_TRACEFORK | + linux.PTRACE_O_TRACESECCOMP | + linux.PTRACE_O_TRACEVFORK | + linux.PTRACE_O_TRACEVFORKDONE) if uintptr(data)&^validOpts != 0 { return syserror.EINVAL } target.ptraceOpts = ptraceOptions{ - ExitKill: data&_PTRACE_O_EXITKILL != 0, - SysGood: data&syscall.PTRACE_O_TRACESYSGOOD != 0, - TraceClone: data&syscall.PTRACE_O_TRACECLONE != 0, - TraceExec: data&syscall.PTRACE_O_TRACEEXEC != 0, - TraceExit: data&syscall.PTRACE_O_TRACEEXIT != 0, - TraceFork: data&syscall.PTRACE_O_TRACEFORK != 0, - TraceSeccomp: data&_PTRACE_O_TRACESECCOMP != 0, - TraceVfork: data&syscall.PTRACE_O_TRACEVFORK != 0, - TraceVforkDone: data&syscall.PTRACE_O_TRACEVFORKDONE != 0, + ExitKill: data&linux.PTRACE_O_EXITKILL != 0, + SysGood: data&linux.PTRACE_O_TRACESYSGOOD != 0, + TraceClone: data&linux.PTRACE_O_TRACECLONE != 0, + TraceExec: data&linux.PTRACE_O_TRACEEXEC != 0, + TraceExit: data&linux.PTRACE_O_TRACEEXIT != 0, + TraceFork: data&linux.PTRACE_O_TRACEFORK != 0, + TraceSeccomp: data&linux.PTRACE_O_TRACESECCOMP != 0, + TraceVfork: data&linux.PTRACE_O_TRACEVFORK != 0, + TraceVforkDone: data&linux.PTRACE_O_TRACEVFORKDONE != 0, } return nil - case syscall.PTRACE_GETEVENTMSG: + case linux.PTRACE_GETEVENTMSG: t.tg.pidns.owner.mu.RLock() defer t.tg.pidns.owner.mu.RUnlock() _, err := t.CopyOut(usermem.Addr(data), target.ptraceEventMsg) diff --git a/pkg/sentry/strace/ptrace.go b/pkg/sentry/strace/ptrace.go index a0dabb27a..fcdb7e9f4 100644 --- a/pkg/sentry/strace/ptrace.go +++ b/pkg/sentry/strace/ptrace.go @@ -15,164 +15,162 @@ package strace import ( - "syscall" - "gvisor.googlesource.com/gvisor/pkg/abi" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" ) // PtraceRequestSet are the possible ptrace(2) requests. var PtraceRequestSet = abi.ValueSet{ { - Value: syscall.PTRACE_TRACEME, + Value: linux.PTRACE_TRACEME, Name: "PTRACE_TRACEME", }, { - Value: syscall.PTRACE_PEEKTEXT, + Value: linux.PTRACE_PEEKTEXT, Name: "PTRACE_PEEKTEXT", }, { - Value: syscall.PTRACE_PEEKDATA, + Value: linux.PTRACE_PEEKDATA, Name: "PTRACE_PEEKDATA", }, { - Value: syscall.PTRACE_PEEKUSR, + Value: linux.PTRACE_PEEKUSR, Name: "PTRACE_PEEKUSR", }, { - Value: syscall.PTRACE_POKETEXT, + Value: linux.PTRACE_POKETEXT, Name: "PTRACE_POKETEXT", }, { - Value: syscall.PTRACE_POKEDATA, + Value: linux.PTRACE_POKEDATA, Name: "PTRACE_POKEDATA", }, { - Value: syscall.PTRACE_POKEUSR, + Value: linux.PTRACE_POKEUSR, Name: "PTRACE_POKEUSR", }, { - Value: syscall.PTRACE_CONT, + Value: linux.PTRACE_CONT, Name: "PTRACE_CONT", }, { - Value: syscall.PTRACE_KILL, + Value: linux.PTRACE_KILL, Name: "PTRACE_KILL", }, { - Value: syscall.PTRACE_SINGLESTEP, + Value: linux.PTRACE_SINGLESTEP, Name: "PTRACE_SINGLESTEP", }, { - Value: syscall.PTRACE_ATTACH, + Value: linux.PTRACE_ATTACH, Name: "PTRACE_ATTACH", }, { - Value: syscall.PTRACE_DETACH, + Value: linux.PTRACE_DETACH, Name: "PTRACE_DETACH", }, { - Value: syscall.PTRACE_SYSCALL, + Value: linux.PTRACE_SYSCALL, Name: "PTRACE_SYSCALL", }, { - Value: syscall.PTRACE_SETOPTIONS, + Value: linux.PTRACE_SETOPTIONS, Name: "PTRACE_SETOPTIONS", }, { - Value: syscall.PTRACE_GETEVENTMSG, + Value: linux.PTRACE_GETEVENTMSG, Name: "PTRACE_GETEVENTMSG", }, { - Value: syscall.PTRACE_GETSIGINFO, + Value: linux.PTRACE_GETSIGINFO, Name: "PTRACE_GETSIGINFO", }, { - Value: syscall.PTRACE_SETSIGINFO, + Value: linux.PTRACE_SETSIGINFO, Name: "PTRACE_SETSIGINFO", }, { - Value: syscall.PTRACE_GETREGSET, + Value: linux.PTRACE_GETREGSET, Name: "PTRACE_GETREGSET", }, { - Value: syscall.PTRACE_SETREGSET, + Value: linux.PTRACE_SETREGSET, Name: "PTRACE_SETREGSET", }, { - Value: kernel.PTRACE_SEIZE, + Value: linux.PTRACE_SEIZE, Name: "PTRACE_SEIZE", }, { - Value: kernel.PTRACE_INTERRUPT, + Value: linux.PTRACE_INTERRUPT, Name: "PTRACE_INTERRUPT", }, { - Value: kernel.PTRACE_LISTEN, + Value: linux.PTRACE_LISTEN, Name: "PTRACE_LISTEN", }, { - Value: kernel.PTRACE_PEEKSIGINFO, + Value: linux.PTRACE_PEEKSIGINFO, Name: "PTRACE_PEEKSIGINFO", }, { - Value: kernel.PTRACE_GETSIGMASK, + Value: linux.PTRACE_GETSIGMASK, Name: "PTRACE_GETSIGMASK", }, { - Value: kernel.PTRACE_SETSIGMASK, + Value: linux.PTRACE_SETSIGMASK, Name: "PTRACE_SETSIGMASK", }, { - Value: syscall.PTRACE_GETREGS, + Value: linux.PTRACE_GETREGS, Name: "PTRACE_GETREGS", }, { - Value: syscall.PTRACE_SETREGS, + Value: linux.PTRACE_SETREGS, Name: "PTRACE_SETREGS", }, { - Value: syscall.PTRACE_GETFPREGS, + Value: linux.PTRACE_GETFPREGS, Name: "PTRACE_GETFPREGS", }, { - Value: syscall.PTRACE_SETFPREGS, + Value: linux.PTRACE_SETFPREGS, Name: "PTRACE_SETFPREGS", }, { - Value: syscall.PTRACE_GETFPXREGS, + Value: linux.PTRACE_GETFPXREGS, Name: "PTRACE_GETFPXREGS", }, { - Value: syscall.PTRACE_SETFPXREGS, + Value: linux.PTRACE_SETFPXREGS, Name: "PTRACE_SETFPXREGS", }, { - Value: syscall.PTRACE_OLDSETOPTIONS, + Value: linux.PTRACE_OLDSETOPTIONS, Name: "PTRACE_OLDSETOPTIONS", }, { - Value: syscall.PTRACE_GET_THREAD_AREA, + Value: linux.PTRACE_GET_THREAD_AREA, Name: "PTRACE_GET_THREAD_AREA", }, { - Value: syscall.PTRACE_SET_THREAD_AREA, + Value: linux.PTRACE_SET_THREAD_AREA, Name: "PTRACE_SET_THREAD_AREA", }, { - Value: syscall.PTRACE_ARCH_PRCTL, + Value: linux.PTRACE_ARCH_PRCTL, Name: "PTRACE_ARCH_PRCTL", }, { - Value: syscall.PTRACE_SYSEMU, + Value: linux.PTRACE_SYSEMU, Name: "PTRACE_SYSEMU", }, { - Value: syscall.PTRACE_SYSEMU_SINGLESTEP, + Value: linux.PTRACE_SYSEMU_SINGLESTEP, Name: "PTRACE_SYSEMU_SINGLESTEP", }, { - Value: syscall.PTRACE_SINGLEBLOCK, + Value: linux.PTRACE_SINGLEBLOCK, Name: "PTRACE_SINGLEBLOCK", }, } -- cgit v1.2.3 From 8f21c0bb2807888d812318def43c2405c9b13f5a Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Mon, 16 Jul 2018 12:19:02 -0700 Subject: Add EventOperations.HostFD() This method allows an eventfd inside the Sentry to be registered with with the host kernel. Update comment about memory mapping host fds via CachingInodeOperations. PiperOrigin-RevId: 204784859 Change-Id: I55823321e2d84c17ae0f7efaabc6b55b852ae257 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/eventfd.go | 22 +++++++ pkg/sentry/fs/fsutil/inode_cached.go | 3 +- pkg/sentry/kernel/eventfd/BUILD | 2 + pkg/sentry/kernel/eventfd/eventfd.go | 119 +++++++++++++++++++++++++++++++++-- 5 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 pkg/abi/linux/eventfd.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index e164945cf..ae7e4378c 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -30,6 +30,7 @@ go_library( "dev.go", "elf.go", "errors.go", + "eventfd.go", "exec.go", "fcntl.go", "file.go", diff --git a/pkg/abi/linux/eventfd.go b/pkg/abi/linux/eventfd.go new file mode 100644 index 000000000..bc0fb44d2 --- /dev/null +++ b/pkg/abi/linux/eventfd.go @@ -0,0 +1,22 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Constants for eventfd2(2). +const ( + EFD_SEMAPHORE = 0x1 + EFD_CLOEXEC = O_CLOEXEC + EFD_NONBLOCK = O_NONBLOCK +) diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index 7c0f96ac2..cba642a8f 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -44,8 +44,7 @@ import ( // // CachingInodeOperations implements Mappable for the CachedFileObject: // -// - If CachedFileObject.FD returns a value >= 0 and the current platform shares -// a host fd table with the sentry, then the value of CachedFileObject.FD +// - If CachedFileObject.FD returns a value >= 0 then the file descriptor // will be memory mapped on the host. // // - Otherwise, the contents of CachedFileObject are buffered into memory diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index 2d5a3c693..561ced852 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -21,6 +21,7 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/eventfd", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/abi/linux", "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -30,6 +31,7 @@ go_library( "//pkg/state", "//pkg/syserror", "//pkg/waiter", + "//pkg/waiter/fdnotifier", ], ) diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index c9333719e..bd50bd9fe 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -21,6 +21,7 @@ import ( "sync" "syscall" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/anon" @@ -28,10 +29,12 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/waiter" + "gvisor.googlesource.com/gvisor/pkg/waiter/fdnotifier" ) // EventOperations represents an event with the semantics of Linux's file-based event -// notification (eventfd). +// notification (eventfd). Eventfds are usually internal to the Sentry but in certain +// situations they may be converted into a host-backed eventfd. type EventOperations struct { fsutil.NoopRelease `state:"nosave"` fsutil.PipeSeek `state:"nosave"` @@ -46,13 +49,16 @@ type EventOperations struct { // Queue is used to notify interested parties when the event object // becomes readable or writable. - waiter.Queue `state:"nosave"` + wq waiter.Queue `state:"nosave"` // val is the current value of the event counter. val uint64 // semMode specifies whether the event is in "semaphore" mode. semMode bool + + // hostfd indicates whether this eventfd is passed through to the host. + hostfd int } // New creates a new event object with the supplied initial value and mode. @@ -62,9 +68,48 @@ func New(ctx context.Context, initVal uint64, semMode bool) *fs.File { return fs.NewFile(ctx, dirent, fs.FileFlags{Read: true, Write: true}, &EventOperations{ val: initVal, semMode: semMode, + hostfd: -1, }) } +// HostFD returns the host eventfd associated with this event. +func (e *EventOperations) HostFD() (int, error) { + e.mu.Lock() + defer e.mu.Unlock() + if e.hostfd >= 0 { + return e.hostfd, nil + } + + flags := linux.EFD_NONBLOCK + if e.semMode { + flags |= linux.EFD_SEMAPHORE + } + + fd, _, err := syscall.Syscall(syscall.SYS_EVENTFD2, uintptr(e.val), uintptr(flags), 0) + if err != 0 { + return -1, err + } + + if err := fdnotifier.AddFD(int32(fd), &e.wq); err != nil { + syscall.Close(int(fd)) + return -1, err + } + + e.hostfd = int(fd) + return e.hostfd, nil +} + +// Release implements fs.FileOperations.Release. +func (e *EventOperations) Release() { + e.mu.Lock() + defer e.mu.Unlock() + if e.hostfd >= 0 { + fdnotifier.RemoveFD(int32(e.hostfd)) + syscall.Close(e.hostfd) + e.hostfd = -1 + } +} + // Read implements fs.FileOperations.Read. func (e *EventOperations) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, _ int64) (int64, error) { if dst.NumBytes() < 8 { @@ -87,9 +132,29 @@ func (e *EventOperations) Write(ctx context.Context, _ *fs.File, src usermem.IOS return 8, nil } +// Must be called with e.mu locked. +func (e *EventOperations) hostRead(ctx context.Context, dst usermem.IOSequence) error { + var buf [8]byte + + if _, err := syscall.Read(e.hostfd, buf[:]); err != nil { + if err == syscall.EWOULDBLOCK { + return syserror.ErrWouldBlock + } + return err + } + + _, err := dst.CopyOut(ctx, buf[:]) + return err +} + func (e *EventOperations) read(ctx context.Context, dst usermem.IOSequence) error { e.mu.Lock() + if e.hostfd >= 0 { + defer e.mu.Unlock() + return e.hostRead(ctx, dst) + } + // We can't complete the read if the value is currently zero. if e.val == 0 { e.mu.Unlock() @@ -112,7 +177,7 @@ func (e *EventOperations) read(ctx context.Context, dst usermem.IOSequence) erro // Notify writers. We do this even if we were already writable because // it is possible that a writer is waiting to write the maximum value // to the event. - e.Notify(waiter.EventOut) + e.wq.Notify(waiter.EventOut) var buf [8]byte usermem.ByteOrder.PutUint64(buf[:], val) @@ -120,6 +185,17 @@ func (e *EventOperations) read(ctx context.Context, dst usermem.IOSequence) erro return err } +// Must be called with e.mu locked. +func (e *EventOperations) hostWrite(val uint64) error { + var buf [8]byte + usermem.ByteOrder.PutUint64(buf[:], val) + _, err := syscall.Write(e.hostfd, buf[:]) + if err == syscall.EWOULDBLOCK { + return syserror.ErrWouldBlock + } + return err +} + func (e *EventOperations) write(ctx context.Context, src usermem.IOSequence) error { var buf [8]byte if _, err := src.CopyIn(ctx, buf[:]); err != nil { @@ -138,6 +214,11 @@ func (e *EventOperations) Signal(val uint64) error { e.mu.Lock() + if e.hostfd >= 0 { + defer e.mu.Unlock() + return e.hostWrite(val) + } + // We only allow writes that won't cause the value to go over the max // uint64 minus 1. if val > math.MaxUint64-1-e.val { @@ -149,16 +230,20 @@ func (e *EventOperations) Signal(val uint64) error { e.mu.Unlock() // Always trigger a notification. - e.Notify(waiter.EventIn) + e.wq.Notify(waiter.EventIn) return nil } // Readiness returns the ready events for the event fd. func (e *EventOperations) Readiness(mask waiter.EventMask) waiter.EventMask { - ready := waiter.EventMask(0) - e.mu.Lock() + if e.hostfd >= 0 { + defer e.mu.Unlock() + return fdnotifier.NonBlockingPoll(int32(e.hostfd), mask) + } + + ready := waiter.EventMask(0) if e.val > 0 { ready |= waiter.EventIn } @@ -170,3 +255,25 @@ func (e *EventOperations) Readiness(mask waiter.EventMask) waiter.EventMask { return mask & ready } + +// EventRegister implements waiter.Waitable.EventRegister. +func (e *EventOperations) EventRegister(entry *waiter.Entry, mask waiter.EventMask) { + e.wq.EventRegister(entry, mask) + + e.mu.Lock() + defer e.mu.Unlock() + if e.hostfd >= 0 { + fdnotifier.UpdateFD(int32(e.hostfd)) + } +} + +// EventUnregister implements waiter.Waitable.EventUnregister. +func (e *EventOperations) EventUnregister(entry *waiter.Entry) { + e.wq.EventUnregister(entry) + + e.mu.Lock() + defer e.mu.Unlock() + if e.hostfd >= 0 { + fdnotifier.UpdateFD(int32(e.hostfd)) + } +} -- cgit v1.2.3 From 29e00c943a61dfcfd4ac8d3f6f526eab641c44a6 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Mon, 16 Jul 2018 22:02:03 -0700 Subject: Add CPUID faulting for ptrace and KVM. PiperOrigin-RevId: 204858314 Change-Id: I8252bf8de3232a7a27af51076139b585e73276d4 --- pkg/abi/linux/prctl.go | 9 +++--- pkg/sentry/kernel/task_run.go | 41 ++++++++++++-------------- pkg/sentry/platform/kvm/machine.go | 22 +++++++------- pkg/sentry/platform/kvm/machine_amd64.go | 22 ++++++++++++++ pkg/sentry/platform/platform.go | 7 +++++ pkg/sentry/platform/ptrace/ptrace.go | 15 +++++++--- pkg/sentry/platform/ptrace/subprocess_linux.go | 5 ++++ pkg/sentry/platform/ring0/kernel_amd64.go | 22 +++++++++++++- pkg/sentry/platform/ring0/x86.go | 14 ++++++--- 9 files changed, 111 insertions(+), 46 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index 6c93601de..074ec03f0 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -65,8 +65,9 @@ const ( // From // Flags are used in syscall arch_prctl(2). const ( - ARCH_SET_GS = 0x1001 - ARCH_SET_FS = 0x1002 - ARCH_GET_FS = 0x1003 - ARCH_GET_GS = 0x1004 + ARCH_SET_GS = 0x1001 + ARCH_SET_FS = 0x1002 + ARCH_GET_FS = 0x1003 + ARCH_GET_GS = 0x1004 + ARCH_SET_CPUID = 0x1012 ) diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 94ce5582b..a03fa6ac0 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -221,6 +221,24 @@ func (*runApp) execute(t *Task) taskRunState { // loop to figure out why. return (*runApp)(nil) + case platform.ErrContextSignalCPUID: + // Is this a CPUID instruction? + expected := arch.CPUIDInstruction[:] + found := make([]byte, len(expected)) + _, err := t.CopyIn(usermem.Addr(t.Arch().IP()), &found) + if err == nil && bytes.Equal(expected, found) { + // Skip the cpuid instruction. + t.Arch().CPUIDEmulate(t) + t.Arch().SetIP(t.Arch().IP() + uintptr(len(expected))) + + // Resume execution. + return (*runApp)(nil) + } + + // The instruction at the given RIP was not a CPUID, and we + // fallthrough to the default signal deliver behavior below. + fallthrough + case platform.ErrContextSignal: // Looks like a signal has been delivered to us. If it's a synchronous // signal (SEGV, SIGBUS, etc.), it should be sent to the application @@ -266,28 +284,7 @@ func (*runApp) execute(t *Task) taskRunState { } switch sig { - case linux.SIGILL: - // N.B. The debug stuff here is arguably - // expensive. Don't fret. This gets called - // about 5 times for a typical application, if - // that. - t.Debugf("SIGILL @ %x", t.Arch().IP()) - - // Is this a CPUID instruction? - expected := arch.CPUIDInstruction[:] - found := make([]byte, len(expected)) - _, err := t.CopyIn(usermem.Addr(t.Arch().IP()), &found) - if err == nil && bytes.Equal(expected, found) { - // Skip the cpuid instruction. - t.Arch().CPUIDEmulate(t) - t.Arch().SetIP(t.Arch().IP() + uintptr(len(expected))) - break - } - - // Treat it like any other synchronous signal. - fallthrough - - case linux.SIGSEGV, linux.SIGBUS, linux.SIGFPE, linux.SIGTRAP: + case linux.SIGILL, linux.SIGSEGV, linux.SIGBUS, linux.SIGFPE, linux.SIGTRAP: // Synchronous signal. Send it to ourselves. Assume the signal is // legitimate and force it (work around the signal being ignored or // blocked) like Linux does. Conveniently, this is even the correct diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index abdc51431..68e099d1b 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -141,11 +141,6 @@ func (m *machine) newVCPU() *vCPU { panic(fmt.Sprintf("error setting signal mask: %v", err)) } - // Initialize architecture state. - if err := c.initArchState(); err != nil { - panic(fmt.Sprintf("error initialization vCPU state: %v", err)) - } - // Map the run data. runData, err := mapRunData(int(fd)) if err != nil { @@ -153,6 +148,11 @@ func (m *machine) newVCPU() *vCPU { } c.runData = runData + // Initialize architecture state. + if err := c.initArchState(); err != nil { + panic(fmt.Sprintf("error initialization vCPU state: %v", err)) + } + return c // Done. } @@ -168,12 +168,6 @@ func newMachine(vm int) (*machine, error) { PageTables: pagetables.New(newAllocator()), }) - // Initialize architecture state. - if err := m.initArchState(); err != nil { - m.Destroy() - return nil, err - } - // Apply the physical mappings. Note that these mappings may point to // guest physical addresses that are not actually available. These // physical pages are mapped on demand, see kernel_unsafe.go. @@ -221,6 +215,12 @@ func newMachine(vm int) (*machine, error) { } }) + // Initialize architecture state. + if err := m.initArchState(); err != nil { + m.Destroy() + return nil, err + } + // Ensure the machine is cleaned up properly. runtime.SetFinalizer(m, (*machine).Destroy) return m, nil diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index 9af4f3f3d..bcd29a947 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -19,6 +19,7 @@ package kvm import ( "fmt" "reflect" + "runtime/debug" "syscall" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" @@ -39,6 +40,21 @@ func (m *machine) initArchState() error { uintptr(reservedMemory-(3*usermem.PageSize))); errno != 0 { return errno } + + // Enable CPUID faulting, if possible. Note that this also serves as a + // basic platform sanity tests, since we will enter guest mode for the + // first time here. The recovery is necessary, since if we fail to read + // the platform info register, we will retry to host mode and + // ultimately need to handle a segmentation fault. + old := debug.SetPanicOnFault(true) + defer func() { + recover() + debug.SetPanicOnFault(old) + }() + m.retryInGuest(func() { + ring0.SetCPUIDFaulting(true) + }) + return nil } @@ -238,6 +254,12 @@ func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts) (*arch.SignalInfo, user Code: arch.SignalInfoKernel, } info.SetAddr(switchOpts.Registers.Rip) // Include address. + if vector == ring0.GeneralProtectionFault { + // When CPUID faulting is enabled, we will generate a #GP(0) when + // userspace executes a CPUID instruction. This is handled above, + // because we need to be able to map and read user memory. + return info, usermem.AccessType{}, platform.ErrContextSignalCPUID + } return info, usermem.AccessType{}, platform.ErrContextSignal case ring0.InvalidOpcode: diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index f2fe163e8..6eb2acbd7 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -154,6 +154,13 @@ var ( // Context was interrupted by a signal. ErrContextSignal = fmt.Errorf("interrupted by signal") + // ErrContextSignalCPUID is equivalent to ErrContextSignal, except that + // a check should be done for execution of the CPUID instruction. If + // the current instruction pointer is a CPUID instruction, then this + // should be emulated appropriately. If not, then the given signal + // should be handled per above. + ErrContextSignalCPUID = fmt.Errorf("interrupted by signal, possible CPUID") + // ErrContextInterrupt is returned by Context.Switch() to indicate that the // Context was interrupted by a call to Context.Interrupt(). ErrContextInterrupt = fmt.Errorf("interrupted by platform.Context.Interrupt()") diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go index 05f8b1d05..a44f549a2 100644 --- a/pkg/sentry/platform/ptrace/ptrace.go +++ b/pkg/sentry/platform/ptrace/ptrace.go @@ -101,9 +101,11 @@ func (c *context) Switch(as platform.AddressSpace, ac arch.Context, cpu int32) ( s := as.(*subprocess) isSyscall := s.switchToApp(c, ac) - var faultSP *subprocess - var faultAddr usermem.Addr - var faultIP usermem.Addr + var ( + faultSP *subprocess + faultAddr usermem.Addr + faultIP usermem.Addr + ) if !isSyscall && linux.Signal(c.signalInfo.Signo) == linux.SIGSEGV { faultSP = s faultAddr = usermem.Addr(c.signalInfo.Addr()) @@ -161,7 +163,12 @@ func (c *context) Switch(as platform.AddressSpace, ac arch.Context, cpu int32) ( lastFaultIP == faultIP { at.Write = true } - return &c.signalInfo, at, platform.ErrContextSignal + + // Unfortunately, we have to unilaterally return ErrContextSignalCPUID + // here, in case this fault was generated by a CPUID exception. There + // is no way to distinguish between CPUID-generated faults and regular + // page faults. + return &c.signalInfo, at, platform.ErrContextSignalCPUID } // Interrupt interrupts the running guest application associated with this context. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index b3f2ebb20..b212bbdfe 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -20,6 +20,7 @@ import ( "fmt" "syscall" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/platform/procid" ) @@ -85,6 +86,10 @@ func createStub() (*thread, error) { syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0) } + // Enable cpuid-faulting; this may fail on older kernels or hardware, + // so we just disregard the result. Host CPUID will be enabled. + syscall.RawSyscall(syscall.SYS_ARCH_PRCTL, linux.ARCH_SET_CPUID, 0, 0) + // Call the stub; should not return. stubCall(stubStart, ppid) panic("unreachable") diff --git a/pkg/sentry/platform/ring0/kernel_amd64.go b/pkg/sentry/platform/ring0/kernel_amd64.go index 117e86104..0d2b0f7dc 100644 --- a/pkg/sentry/platform/ring0/kernel_amd64.go +++ b/pkg/sentry/platform/ring0/kernel_amd64.go @@ -163,7 +163,6 @@ func IsCanonical(addr uint64) bool { // the case for amd64, but may not be the case for other architectures. // // Precondition: the Rip, Rsp, Fs and Gs registers must be canonical. - // //go:nosplit func (c *CPU) SwitchToUser(switchOpts SwitchOpts) (vector Vector) { @@ -237,6 +236,27 @@ func start(c *CPU) { wrmsr(_MSR_CSTAR, kernelFunc(sysenter)) } +// SetCPUIDFaulting sets CPUID faulting per the boolean value. +// +// True is returned if faulting could be set. +// +//go:nosplit +func SetCPUIDFaulting(on bool) bool { + // Per the SDM (Vol 3, Table 2-43), PLATFORM_INFO bit 31 denotes support + // for CPUID faulting, and we enable and disable via the MISC_FEATURES MSR. + if rdmsr(_MSR_PLATFORM_INFO)&_PLATFORM_INFO_CPUID_FAULT != 0 { + features := rdmsr(_MSR_MISC_FEATURES) + if on { + features |= _MISC_FEATURE_CPUID_TRAP + } else { + features &^= _MISC_FEATURE_CPUID_TRAP + } + wrmsr(_MSR_MISC_FEATURES, features) + return true // Setting successful. + } + return false +} + // ReadCR2 reads the current CR2 value. // //go:nosplit diff --git a/pkg/sentry/platform/ring0/x86.go b/pkg/sentry/platform/ring0/x86.go index 3d437a77c..f489fcecb 100644 --- a/pkg/sentry/platform/ring0/x86.go +++ b/pkg/sentry/platform/ring0/x86.go @@ -50,10 +50,16 @@ const ( _EFER_LMA = 0x400 _EFER_NX = 0x800 - _MSR_STAR = 0xc0000081 - _MSR_LSTAR = 0xc0000082 - _MSR_CSTAR = 0xc0000083 - _MSR_SYSCALL_MASK = 0xc0000084 + _MSR_STAR = 0xc0000081 + _MSR_LSTAR = 0xc0000082 + _MSR_CSTAR = 0xc0000083 + _MSR_SYSCALL_MASK = 0xc0000084 + _MSR_PLATFORM_INFO = 0xce + _MSR_MISC_FEATURES = 0x140 + + _PLATFORM_INFO_CPUID_FAULT = 1 << 31 + + _MISC_FEATURE_CPUID_TRAP = 0x1 ) const ( -- cgit v1.2.3 From ed2e03d3780b8d96b189c1311c92b9db2fbcb35a Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Tue, 17 Jul 2018 10:50:02 -0700 Subject: Add API to decode 'stat.st_rdev' into major and minor numbers. PiperOrigin-RevId: 204936533 Change-Id: Ib060920077fc914f97c4a0548a176d1368510c7b --- pkg/abi/linux/dev.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go index d3b63063f..ea5b16b7b 100644 --- a/pkg/abi/linux/dev.go +++ b/pkg/abi/linux/dev.go @@ -25,6 +25,13 @@ func MakeDeviceID(major uint16, minor uint32) uint32 { return (minor & 0xff) | ((uint32(major) & 0xfff) << 8) | ((minor >> 8) << 20) } +// DecodeDeviceID decodes a device ID into major and minor device numbers. +func DecodeDeviceID(rdev uint32) (uint16, uint32) { + major := uint16((rdev >> 8) & 0xfff) + minor := (rdev & 0xff) | ((rdev >> 20) << 8) + return major, minor +} + // Character device IDs. // // See Documentations/devices.txt and uapi/linux/major.h. -- cgit v1.2.3 From be7fcbc5582fe831b5ec63f773d867d7591e27a1 Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Fri, 27 Jul 2018 10:16:27 -0700 Subject: stateify: support explicit annotation mode; convert refs and stack packages. We have been unnecessarily creating too many savable types implicitly. PiperOrigin-RevId: 206334201 Change-Id: Idc5a3a14bfb7ee125c4f2bb2b1c53164e46f29a8 --- pkg/abi/BUILD | 3 +- pkg/abi/linux/BUILD | 3 +- pkg/amutex/BUILD | 2 +- pkg/atomicbitops/BUILD | 2 +- pkg/binary/BUILD | 2 +- pkg/bits/BUILD | 2 +- pkg/bpf/BUILD | 3 +- pkg/compressio/BUILD | 2 +- pkg/control/client/BUILD | 2 +- pkg/control/server/BUILD | 2 +- pkg/cpuid/BUILD | 3 +- pkg/dhcp/BUILD | 2 +- pkg/eventchannel/BUILD | 2 +- pkg/fd/BUILD | 2 +- pkg/gate/BUILD | 2 +- pkg/hashio/BUILD | 2 +- pkg/ilist/BUILD | 3 +- pkg/linewriter/BUILD | 2 +- pkg/log/BUILD | 2 +- pkg/metric/BUILD | 2 +- pkg/p9/BUILD | 2 +- pkg/p9/p9test/BUILD | 2 +- pkg/rand/BUILD | 2 +- pkg/refs/BUILD | 20 +------- pkg/refs/refcounter.go | 4 ++ pkg/refs/refcounter_state.go | 1 + pkg/seccomp/BUILD | 3 +- pkg/secio/BUILD | 2 +- pkg/segment/test/BUILD | 2 +- pkg/sentry/arch/BUILD | 3 +- pkg/sentry/context/BUILD | 2 +- pkg/sentry/context/contexttest/BUILD | 3 +- pkg/sentry/control/BUILD | 2 +- pkg/sentry/device/BUILD | 2 +- pkg/sentry/fs/BUILD | 3 +- pkg/sentry/fs/anon/BUILD | 2 +- pkg/sentry/fs/ashmem/BUILD | 3 +- pkg/sentry/fs/binder/BUILD | 3 +- pkg/sentry/fs/dev/BUILD | 3 +- pkg/sentry/fs/fdpipe/BUILD | 3 +- pkg/sentry/fs/filetest/BUILD | 3 +- pkg/sentry/fs/fsutil/BUILD | 3 +- pkg/sentry/fs/gofer/BUILD | 3 +- pkg/sentry/fs/host/BUILD | 3 +- pkg/sentry/fs/lock/BUILD | 3 +- pkg/sentry/fs/proc/BUILD | 3 +- pkg/sentry/fs/proc/device/BUILD | 2 +- pkg/sentry/fs/proc/seqfile/BUILD | 3 +- pkg/sentry/fs/ramfs/BUILD | 3 +- pkg/sentry/fs/ramfs/test/BUILD | 3 +- pkg/sentry/fs/sys/BUILD | 3 +- pkg/sentry/fs/timerfd/BUILD | 3 +- pkg/sentry/fs/tmpfs/BUILD | 3 +- pkg/sentry/fs/tty/BUILD | 3 +- pkg/sentry/hostcpu/BUILD | 2 +- pkg/sentry/inet/BUILD | 4 +- pkg/sentry/kernel/BUILD | 3 +- pkg/sentry/kernel/auth/BUILD | 3 +- pkg/sentry/kernel/epoll/BUILD | 3 +- pkg/sentry/kernel/eventfd/BUILD | 3 +- pkg/sentry/kernel/fasync/BUILD | 2 +- pkg/sentry/kernel/futex/BUILD | 3 +- pkg/sentry/kernel/kdefs/BUILD | 2 +- pkg/sentry/kernel/memevent/BUILD | 2 +- pkg/sentry/kernel/pipe/BUILD | 3 +- pkg/sentry/kernel/sched/BUILD | 2 +- pkg/sentry/kernel/semaphore/BUILD | 3 +- pkg/sentry/kernel/shm/BUILD | 3 +- pkg/sentry/kernel/time/BUILD | 3 +- pkg/sentry/limits/BUILD | 3 +- pkg/sentry/loader/BUILD | 4 +- pkg/sentry/memmap/BUILD | 3 +- pkg/sentry/memutil/BUILD | 2 +- pkg/sentry/mm/BUILD | 3 +- pkg/sentry/platform/BUILD | 3 +- pkg/sentry/platform/filemem/BUILD | 3 +- pkg/sentry/platform/interrupt/BUILD | 2 +- pkg/sentry/platform/kvm/BUILD | 2 +- pkg/sentry/platform/kvm/testutil/BUILD | 2 +- pkg/sentry/platform/procid/BUILD | 2 +- pkg/sentry/platform/ptrace/BUILD | 2 +- pkg/sentry/platform/ring0/BUILD | 2 +- pkg/sentry/platform/ring0/pagetables/BUILD | 2 +- pkg/sentry/platform/safecopy/BUILD | 2 +- pkg/sentry/safemem/BUILD | 2 +- pkg/sentry/sighandling/BUILD | 2 +- pkg/sentry/socket/BUILD | 3 +- pkg/sentry/socket/control/BUILD | 3 +- pkg/sentry/socket/epsocket/BUILD | 3 +- pkg/sentry/socket/hostinet/BUILD | 3 +- pkg/sentry/socket/netlink/BUILD | 3 +- pkg/sentry/socket/netlink/port/BUILD | 3 +- pkg/sentry/socket/netlink/route/BUILD | 3 +- pkg/sentry/socket/rpcinet/BUILD | 2 +- pkg/sentry/socket/rpcinet/conn/BUILD | 2 +- pkg/sentry/socket/rpcinet/notifier/BUILD | 2 +- pkg/sentry/socket/unix/BUILD | 3 +- pkg/sentry/state/BUILD | 2 +- pkg/sentry/strace/BUILD | 2 +- pkg/sentry/syscalls/BUILD | 2 +- pkg/sentry/syscalls/linux/BUILD | 3 +- pkg/sentry/time/BUILD | 2 +- pkg/sentry/uniqueid/BUILD | 2 +- pkg/sentry/usage/BUILD | 3 +- pkg/sentry/usermem/BUILD | 3 +- pkg/sentry/watchdog/BUILD | 2 +- pkg/sleep/BUILD | 2 +- pkg/state/BUILD | 2 +- pkg/state/statefile/BUILD | 2 +- pkg/sync/BUILD | 2 +- pkg/sync/seqatomictest/BUILD | 2 +- pkg/syserr/BUILD | 2 +- pkg/syserror/BUILD | 2 +- pkg/tcpip/BUILD | 3 +- pkg/tcpip/adapters/gonet/BUILD | 2 +- pkg/tcpip/buffer/BUILD | 3 +- pkg/tcpip/checker/BUILD | 2 +- pkg/tcpip/header/BUILD | 3 +- pkg/tcpip/link/channel/BUILD | 2 +- pkg/tcpip/link/fdbased/BUILD | 2 +- pkg/tcpip/link/loopback/BUILD | 2 +- pkg/tcpip/link/rawfile/BUILD | 2 +- pkg/tcpip/link/sharedmem/BUILD | 2 +- pkg/tcpip/link/sharedmem/pipe/BUILD | 2 +- pkg/tcpip/link/sharedmem/queue/BUILD | 2 +- pkg/tcpip/link/sniffer/BUILD | 2 +- pkg/tcpip/link/tun/BUILD | 2 +- pkg/tcpip/link/waitable/BUILD | 2 +- pkg/tcpip/network/BUILD | 2 +- pkg/tcpip/network/arp/BUILD | 2 +- pkg/tcpip/network/fragmentation/BUILD | 3 +- pkg/tcpip/network/hash/BUILD | 2 +- pkg/tcpip/network/ipv4/BUILD | 2 +- pkg/tcpip/network/ipv6/BUILD | 2 +- pkg/tcpip/ports/BUILD | 2 +- pkg/tcpip/seqnum/BUILD | 3 +- pkg/tcpip/stack/BUILD | 15 +----- pkg/tcpip/stack/registration.go | 2 + pkg/tcpip/transport/ping/BUILD | 3 +- pkg/tcpip/transport/queue/BUILD | 3 +- pkg/tcpip/transport/tcp/BUILD | 3 +- pkg/tcpip/transport/tcp/testing/context/BUILD | 2 +- pkg/tcpip/transport/tcpconntrack/BUILD | 2 +- pkg/tcpip/transport/udp/BUILD | 3 +- pkg/tcpip/transport/unix/BUILD | 3 +- pkg/tmutex/BUILD | 2 +- pkg/unet/BUILD | 2 +- pkg/urpc/BUILD | 2 +- pkg/waiter/BUILD | 3 +- pkg/waiter/fdnotifier/BUILD | 2 +- tools/go_stateify/defs.bzl | 58 ++++++++++++++++++----- tools/go_stateify/main.go | 66 +++++++++++++++++++++------ 152 files changed, 255 insertions(+), 267 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index 4d507161f..f1e6bac67 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "abi_state", diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index ae7e4378c..38b4829c9 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -4,8 +4,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "linux_state", diff --git a/pkg/amutex/BUILD b/pkg/amutex/BUILD index 442096319..84e6b79a5 100644 --- a/pkg/amutex/BUILD +++ b/pkg/amutex/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "amutex", diff --git a/pkg/atomicbitops/BUILD b/pkg/atomicbitops/BUILD index f20a9f855..a8dd17825 100644 --- a/pkg/atomicbitops/BUILD +++ b/pkg/atomicbitops/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "atomicbitops", diff --git a/pkg/binary/BUILD b/pkg/binary/BUILD index 16f08b13f..586d05634 100644 --- a/pkg/binary/BUILD +++ b/pkg/binary/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "binary", diff --git a/pkg/bits/BUILD b/pkg/bits/BUILD index 9897e5dc3..8c943b615 100644 --- a/pkg/bits/BUILD +++ b/pkg/bits/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") go_library( diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index d4f12f13a..403270049 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "bpf_state", diff --git a/pkg/compressio/BUILD b/pkg/compressio/BUILD index 721b2d983..d70f982c1 100644 --- a/pkg/compressio/BUILD +++ b/pkg/compressio/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "compressio", diff --git a/pkg/control/client/BUILD b/pkg/control/client/BUILD index 9e1c058e4..d58cd1b71 100644 --- a/pkg/control/client/BUILD +++ b/pkg/control/client/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "client", diff --git a/pkg/control/server/BUILD b/pkg/control/server/BUILD index 2d0fdd8b8..c3f74a532 100644 --- a/pkg/control/server/BUILD +++ b/pkg/control/server/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "server", diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index a503b7ae8..9a0ca1b33 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "cpuid_state", diff --git a/pkg/dhcp/BUILD b/pkg/dhcp/BUILD index f56969ad8..bd9f592b4 100644 --- a/pkg/dhcp/BUILD +++ b/pkg/dhcp/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "dhcp", diff --git a/pkg/eventchannel/BUILD b/pkg/eventchannel/BUILD index ea0c587be..ac2ea869d 100644 --- a/pkg/eventchannel/BUILD +++ b/pkg/eventchannel/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "eventchannel", diff --git a/pkg/fd/BUILD b/pkg/fd/BUILD index e69d83d06..435b6fa34 100644 --- a/pkg/fd/BUILD +++ b/pkg/fd/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fd", diff --git a/pkg/gate/BUILD b/pkg/gate/BUILD index 0b8b01da8..872eff531 100644 --- a/pkg/gate/BUILD +++ b/pkg/gate/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "gate", diff --git a/pkg/hashio/BUILD b/pkg/hashio/BUILD index aaa58b58f..5736e2e73 100644 --- a/pkg/hashio/BUILD +++ b/pkg/hashio/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "hashio", diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index 16a738e89..e32f26ffa 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "list_state", diff --git a/pkg/linewriter/BUILD b/pkg/linewriter/BUILD index 4a96c6f1d..6c3795432 100644 --- a/pkg/linewriter/BUILD +++ b/pkg/linewriter/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "linewriter", diff --git a/pkg/log/BUILD b/pkg/log/BUILD index 2530cfd18..fc9281079 100644 --- a/pkg/log/BUILD +++ b/pkg/log/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "log", diff --git a/pkg/metric/BUILD b/pkg/metric/BUILD index e3f50d528..c0cd40c7b 100644 --- a/pkg/metric/BUILD +++ b/pkg/metric/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "metric", diff --git a/pkg/p9/BUILD b/pkg/p9/BUILD index f348ff2e9..1cf5c6458 100644 --- a/pkg/p9/BUILD +++ b/pkg/p9/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:public"], diff --git a/pkg/p9/p9test/BUILD b/pkg/p9/p9test/BUILD index 339c86089..d6f428e11 100644 --- a/pkg/p9/p9test/BUILD +++ b/pkg/p9/p9test/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_test( name = "p9test_test", diff --git a/pkg/rand/BUILD b/pkg/rand/BUILD index 2bb59f895..12e6cf25a 100644 --- a/pkg/rand/BUILD +++ b/pkg/rand/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "rand", diff --git a/pkg/refs/BUILD b/pkg/refs/BUILD index 4b7c9345d..3ea877ccf 100644 --- a/pkg/refs/BUILD +++ b/pkg/refs/BUILD @@ -1,32 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") - -go_stateify( - name = "refs_state", - srcs = [ - "refcounter.go", - "refcounter_state.go", - ], - out = "refs_state.go", - package = "refs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "refs", srcs = [ "refcounter.go", "refcounter_state.go", - "refs_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/refs", visibility = ["//:sandbox"], - deps = [ - "//pkg/ilist", - "//pkg/log", - "//pkg/state", - ], + deps = ["//pkg/ilist"], ) go_test( diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 3162001e1..0d44c2499 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -58,6 +58,8 @@ type WeakRefUser interface { } // WeakRef is a weak reference. +// +// +stateify savable type WeakRef struct { ilist.Entry `state:"nosave"` @@ -177,6 +179,8 @@ func (w *WeakRef) zap() { // // N.B. To allow the zero-object to be initialized, the count is offset by // 1, that is, when refCount is n, there are really n+1 references. +// +// +stateify savable type AtomicRefCount struct { // refCount is composed of two fields: // diff --git a/pkg/refs/refcounter_state.go b/pkg/refs/refcounter_state.go index 1be67f951..093eae785 100644 --- a/pkg/refs/refcounter_state.go +++ b/pkg/refs/refcounter_state.go @@ -14,6 +14,7 @@ package refs +// +stateify savable type savedReference struct { obj interface{} } diff --git a/pkg/seccomp/BUILD b/pkg/seccomp/BUILD index cadd24505..b3e2f0b38 100644 --- a/pkg/seccomp/BUILD +++ b/pkg/seccomp/BUILD @@ -1,6 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_embed_data", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_embed_data") go_binary( name = "victim", diff --git a/pkg/secio/BUILD b/pkg/secio/BUILD index 9a28d2c1f..0ed38c64a 100644 --- a/pkg/secio/BUILD +++ b/pkg/secio/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "secio", diff --git a/pkg/segment/test/BUILD b/pkg/segment/test/BUILD index 9d398d71a..bdf53e24e 100644 --- a/pkg/segment/test/BUILD +++ b/pkg/segment/test/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:private"], diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index a88f57ac7..0a2a35400 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "arch_state", diff --git a/pkg/sentry/context/BUILD b/pkg/sentry/context/BUILD index ff39f94ba..2a7a6df23 100644 --- a/pkg/sentry/context/BUILD +++ b/pkg/sentry/context/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "context", diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 5977344de..591b11a4d 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "contexttest_state", diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD index 6169891f7..fbdde0721 100644 --- a/pkg/sentry/control/BUILD +++ b/pkg/sentry/control/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "control", diff --git a/pkg/sentry/device/BUILD b/pkg/sentry/device/BUILD index 1a8b461ba..69c99b0b3 100644 --- a/pkg/sentry/device/BUILD +++ b/pkg/sentry/device/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "device", diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 9b7264753..e3c9a9b70 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "fs_state", diff --git a/pkg/sentry/fs/anon/BUILD b/pkg/sentry/fs/anon/BUILD index 6b18aee47..ff4ab850a 100644 --- a/pkg/sentry/fs/anon/BUILD +++ b/pkg/sentry/fs/anon/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "anon", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index e20e22a0f..9f166799a 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_stateify( diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index 15f91699f..ec3928baf 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "binder_state", diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index d33a19c2f..ea41615fd 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "dev_state", diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 9e1f65d3e..4fcb06f1f 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "pipe_state", diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index 51a390d77..f481c57fb 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "filetest_state", diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 4fa6395f7..6eea64298 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "fsutil_state", diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index e6f659c53..1277379e7 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "gofer_state", diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 97b64daed..23ec66f50 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "host_state", diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index c15dde800..2607d7ed3 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "lock_state", diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 21b5fc0c3..870df47b2 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "proc_state", diff --git a/pkg/sentry/fs/proc/device/BUILD b/pkg/sentry/fs/proc/device/BUILD index b62062bd7..34582f275 100644 --- a/pkg/sentry/fs/proc/device/BUILD +++ b/pkg/sentry/fs/proc/device/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "device", diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index 48dd25e5b..c84f7e20d 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "seqfile_state", diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index 663a1aeb9..d84f2c624 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "ramfs_state", diff --git a/pkg/sentry/fs/ramfs/test/BUILD b/pkg/sentry/fs/ramfs/test/BUILD index 074b0f5ad..57fee45e2 100644 --- a/pkg/sentry/fs/ramfs/test/BUILD +++ b/pkg/sentry/fs/ramfs/test/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "test_state", diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 0ae2cbac8..095ff1f25 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "sys_state", diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index 7fddc29f4..8b1b7872e 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "timerfd_state", diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index be4e695d3..473ab4296 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tmpfs_state", diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index fce327dfe..363897b2c 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tty_state", diff --git a/pkg/sentry/hostcpu/BUILD b/pkg/sentry/hostcpu/BUILD index 9457618d8..f362d15c8 100644 --- a/pkg/sentry/hostcpu/BUILD +++ b/pkg/sentry/hostcpu/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "hostcpu", diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index 1150ced57..eaf8f15b2 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -1,11 +1,9 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - package( default_visibility = ["//:sandbox"], licenses = ["notice"], # Apache 2.0 ) -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "inet_state", diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 07568b47c..c4a7dacb2 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "kernel_state", diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 7f0680b88..5b7b30557 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "auth_state", diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 04651d961..7d491efbc 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "epoll_autogen_state", diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index 561ced852..7ec179bd8 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "eventfd_state", diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD index 8d06e1182..17749c0de 100644 --- a/pkg/sentry/kernel/fasync/BUILD +++ b/pkg/sentry/kernel/fasync/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "fasync", diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index de9897c58..a97a43549 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_template_instance( name = "waiter_list", diff --git a/pkg/sentry/kernel/kdefs/BUILD b/pkg/sentry/kernel/kdefs/BUILD index b6c00042a..fe6fa2260 100644 --- a/pkg/sentry/kernel/kdefs/BUILD +++ b/pkg/sentry/kernel/kdefs/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "kdefs", diff --git a/pkg/sentry/kernel/memevent/BUILD b/pkg/sentry/kernel/memevent/BUILD index c7779e1d5..66899910c 100644 --- a/pkg/sentry/kernel/memevent/BUILD +++ b/pkg/sentry/kernel/memevent/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "memevent", diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index ca9825f9d..4600d19bd 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "pipe_state", diff --git a/pkg/sentry/kernel/sched/BUILD b/pkg/sentry/kernel/sched/BUILD index b533c51c4..125792f39 100644 --- a/pkg/sentry/kernel/sched/BUILD +++ b/pkg/sentry/kernel/sched/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "sched", diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index 1656ad126..969145fe1 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_template_instance( name = "waiter_list", diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 182cc1c76..0f88eb0ac 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "shm_state", diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index 84f31b2dc..b3ed42aa4 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "time_state", diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 06c3e72b0..3ce41cacc 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "limits_state", diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 01a0ec426..e63052c6d 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_embed_data", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_embed_data( name = "vdso_bin", diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index 7525fea45..2e367e189 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "memmap_state", diff --git a/pkg/sentry/memutil/BUILD b/pkg/sentry/memutil/BUILD index a387a0c9f..341b30b98 100644 --- a/pkg/sentry/memutil/BUILD +++ b/pkg/sentry/memutil/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "memutil", diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 258389bb2..3f396986a 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "mm_state", diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index d5be81f8d..15a7fbbc3 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "platform_state", diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index 3c4d5b0b6..dadba1d38 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "filemem_autogen_state", diff --git a/pkg/sentry/platform/interrupt/BUILD b/pkg/sentry/platform/interrupt/BUILD index 33dde2a31..35121321a 100644 --- a/pkg/sentry/platform/interrupt/BUILD +++ b/pkg/sentry/platform/interrupt/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "interrupt", diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD index 673393fad..4ef9e20d7 100644 --- a/pkg/sentry/platform/kvm/BUILD +++ b/pkg/sentry/platform/kvm/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/sentry/platform/kvm/testutil/BUILD b/pkg/sentry/platform/kvm/testutil/BUILD index 8533a8d89..e779e3893 100644 --- a/pkg/sentry/platform/kvm/testutil/BUILD +++ b/pkg/sentry/platform/kvm/testutil/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "testutil", diff --git a/pkg/sentry/platform/procid/BUILD b/pkg/sentry/platform/procid/BUILD index 5db4f6261..ba68d48f4 100644 --- a/pkg/sentry/platform/procid/BUILD +++ b/pkg/sentry/platform/procid/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "procid", diff --git a/pkg/sentry/platform/ptrace/BUILD b/pkg/sentry/platform/ptrace/BUILD index 16b0b3c69..ceee895dc 100644 --- a/pkg/sentry/platform/ptrace/BUILD +++ b/pkg/sentry/platform/ptrace/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ptrace", diff --git a/pkg/sentry/platform/ring0/BUILD b/pkg/sentry/platform/ring0/BUILD index 2df232a64..2485eb2eb 100644 --- a/pkg/sentry/platform/ring0/BUILD +++ b/pkg/sentry/platform/ring0/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") go_template( diff --git a/pkg/sentry/platform/ring0/pagetables/BUILD b/pkg/sentry/platform/ring0/pagetables/BUILD index 023e298a0..7a86e2234 100644 --- a/pkg/sentry/platform/ring0/pagetables/BUILD +++ b/pkg/sentry/platform/ring0/pagetables/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") go_template( diff --git a/pkg/sentry/platform/safecopy/BUILD b/pkg/sentry/platform/safecopy/BUILD index 8b9f29403..7dcf6e561 100644 --- a/pkg/sentry/platform/safecopy/BUILD +++ b/pkg/sentry/platform/safecopy/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "safecopy", diff --git a/pkg/sentry/safemem/BUILD b/pkg/sentry/safemem/BUILD index dc4cfce41..e96509ce1 100644 --- a/pkg/sentry/safemem/BUILD +++ b/pkg/sentry/safemem/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "safemem", diff --git a/pkg/sentry/sighandling/BUILD b/pkg/sentry/sighandling/BUILD index daaad7c90..f480f0735 100644 --- a/pkg/sentry/sighandling/BUILD +++ b/pkg/sentry/sighandling/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "sighandling", diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 5500a676e..929787aa0 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "socket_state", diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index 25de2f655..faf2b4c27 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "control_state", diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index 8430886cb..7ad5e88c5 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "epsocket_state", diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index 60ec265ba..227ca3926 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "hostinet_state", diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index 9df3ab17c..b23a243f7 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "netlink_state", diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index 7340b95c9..ba6f686e4 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "port_state", diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index ff3f7b7a4..726469fc9 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "route_state", diff --git a/pkg/sentry/socket/rpcinet/BUILD b/pkg/sentry/socket/rpcinet/BUILD index 8973453f9..288199779 100644 --- a/pkg/sentry/socket/rpcinet/BUILD +++ b/pkg/sentry/socket/rpcinet/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "rpcinet", diff --git a/pkg/sentry/socket/rpcinet/conn/BUILD b/pkg/sentry/socket/rpcinet/conn/BUILD index 4923dee4b..c51ca14b1 100644 --- a/pkg/sentry/socket/rpcinet/conn/BUILD +++ b/pkg/sentry/socket/rpcinet/conn/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # BSD -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "conn", diff --git a/pkg/sentry/socket/rpcinet/notifier/BUILD b/pkg/sentry/socket/rpcinet/notifier/BUILD index 6f3b06a05..2ae902b3f 100644 --- a/pkg/sentry/socket/rpcinet/notifier/BUILD +++ b/pkg/sentry/socket/rpcinet/notifier/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # BSD -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "notifier", diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index 1ec6eb7ed..7d04d6b6b 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "unix_state", diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD index 9bd98f445..a57a8298e 100644 --- a/pkg/sentry/state/BUILD +++ b/pkg/sentry/state/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "state", diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index c5946a564..e1c8db67a 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "strace", diff --git a/pkg/sentry/syscalls/BUILD b/pkg/sentry/syscalls/BUILD index d667b42c8..22a757095 100644 --- a/pkg/sentry/syscalls/BUILD +++ b/pkg/sentry/syscalls/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "syscalls", diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index d3f3cc459..574621ad2 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "linux_state", diff --git a/pkg/sentry/time/BUILD b/pkg/sentry/time/BUILD index cbcd699d5..9452787fb 100644 --- a/pkg/sentry/time/BUILD +++ b/pkg/sentry/time/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/sentry/uniqueid/BUILD b/pkg/sentry/uniqueid/BUILD index c8ab03c3d..8eba3609e 100644 --- a/pkg/sentry/uniqueid/BUILD +++ b/pkg/sentry/uniqueid/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "uniqueid", diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index a0fe0aa07..edee44d96 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "usage_state", diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index 36c0760dd..9dd1cd2b5 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "usermem_state", diff --git a/pkg/sentry/watchdog/BUILD b/pkg/sentry/watchdog/BUILD index 28fae4490..13bc33eb1 100644 --- a/pkg/sentry/watchdog/BUILD +++ b/pkg/sentry/watchdog/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "watchdog", diff --git a/pkg/sleep/BUILD b/pkg/sleep/BUILD index f2b69b225..05e4ca540 100644 --- a/pkg/sleep/BUILD +++ b/pkg/sleep/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "sleep", diff --git a/pkg/state/BUILD b/pkg/state/BUILD index bb6415d9b..012b0484e 100644 --- a/pkg/state/BUILD +++ b/pkg/state/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/state/statefile/BUILD b/pkg/state/statefile/BUILD index df2c6a578..16abe1930 100644 --- a/pkg/state/statefile/BUILD +++ b/pkg/state/statefile/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "statefile", diff --git a/pkg/sync/BUILD b/pkg/sync/BUILD index 1fc0c25b5..3959fea36 100644 --- a/pkg/sync/BUILD +++ b/pkg/sync/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//:sandbox"], diff --git a/pkg/sync/seqatomictest/BUILD b/pkg/sync/seqatomictest/BUILD index 9d6ee2dfb..07b4f85ab 100644 --- a/pkg/sync/seqatomictest/BUILD +++ b/pkg/sync/seqatomictest/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") go_template_instance( diff --git a/pkg/syserr/BUILD b/pkg/syserr/BUILD index e5ce48412..c0850f3d9 100644 --- a/pkg/syserr/BUILD +++ b/pkg/syserr/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "syserr", diff --git a/pkg/syserror/BUILD b/pkg/syserror/BUILD index 68ddec786..e050c2043 100644 --- a/pkg/syserror/BUILD +++ b/pkg/syserror/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "syserror", diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 186a0d3bf..391d801d0 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tcpip_state", diff --git a/pkg/tcpip/adapters/gonet/BUILD b/pkg/tcpip/adapters/gonet/BUILD index 97da46776..bf618831a 100644 --- a/pkg/tcpip/adapters/gonet/BUILD +++ b/pkg/tcpip/adapters/gonet/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "gonet", diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index 08adf18cd..efeb6a448 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "buffer_state", diff --git a/pkg/tcpip/checker/BUILD b/pkg/tcpip/checker/BUILD index 5447cfbf4..e8a524918 100644 --- a/pkg/tcpip/checker/BUILD +++ b/pkg/tcpip/checker/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "checker", diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 859c2a106..3aa2cfb24 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tcp_header_state", diff --git a/pkg/tcpip/link/channel/BUILD b/pkg/tcpip/link/channel/BUILD index f2f0c8b6f..9a6f49c45 100644 --- a/pkg/tcpip/link/channel/BUILD +++ b/pkg/tcpip/link/channel/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "channel", diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index aca3b14ca..6e75e9f47 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fdbased", diff --git a/pkg/tcpip/link/loopback/BUILD b/pkg/tcpip/link/loopback/BUILD index 9714e93db..cc4247ffd 100644 --- a/pkg/tcpip/link/loopback/BUILD +++ b/pkg/tcpip/link/loopback/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "loopback", diff --git a/pkg/tcpip/link/rawfile/BUILD b/pkg/tcpip/link/rawfile/BUILD index 4b30c7c1c..10b35a37e 100644 --- a/pkg/tcpip/link/rawfile/BUILD +++ b/pkg/tcpip/link/rawfile/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "rawfile", diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index 1bd79a3f4..5390257c5 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "sharedmem", diff --git a/pkg/tcpip/link/sharedmem/pipe/BUILD b/pkg/tcpip/link/sharedmem/pipe/BUILD index e6c658071..ff798ae6f 100644 --- a/pkg/tcpip/link/sharedmem/pipe/BUILD +++ b/pkg/tcpip/link/sharedmem/pipe/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "pipe", diff --git a/pkg/tcpip/link/sharedmem/queue/BUILD b/pkg/tcpip/link/sharedmem/queue/BUILD index 80cedade1..c4a7879c4 100644 --- a/pkg/tcpip/link/sharedmem/queue/BUILD +++ b/pkg/tcpip/link/sharedmem/queue/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "queue", diff --git a/pkg/tcpip/link/sniffer/BUILD b/pkg/tcpip/link/sniffer/BUILD index d14f150d1..1e844f949 100644 --- a/pkg/tcpip/link/sniffer/BUILD +++ b/pkg/tcpip/link/sniffer/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "sniffer", diff --git a/pkg/tcpip/link/tun/BUILD b/pkg/tcpip/link/tun/BUILD index 21da7d57e..a8bb03661 100644 --- a/pkg/tcpip/link/tun/BUILD +++ b/pkg/tcpip/link/tun/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "tun", diff --git a/pkg/tcpip/link/waitable/BUILD b/pkg/tcpip/link/waitable/BUILD index 3b513383a..7582df32e 100644 --- a/pkg/tcpip/link/waitable/BUILD +++ b/pkg/tcpip/link/waitable/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "waitable", diff --git a/pkg/tcpip/network/BUILD b/pkg/tcpip/network/BUILD index 963857f51..9a26b46c4 100644 --- a/pkg/tcpip/network/BUILD +++ b/pkg/tcpip/network/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_test") +load("//tools/go_stateify:defs.bzl", "go_test") go_test( name = "ip_test", diff --git a/pkg/tcpip/network/arp/BUILD b/pkg/tcpip/network/arp/BUILD index 689f66d6e..44f2b66e5 100644 --- a/pkg/tcpip/network/arp/BUILD +++ b/pkg/tcpip/network/arp/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "arp", diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index a173f87fb..ac97ebe43 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "fragmentation_state", diff --git a/pkg/tcpip/network/hash/BUILD b/pkg/tcpip/network/hash/BUILD index e1b5f26c4..1c22c52fc 100644 --- a/pkg/tcpip/network/hash/BUILD +++ b/pkg/tcpip/network/hash/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "hash", diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index ae42b662f..19314e9bd 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ipv4", diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index d008ac7fb..1c3eccae0 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "ipv6", diff --git a/pkg/tcpip/ports/BUILD b/pkg/tcpip/ports/BUILD index 710c283f7..3c3374275 100644 --- a/pkg/tcpip/ports/BUILD +++ b/pkg/tcpip/ports/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ports", diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index 6d28dbc3f..a75869dac 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "seqnum_state", diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 6d201d0a2..5e7355135 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -1,17 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") - -go_stateify( - name = "stack_state", - srcs = [ - "registration.go", - "stack.go", - ], - out = "stack_state.go", - package = "stack", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "stack", @@ -22,7 +11,6 @@ go_library( "route.go", "stack.go", "stack_global_state.go", - "stack_state.go", "transport_demuxer.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/stack", @@ -32,7 +20,6 @@ go_library( deps = [ "//pkg/ilist", "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index e9550a062..c66f925a8 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -31,6 +31,8 @@ type NetworkEndpointID struct { } // TransportEndpointID is the identifier of a transport layer protocol endpoint. +// +// +stateify savable type TransportEndpointID struct { // LocalPort is the local port associated with the endpoint. LocalPort uint16 diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 1febbf7f5..28e3e1700 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "ping_state", diff --git a/pkg/tcpip/transport/queue/BUILD b/pkg/tcpip/transport/queue/BUILD index 7e8ee1f66..fb878ad36 100644 --- a/pkg/tcpip/transport/queue/BUILD +++ b/pkg/tcpip/transport/queue/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "queue_state", diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 53623787d..6a7153e4d 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "tcp_state", diff --git a/pkg/tcpip/transport/tcp/testing/context/BUILD b/pkg/tcpip/transport/tcp/testing/context/BUILD index 3caa38bcb..7a95594ef 100644 --- a/pkg/tcpip/transport/tcp/testing/context/BUILD +++ b/pkg/tcpip/transport/tcp/testing/context/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "context", diff --git a/pkg/tcpip/transport/tcpconntrack/BUILD b/pkg/tcpip/transport/tcpconntrack/BUILD index 3d748528e..46da3e6f1 100644 --- a/pkg/tcpip/transport/tcpconntrack/BUILD +++ b/pkg/tcpip/transport/tcpconntrack/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tcpconntrack", diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 4f7a47973..790dd55a3 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,8 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "udp_state", diff --git a/pkg/tcpip/transport/unix/BUILD b/pkg/tcpip/transport/unix/BUILD index d58f06544..676f2cf92 100644 --- a/pkg/tcpip/transport/unix/BUILD +++ b/pkg/tcpip/transport/unix/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_stateify( name = "unix_state", diff --git a/pkg/tmutex/BUILD b/pkg/tmutex/BUILD index d9a2c5ae5..d18338fff 100644 --- a/pkg/tmutex/BUILD +++ b/pkg/tmutex/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tmutex", diff --git a/pkg/unet/BUILD b/pkg/unet/BUILD index e8e40315a..acdfd7cb6 100644 --- a/pkg/unet/BUILD +++ b/pkg/unet/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "unet", diff --git a/pkg/urpc/BUILD b/pkg/urpc/BUILD index b29b25637..d32c57d1a 100644 --- a/pkg/urpc/BUILD +++ b/pkg/urpc/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "urpc", diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 032ec3237..8256acdb4 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("//tools/go_stateify:defs.bzl", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_stateify( name = "waiter_state", diff --git a/pkg/waiter/fdnotifier/BUILD b/pkg/waiter/fdnotifier/BUILD index d5b5ee82d..4e582755d 100644 --- a/pkg/waiter/fdnotifier/BUILD +++ b/pkg/waiter/fdnotifier/BUILD @@ -1,6 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "fdnotifier", diff --git a/tools/go_stateify/defs.bzl b/tools/go_stateify/defs.bzl index 60a9895ff..2b2582b7a 100644 --- a/tools/go_stateify/defs.bzl +++ b/tools/go_stateify/defs.bzl @@ -22,6 +22,8 @@ go_library( ) """ +load("@io_bazel_rules_go//go:def.bzl", _go_library = "go_library", _go_test = "go_test") + def _go_stateify_impl(ctx): """Implementation for the stateify tool.""" output = ctx.outputs.out @@ -33,6 +35,8 @@ def _go_stateify_impl(ctx): args += ["-statepkg=%s" % ctx.attr._statepkg] if ctx.attr.imports: args += ["-imports=%s" % ",".join(ctx.attr.imports)] + if ctx.attr.explicit: + args += ["-explicit=true"] args += ["--"] for src in ctx.attr.srcs: args += [f.path for f in src.files] @@ -45,17 +49,15 @@ def _go_stateify_impl(ctx): executable = ctx.executable._tool, ) -""" -Generates save and restore logic from a set of Go files. - - -Args: - name: the name of the rule. - srcs: the input source files. These files should include all structs in the package that need to be saved. - imports: an optional list of extra non-aliased, Go-style absolute import paths. - out: the name of the generated file output. This must not conflict with any other files and must be added to the srcs of the relevant go_library. - package: the package name for the input sources. -""" +# Generates save and restore logic from a set of Go files. +# +# Args: +# name: the name of the rule. +# srcs: the input source files. These files should include all structs in the package that need to be saved. +# imports: an optional list of extra non-aliased, Go-style absolute import paths. +# out: the name of the generated file output. This must not conflict with any other files and must be added to the srcs of the relevant go_library. +# package: the package name for the input sources. +# explicit: only generate for types explicitly annotated as savable. go_stateify = rule( implementation = _go_stateify_impl, attrs = { @@ -63,7 +65,41 @@ go_stateify = rule( "imports": attr.string_list(mandatory = False), "package": attr.string(mandatory = True), "out": attr.output(mandatory = True), + "explicit": attr.bool(default = False), "_tool": attr.label(executable = True, cfg = "host", default = Label("//tools/go_stateify:stateify")), "_statepkg": attr.string(default = "gvisor.googlesource.com/gvisor/pkg/state"), }, ) + +def go_library(name, srcs, deps = [], imports = [], **kwargs): + """wraps the standard go_library and does stateification.""" + if "encode_unsafe.go" not in srcs and (name + "_state_autogen.go") not in srcs: + # Only do stateification for non-state packages without manual autogen. + go_stateify( + name = name + "_state_autogen", + srcs = [src for src in srcs if src.endswith(".go")], + imports = imports, + package = name, + out = name + "_state_autogen.go", + explicit = True, + ) + all_srcs = srcs + [name + "_state_autogen.go"] + if "//pkg/state" not in deps: + all_deps = deps + ["//pkg/state"] + else: + all_deps = deps + else: + all_deps = deps + all_srcs = srcs + _go_library( + name = name, + srcs = all_srcs, + deps = all_deps, + **kwargs + ) + +def go_test(**kwargs): + """Wraps the standard go_test.""" + _go_test( + **kwargs + ) diff --git a/tools/go_stateify/main.go b/tools/go_stateify/main.go index 6c3583c62..231c6d80b 100644 --- a/tools/go_stateify/main.go +++ b/tools/go_stateify/main.go @@ -25,6 +25,7 @@ import ( "os" "reflect" "strings" + "sync" ) var ( @@ -32,6 +33,7 @@ var ( imports = flag.String("imports", "", "extra imports for the output file") output = flag.String("output", "", "output file") statePkg = flag.String("statepkg", "", "state import package; defaults to empty") + explicit = flag.Bool("explicit", false, "only generate for types explicitly tagged '// +stateify savable'") ) // resolveTypeName returns a qualified type name. @@ -224,16 +226,24 @@ func main() { // Emit the package name. fmt.Fprint(outputFile, "// automatically generated by stateify.\n\n") fmt.Fprintf(outputFile, "package %s\n\n", *pkg) - fmt.Fprint(outputFile, "import (\n") - if *statePkg != "" { - fmt.Fprintf(outputFile, " \"%s\"\n", *statePkg) - } - if *imports != "" { - for _, i := range strings.Split(*imports, ",") { - fmt.Fprintf(outputFile, " \"%s\"\n", i) - } + + // Emit the imports lazily. + var once sync.Once + maybeEmitImports := func() { + once.Do(func() { + // Emit the imports. + fmt.Fprint(outputFile, "import (\n") + if *statePkg != "" { + fmt.Fprintf(outputFile, " \"%s\"\n", *statePkg) + } + if *imports != "" { + for _, i := range strings.Split(*imports, ",") { + fmt.Fprintf(outputFile, " \"%s\"\n", i) + } + } + fmt.Fprint(outputFile, ")\n\n") + }) } - fmt.Fprint(outputFile, ")\n\n") files := make([]*ast.File, 0, len(flag.Args())) @@ -241,7 +251,7 @@ func main() { for _, filename := range flag.Args() { // Parse the file. fset := token.NewFileSet() - f, err := parser.ParseFile(fset, filename, nil, 0) + f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) if err != nil { // Not a valid input file? fmt.Fprintf(os.Stderr, "Input %q can't be parsed: %v\n", filename, err) @@ -308,6 +318,26 @@ func main() { continue } + if *explicit { + // In explicit mode, only generate code for + // types explicitly marked + // "// +stateify savable" in one of the + // proceeding comment lines. + if d.Doc == nil { + continue + } + savable := false + for _, l := range d.Doc.List { + if l.Text == "// +stateify savable" { + savable = true + break + } + } + if !savable { + continue + } + } + for _, gs := range d.Specs { ts := gs.(*ast.TypeSpec) switch ts.Type.(type) { @@ -315,6 +345,8 @@ func main() { // Don't register. break case *ast.StructType: + maybeEmitImports() + ss := ts.Type.(*ast.StructType) // Define beforeSave if a definition was not found. This @@ -360,6 +392,8 @@ func main() { // Add to our registration. emitRegister(ts.Name.Name) case *ast.Ident, *ast.SelectorExpr, *ast.ArrayType: + maybeEmitImports() + _, val := resolveTypeName(ts.Name.Name, ts.Type) // Dispatch directly. @@ -377,10 +411,12 @@ func main() { } } - // Emit the init() function. - fmt.Fprintf(outputFile, "func init() {\n") - for _, ic := range initCalls { - fmt.Fprintf(outputFile, " %s\n", ic) + if len(initCalls) > 0 { + // Emit the init() function. + fmt.Fprintf(outputFile, "func init() {\n") + for _, ic := range initCalls { + fmt.Fprintf(outputFile, " %s\n", ic) + } + fmt.Fprintf(outputFile, "}\n") } - fmt.Fprintf(outputFile, "}\n") } -- cgit v1.2.3 From 2793f7ac5f96b474decfff68cfde86bb5c2ed0a4 Mon Sep 17 00:00:00 2001 From: Justine Olshan Date: Fri, 27 Jul 2018 12:26:42 -0700 Subject: Added the O_LARGEFILE flag. This flag will always be true for gVisor files. PiperOrigin-RevId: 206355963 Change-Id: I2f03d2412e2609042df43b06d1318cba674574d0 --- pkg/abi/linux/fcntl.go | 5 +++ pkg/abi/linux/file.go | 16 ++++++++-- pkg/sentry/fs/flags.go | 6 ++++ pkg/sentry/syscalls/linux/flags.go | 59 ++++++++++++++++++----------------- pkg/sentry/syscalls/linux/sys_file.go | 2 ++ 5 files changed, 57 insertions(+), 31 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index f5dbe5199..2a5ad6ed7 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -27,3 +27,8 @@ const ( F_SETLKW = 7 F_SETOWN = 8 ) + +// Flags for fcntl. +const ( + FD_CLOEXEC = 00000001 +) diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 44672647b..f2b7e26ca 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -23,9 +23,19 @@ import ( // Constants for open(2). const ( - O_NONBLOCK = 00004000 - O_CLOEXEC = 02000000 - O_PATH = 010000000 + O_ACCMODE = 00000003 + O_RDONLY = 00000000 + O_WRONLY = 00000001 + O_RDWR = 00000002 + O_APPEND = 00002000 + O_NONBLOCK = 00004000 + O_ASYNC = 00020000 + O_DIRECT = 00040000 + O_LARGEFILE = 00100000 + O_DIRECTORY = 00200000 + O_CLOEXEC = 02000000 + O_SYNC = 04010000 + O_PATH = 010000000 ) // Constants for fstatat(2). diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index 7a8eefd02..810452584 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -45,6 +45,12 @@ type FileFlags struct { // Async indicates that this file sends signals on IO events. Async bool + + // LargeFile indicates that this file should be opened even if it has + // size greater than linux's off_t. When running in 64-bit mode, + // Linux sets this flag for all files. Since gVisor is only compatible + // with 64-bit Linux, it also sets this flag for all files. + LargeFile bool } // SettableFileFlags is a subset of FileFlags above that can be changed diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index 3d39a20f4..b2e173f3e 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -15,8 +15,7 @@ package linux import ( - "syscall" - + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" ) @@ -24,13 +23,13 @@ import ( // flagsToPermissions returns a Permissions object from Linux flags. // This includes truncate permission if O_TRUNC is set in the mask. func flagsToPermissions(mask uint) (p fs.PermMask) { - switch mask & syscall.O_ACCMODE { - case syscall.O_WRONLY: + switch mask & linux.O_ACCMODE { + case linux.O_WRONLY: p.Write = true - case syscall.O_RDWR: + case linux.O_RDWR: p.Write = true p.Read = true - case syscall.O_RDONLY: + case linux.O_RDONLY: p.Read = true } return @@ -39,7 +38,7 @@ func flagsToPermissions(mask uint) (p fs.PermMask) { // fdFlagsToLinux converts a kernel.FDFlags object to a Linux representation. func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) { if flags.CloseOnExec { - mask |= syscall.FD_CLOEXEC + mask |= linux.FD_CLOEXEC } return } @@ -47,30 +46,33 @@ func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) { // flagsToLinux converts a FileFlags object to a Linux representation. func flagsToLinux(flags fs.FileFlags) (mask uint) { if flags.Direct { - mask |= syscall.O_DIRECT + mask |= linux.O_DIRECT } if flags.NonBlocking { - mask |= syscall.O_NONBLOCK + mask |= linux.O_NONBLOCK } if flags.Sync { - mask |= syscall.O_SYNC + mask |= linux.O_SYNC } if flags.Append { - mask |= syscall.O_APPEND + mask |= linux.O_APPEND } if flags.Directory { - mask |= syscall.O_DIRECTORY + mask |= linux.O_DIRECTORY } if flags.Async { - mask |= syscall.O_ASYNC + mask |= linux.O_ASYNC + } + if flags.LargeFile { + mask |= linux.O_LARGEFILE } switch { case flags.Read && flags.Write: - mask |= syscall.O_RDWR + mask |= linux.O_RDWR case flags.Write: - mask |= syscall.O_WRONLY + mask |= linux.O_WRONLY case flags.Read: - mask |= syscall.O_RDONLY + mask |= linux.O_RDONLY } return } @@ -78,23 +80,24 @@ func flagsToLinux(flags fs.FileFlags) (mask uint) { // linuxToFlags converts linux file flags to a FileFlags object. func linuxToFlags(mask uint) (flags fs.FileFlags) { return fs.FileFlags{ - Direct: mask&syscall.O_DIRECT != 0, - Sync: mask&syscall.O_SYNC != 0, - NonBlocking: mask&syscall.O_NONBLOCK != 0, - Read: (mask & syscall.O_ACCMODE) != syscall.O_WRONLY, - Write: (mask & syscall.O_ACCMODE) != syscall.O_RDONLY, - Append: mask&syscall.O_APPEND != 0, - Directory: mask&syscall.O_DIRECTORY != 0, - Async: mask&syscall.O_ASYNC != 0, + Direct: mask&linux.O_DIRECT != 0, + Sync: mask&linux.O_SYNC != 0, + NonBlocking: mask&linux.O_NONBLOCK != 0, + Read: (mask & linux.O_ACCMODE) != linux.O_WRONLY, + Write: (mask & linux.O_ACCMODE) != linux.O_RDONLY, + Append: mask&linux.O_APPEND != 0, + Directory: mask&linux.O_DIRECTORY != 0, + Async: mask&linux.O_ASYNC != 0, + LargeFile: mask&linux.O_LARGEFILE != 0, } } // linuxToSettableFlags converts linux file flags to a SettableFileFlags object. func linuxToSettableFlags(mask uint) fs.SettableFileFlags { return fs.SettableFileFlags{ - Direct: mask&syscall.O_DIRECT != 0, - NonBlocking: mask&syscall.O_NONBLOCK != 0, - Append: mask&syscall.O_APPEND != 0, - Async: mask&syscall.O_ASYNC != 0, + Direct: mask&linux.O_DIRECT != 0, + NonBlocking: mask&linux.O_NONBLOCK != 0, + Append: mask&linux.O_APPEND != 0, + Async: mask&linux.O_ASYNC != 0, } } diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 66e6fd9d4..2f28fbea6 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -148,6 +148,8 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u } fileFlags := linuxToFlags(flags) + // Linux always adds the O_LARGEFILE flag when running in 64-bit mode. + fileFlags.LargeFile = true if fs.IsDir(d.Inode.StableAttr) { // Don't allow directories to be opened writable. if fileFlags.Write { -- cgit v1.2.3 From b9e1cf8404ce1263176643dee1a1cc835c9d1448 Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Wed, 1 Aug 2018 15:42:07 -0700 Subject: stateify: convert all packages to use explicit mode. PiperOrigin-RevId: 207007153 Change-Id: Ifedf1cc3758dc18be16647a4ece9c840c1c636c9 --- pkg/abi/BUILD | 13 +----- pkg/abi/linux/BUILD | 16 +------ pkg/abi/linux/bpf.go | 2 + pkg/abi/linux/tty.go | 2 + pkg/bpf/BUILD | 17 +------- pkg/bpf/interpreter.go | 2 + pkg/cpuid/BUILD | 15 +------ pkg/cpuid/cpuid.go | 2 + pkg/ilist/BUILD | 15 +------ pkg/ilist/list.go | 4 ++ pkg/segment/range.go | 2 + pkg/segment/set.go | 5 +++ pkg/sentry/arch/BUILD | 18 +------- pkg/sentry/arch/arch.go | 2 + pkg/sentry/arch/arch_amd64.go | 2 + pkg/sentry/arch/arch_state_x86.go | 1 + pkg/sentry/arch/arch_x86.go | 2 + pkg/sentry/arch/auxv.go | 2 + pkg/sentry/arch/signal_amd64.go | 6 +++ pkg/sentry/context/contexttest/BUILD | 17 +------- pkg/sentry/fs/BUILD | 36 +--------------- pkg/sentry/fs/ashmem/BUILD | 17 +------- pkg/sentry/fs/ashmem/area.go | 8 ++-- pkg/sentry/fs/ashmem/device.go | 22 +++++----- pkg/sentry/fs/ashmem/pin_board.go | 2 + pkg/sentry/fs/attr.go | 12 ++++++ pkg/sentry/fs/binder/BUILD | 13 +----- pkg/sentry/fs/binder/binder.go | 26 +++++++----- pkg/sentry/fs/dentry.go | 4 ++ pkg/sentry/fs/dev/BUILD | 20 +-------- pkg/sentry/fs/dev/dev.go | 2 + pkg/sentry/fs/dev/fs.go | 2 + pkg/sentry/fs/dev/full.go | 2 + pkg/sentry/fs/dev/null.go | 3 ++ pkg/sentry/fs/dev/random.go | 1 + pkg/sentry/fs/dirent.go | 2 + pkg/sentry/fs/dirent_cache.go | 2 + pkg/sentry/fs/fdpipe/BUILD | 31 +------------- pkg/sentry/fs/fdpipe/pipe.go | 2 + pkg/sentry/fs/file.go | 2 + pkg/sentry/fs/file_overlay.go | 4 ++ pkg/sentry/fs/filesystems.go | 2 + pkg/sentry/fs/filetest/BUILD | 18 +------- pkg/sentry/fs/flags.go | 2 + pkg/sentry/fs/fsutil/BUILD | 20 +-------- pkg/sentry/fs/fsutil/dirty_set.go | 2 + pkg/sentry/fs/fsutil/handle.go | 2 + pkg/sentry/fs/fsutil/host_file_mapper.go | 2 + pkg/sentry/fs/fsutil/inode.go | 6 +++ pkg/sentry/fs/fsutil/inode_cached.go | 2 + pkg/sentry/fs/gofer/BUILD | 23 +--------- pkg/sentry/fs/gofer/file.go | 2 + pkg/sentry/fs/gofer/fs.go | 2 + pkg/sentry/fs/gofer/inode.go | 4 ++ pkg/sentry/fs/gofer/session.go | 3 ++ pkg/sentry/fs/host/BUILD | 27 +----------- pkg/sentry/fs/host/descriptor.go | 2 + pkg/sentry/fs/host/file.go | 2 + pkg/sentry/fs/host/fs.go | 6 ++- pkg/sentry/fs/host/inode.go | 4 ++ pkg/sentry/fs/inode.go | 4 ++ pkg/sentry/fs/inode_inotify.go | 2 + pkg/sentry/fs/inotify.go | 2 + pkg/sentry/fs/inotify_event.go | 2 + pkg/sentry/fs/inotify_watch.go | 2 + pkg/sentry/fs/lock/BUILD | 15 +------ pkg/sentry/fs/lock/lock.go | 6 ++- pkg/sentry/fs/mount.go | 4 ++ pkg/sentry/fs/mount_overlay.go | 4 ++ pkg/sentry/fs/mounts.go | 2 + pkg/sentry/fs/overlay.go | 2 + pkg/sentry/fs/proc/BUILD | 34 +-------------- pkg/sentry/fs/proc/cpuinfo.go | 2 + pkg/sentry/fs/proc/exec_args.go | 2 + pkg/sentry/fs/proc/fds.go | 6 +++ pkg/sentry/fs/proc/file.go | 1 + pkg/sentry/fs/proc/filesystems.go | 2 + pkg/sentry/fs/proc/fs.go | 2 + pkg/sentry/fs/proc/loadavg.go | 2 + pkg/sentry/fs/proc/meminfo.go | 2 + pkg/sentry/fs/proc/mounts.go | 4 ++ pkg/sentry/fs/proc/proc.go | 4 ++ pkg/sentry/fs/proc/seqfile/BUILD | 30 ++----------- pkg/sentry/fs/proc/seqfile/seqfile.go | 4 ++ pkg/sentry/fs/proc/stat.go | 2 + pkg/sentry/fs/proc/sys.go | 5 +++ pkg/sentry/fs/proc/sys_net.go | 2 + pkg/sentry/fs/proc/task.go | 20 +++++++++ pkg/sentry/fs/proc/uid_gid_map.go | 3 ++ pkg/sentry/fs/proc/uptime.go | 2 + pkg/sentry/fs/proc/version.go | 2 + pkg/sentry/fs/ramfs/BUILD | 21 +-------- pkg/sentry/fs/ramfs/dir.go | 2 + pkg/sentry/fs/ramfs/ramfs.go | 2 + pkg/sentry/fs/ramfs/socket.go | 2 + pkg/sentry/fs/ramfs/symlink.go | 2 + pkg/sentry/fs/ramfs/test/BUILD | 18 +------- pkg/sentry/fs/sys/BUILD | 14 +----- pkg/sentry/fs/sys/fs.go | 2 + pkg/sentry/fs/sys/sys.go | 5 ++- pkg/sentry/fs/timerfd/BUILD | 18 +------- pkg/sentry/fs/timerfd/timerfd.go | 4 +- pkg/sentry/fs/tmpfs/BUILD | 17 +------- pkg/sentry/fs/tmpfs/file_regular.go | 2 + pkg/sentry/fs/tmpfs/fs.go | 2 + pkg/sentry/fs/tmpfs/inode_file.go | 2 + pkg/sentry/fs/tmpfs/tmpfs.go | 8 ++++ pkg/sentry/fs/tty/BUILD | 20 +-------- pkg/sentry/fs/tty/dir.go | 18 +++++--- pkg/sentry/fs/tty/fs.go | 4 ++ pkg/sentry/fs/tty/inode.go | 2 + pkg/sentry/fs/tty/line_discipline.go | 6 +++ pkg/sentry/fs/tty/master.go | 4 ++ pkg/sentry/fs/tty/queue.go | 4 +- pkg/sentry/fs/tty/slave.go | 4 ++ pkg/sentry/fs/tty/terminal.go | 2 + pkg/sentry/inet/BUILD | 15 +------ pkg/sentry/inet/inet.go | 2 + pkg/sentry/kernel/BUILD | 59 +++----------------------- pkg/sentry/kernel/abstract_socket_namespace.go | 3 ++ pkg/sentry/kernel/auth/BUILD | 17 +------- pkg/sentry/kernel/auth/credentials.go | 2 + pkg/sentry/kernel/auth/id_map.go | 2 + pkg/sentry/kernel/auth/user_namespace.go | 2 + pkg/sentry/kernel/epoll/BUILD | 15 +------ pkg/sentry/kernel/epoll/epoll.go | 8 +++- pkg/sentry/kernel/eventfd/BUILD | 18 +------- pkg/sentry/kernel/eventfd/eventfd.go | 4 +- pkg/sentry/kernel/fd_map.go | 6 +++ pkg/sentry/kernel/fs_context.go | 2 + pkg/sentry/kernel/futex/BUILD | 18 +------- pkg/sentry/kernel/futex/futex.go | 2 + pkg/sentry/kernel/ipc_namespace.go | 2 + pkg/sentry/kernel/kernel.go | 4 +- pkg/sentry/kernel/pending_signals.go | 5 +++ pkg/sentry/kernel/pipe/BUILD | 20 +-------- pkg/sentry/kernel/pipe/buffers.go | 2 + pkg/sentry/kernel/pipe/node.go | 2 + pkg/sentry/kernel/pipe/pipe.go | 2 + pkg/sentry/kernel/pipe/reader.go | 2 + pkg/sentry/kernel/pipe/reader_writer.go | 2 + pkg/sentry/kernel/pipe/writer.go | 2 + pkg/sentry/kernel/ptrace.go | 4 ++ pkg/sentry/kernel/rseq.go | 2 + pkg/sentry/kernel/semaphore/BUILD | 15 +------ pkg/sentry/kernel/semaphore/semaphore.go | 8 ++++ pkg/sentry/kernel/sessions.go | 4 ++ pkg/sentry/kernel/shm/BUILD | 13 +----- pkg/sentry/kernel/shm/shm.go | 4 ++ pkg/sentry/kernel/signal_handlers.go | 2 + pkg/sentry/kernel/syscalls.go | 2 + pkg/sentry/kernel/syslog.go | 2 + pkg/sentry/kernel/task.go | 2 + pkg/sentry/kernel/task_clone.go | 4 ++ pkg/sentry/kernel/task_context.go | 2 + pkg/sentry/kernel/task_exec.go | 4 ++ pkg/sentry/kernel/task_exit.go | 6 +++ pkg/sentry/kernel/task_resources.go | 2 + pkg/sentry/kernel/task_run.go | 2 + pkg/sentry/kernel/task_sched.go | 2 + pkg/sentry/kernel/task_signals.go | 5 +++ pkg/sentry/kernel/task_syscall.go | 4 ++ pkg/sentry/kernel/thread_group.go | 2 + pkg/sentry/kernel/threads.go | 8 ++++ pkg/sentry/kernel/time/BUILD | 14 +----- pkg/sentry/kernel/time/time.go | 6 +++ pkg/sentry/kernel/timekeeper.go | 2 + pkg/sentry/kernel/timer.go | 8 ++++ pkg/sentry/kernel/uts_namespace.go | 2 + pkg/sentry/kernel/vdso.go | 2 + pkg/sentry/limits/BUILD | 13 +----- pkg/sentry/limits/limits.go | 4 ++ pkg/sentry/loader/BUILD | 15 +------ pkg/sentry/loader/vdso.go | 2 + pkg/sentry/loader/vdso_state.go | 1 + pkg/sentry/memmap/BUILD | 15 +------ pkg/sentry/memmap/mapping_set.go | 2 + pkg/sentry/mm/BUILD | 21 +-------- pkg/sentry/mm/aio_context.go | 8 ++++ pkg/sentry/mm/mm.go | 7 +++ pkg/sentry/mm/special_mappable.go | 2 + pkg/sentry/platform/BUILD | 13 +----- pkg/sentry/platform/filemem/BUILD | 14 +----- pkg/sentry/platform/filemem/filemem.go | 2 + pkg/sentry/socket/BUILD | 17 +------- pkg/sentry/socket/control/BUILD | 23 +++------- pkg/sentry/socket/control/control.go | 4 ++ pkg/sentry/socket/epsocket/BUILD | 16 +------ pkg/sentry/socket/epsocket/epsocket.go | 2 + pkg/sentry/socket/epsocket/stack.go | 2 + pkg/sentry/socket/hostinet/BUILD | 15 +------ pkg/sentry/socket/netlink/BUILD | 13 +----- pkg/sentry/socket/netlink/port/BUILD | 15 +------ pkg/sentry/socket/netlink/port/port.go | 2 + pkg/sentry/socket/netlink/route/BUILD | 17 +------- pkg/sentry/socket/netlink/route/protocol.go | 2 + pkg/sentry/socket/netlink/socket.go | 2 + pkg/sentry/socket/socket.go | 2 + pkg/sentry/socket/unix/BUILD | 13 +----- pkg/sentry/socket/unix/unix.go | 2 + pkg/sentry/syscalls/linux/BUILD | 20 +-------- pkg/sentry/syscalls/linux/sys_aio.go | 2 + pkg/sentry/syscalls/linux/sys_futex.go | 2 + pkg/sentry/syscalls/linux/sys_poll.go | 2 + pkg/sentry/syscalls/linux/sys_time.go | 2 + pkg/sentry/usage/BUILD | 17 +------- pkg/sentry/usage/cpu.go | 2 + pkg/sentry/usage/io.go | 2 + pkg/sentry/usermem/BUILD | 16 +------ pkg/sentry/usermem/access_type.go | 2 + pkg/sentry/usermem/addr.go | 2 + pkg/tcpip/BUILD | 17 +------- pkg/tcpip/buffer/BUILD | 13 +----- pkg/tcpip/buffer/view.go | 2 + pkg/tcpip/header/BUILD | 13 +----- pkg/tcpip/header/tcp.go | 4 ++ pkg/tcpip/network/fragmentation/BUILD | 11 +---- pkg/tcpip/seqnum/BUILD | 17 +------- pkg/tcpip/tcpip.go | 4 ++ pkg/tcpip/transport/ping/BUILD | 17 +------- pkg/tcpip/transport/ping/endpoint.go | 1 + pkg/tcpip/transport/queue/BUILD | 17 +------- pkg/tcpip/transport/queue/queue.go | 2 + pkg/tcpip/transport/tcp/BUILD | 25 +---------- pkg/tcpip/transport/tcp/endpoint.go | 4 ++ pkg/tcpip/transport/tcp/rcv.go | 2 + pkg/tcpip/transport/tcp/reno.go | 2 + pkg/tcpip/transport/tcp/segment.go | 2 + pkg/tcpip/transport/tcp/segment_queue.go | 2 + pkg/tcpip/transport/tcp/snd.go | 4 ++ pkg/tcpip/transport/tcp/snd_state.go | 1 + pkg/tcpip/transport/udp/BUILD | 17 +------- pkg/tcpip/transport/udp/endpoint.go | 3 ++ pkg/tcpip/transport/unix/BUILD | 16 +------ pkg/tcpip/transport/unix/connectioned.go | 2 + pkg/tcpip/transport/unix/connectionless.go | 2 + pkg/tcpip/transport/unix/unix.go | 11 +++++ pkg/waiter/BUILD | 21 ++------- pkg/waiter/waiter.go | 2 + 239 files changed, 662 insertions(+), 1108 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index f1e6bac67..c014d2c4b 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,24 +1,13 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "abi_state", - srcs = [ - "abi.go", - ], - out = "abi_state.go", - package = "abi", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "abi", srcs = [ "abi.go", - "abi_state.go", "flag.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/abi", visibility = ["//:sandbox"], - deps = ["//pkg/state"], ) diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 38b4829c9..ac4ceefbc 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -4,19 +4,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "linux_state", - srcs = [ - "binder.go", - "bpf.go", - "time.go", - "tty.go", - ], - out = "linux_state.go", - package = "linux", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "linux", @@ -41,7 +29,6 @@ go_library( "ipc.go", "limits.go", "linux.go", - "linux_state.go", "mm.go", "netdevice.go", "netlink.go", @@ -67,6 +54,5 @@ go_library( "//pkg/abi", "//pkg/binary", "//pkg/bits", - "//pkg/state", ], ) diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index f597ef4f5..80e5b1af1 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -15,6 +15,8 @@ package linux // BPFInstruction is a raw BPF virtual machine instruction. +// +// +stateify savable type BPFInstruction struct { // OpCode is the operation to execute. OpCode uint16 diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index 84b6ccc87..b640f7627 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -38,6 +38,8 @@ type Termios struct { // KernelTermios is struct ktermios/struct termios2, defined in // uapi/asm-generic/termbits.h. +// +// +stateify savable type KernelTermios struct { InputFlags uint32 OutputFlags uint32 diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index 403270049..564df3af5 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,21 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "bpf_state", - srcs = [ - "interpreter.go", - ], - out = "bpf_state.go", - package = "bpf", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "bpf", srcs = [ "bpf.go", - "bpf_state.go", "decoder.go", "input_bytes.go", "interpreter.go", @@ -23,10 +13,7 @@ go_library( ], importpath = "gvisor.googlesource.com/gvisor/pkg/bpf", visibility = ["//visibility:public"], - deps = [ - "//pkg/abi/linux", - "//pkg/state", - ], + deps = ["//pkg/abi/linux"], ) go_test( diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index b7dee86a8..111ada9d1 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -88,6 +88,8 @@ func (e Error) Error() string { } // Program is a BPF program that has been validated for consistency. +// +// +stateify savable type Program struct { instructions []linux.BPFInstruction } diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index 9a0ca1b33..46fc4703b 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,27 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "cpuid_state", - srcs = ["cpuid.go"], - out = "cpuid_state.go", - package = "cpuid", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "cpuid", srcs = [ "cpu_amd64.s", "cpuid.go", - "cpuid_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/cpuid", visibility = ["//:sandbox"], - deps = [ - "//pkg/log", - "//pkg/state", - ], + deps = ["//pkg/log"], ) go_test( diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index b486ab037..e91e34dc7 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -409,6 +409,8 @@ func (f Feature) flagString(cpuinfoOnly bool) string { } // FeatureSet is a set of Features for a cpu. +// +// +stateify savable type FeatureSet struct { // Set is the set of features that are enabled in this FeatureSet. Set map[Feature]bool diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index e32f26ffa..b26a39132 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,28 +1,15 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "list_state", - srcs = [ - "interface_list.go", - ], - out = "interface_list_state.go", - package = "ilist", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ilist", srcs = [ "interface_list.go", - "interface_list_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/ilist", visibility = ["//visibility:public"], - deps = [ - "//pkg/state", - ], ) go_template_instance( diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 5efb6c072..a88b82196 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -36,6 +36,8 @@ type Linker interface { // for e := l.Front(); e != nil; e = e.Next() { // // do something with e. // } +// +// +stateify savable type List struct { head Linker tail Linker @@ -155,6 +157,8 @@ func (l *List) Remove(e Linker) { // Entry is a default implementation of Linker. Users can add anonymous fields // of this type to their structs to make them automatically implement the // methods needed by List. +// +// +stateify savable type Entry struct { next Linker prev Linker diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 5ff30d489..34c067265 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -18,6 +18,8 @@ package segment type T uint64 // A Range represents a contiguous range of T. +// +// +stateify savable type Range struct { // Start is the inclusive start of the range. Start T diff --git a/pkg/segment/set.go b/pkg/segment/set.go index 6eed1d930..cffec2a2c 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -88,6 +88,8 @@ const ( // A Set is a mapping of segments with non-overlapping Range keys. The zero // value for a Set is an empty set. Set values are not safely movable nor // copyable. Set is thread-compatible. +// +// +stateify savable type Set struct { root node `state:".(*SegmentDataSlices)"` } @@ -596,6 +598,7 @@ func (s *Set) ApplyContiguous(r Range, fn func(seg Iterator)) GapIterator { } } +// +stateify savable type node struct { // An internal binary tree node looks like: // @@ -1317,6 +1320,8 @@ func (n *node) writeDebugString(buf *bytes.Buffer, prefix string) { // SegmentDataSlices represents segments from a set as slices of start, end, and // values. SegmentDataSlices is primarily used as an intermediate representation // for save/restore and the layout here is optimized for that. +// +// +stateify savable type SegmentDataSlices struct { Start []Key End []Key diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index 0a2a35400..314b3e962 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,21 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "arch_state", - srcs = [ - "arch.go", - "arch_amd64.go", - "arch_state_x86.go", - "arch_x86.go", - "auxv.go", - "signal_amd64.go", - ], - out = "arch_state.go", - package = "arch", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "arch", @@ -24,7 +10,6 @@ go_library( "arch.go", "arch_amd64.go", "arch_amd64.s", - "arch_state.go", "arch_state_x86.go", "arch_x86.go", "auxv.go", @@ -46,7 +31,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/limits", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 0189e958d..21cb84502 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -254,6 +254,8 @@ const ( // MemoryManager. // // Note that "highest address" below is always exclusive. +// +// +stateify savable type MmapLayout struct { // MinAddr is the lowest mappable address. MinAddr usermem.Addr diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 23526fe8e..f1e408af9 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -95,6 +95,8 @@ const ( ) // context64 represents an AMD64 context. +// +// +stateify savable type context64 struct { State sigFPState []x86FPState // fpstate to be restored on sigreturn. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index cb38d098a..e9c23a06b 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -56,6 +56,7 @@ func (s *State) afterLoad() { copy(s.x86FPState, old) } +// +stateify savable type syscallPtraceRegs struct { R15 uint64 R14 uint64 diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index 5cc4f8377..b35eec53c 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -153,6 +153,8 @@ func NewFloatingPointData() *FloatingPointData { // State contains the common architecture bits for X86 (the build tag of this // file ensures it's only built on x86). +// +// +stateify savable type State struct { // The system registers. Regs syscall.PtraceRegs `state:".(syscallPtraceRegs)"` diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 70e0e35b7..81cfb4a01 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -19,6 +19,8 @@ import ( ) // An AuxEntry represents an entry in an ELF auxiliary vector. +// +// +stateify savable type AuxEntry struct { Key uint64 Value usermem.Addr diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index c1d743f38..e81717e8b 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -28,6 +28,8 @@ import ( // SignalAct represents the action that should be taken when a signal is // delivered, and is equivalent to struct sigaction on 64-bit x86. +// +// +stateify savable type SignalAct struct { Handler uint64 Flags uint64 @@ -47,6 +49,8 @@ func (s *SignalAct) DeserializeTo(other *SignalAct) { // SignalStack represents information about a user stack, and is equivalent to // stack_t on 64-bit x86. +// +// +stateify savable type SignalStack struct { Addr uint64 Flags uint32 @@ -66,6 +70,8 @@ func (s *SignalStack) DeserializeTo(other *SignalStack) { // SignalInfo represents information about a signal being delivered, and is // equivalent to struct siginfo on 64-bit x86. +// +// +stateify savable type SignalInfo struct { Signo int32 // Signal number Errno int32 // Errno value diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 591b11a4d..01bb40b04 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,23 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "contexttest_state", - srcs = [ - "contexttest.go", - ], - out = "contexttest_state.go", - package = "contexttest", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "contexttest", testonly = 1, - srcs = [ - "contexttest.go", - "contexttest_state.go", - ], + srcs = ["contexttest.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest", visibility = ["//pkg/sentry:internal"], deps = [ @@ -28,6 +16,5 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/platform/ptrace", "//pkg/sentry/uniqueid", - "//pkg/state", ], ) diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index e3c9a9b70..18cd5ae8e 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,40 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "fs_state", - srcs = [ - "attr.go", - "dentry.go", - "dirent.go", - "dirent_cache.go", - "dirent_list.go", - "dirent_state.go", - "file.go", - "file_overlay.go", - "file_state.go", - "filesystems.go", - "flags.go", - "inode.go", - "inode_inotify.go", - "inode_operations.go", - "inode_overlay.go", - "inotify.go", - "inotify_event.go", - "inotify_watch.go", - "mock.go", - "mount.go", - "mount_overlay.go", - "mount_state.go", - "mounts.go", - "overlay.go", - "path.go", - ], - out = "fs_state.go", - package = "fs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fs", @@ -54,7 +21,6 @@ go_library( "filesystems.go", "flags.go", "fs.go", - "fs_state.go", "inode.go", "inode_inotify.go", "inode_operations.go", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index 9f166799a..dc893d22f 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,26 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -go_stateify( - name = "ashmem_state", - srcs = [ - "area.go", - "device.go", - "pin_board.go", - "uint64_range.go", - "uint64_set.go", - ], - out = "ashmem_state.go", - package = "ashmem", -) - go_library( name = "ashmem", srcs = [ "area.go", - "ashmem_state.go", "device.go", "pin_board.go", "uint64_range.go", @@ -41,7 +27,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", ], diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index e4f76f0d0..bfd7f2762 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -39,10 +39,12 @@ const ( ) // Area implements fs.FileOperations. +// +// +stateify savable type Area struct { - fsutil.NoFsync - fsutil.DeprecatedFileOperations - fsutil.NotDirReaddir + fsutil.NoFsync `state:"nosave"` + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.NotDirReaddir `state:"nosave"` ad *Device diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index c5b51d4a7..d0986fa11 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -27,17 +27,19 @@ import ( ) // Device implements fs.InodeOperations. +// +// +stateify savable type Device struct { - fsutil.DeprecatedFileOperations - fsutil.InodeNoExtendedAttributes - fsutil.InodeNotDirectory - fsutil.InodeNotRenameable - fsutil.InodeNotSocket - fsutil.InodeNotSymlink - fsutil.NoFsync - fsutil.NoMappable - fsutil.NoopWriteOut - fsutil.NotDirReaddir + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.NoFsync `state:"nosave"` + fsutil.NoMappable `state:"nosave"` + fsutil.NoopWriteOut `state:"nosave"` + fsutil.NotDirReaddir `state:"nosave"` mu sync.Mutex `state:"nosave"` unstable fs.UnstableAttr diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index c7fb3822c..ecba395a0 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -56,6 +56,8 @@ func (setFunctions) Split(Range, noValue, uint64) (noValue, noValue) { // segment.Set is used for implementation where segments represent // ranges of pinned bytes, while gaps represent ranges of unpinned // bytes. All ranges are page-aligned. +// +// +stateify savable type PinBoard struct { Set } diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 56a2ad6f7..4178f18b2 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -91,6 +91,8 @@ func (n InodeType) String() string { // StableAttr contains Inode attributes that will be stable throughout the // lifetime of the Inode. +// +// +stateify savable type StableAttr struct { // Type is the InodeType of a InodeOperations. Type InodeType @@ -150,6 +152,8 @@ func IsCharDevice(s StableAttr) bool { // UnstableAttr contains Inode attributes that may change over the lifetime // of the Inode. +// +// +stateify savable type UnstableAttr struct { // Size is the file size in bytes. Size int64 @@ -186,6 +190,8 @@ func WithCurrentTime(ctx context.Context, u UnstableAttr) UnstableAttr { } // AttrMask contains fields to mask StableAttr and UnstableAttr. +// +// +stateify savable type AttrMask struct { Type bool DeviceID bool @@ -227,6 +233,8 @@ func (a AttrMask) Union(b AttrMask) AttrMask { } // PermMask are file access permissions. +// +// +stateify savable type PermMask struct { // Read indicates reading is permitted. Read bool @@ -280,6 +288,8 @@ func (p PermMask) SupersetOf(other PermMask) bool { // FilePermissions represents the permissions of a file, with // Read/Write/Execute bits for user, group, and other. +// +// +stateify savable type FilePermissions struct { User PermMask Group PermMask @@ -370,6 +380,8 @@ func (f FilePermissions) AnyRead() bool { } // FileOwner represents ownership of a file. +// +// +stateify savable type FileOwner struct { UID auth.KUID GID auth.KGID diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index ec3928baf..a077b91d2 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,25 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "binder_state", - srcs = ["binder.go"], - out = "binder_state.go", - package = "binder", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "binder", srcs = [ "binder.go", - "binder_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/binder", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -30,8 +21,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", - "//pkg/tcpip/transport/unix", ], ) diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index 3f87b6b08..502a262dd 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -40,15 +40,17 @@ const ( ) // Device implements fs.InodeOperations. +// +// +stateify savable type Device struct { - fsutil.InodeNoExtendedAttributes - fsutil.InodeNotDirectory - fsutil.InodeNotRenameable - fsutil.InodeNotSocket - fsutil.InodeNotSymlink - fsutil.NoMappable - fsutil.NoopWriteOut - fsutil.DeprecatedFileOperations + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.NoMappable `state:"nosave"` + fsutil.NoopWriteOut `state:"nosave"` + fsutil.DeprecatedFileOperations `state:"nosave"` // mu protects unstable. mu sync.Mutex `state:"nosave"` @@ -186,10 +188,12 @@ func (bd *Device) StatFS(context.Context) (fs.Info, error) { } // Proc implements fs.FileOperations and fs.IoctlGetter. +// +// +stateify savable type Proc struct { - fsutil.NoFsync - fsutil.DeprecatedFileOperations - fsutil.NotDirReaddir + fsutil.NoFsync `state:"nosave"` + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.NotDirReaddir `state:"nosave"` bd *Device task *kernel.Task diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index d42e8da81..b347468ff 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -21,6 +21,8 @@ import ( ) // DentAttr is the metadata of a directory entry. It is a subset of StableAttr. +// +// +stateify savable type DentAttr struct { // Type is the InodeType of an Inode. Type InodeType @@ -154,6 +156,8 @@ func GenericReaddir(ctx *DirCtx, s *SortedDentryMap) (int, error) { } // SortedDentryMap is a sorted map of names and fs.DentAttr entries. +// +// +stateify savable type SortedDentryMap struct { // names is always kept in sorted-order. names []string diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index ea41615fd..fc069bb5f 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,25 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "dev_state", - srcs = [ - "dev.go", - "fs.go", - "full.go", - "null.go", - "random.go", - ], - out = "dev_state.go", - package = "dev", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "dev", srcs = [ "dev.go", - "dev_state.go", "device.go", "fs.go", "full.go", @@ -30,8 +16,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", - "//pkg/log", "//pkg/rand", "//pkg/sentry/context", "//pkg/sentry/device", @@ -45,9 +29,7 @@ go_library( "//pkg/sentry/mm", "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index 36c61bfc2..3f4f2a40a 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -27,6 +27,8 @@ import ( ) // Dev is the root node. +// +// +stateify savable type Dev struct { ramfs.Dir } diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index 3c79f3782..2ae49be4e 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -29,6 +29,8 @@ const binderEnabledKey = "binder_enabled" const ashmemEnabledKey = "ashmem_enabled" // filesystem is a devtmpfs. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index e13eb6c03..492b8eb3a 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -26,6 +26,8 @@ import ( ) // fullDevice is used to implement /dev/full. +// +// +stateify savable type fullDevice struct { ramfs.Entry } diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 66b8ba967..2977c8670 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -29,6 +29,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// +stateify savable type nullDevice struct { ramfs.Entry } @@ -54,6 +55,7 @@ func (n *nullDevice) Truncate(context.Context, *fs.Inode, int64) error { return nil } +// +stateify savable type zeroDevice struct { nullDevice } @@ -80,6 +82,7 @@ func (zd *zeroDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.F }), nil } +// +stateify savable type zeroFileOperations struct { fs.FileOperations } diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index 33a045a05..47b76218f 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -24,6 +24,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// +stateify savable type randomDevice struct { ramfs.Entry } diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index f9bf2fba6..4658d044f 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -81,6 +81,8 @@ var renameMu sync.RWMutex // // Dirents currently do not attempt to free entries that lack application references under // memory pressure. +// +// +stateify savable type Dirent struct { // AtomicRefCount is our reference count. refs.AtomicRefCount diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index e786e4f65..c680e4828 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -25,6 +25,8 @@ import ( // // A nil DirentCache corresponds to a cache with size 0. All methods can be // called, but nothing is actually cached. +// +// +stateify savable type DirentCache struct { // Maximum size of the cache. This must be saved manually, to handle the case // when cache is nil. diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 4fcb06f1f..ffe4204bc 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,54 +1,27 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "pipe_state", - srcs = [ - "pipe.go", - "pipe_state.go", - ], - out = "pipe_autogen_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], - package = "fdpipe", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fdpipe", srcs = [ "pipe.go", - "pipe_autogen_state.go", "pipe_opener.go", "pipe_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fdpipe", + imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/abi/linux", - "//pkg/amutex", "//pkg/fd", "//pkg/log", - "//pkg/metric", - "//pkg/p9", - "//pkg/refs", "//pkg/secio", "//pkg/sentry/context", - "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", - "//pkg/sentry/fs/lock", - "//pkg/sentry/kernel/auth", - "//pkg/sentry/kernel/time", - "//pkg/sentry/memmap", - "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", - "//pkg/tcpip", - "//pkg/tcpip/transport/unix", - "//pkg/unet", "//pkg/waiter", "//pkg/waiter/fdnotifier", ], diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 7b318e35f..2e34604e6 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -34,6 +34,8 @@ import ( ) // pipeOperations are the fs.FileOperations of a host pipe. +// +// +stateify savable type pipeOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 6d93ef760..8e535a618 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -47,6 +47,8 @@ const FileMaxOffset = math.MaxInt64 // and write(2). // // FIXME: Split synchronization from cancellation. +// +// +stateify savable type File struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 36b2cf75e..113962368 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -60,6 +60,8 @@ func overlayFile(ctx context.Context, inode *Inode, flags FileFlags) (*File, err } // overlayFileOperations implements FileOperations for a file in an overlay. +// +// +stateify savable type overlayFileOperations struct { // upperMu protects upper below. In contrast lower is stable. upperMu sync.Mutex `state:"nosave"` @@ -375,6 +377,8 @@ func readdirOne(ctx context.Context, d *Dirent) (map[string]DentAttr, error) { // overlayMappingIdentity wraps a MappingIdentity, and also holds a reference // on a file during its lifetime. +// +// +stateify savable type overlayMappingIdentity struct { refs.AtomicRefCount id memmap.MappingIdentity diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index 200e792f4..5a1e7a270 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -125,6 +125,8 @@ func GetFilesystems() []Filesystem { } // MountSourceFlags represents all mount option flags as a struct. +// +// +stateify savable type MountSourceFlags struct { // ReadOnly corresponds to mount(2)'s "MS_RDONLY" and indicates that // the filesystem should be mounted read-only. diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index f481c57fb..d137fee4c 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,34 +1,20 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "filetest_state", - srcs = [ - "filetest.go", - ], - out = "filetest_state.go", - package = "filetest", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "filetest", testonly = 1, - srcs = [ - "filetest.go", - "filetest_state.go", - ], + srcs = ["filetest.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/filetest", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index da0ff58af..1aa271560 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -19,6 +19,8 @@ import ( ) // FileFlags encodes file flags. +// +// +stateify savable type FileFlags struct { // Direct indicates that I/O should be done directly. Direct bool diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 6eea64298..3512bae6f 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,24 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "fsutil_state", - srcs = [ - "dirty_set_impl.go", - "file.go", - "file_range_set_impl.go", - "frame_ref_set_impl.go", - "handle.go", - "host_file_mapper.go", - "host_file_mapper_state.go", - "inode.go", - "inode_cached.go", - ], - out = "fsutil_state.go", - package = "fsutil", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "dirty_set_impl", @@ -84,7 +67,6 @@ go_library( "frame_ref_set.go", "frame_ref_set_impl.go", "fsutil.go", - "fsutil_state.go", "handle.go", "host_file_mapper.go", "host_file_mapper_state.go", diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 9c6c98542..8e31e48fd 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -32,6 +32,8 @@ import ( // DirtyInfo is the value type of DirtySet, and represents information about a // Mappable offset that is dirty (the cached data for that offset is newer than // its source). +// +// +stateify savable type DirtyInfo struct { // Keep is true if the represented offset is concurrently writable, such // that writing the data for that offset back to the source does not diff --git a/pkg/sentry/fs/fsutil/handle.go b/pkg/sentry/fs/fsutil/handle.go index 149c0f84a..e7efd3c0f 100644 --- a/pkg/sentry/fs/fsutil/handle.go +++ b/pkg/sentry/fs/fsutil/handle.go @@ -27,6 +27,8 @@ import ( // // FIXME: Remove Handle entirely in favor of individual fs.File // implementations using simple generic utilities. +// +// +stateify savable type Handle struct { NoopRelease `state:"nosave"` NoIoctl `state:"nosave"` diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index d0a27fc1c..9c1e2f76f 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -29,6 +29,8 @@ import ( // HostFileMapper caches mappings of an arbitrary host file descriptor. It is // used by implementations of memmap.Mappable that represent a host file // descriptor. +// +// +stateify savable type HostFileMapper struct { // HostFile conceptually breaks the file into pieces called chunks, of // size and alignment chunkSize, and caches mappings of the file on a chunk diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index e1ad07df2..177396fdc 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -31,6 +31,8 @@ func NewSimpleInodeOperations(i InodeSimpleAttributes) fs.InodeOperations { } // simpleInodeOperations is a simple implementation of Inode. +// +// +stateify savable type simpleInodeOperations struct { DeprecatedFileOperations `state:"nosave"` InodeNotDirectory `state:"nosave"` @@ -48,6 +50,8 @@ type simpleInodeOperations struct { // InodeSimpleAttributes implements a subset of the Inode interface. It provides // read-only access to attributes. +// +// +stateify savable type InodeSimpleAttributes struct { // FSType is the filesystem type reported by StatFS. FSType uint64 @@ -110,6 +114,8 @@ func (*InodeSimpleAttributes) Truncate(context.Context, *fs.Inode, int64) error // // Users need not initialize Xattrs to non-nil (it will be initialized // when the first extended attribute is set. +// +// +stateify savable type InMemoryAttributes struct { Unstable fs.UnstableAttr Xattrs map[string][]byte diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index cba642a8f..0a320e2d8 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -55,6 +55,8 @@ import ( // // Implementations of InodeOperations.WriteOut must call Sync to write out // in-memory modifications of data and metadata to the CachedFileObject. +// +// +stateify savable type CachingInodeOperations struct { // backingFile is a handle to a cached file object. backingFile CachedFileObject diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index 1277379e7..cb17339c9 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,21 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "gofer_state", - srcs = [ - "file.go", - "file_state.go", - "fs.go", - "inode.go", - "inode_state.go", - "session.go", - "session_state.go", - ], - out = "gofer_state.go", - package = "gofer", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "gofer", @@ -27,7 +12,6 @@ go_library( "file.go", "file_state.go", "fs.go", - "gofer_state.go", "handles.go", "inode.go", "inode_state.go", @@ -41,7 +25,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", "//pkg/fd", "//pkg/log", "//pkg/metric", @@ -54,15 +37,11 @@ go_library( "//pkg/sentry/fs/fdpipe", "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/host", - "//pkg/sentry/fs/lock", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", - "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 039618808..46a6bbd5d 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -33,6 +33,8 @@ import ( var openedWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.") // fileOperations implements fs.FileOperations for a remote file system. +// +// +stateify savable type fileOperations struct { fsutil.NoIoctl `state:"nosave"` waiter.AlwaysReady `state:"nosave"` diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index dd5d43c47..3ae93f059 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -83,6 +83,8 @@ var ( ) // filesystem is a 9p client. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index df584c382..7fc8f77b0 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -35,6 +35,8 @@ import ( ) // inodeOperations implements fs.InodeOperations. +// +// +stateify savable type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` @@ -68,6 +70,8 @@ type inodeOperations struct { // circular load dependency between it and inodeOperations). Even with // lazy loading, this approach defines the dependencies between objects // and the expected load behavior more concretely. +// +// +stateify savable type inodeFileState struct { // s is common file system state for Gofers. s *session `state:"wait"` diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index b6841526a..648a11435 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -27,6 +27,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/unet" ) +// +stateify savable type endpointMap struct { mu sync.RWMutex `state:"nosave"` // TODO: Make map with private unix sockets savable. @@ -63,6 +64,8 @@ func (e *endpointMap) get(key device.MultiDeviceKey) unix.BoundEndpoint { } // session holds state for each 9p session established during sys_mount. +// +// +stateify savable type session struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 23ec66f50..29c79284a 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,23 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "host_state", - srcs = [ - "control.go", - "descriptor.go", - "descriptor_state.go", - "file.go", - "fs.go", - "inode.go", - "inode_state.go", - "socket.go", - "socket_state.go", - ], - out = "host_state.go", - package = "host", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "host", @@ -28,7 +11,6 @@ go_library( "device.go", "file.go", "fs.go", - "host_state.go", "inode.go", "inode_state.go", "ioctl_unsafe.go", @@ -42,7 +24,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", "//pkg/fd", "//pkg/log", "//pkg/refs", @@ -52,20 +33,14 @@ go_library( "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", - "//pkg/sentry/fs/lock", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", - "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/socket", "//pkg/sentry/socket/control", "//pkg/sentry/socket/unix", - "//pkg/sentry/uniqueid", - "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/link/rawfile", diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 613bd06e8..3aee4d11c 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -25,6 +25,8 @@ import ( ) // descriptor wraps a host fd. +// +// +stateify savable type descriptor struct { // donated is true if the host fd was donated by another process. donated bool diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index bdf844337..f9bef6d93 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -37,6 +37,8 @@ import ( ) // fileOperations implements fs.FileOperations for a host file descriptor. +// +// +stateify savable type fileOperations struct { fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index 974700636..e46ae433c 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -51,6 +51,8 @@ const maxTraversals = 10 // to lock down the configurations. This filesystem should only be mounted at root. // // Think twice before exposing this to applications. +// +// +stateify savable type Filesystem struct { // whitelist is a set of host paths to whitelist. paths []string @@ -266,8 +268,10 @@ func newMountSource(ctx context.Context, root string, mounter fs.FileOwner, file } // superOperations implements fs.MountSourceOperations. +// +// +stateify savable type superOperations struct { - fs.SimpleMountSourceOperations `state:"nosave"` + fs.SimpleMountSourceOperations // root is the path of the mount point. All inode mappings // are relative to this root. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 226bc5164..761ccde33 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -34,6 +34,8 @@ import ( // inodeOperations implements fs.InodeOperations for an fs.Inodes backed // by a host file descriptor. +// +// +stateify savable type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` @@ -65,6 +67,8 @@ type inodeOperations struct { // circular load dependency between it and inodeOperations). Even with // lazy loading, this approach defines the dependencies between objects // and the expected load behavior more concretely. +// +// +stateify savable type inodeFileState struct { // Common file system state. mops *superOperations `state:"wait"` diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index 6c8e6f188..d0dbce5dd 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -28,6 +28,8 @@ import ( // Inode is a file system object that can be simultaneously referenced by different // components of the VFS (Dirent, fs.File, etc). +// +// +stateify savable type Inode struct { // AtomicRefCount is our reference count. refs.AtomicRefCount @@ -58,6 +60,8 @@ type Inode struct { // Note that in Linux fcntl(2) and flock(2) locks are _not_ cooperative, because race and // deadlock conditions make merging them prohibitive. We do the same and keep them oblivious // to each other but provide a "context" as a convenient container. +// +// +stateify savable type LockCtx struct { // Posix is a set of POSIX-style regional advisory locks, see fcntl(2). Posix lock.Locks diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index 358bbecdf..683140afe 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -20,6 +20,8 @@ import ( ) // Watches is the collection of inotify watches on an inode. +// +// +stateify savable type Watches struct { // mu protects the fields below. mu sync.RWMutex `state:"nosave"` diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 6f5e8ce5e..2aabdded8 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -34,6 +34,8 @@ import ( // // Lock ordering: // Inotify.mu -> Inode.Watches.mu -> Watch.mu -> Inotify.evMu +// +// +stateify savable type Inotify struct { // Unique identifier for this inotify instance. We don't just reuse the // inotify fd because fds can be duped. These should not be exposed to the diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index 217915ba4..e9b5e0f56 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -28,6 +28,8 @@ import ( const inotifyEventBaseSize = 16 // Event represents a struct inotify_event from linux. +// +// +stateify savable type Event struct { ilist.Entry diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index 8904ef544..3e1959e83 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -27,6 +27,8 @@ import ( // holding an extra ref on each dirent known (by inotify) to point to the // inode. These are known as pins. For a full discussion, see // fs/g3doc/inotify.md. +// +// +stateify savable type Watch struct { // Inotify instance which owns this watch. owner *Inotify diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index 2607d7ed3..3159ff1da 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,18 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "lock_state", - srcs = [ - "lock.go", - "lock_range.go", - "lock_set.go", - ], - out = "lock_state.go", - package = "lock", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "lock_range", @@ -49,13 +38,11 @@ go_library( "lock_range.go", "lock_set.go", "lock_set_functions.go", - "lock_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/lock", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/log", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 24d54c989..e9b376eb6 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -88,6 +88,8 @@ const LockEOF = math.MaxUint64 // // A Lock may be downgraded from a write lock to a read lock only if // the write lock's uid is the same as the read lock. +// +// +stateify savable type Lock struct { // Readers are the set of read lock holders identified by UniqueID. // If len(Readers) > 0 then HasWriter must be false. @@ -103,6 +105,8 @@ type Lock struct { } // Locks is a thread-safe wrapper around a LockSet. +// +// +stateify savable type Locks struct { // mu protects locks below. mu sync.Mutex `state:"nosave"` @@ -111,7 +115,7 @@ type Locks struct { locks LockSet // blockedQueue is the queue of waiters that are waiting on a lock. - blockedQueue waiter.Queue + blockedQueue waiter.Queue `state:"zerovalue"` } // Blocker is the interface used for blocking locks. Passing a nil Blocker diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index eb1897174..4ede767f9 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -101,6 +101,8 @@ func (i InodeMappings) String() string { // (e.g. cannot be mounted at different locations). // // TODO: Move mount-specific information out of MountSource. +// +// +stateify savable type MountSource struct { refs.AtomicRefCount @@ -260,6 +262,8 @@ func NewNonCachingMountSource(filesystem Filesystem, flags MountSourceFlags) *Mo } // SimpleMountSourceOperations implements MountSourceOperations. +// +// +stateify savable type SimpleMountSourceOperations struct { keep bool } diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index 1be81e3a1..d135e8a37 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -18,6 +18,8 @@ import "gvisor.googlesource.com/gvisor/pkg/sentry/context" // overlayMountSourceOperations implements MountSourceOperations for an overlay // mount point. +// +// +stateify savable type overlayMountSourceOperations struct { upper *MountSource lower *MountSource @@ -72,6 +74,8 @@ func (o *overlayMountSourceOperations) Destroy() { } // type overlayFilesystem is the filesystem for overlay mounts. +// +// +stateify savable type overlayFilesystem struct{} // Name implements Filesystem.Name. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index 87da4ee0e..144d3427d 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -32,6 +32,8 @@ import ( const DefaultTraversalLimit = 10 // MountNamespace defines a collection of mounts. +// +// +stateify savable type MountNamespace struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index 7357d6401..af13dc8c7 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -145,6 +145,8 @@ func newOverlayInode(ctx context.Context, o *overlayEntry, msrc *MountSource) *I } // overlayEntry is the overlay metadata of an Inode. It implements Mappable. +// +// +stateify savable type overlayEntry struct { // lowerExists is true if an Inode exists for this file in the lower // filesystem. If lowerExists is true, then the overlay must create diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 870df47b2..2d9f07f2f 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,32 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "proc_state", - srcs = [ - "cpuinfo.go", - "exec_args.go", - "fds.go", - "file.go", - "filesystems.go", - "fs.go", - "loadavg.go", - "meminfo.go", - "mounts.go", - "net.go", - "proc.go", - "stat.go", - "sys.go", - "sys_net.go", - "task.go", - "uid_gid_map.go", - "uptime.go", - "version.go", - ], - out = "proc_state.go", - package = "proc", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "proc", @@ -42,7 +16,6 @@ go_library( "mounts.go", "net.go", "proc.go", - "proc_state.go", "rpcinet_proc.go", "stat.go", "sys.go", @@ -56,9 +29,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", - "//pkg/log", - "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/device", @@ -73,8 +43,6 @@ go_library( "//pkg/sentry/socket/rpcinet", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", - "//pkg/syserr", "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index f80aaa5b1..4dfec03a4 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -27,6 +27,8 @@ import ( // cpuinfo is a file describing the CPU capabilities. // // Presently cpuinfo never changes, so it doesn't need to be a SeqFile. +// +// +stateify savable type cpuinfo struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index 0e1523bf1..a69cbaa0e 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -37,6 +37,8 @@ const ( // execArgFile is a file containing the exec args (either cmdline or environ) // for a given task. +// +// +stateify savable type execArgFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index 194a9c12a..cca8f874c 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -138,6 +138,8 @@ func (f *fd) Close() error { } // fdDir implements /proc/TID/fd. +// +// +stateify savable type fdDir struct { ramfs.Dir @@ -197,6 +199,8 @@ func (f *fdDir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset } // fdInfo is a single file in /proc/TID/fdinfo/. +// +// +stateify savable type fdInfo struct { ramfs.File @@ -229,6 +233,8 @@ func (*fdInfo) Truncate(ctx context.Context, inode *fs.Inode, size int64) error // fdInfoDir implements /proc/TID/fdinfo. It embeds an fdDir, but overrides // Lookup and Readdir. +// +// +stateify savable type fdInfoDir struct { ramfs.Dir diff --git a/pkg/sentry/fs/proc/file.go b/pkg/sentry/fs/proc/file.go index 9a433cdf8..4b2d08e75 100644 --- a/pkg/sentry/fs/proc/file.go +++ b/pkg/sentry/fs/proc/file.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// +stateify savable type file struct { fs.InodeOperations diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index 37db9cf9c..49b92fd8a 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -24,6 +24,8 @@ import ( ) // filesystemsData backs /proc/filesystems. +// +// +stateify savable type filesystemsData struct{} // NeedsUpdate returns true on the first generation. The set of registered file diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 3aadd6ac4..061824b8c 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -22,6 +22,8 @@ import ( ) // filesystem is a procfs. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 7583b6ccd..6fac251d2 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -23,6 +23,8 @@ import ( ) // loadavgData backs /proc/loadavg. +// +// +stateify savable type loadavgData struct{} // NeedsUpdate implements seqfile.SeqSource.NeedsUpdate. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 49cb0faed..53dfd59ef 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -26,6 +26,8 @@ import ( ) // meminfoData backs /proc/meminfo. +// +// +stateify savable type meminfoData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index 108432f4e..2b8167c28 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -71,6 +71,8 @@ func forEachMountSource(t *kernel.Task, fn func(string, *fs.MountSource)) { } // mountInfoFile is used to implement /proc/[pid]/mountinfo. +// +// +stateify savable type mountInfoFile struct { t *kernel.Task } @@ -152,6 +154,8 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se } // mountsFile is used to implement /proc/[pid]/mountinfo. +// +// +stateify savable type mountsFile struct { t *kernel.Task } diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index b2a8d639c..07029a7bb 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -33,6 +33,8 @@ import ( ) // proc is a root proc node. +// +// +stateify savable type proc struct { ramfs.Dir @@ -47,6 +49,8 @@ type proc struct { // stubProcFSFile is a file type that can be used to return file contents // which are constant. This file is not writable and will always have mode // 0444. +// +// +stateify savable type stubProcFSFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index c84f7e20d..53c475652 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,22 +1,10 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "seqfile_state", - srcs = [ - "seqfile.go", - ], - out = "seqfile_state.go", - package = "seqfile", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "seqfile", - srcs = [ - "seqfile.go", - "seqfile_state.go", - ], + srcs = ["seqfile.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile", visibility = ["//pkg/sentry:internal"], deps = [ @@ -26,26 +14,16 @@ go_library( "//pkg/sentry/fs/ramfs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", ], ) -go_stateify( - name = "seqfile_test_state", - srcs = ["seqfile_test.go"], - out = "seqfile_test_state.go", - package = "seqfile", -) - go_test( name = "seqfile_test", size = "small", - srcs = [ - "seqfile_test.go", - "seqfile_test_state.go", - ], + srcs = ["seqfile_test.go"], embed = [":seqfile"], deps = [ + "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs/test", diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index c08565f8a..51cae5e37 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -30,6 +30,8 @@ import ( type SeqHandle interface{} // SeqData holds the data for one unit in the file. +// +// +stateify savable type SeqData struct { // The data to be returned to the user. Buf []byte @@ -82,6 +84,8 @@ func (s *SeqGenerationCounter) IsCurrent(generation int64) bool { } // SeqFile is used to provide dynamic files that can be ordered by record. +// +// +stateify savable type SeqFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index 284f3e52b..bf7650211 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -25,6 +25,8 @@ import ( ) // statData backs /proc/stat. +// +// +stateify savable type statData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index aab891c53..a2d36ca23 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -28,6 +28,8 @@ import ( ) // hostname is a file containing the system hostname. +// +// +stateify savable type hostname struct { ramfs.Entry } @@ -52,6 +54,8 @@ func (p *proc) newHostname(ctx context.Context, msrc *fs.MountSource) *fs.Inode } // mmapMinAddrData backs /proc/sys/vm/mmap_min_addr. +// +// +stateify savable type mmapMinAddrData struct { k *kernel.Kernel } @@ -74,6 +78,7 @@ func (d *mmapMinAddrData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHand }, 0 } +// +stateify savable type overcommitMemory struct{} func (*overcommitMemory) NeedsUpdate(generation int64) bool { diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index f3a5043f8..beb25be20 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -33,6 +33,7 @@ const ( tcpWMem ) +// +stateify savable type tcpMem struct { ramfs.Entry s inet.Stack @@ -100,6 +101,7 @@ func (m *tcpMem) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, return n, cperr } +// +stateify savable type tcpSack struct { ramfs.Entry s inet.Stack diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index efc635946..748ca4320 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -52,6 +52,8 @@ func getTaskMM(t *kernel.Task) (*mm.MemoryManager, error) { } // taskDir represents a task-level directory. +// +// +stateify savable type taskDir struct { ramfs.Dir @@ -92,6 +94,8 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace } // subtasks represents a /proc/TID/task directory. +// +// +stateify savable type subtasks struct { ramfs.Dir @@ -167,6 +171,8 @@ func (s *subtasks) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, off } // exe is an fs.InodeOperations symlink for the /proc/PID/exe file. +// +// +stateify savable type exe struct { ramfs.Symlink @@ -226,6 +232,8 @@ func (e *exe) Readlink(ctx context.Context, inode *fs.Inode) (string, error) { // namespaceFile represents a file in the namespacefs, such as the files in // /proc//ns. +// +// +stateify savable type namespaceFile struct { ramfs.Symlink @@ -274,6 +282,8 @@ func newNamespaceDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { } // mapsData implements seqfile.SeqSource for /proc/[pid]/maps. +// +// +stateify savable type mapsData struct { t *kernel.Task } @@ -311,6 +321,7 @@ func (md *mapsData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([ return []seqfile.SeqData{}, 0 } +// +stateify savable type taskStatData struct { t *kernel.Task @@ -391,6 +402,8 @@ func (s *taskStatData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) } // statmData implements seqfile.SeqSource for /proc/[pid]/statm. +// +// +stateify savable type statmData struct { t *kernel.Task } @@ -425,6 +438,8 @@ func (s *statmData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([ } // statusData implements seqfile.SeqSource for /proc/[pid]/status. +// +// +stateify savable type statusData struct { t *kernel.Task pidns *kernel.PIDNamespace @@ -490,6 +505,7 @@ type ioUsage interface { IOUsage() *usage.IO } +// +stateify savable type ioData struct { ioUsage } @@ -530,6 +546,8 @@ func (i *ioData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se // On Linux, /proc/[pid]/comm is writable, and writing to the comm file changes // the thread name. We don't implement this yet as there are no known users of // this feature. +// +// +stateify savable type comm struct { ramfs.Entry @@ -559,6 +577,8 @@ func (c *comm) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, off } // auxvec is a file containing the auxiliary vector for a task. +// +// +stateify savable type auxvec struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index 85acb5163..9811d9c9d 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -29,6 +29,8 @@ import ( // An idMapSeqSource is a seqfile.SeqSource that returns UID or GID mappings // from a task's user namespace. +// +// +stateify savable type idMapSeqSource struct { t *kernel.Task gids bool @@ -70,6 +72,7 @@ type idMapSeqHandle struct { value int } +// +stateify savable type idMapSeqFile struct { seqfile.SeqFile } diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index 4679d5821..f3a9b81df 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -27,6 +27,8 @@ import ( ) // uptime is a file containing the system uptime. +// +// +stateify savable type uptime struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index c0f2e87e3..00f6a2afd 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -23,6 +23,8 @@ import ( ) // versionData backs /proc/version. +// +// +stateify savable type versionData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index d84f2c624..5230157fe 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,19 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "ramfs_state", - srcs = [ - "dir.go", - "file.go", - "ramfs.go", - "socket.go", - "symlink.go", - ], - out = "ramfs_state.go", - package = "ramfs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ramfs", @@ -21,7 +8,6 @@ go_library( "dir.go", "file.go", "ramfs.go", - "ramfs_state.go", "socket.go", "symlink.go", "tree.go", @@ -29,12 +15,8 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/amutex", - "//pkg/log", - "//pkg/refs", "//pkg/secio", "//pkg/sentry/context", - "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", @@ -42,7 +24,6 @@ go_library( "//pkg/sentry/memmap", "//pkg/sentry/safemem", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 19d5612ed..04432f28c 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -44,6 +44,8 @@ type CreateOps struct { } // Dir represents a single directory in the filesystem. +// +// +stateify savable type Dir struct { Entry diff --git a/pkg/sentry/fs/ramfs/ramfs.go b/pkg/sentry/fs/ramfs/ramfs.go index d6cfaf753..13e72e775 100644 --- a/pkg/sentry/fs/ramfs/ramfs.go +++ b/pkg/sentry/fs/ramfs/ramfs.go @@ -60,6 +60,8 @@ var ( // Entry represents common internal state for file and directory nodes. // This may be used by other packages to easily create ramfs files. +// +// +stateify savable type Entry struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoMappable `state:"nosave"` diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index b0c79325f..93427a1ff 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -21,6 +21,8 @@ import ( ) // Socket represents a socket. +// +// +stateify savable type Socket struct { Entry diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 9bbf78619..1c54d9991 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -22,6 +22,8 @@ import ( ) // Symlink represents a symlink. +// +// +stateify savable type Symlink struct { Entry diff --git a/pkg/sentry/fs/ramfs/test/BUILD b/pkg/sentry/fs/ramfs/test/BUILD index 57fee45e2..187eac49d 100644 --- a/pkg/sentry/fs/ramfs/test/BUILD +++ b/pkg/sentry/fs/ramfs/test/BUILD @@ -1,30 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "test_state", - srcs = [ - "test.go", - ], - out = "test_state.go", - package = "test", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "test", testonly = 1, - srcs = [ - "test.go", - "test_state.go", - ], + srcs = ["test.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/sentry/context", - "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs", - "//pkg/state", ], ) diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 095ff1f25..bc24e980e 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,16 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "sys_state", - srcs = [ - "fs.go", - "sys.go", - ], - out = "sys_state.go", - package = "sys", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "sys", @@ -18,7 +8,6 @@ go_library( "device.go", "fs.go", "sys.go", - "sys_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/sys", visibility = ["//pkg/sentry:internal"], @@ -28,6 +17,5 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs", "//pkg/sentry/usermem", - "//pkg/state", ], ) diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index c6d5f7fd8..625525540 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -20,6 +20,8 @@ import ( ) // filesystem is a sysfs. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index ccf56f644..b9b2fb4a1 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -22,12 +22,13 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -type Dir struct { +// +stateify savable +type dir struct { ramfs.Dir } func newDir(ctx context.Context, msrc *fs.MountSource, contents map[string]*fs.Inode) *fs.Inode { - d := &Dir{} + d := &dir{} d.InitDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(d, msrc, fs.StableAttr{ DeviceID: sysfsDevice.DeviceID(), diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index 8b1b7872e..ffdd7e0dc 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,33 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "timerfd_state", - srcs = [ - "timerfd.go", - ], - out = "timerfd_state.go", - package = "timerfd", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "timerfd", - srcs = [ - "timerfd.go", - "timerfd_state.go", - ], + srcs = ["timerfd.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/timerfd", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index ae58f6fd7..767db95a0 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -30,6 +30,8 @@ import ( ) // TimerOperations implements fs.FileOperations for timerfds. +// +// +stateify savable type TimerOperations struct { fsutil.ZeroSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` @@ -38,7 +40,7 @@ type TimerOperations struct { fsutil.NoMMap `state:"nosave"` fsutil.NoIoctl `state:"nosave"` - events waiter.Queue `state:"nosave"` + events waiter.Queue `state:"zerovalue"` timer *ktime.Timer // val is the number of timer expirations since the last successful call to diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index 473ab4296..cfe11ab02 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,18 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tmpfs_state", - srcs = [ - "file_regular.go", - "fs.go", - "inode_file.go", - "tmpfs.go", - ], - out = "tmpfs_state.go", - package = "tmpfs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tmpfs", @@ -22,13 +10,11 @@ go_library( "fs.go", "inode_file.go", "tmpfs.go", - "tmpfs_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tmpfs", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", @@ -41,7 +27,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/tcpip/transport/unix", "//pkg/waiter", ], diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 9811d90bc..342688f81 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -25,6 +25,8 @@ import ( // regularFileOperations implements fs.FileOperations for a regular // tmpfs file. +// +// +stateify savable type regularFileOperations struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index 5bd9ade52..ca620e65e 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -47,6 +47,8 @@ const ( var modeRegexp = regexp.MustCompile("0[0-7][0-7][0-7]") // Filesystem is a tmpfs. +// +// +stateify savable type Filesystem struct{} func init() { diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 4e803c9ff..1e4fe47d2 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -43,6 +43,8 @@ import ( // include an InvalidatorRegion associated with that reference. When the // referenced portion of the file is removed (with Truncate), the associated // InvalidatorRegion is invalidated. +// +// +stateify savable type fileInodeOperations struct { fsutil.DeprecatedFileOperations `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 1cc7ae491..10cb5451d 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -49,6 +49,8 @@ func rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent } // Dir is a directory. +// +// +stateify savable type Dir struct { ramfs.Dir @@ -122,6 +124,8 @@ func (*Dir) StatFS(context.Context) (fs.Info, error) { } // Symlink is a symlink. +// +// +stateify savable type Symlink struct { ramfs.Symlink } @@ -149,6 +153,8 @@ func (s *Symlink) StatFS(context.Context) (fs.Info, error) { } // Socket is a socket. +// +// +stateify savable type Socket struct { ramfs.Socket } @@ -176,6 +182,8 @@ func (s *Socket) StatFS(context.Context) (fs.Info, error) { } // Fifo is a tmpfs named pipe. +// +// +stateify savable type Fifo struct { ramfs.Entry } diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index 363897b2c..3c446eef4 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,22 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tty_state", - srcs = [ - "dir.go", - "fs.go", - "inode.go", - "line_discipline.go", - "master.go", - "queue.go", - "slave.go", - "terminal.go", - ], - out = "tty_state.go", - package = "tty", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tty", @@ -29,7 +13,6 @@ go_library( "queue.go", "slave.go", "terminal.go", - "tty_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tty", visibility = ["//pkg/sentry:internal"], @@ -44,7 +27,6 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 2c5b2aed6..c91091db4 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -49,14 +49,16 @@ import ( // corresponding Dirents hold on their parent (this directory). // // dirInodeOperations implements fs.InodeOperations. +// +// +stateify savable type dirInodeOperations struct { - fsutil.DeprecatedFileOperations - fsutil.InodeNotSocket - fsutil.InodeNotRenameable - fsutil.InodeNotSymlink - fsutil.InodeNoExtendedAttributes - fsutil.NoMappable - fsutil.NoopWriteOut + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.NoMappable `state:"nosave"` + fsutil.NoopWriteOut `state:"nosave"` // msrc is the super block this directory is on. // @@ -348,6 +350,8 @@ func (d *dirInodeOperations) masterClose(t *Terminal) { // // This is nearly identical to fsutil.DirFileOperations, except that it takes // df.di.mu in IterateDir. +// +// +stateify savable type dirFileOperations struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index dbaffe95e..e28635607 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -28,6 +28,8 @@ var ptsDevice = device.NewAnonDevice() // // This devpts is always in the new "multi-instance" mode. i.e., it contains a // ptmx device tied to this mount. +// +// +stateify savable type filesystem struct{} func init() { @@ -69,6 +71,8 @@ func (f *filesystem) Mount(ctx context.Context, device string, flags fs.MountSou } // superOperations implements fs.MountSourceOperations, preventing caching. +// +// +stateify savable type superOperations struct{} // Revalidate implements fs.DirentOperations.Revalidate. diff --git a/pkg/sentry/fs/tty/inode.go b/pkg/sentry/fs/tty/inode.go index 04b9a7727..c0fa2b407 100644 --- a/pkg/sentry/fs/tty/inode.go +++ b/pkg/sentry/fs/tty/inode.go @@ -31,6 +31,8 @@ import ( // // * fs.InodeOperations.Release // * fs.InodeOperations.GetFile +// +// +stateify savable type inodeOperations struct { fsutil.DeprecatedFileOperations `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index f094635f5..d243ee40e 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -72,6 +72,8 @@ const ( // termiosMu // inQueue.mu // outQueue.mu +// +// +stateify savable type lineDiscipline struct { // inQueue is the input queue of the terminal. inQueue queue @@ -183,6 +185,8 @@ type transformer interface { // outputQueueTransformer implements transformer. It performs line discipline // transformations on the output queue. +// +// +stateify savable type outputQueueTransformer struct{} // transform does output processing for one end of the pty. See @@ -254,6 +258,8 @@ func (*outputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte // inputQueueTransformer implements transformer. It performs line discipline // transformations on the input queue. +// +// +stateify savable type inputQueueTransformer struct{} // transform does input processing for one end of the pty. Characters read are diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index 74cdbe874..c7198e218 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -27,6 +27,8 @@ import ( // masterInodeOperations are the fs.InodeOperations for the master end of the // Terminal (ptmx file). +// +// +stateify savable type masterInodeOperations struct { inodeOperations @@ -96,6 +98,8 @@ func (mi *masterInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flag } // masterFileOperations are the fs.FileOperations for the master end of a terminal. +// +// +stateify savable type masterFileOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 026d5e077..42c105abc 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -32,11 +32,13 @@ import ( // processed (i.e. undergo termios transformations) as they are added to the // read buffer. The read buffer is readable when its length is nonzero and // readable is true. +// +// +stateify savable type queue struct { // mu protects everything in queue. mu sync.Mutex `state:"nosave"` - waiter.Queue `state:"nosave"` + waiter.Queue `state:"zerovalue"` // readBuf is buffer of data ready to be read when readable is true. // This data has been processed. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index f5eec726e..1c562b172 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -27,6 +27,8 @@ import ( // slaveInodeOperations are the fs.InodeOperations for the slave end of the // Terminal (pts file). +// +// +stateify savable type slaveInodeOperations struct { inodeOperations @@ -86,6 +88,8 @@ func (si *slaveInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags } // slaveFileOperations are the fs.FileOperations for the slave end of a terminal. +// +// +stateify savable type slaveFileOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index fa5b00409..3cb135124 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -21,6 +21,8 @@ import ( ) // Terminal is a pseudoterminal. +// +// +stateify savable type Terminal struct { refs.AtomicRefCount diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index eaf8f15b2..159c50efb 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -3,26 +3,15 @@ package( licenses = ["notice"], # Apache 2.0 ) -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "inet_state", - srcs = ["inet.go"], - out = "inet_state.go", - package = "inet", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "inet", srcs = [ "context.go", "inet.go", - "inet_state.go", "test_stack.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/inet", - deps = [ - "//pkg/sentry/context", - "//pkg/state", - ], + deps = ["//pkg/sentry/context"], ) diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index e4b326993..e54a61196 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -87,6 +87,8 @@ type InterfaceAddr struct { } // TCPBufferSize contains settings controlling TCP buffer sizing. +// +// +stateify savable type TCPBufferSize struct { // Min is the minimum size. Min int diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index c4a7dacb2..0ebacefa6 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,58 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "kernel_state", - srcs = [ - "abstract_socket_namespace.go", - "fd_map.go", - "fs_context.go", - "ipc_namespace.go", - "kernel.go", - "kernel_state.go", - "pending_signals.go", - "pending_signals_state.go", - "process_group_list.go", - "ptrace.go", - "rseq.go", - "session_list.go", - "sessions.go", - "signal.go", - "signal_handlers.go", - "syscalls.go", - "syscalls_state.go", - "syslog.go", - "task.go", - "task_clone.go", - "task_context.go", - "task_exec.go", - "task_exit.go", - "task_list.go", - "task_resources.go", - "task_run.go", - "task_sched.go", - "task_signals.go", - "task_start.go", - "task_syscall.go", - "thread_group.go", - "threads.go", - "timekeeper.go", - "timekeeper_state.go", - "timer.go", - "uts_namespace.go", - "vdso.go", - "version.go", - ], - out = "kernel_autogen_state.go", - imports = [ - "gvisor.googlesource.com/gvisor/pkg/sentry/arch", - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", - "gvisor.googlesource.com/gvisor/pkg/tcpip", - ], - package = "kernel", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "pending_signals_list", @@ -118,7 +67,6 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", - "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", @@ -164,6 +112,11 @@ go_library( "version.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel", + imports = [ + "gvisor.googlesource.com/gvisor/pkg/sentry/arch", + # "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", + "gvisor.googlesource.com/gvisor/pkg/tcpip", + ], visibility = ["//:sandbox"], deps = [ "//pkg/abi", diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 014c4a3bf..d6d1d341d 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" ) +// +stateify savable type abstractEndpoint struct { ep unix.BoundEndpoint wr *refs.WeakRef @@ -39,6 +40,8 @@ func (e *abstractEndpoint) WeakRefGone() { } // AbstractSocketNamespace is used to implement the Linux abstract socket functionality. +// +// +stateify savable type AbstractSocketNamespace struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 5b7b30557..a81085372 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,20 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "auth_state", - srcs = [ - "credentials.go", - "id.go", - "id_map_range.go", - "id_map_set.go", - "user_namespace.go", - ], - out = "auth_state.go", - package = "auth", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "id_map_range", @@ -48,7 +35,6 @@ go_library( name = "auth", srcs = [ "auth.go", - "auth_state.go", "capability_set.go", "context.go", "credentials.go", @@ -66,7 +52,6 @@ go_library( "//pkg/bits", "//pkg/log", "//pkg/sentry/context", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index f6fb05285..f18f7dac9 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -21,6 +21,8 @@ import ( // Credentials contains information required to authorize privileged operations // in a user namespace. +// +// +stateify savable type Credentials struct { // Real/effective/saved user/group IDs in the root user namespace. None of // these should ever be NoID. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index 6adb33530..bd0090e0f 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -77,6 +77,8 @@ func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool { // An IDMapEntry represents a mapping from a range of contiguous IDs in a user // namespace to an equally-sized range of contiguous IDs in the namespace's // parent. +// +// +stateify savable type IDMapEntry struct { // FirstID is the first ID in the range in the namespace. FirstID uint32 diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 0980aeadf..d359f3f31 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -23,6 +23,8 @@ import ( // A UserNamespace represents a user namespace. See user_namespaces(7) for // details. +// +// +stateify savable type UserNamespace struct { // parent is this namespace's parent. If this is the root namespace, parent // is nil. The parent pointer is immutable. diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 7d491efbc..5e8b36ed6 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,22 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "epoll_autogen_state", - srcs = [ - "epoll.go", - "epoll_state.go", - ], - out = "epoll_autogen_state.go", - package = "epoll", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "epoll", srcs = [ "epoll.go", - "epoll_autogen_state.go", "epoll_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/epoll", @@ -29,9 +18,7 @@ go_library( "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/kdefs", - "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index b572fcd7e..d87e64a1c 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -58,6 +58,8 @@ const ( // potentially be reassigned. We also cannot use just the file pointer because // it is possible to have multiple entries for the same file object as long as // they are created with different FDs (i.e., the FDs point to the same file). +// +// +stateify savable type FileIdentifier struct { File *fs.File Fd kdefs.FD @@ -65,6 +67,8 @@ type FileIdentifier struct { // pollEntry holds all the state associated with an event poll entry, that is, // a file being observed by an event poll object. +// +// +stateify savable type pollEntry struct { ilist.Entry file *refs.WeakRef `state:"manual"` @@ -92,6 +96,8 @@ func (p *pollEntry) WeakRefGone() { // EventPoll holds all the state associated with an event poll object, that is, // collection of files to observe and their current state. +// +// +stateify savable type EventPoll struct { fsutil.PipeSeek `state:"zerovalue"` fsutil.NotDirReaddir `state:"zerovalue"` @@ -102,7 +108,7 @@ type EventPoll struct { // Wait queue is used to notify interested parties when the event poll // object itself becomes readable or writable. - waiter.Queue + waiter.Queue `state:"zerovalue"` // files is the map of all the files currently being observed, it is // protected by mu. diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index 7ec179bd8..cc1120b4f 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,33 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "eventfd_state", - srcs = [ - "eventfd.go", - ], - out = "eventfd_state.go", - package = "eventfd", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "eventfd", - srcs = [ - "eventfd.go", - "eventfd_state.go", - ], + srcs = ["eventfd.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/eventfd", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", "//pkg/waiter/fdnotifier", diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index bd50bd9fe..a4ada0e78 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -35,6 +35,8 @@ import ( // EventOperations represents an event with the semantics of Linux's file-based event // notification (eventfd). Eventfds are usually internal to the Sentry but in certain // situations they may be converted into a host-backed eventfd. +// +// +stateify savable type EventOperations struct { fsutil.NoopRelease `state:"nosave"` fsutil.PipeSeek `state:"nosave"` @@ -49,7 +51,7 @@ type EventOperations struct { // Queue is used to notify interested parties when the event object // becomes readable or writable. - wq waiter.Queue `state:"nosave"` + wq waiter.Queue `state:"zerovalue"` // val is the current value of the event counter. val uint64 diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index 299506330..d5d4aaacb 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -46,6 +46,8 @@ func (f FDs) Less(i, j int) bool { } // FDFlags define flags for an individual descriptor. +// +// +stateify savable type FDFlags struct { // CloseOnExec indicates the descriptor should be closed on exec. CloseOnExec bool @@ -69,12 +71,16 @@ func (f FDFlags) ToLinuxFDFlags() (mask uint) { // descriptor holds the details about a file descriptor, namely a pointer the // file itself and the descriptor flags. +// +// +stateify savable type descriptor struct { file *fs.File flags FDFlags } // FDMap is used to manage File references and flags. +// +// +stateify savable type FDMap struct { refs.AtomicRefCount k *Kernel diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index dbc097696..f3f05e8f5 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -25,6 +25,8 @@ import ( // FSContext contains filesystem context. // // This includes umask and working directory. +// +// +stateify savable type FSContext struct { refs.AtomicRefCount diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index a97a43549..b44a26974 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "waiter_list", @@ -14,29 +14,15 @@ go_template_instance( }, ) -go_stateify( - name = "futex_state", - srcs = [ - "futex.go", - "waiter_list.go", - ], - out = "futex_state.go", - package = "futex", -) - go_library( name = "futex", srcs = [ "futex.go", - "futex_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex", visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/state", - "//pkg/syserror", - ], + deps = ["//pkg/syserror"], ) go_test( diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 15e3e5e2c..4a1f2a0ef 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -196,6 +196,8 @@ func bucketIndexForAddr(addr uintptr) uintptr { } // Manager holds futex state for a single virtual address space. +// +// +stateify savable type Manager struct { buckets [bucketCount]bucket `state:"zerovalue"` } diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index a86bda77b..5eef49f59 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -21,6 +21,8 @@ import ( ) // IPCNamespace represents an IPC namespace. +// +// +stateify savable type IPCNamespace struct { // User namespace which owns this IPC namespace. Immutable. userNS *auth.UserNamespace diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 64439cd9d..419a1d473 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -62,6 +62,8 @@ import ( // Kernel represents an emulated Linux kernel. It must be initialized by calling // Init() or LoadFrom(). +// +// +stateify savable type Kernel struct { // extMu serializes external changes to the Kernel with calls to // Kernel.SaveTo. (Kernel.SaveTo requires that the state of the Kernel @@ -158,7 +160,7 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. - exitErr error + exitErr error `state:"nosave"` // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index 5dc0f266c..06be5a7e1 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -38,6 +38,8 @@ const ( // pendingSignals holds a collection of pending signals. The zero value of // pendingSignals is a valid empty collection. pendingSignals is thread-unsafe; // users must provide synchronization. +// +// +stateify savable type pendingSignals struct { // signals contains all pending signals. // @@ -52,11 +54,14 @@ type pendingSignals struct { } // pendingSignalQueue holds a pendingSignalList for a single signal number. +// +// +stateify savable type pendingSignalQueue struct { pendingSignalList length int } +// +stateify savable type pendingSignal struct { // pendingSignalEntry links into a pendingSignalList. pendingSignalEntry diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 4600d19bd..19b23c6d2 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,20 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "pipe_state", - srcs = [ - "buffers.go", - "node.go", - "pipe.go", - "reader.go", - "reader_writer.go", - "writer.go", - ], - out = "pipe_state.go", - package = "pipe", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "pipe", @@ -23,7 +9,6 @@ go_library( "device.go", "node.go", "pipe.go", - "pipe_state.go", "reader.go", "reader_writer.go", "writer.go", @@ -34,15 +19,12 @@ go_library( "//pkg/abi/linux", "//pkg/amutex", "//pkg/ilist", - "//pkg/log", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index f300537c5..a82e45c3f 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -20,6 +20,8 @@ import ( // Buffer encapsulates a queueable byte buffer that can // easily be truncated. It is designed only for use with pipes. +// +// +stateify savable type Buffer struct { ilist.Entry data []byte diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index e418cf174..23d692da1 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -24,6 +24,8 @@ import ( ) // inodeOperations wraps fs.InodeOperations operations with common pipe opening semantics. +// +// +stateify savable type inodeOperations struct { fs.InodeOperations diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index 9a21df5b4..ced2559a7 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -41,6 +41,8 @@ const DefaultPipeSize = 65536 // Pipe is an encapsulation of a platform-independent pipe. // It manages a buffered byte queue shared between a reader/writer // pair. +// +// +stateify savable type Pipe struct { waiter.Queue `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 40d5e4943..1fa5e9a32 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -20,6 +20,8 @@ import ( // Reader satisfies the fs.FileOperations interface for read-only pipes. // Reader should be used with !fs.FileFlags.Write to reject writes. +// +// +stateify savable type Reader struct { ReaderWriter } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index dc642a3a6..82607367b 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -31,6 +31,8 @@ import ( // read and write requests. This should only be used directly for named pipes. // pipe(2) and pipe2(2) only support unidirectional pipes and should use // either pipe.Reader or pipe.Writer. +// +// +stateify savable type ReaderWriter struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index fd13008ac..d93324b53 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -20,6 +20,8 @@ import ( // Writer satisfies the fs.FileOperations interface for write-only pipes. // Writer should be used with !fs.FileFlags.Read to reject reads. +// +// +stateify savable type Writer struct { ReaderWriter } diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index f1c2c4bf0..e9e69004d 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -25,6 +25,8 @@ import ( // ptraceOptions are the subset of options controlling a task's ptrace behavior // that are set by ptrace(PTRACE_SETOPTIONS). +// +// +stateify savable type ptraceOptions struct { // ExitKill is true if the tracee should be sent SIGKILL when the tracer // exits. @@ -185,6 +187,8 @@ func (t *Task) hasTracer() bool { } // ptraceStop is a TaskStop placed on tasks in a ptrace-stop. +// +// +stateify savable type ptraceStop struct { // If frozen is true, the stopped task's tracer is currently operating on // it, so Task.Kill should not remove the stop. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 635372993..1f3de58e3 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -23,6 +23,8 @@ import ( // Restartable sequences, as described in https://lwn.net/Articles/650333/. // RSEQCriticalRegion describes a restartable sequence critical region. +// +// +stateify savable type RSEQCriticalRegion struct { // When a task in this thread group has its CPU preempted (as defined by // platform.ErrContextCPUPreempted) or has a signal delivered to an diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index 969145fe1..e7fa44e2c 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "waiter_list", @@ -14,21 +14,10 @@ go_template_instance( }, ) -go_stateify( - name = "semaphore_state", - srcs = [ - "semaphore.go", - "waiter_list.go", - ], - out = "semaphore_autogen_state.go", - package = "semaphore", -) - go_library( name = "semaphore", srcs = [ "semaphore.go", - "semaphore_autogen_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/semaphore", @@ -40,8 +29,6 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", - "//pkg/state", - "//pkg/state/statefile", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index a1ee83ce5..aa07946cf 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -42,6 +42,8 @@ const ( ) // Registry maintains a set of semaphores that can be found by key or ID. +// +// +stateify savable type Registry struct { // userNS owning the ipc name this registry belongs to. Immutable. userNS *auth.UserNamespace @@ -52,6 +54,8 @@ type Registry struct { } // Set represents a set of semaphores that can be operated atomically. +// +// +stateify savable type Set struct { // registry owning this sem set. Immutable. registry *Registry @@ -79,6 +83,8 @@ type Set struct { } // sem represents a single semanphore from a set. +// +// +stateify savable type sem struct { value int16 waiters waiterList `state:"zerovalue"` @@ -86,6 +92,8 @@ type sem struct { // waiter represents a caller that is waiting for the semaphore value to // become positive or zero. +// +// +stateify savable type waiter struct { waiterEntry diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index fa4c7b8f6..cf4e18805 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -27,6 +27,8 @@ type SessionID ThreadID type ProcessGroupID ThreadID // Session contains a leader threadgroup and a list of ProcessGroups. +// +// +stateify savable type Session struct { refs refs.AtomicRefCount @@ -76,6 +78,8 @@ func (s *Session) decRef() { } // ProcessGroup contains an originator threadgroup and a parent Session. +// +// +stateify savable type ProcessGroup struct { refs refs.AtomicRefCount // not exported. diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 0f88eb0ac..40e641355 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,22 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "shm_state", - srcs = [ - "shm.go", - ], - out = "shm_autogen_state.go", - package = "shm", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "shm", srcs = [ "device.go", "shm.go", - "shm_autogen_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm", visibility = ["//pkg/sentry:internal"], @@ -33,7 +23,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 7217e8103..1ac444094 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -72,6 +72,8 @@ const ( // Registry tracks all shared memory segments in an IPC namespace. The registry // provides the mechanisms for creating and finding segments, and reporting // global shm parameters. +// +// +stateify savable type Registry struct { // userNS owns the IPC namespace this registry belong to. Immutable. userNS *auth.UserNamespace @@ -288,6 +290,8 @@ func (r *Registry) remove(s *Shm) { // shmctl(SHM_RMID). // // Shm implements memmap.Mappable and memmap.MappingIdentity. +// +// +stateify savable type Shm struct { // AtomicRefCount tracks the number of references to this segment from // maps. A segment always holds a reference to itself, until it's marked for diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 21ba4ee70..3649f5e4d 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -22,6 +22,8 @@ import ( ) // SignalHandlers holds information about signal actions. +// +// +stateify savable type SignalHandlers struct { // mu protects actions, as well as the signal state of all tasks and thread // groups using this SignalHandlers object. (See comment on diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index e20fa3eb6..4c7811b6c 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -176,6 +176,8 @@ type Stracer interface { // SyscallTable is a lookup table of system calls. Critically, a SyscallTable // is *immutable*. In order to make supporting suspend and resume sane, they // must be uniquely registered and may not change during operation. +// +// +stateify savable type SyscallTable struct { // OS is the operating system that this syscall table implements. OS abi.OS `state:"wait"` diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 31541749e..125312b6a 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -23,6 +23,8 @@ import ( // syslog represents a sentry-global kernel log. // // Currently, it contains only fun messages for a dmesg easter egg. +// +// +stateify savable type syslog struct { // mu protects the below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index 7f6735320..ae9b3d175 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -52,6 +52,8 @@ import ( // All fields that are "exclusive to the task goroutine" can only be accessed // by the task goroutine while it is running. The task goroutine does not // require synchronization to read or write these fields. +// +// +stateify savable type Task struct { taskNode diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index a61283267..38f7826e2 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -349,6 +349,7 @@ func (t *Task) unstopVforkParent() { } } +// +stateify savable type runSyscallAfterPtraceEventClone struct { vforkChild *Task @@ -366,6 +367,7 @@ func (r *runSyscallAfterPtraceEventClone) execute(t *Task) taskRunState { return (*runSyscallExit)(nil) } +// +stateify savable type runSyscallAfterVforkStop struct { // childTID has the same meaning as // runSyscallAfterPtraceEventClone.vforkChildTID. @@ -471,6 +473,8 @@ func (t *Task) Unshare(opts *SharingOptions) error { // current MM. (Normally, CLONE_VFORK is used in conjunction with CLONE_VM, so // that the child and parent share mappings until the child execve()s into a // new process image or exits.) +// +// +stateify savable type vforkStop struct{} // StopIgnoresKill implements TaskStop.Killable. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index 5c563ba08..9a59cbd33 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -35,6 +35,8 @@ var ErrNoSyscalls = errors.New("no syscall table found") type Auxmap map[string]interface{} // TaskContext is the subset of a task's data that is provided by the loader. +// +// +stateify savable type TaskContext struct { // Name is the thread name set by the prctl(PR_SET_NAME) system call. Name string diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 2285847a2..385299b24 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -73,6 +73,8 @@ import ( // execStop is a TaskStop that a task sets on itself when it wants to execve // and is waiting for the other tasks in its thread group to exit first. +// +// +stateify savable type execStop struct{} // Killable implements TaskStop.Killable. @@ -119,6 +121,8 @@ func (t *Task) Execve(newTC *TaskContext) (*SyscallControl, error) { // The runSyscallAfterExecStop state continues execve(2) after all siblings of // a thread in the execve syscall have exited. +// +// +stateify savable type runSyscallAfterExecStop struct { tc *TaskContext } diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index d6604f37b..b16844e91 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -38,6 +38,8 @@ import ( // An ExitStatus is a value communicated from an exiting task or thread group // to the party that reaps it. +// +// +stateify savable type ExitStatus struct { // Code is the numeric value passed to the call to exit or exit_group that // caused the exit. If the exit was not caused by such a call, Code is 0. @@ -222,6 +224,8 @@ func (t *Task) advanceExitStateLocked(oldExit, newExit TaskExitState) { } // runExit is the entry point into the task exit path. +// +// +stateify savable type runExit struct{} func (*runExit) execute(t *Task) taskRunState { @@ -229,6 +233,7 @@ func (*runExit) execute(t *Task) taskRunState { return (*runExitMain)(nil) } +// +stateify savable type runExitMain struct{} func (*runExitMain) execute(t *Task) taskRunState { @@ -531,6 +536,7 @@ func (t *Task) reparentLocked(parent *Task) { // tracer (if one exists) and reaps the leader immediately. In Linux, this is // in fs/exec.c:de_thread(); in the sentry, this is in Task.promoteLocked(). +// +stateify savable type runExitNotify struct{} func (*runExitNotify) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_resources.go b/pkg/sentry/kernel/task_resources.go index 4ca25664a..0832bf989 100644 --- a/pkg/sentry/kernel/task_resources.go +++ b/pkg/sentry/kernel/task_resources.go @@ -21,6 +21,8 @@ import ( // TaskResources is the subset of a task's data provided by its creator that is // not provided by the loader. +// +// +stateify savable type TaskResources struct { // SignalMask is the set of signals whose delivery is currently blocked. // diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index a03fa6ac0..8dd0ef6ea 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -131,6 +131,8 @@ func (t *Task) doStop() { // The runApp state checks for interrupts before executing untrusted // application code. +// +// +stateify savable type runApp struct{} func (*runApp) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index b50139077..49141ab74 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -65,6 +65,8 @@ const ( // TaskGoroutineSchedInfo contains task goroutine scheduling state which must // be read and updated atomically. +// +// +stateify savable type TaskGoroutineSchedInfo struct { // Timestamp was the value of Kernel.cpuClock when this // TaskGoroutineSchedInfo was last updated. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 91f6c0874..62ec530be 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -748,6 +748,8 @@ func (t *Task) CopyInSignalStack(addr usermem.Addr) (arch.SignalStack, error) { // groupStop is a TaskStop placed on tasks that have received a stop signal // (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU). (The term "group-stop" originates from // the ptrace man page.) +// +// +stateify savable type groupStop struct{} // Killable implements TaskStop.Killable. @@ -881,6 +883,8 @@ func (t *Task) signalStop(target *Task, code int32, status int32) { } // The runInterrupt state handles conditions indicated by interrupts. +// +// +stateify savable type runInterrupt struct{} func (*runInterrupt) execute(t *Task) taskRunState { @@ -1020,6 +1024,7 @@ func (*runInterrupt) execute(t *Task) taskRunState { return (*runApp)(nil) } +// +stateify savable type runInterruptAfterSignalDeliveryStop struct{} func (*runInterruptAfterSignalDeliveryStop) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 79f4ff60c..3b9652504 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -241,6 +241,7 @@ func (t *Task) doSyscallEnter(sysno uintptr, args arch.SyscallArguments) taskRun return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallAfterSyscallEnterStop struct{} func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { @@ -260,6 +261,7 @@ func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallAfterSysemuStop struct{} func (*runSyscallAfterSysemuStop) execute(t *Task) taskRunState { @@ -294,6 +296,7 @@ func (t *Task) doSyscallInvoke(sysno uintptr, args arch.SyscallArguments) taskRu return (*runSyscallExit)(nil).execute(t) } +// +stateify savable type runSyscallReinvoke struct{} func (*runSyscallReinvoke) execute(t *Task) taskRunState { @@ -310,6 +313,7 @@ func (*runSyscallReinvoke) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallExit struct{} func (*runSyscallExit) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 8fffd3446..441b8a822 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -28,6 +28,8 @@ import ( // groups" are usually called "processes" in userspace documentation.) // // ThreadGroup is a superset of Linux's struct signal_struct. +// +// +stateify savable type ThreadGroup struct { threadGroupNode diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 440da9dad..844213c35 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -50,6 +50,8 @@ func (tid ThreadID) String() string { const InitTID ThreadID = 1 // A TaskSet comprises all tasks in a system. +// +// +stateify savable type TaskSet struct { // mu protects all relationships betweens tasks and thread groups in the // TaskSet. (mu is approximately equivalent to Linux's tasklist_lock.) @@ -110,6 +112,8 @@ func (ts *TaskSet) forEachThreadGroupLocked(f func(tg *ThreadGroup)) { // // N.B. A task is said to be visible in a PID namespace if the PID namespace // contains a thread ID that maps to that task. +// +// +stateify savable type PIDNamespace struct { // owner is the TaskSet that this PID namespace belongs to. The owner // pointer is immutable. @@ -263,6 +267,8 @@ func (ns *PIDNamespace) UserNamespace() *auth.UserNamespace { // (threadGroupNode is an anonymous field in ThreadGroup; this is to expose // threadGroupEntry's methods on ThreadGroup to make it implement // threadGroupLinker.) +// +// +stateify savable type threadGroupNode struct { // pidns is the PID namespace containing the thread group and all of its // member tasks. The pidns pointer is immutable. @@ -382,6 +388,8 @@ func (tg *ThreadGroup) ID() ThreadID { // A taskNode defines the relationship between a task and the rest of the // system. The comments on threadGroupNode also apply to taskNode. +// +// +stateify savable type taskNode struct { // tg is the thread group that this task belongs to. The tg pointer is // immutable. diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index b3ed42aa4..5d8db2273 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,30 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "time_state", - srcs = [ - "time.go", - ], - out = "time_state.go", - package = "time", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "time", srcs = [ "context.go", "time.go", - "time_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/context", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index c223c2f19..6eadd2878 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -42,6 +42,8 @@ const ( // // Time may represent time with respect to any clock and may not have any // meaning in the real world. +// +// +stateify savable type Time struct { ns int64 } @@ -286,6 +288,8 @@ type TimerListener interface { } // Setting contains user-controlled mutable Timer properties. +// +// +stateify savable type Setting struct { // Enabled is true if the timer is running. Enabled bool @@ -371,6 +375,8 @@ func (s Setting) advancedTo(now Time) (Setting, uint64) { // // Timers should be created using NewTimer and must be cleaned up by calling // Timer.Destroy when no longer used. +// +// +stateify savable type Timer struct { // clock is the time source. clock is immutable. clock Clock diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index 4de8ac13b..df5dbe128 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -25,6 +25,8 @@ import ( ) // Timekeeper manages all of the kernel clocks. +// +// +stateify savable type Timekeeper struct { // clocks are the clock sources. // diff --git a/pkg/sentry/kernel/timer.go b/pkg/sentry/kernel/timer.go index 03a3310be..534d03d0f 100644 --- a/pkg/sentry/kernel/timer.go +++ b/pkg/sentry/kernel/timer.go @@ -26,6 +26,8 @@ import ( // timekeeperClock is a ktime.Clock that reads time from a // kernel.Timekeeper-managed clock. +// +// +stateify savable type timekeeperClock struct { tk *Timekeeper c sentrytime.ClockID @@ -49,6 +51,8 @@ func (tc *timekeeperClock) Now() ktime.Time { // tgClock is a ktime.Clock that measures the time a thread group has spent // executing. +// +// +stateify savable type tgClock struct { tg *ThreadGroup @@ -155,6 +159,8 @@ func (tc *taskClock) Now() ktime.Time { } // signalNotifier is a ktime.Listener that sends signals to a ThreadGroup. +// +// +stateify savable type signalNotifier struct { tg *ThreadGroup signal linux.Signal @@ -179,6 +185,8 @@ func (s *signalNotifier) Notify(exp uint64) { func (s *signalNotifier) Destroy() {} // TimerManager is a collection of supported process cpu timers. +// +// +stateify savable type TimerManager struct { // Clocks used to drive thread group execution time timers. virtClock *tgClock diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index 58e9b4d1b..7e0fe0d21 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -22,6 +22,8 @@ import ( // UTSNamespace represents a UTS namespace, a holder of two system identifiers: // the hostname and domain name. +// +// +stateify savable type UTSNamespace struct { // mu protects all fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 0bacbea49..971e8bc59 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -52,6 +52,8 @@ type vdsoParams struct { // Everything in the struct is 8 bytes for easy alignment. // // It must be kept in sync with params in vdso/vdso_time.cc. +// +// +stateify savable type VDSOParamPage struct { // The parameter page is fr, allocated from platform.Memory(). platform platform.Platform diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 3ce41cacc..90f4395d4 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,22 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "limits_state", - srcs = [ - "limits.go", - ], - out = "limits_state.go", - package = "limits", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "limits", srcs = [ "context.go", "limits.go", - "limits_state.go", "linux.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/limits", @@ -24,7 +14,6 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/sentry/context", - "//pkg/state", ], ) diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index 4230ba958..02c8b60e3 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -47,6 +47,8 @@ const ( const Infinity = ^uint64(0) // Limit specifies a system limit. +// +// +stateify savable type Limit struct { // Cur specifies the current limit. Cur uint64 @@ -55,6 +57,8 @@ type Limit struct { } // LimitSet represents the Limits that correspond to each LimitType. +// +// +stateify savable type LimitSet struct { mu sync.Mutex `state:"nosave"` data map[LimitType]Limit diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index e63052c6d..0beb4561b 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library") go_embed_data( name = "vdso_bin", @@ -10,23 +10,12 @@ go_embed_data( var = "vdsoBin", ) -go_stateify( - name = "loader_state", - srcs = [ - "vdso.go", - "vdso_state.go", - ], - out = "loader_state.go", - package = "loader", -) - go_library( name = "loader", srcs = [ "elf.go", "interpreter.go", "loader.go", - "loader_state.go", "vdso.go", "vdso_state.go", ":vdso_bin", @@ -40,7 +29,6 @@ go_library( "//pkg/cpuid", "//pkg/log", "//pkg/rand", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -55,7 +43,6 @@ go_library( "//pkg/sentry/uniqueid", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 2e8693f8e..a06e27ac9 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -193,6 +193,8 @@ func validateVDSO(ctx context.Context, f *fs.File, size uint64) (elfInfo, error) // // NOTE: to support multiple architectures or operating systems, this // would need to contain a VDSO for each. +// +// +stateify savable type VDSO struct { // ParamPage is the VDSO parameter page. This page should be updated to // inform the VDSO for timekeeping data. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index 92004ad9e..dc71e1c2d 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -18,6 +18,7 @@ import ( "debug/elf" ) +// +stateify savable type elfProgHeader struct { Type elf.ProgType Flags elf.ProgFlag diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index 2e367e189..c9e0b95a0 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,18 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "memmap_state", - srcs = [ - "mappable_range.go", - "mapping_set.go", - "mapping_set_impl.go", - ], - out = "memmap_state.go", - package = "memmap", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "mappable_range", @@ -46,7 +35,6 @@ go_library( "mapping_set.go", "mapping_set_impl.go", "memmap.go", - "memmap_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/memmap", visibility = ["//pkg/sentry:internal"], @@ -56,7 +44,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/platform", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index 0cd42ffbf..c9483905d 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -35,6 +35,8 @@ import ( type MappingsOfRange map[MappingOfRange]struct{} // MappingOfRange represents a mapping of a MappableRange. +// +// +stateify savable type MappingOfRange struct { MappingSpace MappingSpace AddrRange usermem.AddrRange diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 3f396986a..bbdfae247 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,24 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "mm_state", - srcs = [ - "aio_context.go", - "aio_context_state.go", - "file_refcount_set.go", - "io_list.go", - "mm.go", - "pma_set.go", - "save_restore.go", - "special_mappable.go", - "vma_set.go", - ], - out = "mm_state.go", - package = "mm", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "file_refcount_set", @@ -101,7 +84,6 @@ go_library( "lifecycle.go", "metadata.go", "mm.go", - "mm_state.go", "pma.go", "pma_set.go", "proc_pid_maps.go", @@ -131,7 +113,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/sync", "//pkg/syserror", "//pkg/tcpip/buffer", diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index 992bde5a5..b42156d45 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -28,6 +28,8 @@ import ( ) // aioManager creates and manages asynchronous I/O contexts. +// +// +stateify savable type aioManager struct { // mu protects below. mu sync.Mutex `state:"nosave"` @@ -89,12 +91,16 @@ func (a *aioManager) lookupAIOContext(id uint64) (*AIOContext, bool) { } // ioResult is a completed I/O operation. +// +// +stateify savable type ioResult struct { data interface{} ioEntry } // AIOContext is a single asynchronous I/O context. +// +// +stateify savable type AIOContext struct { // done is the notification channel used for all requests. done chan struct{} `state:"nosave"` @@ -190,6 +196,8 @@ func (ctx *AIOContext) WaitChannel() (chan struct{}, bool) { // aioMappable implements memmap.MappingIdentity and memmap.Mappable for AIO // ring buffers. +// +// +stateify savable type aioMappable struct { refs.AtomicRefCount diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index ce8097b7f..3299ae164 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -46,6 +46,8 @@ import ( ) // MemoryManager implements a virtual address space. +// +// +stateify savable type MemoryManager struct { // p is the platform. // @@ -207,6 +209,8 @@ type MemoryManager struct { } // vma represents a virtual memory area. +// +// +stateify savable type vma struct { // mappable is the virtual memory object mapped by this vma. If mappable is // nil, the vma represents a private anonymous mapping. @@ -346,6 +350,8 @@ func (v *vma) loadRealPerms(b int) { } // pma represents a platform mapping area. +// +// +stateify savable type pma struct { // file is the file mapped by this pma. Only pmas for which file == // platform.Platform.Memory() may be saved. pmas hold a reference to the @@ -380,6 +386,7 @@ type pma struct { internalMappings safemem.BlockSeq `state:"nosave"` } +// +stateify savable type privateRefs struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index 9d3614034..aa2f87107 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -28,6 +28,8 @@ import ( // semantics similar to Linux's mm/mmap.c:_install_special_mapping(), except // that SpecialMappable takes ownership of the memory that it represents // (_install_special_mapping() does not.) +// +// +stateify savable type SpecialMappable struct { refs.AtomicRefCount diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index 15a7fbbc3..af9ba5394 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,16 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "platform_state", - srcs = [ - "file_range.go", - ], - out = "platform_state.go", - package = "platform", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "file_range", @@ -30,7 +21,6 @@ go_library( "file_range.go", "mmap_min_addr.go", "platform.go", - "platform_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/platform", visibility = ["//pkg/sentry:internal"], @@ -44,7 +34,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index dadba1d38..2a5982763 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,18 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "filemem_autogen_state", - srcs = [ - "filemem.go", - "filemem_state.go", - "usage_set.go", - ], - out = "filemem_autogen_state.go", - package = "filemem", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "usage_set", @@ -38,7 +27,6 @@ go_library( name = "filemem", srcs = [ "filemem.go", - "filemem_autogen_state.go", "filemem_state.go", "filemem_unsafe.go", "usage_set.go", diff --git a/pkg/sentry/platform/filemem/filemem.go b/pkg/sentry/platform/filemem/filemem.go index 870274ae1..feb020ef8 100644 --- a/pkg/sentry/platform/filemem/filemem.go +++ b/pkg/sentry/platform/filemem/filemem.go @@ -155,6 +155,8 @@ type FileMem struct { } // usage tracks usage information. +// +// +stateify savable type usageInfo struct { // kind is the usage kind. kind usage.MemoryKind diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 929787aa0..a320fca0b 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,22 +1,10 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "socket_state", - srcs = [ - "socket.go", - ], - out = "socket_state_autogen.go", - package = "socket", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "socket", - srcs = [ - "socket.go", - "socket_state_autogen.go", - ], + srcs = ["socket.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket", visibility = ["//pkg/sentry:internal"], deps = [ @@ -29,7 +17,6 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/tcpip", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index faf2b4c27..c4874fdfb 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,26 +1,14 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "control_state", - srcs = [ - "control.go", - ], - out = "control_state.go", - imports = [ - "gvisor.googlesource.com/gvisor/pkg/sentry/fs", - ], - package = "control", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "control", - srcs = [ - "control.go", - "control_state.go", - ], + srcs = ["control.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/control", + imports = [ + "gvisor.googlesource.com/gvisor/pkg/sentry/fs", + ], visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", @@ -31,7 +19,6 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/kdefs", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", ], diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index 17ecdd11c..c31182e69 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -51,6 +51,8 @@ type SCMRights interface { // RightsFiles represents a SCM_RIGHTS socket control message. A reference is // maintained for each fs.File and is release either when an FD is created or // when the Release method is called. +// +// +stateify savable type RightsFiles []*fs.File // NewSCMRights creates a new SCM_RIGHTS socket control message representation @@ -128,6 +130,8 @@ func PackRights(t *kernel.Task, rights SCMRights, cloexec bool, buf []byte) []by } // scmCredentials represents an SCM_CREDENTIALS socket control message. +// +// +stateify savable type scmCredentials struct { t *kernel.Task kuid auth.KUID diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index 7ad5e88c5..49af8db85 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,24 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "epsocket_state", - srcs = [ - "epsocket.go", - "save_restore.go", - "stack.go", - ], - out = "epsocket_state.go", - package = "epsocket", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "epsocket", srcs = [ "device.go", "epsocket.go", - "epsocket_state.go", "provider.go", "save_restore.go", "stack.go", @@ -31,7 +19,6 @@ go_library( "//pkg/abi/linux", "//pkg/binary", "//pkg/log", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", @@ -44,7 +31,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index a2927e1b9..f969a1d7c 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -95,6 +95,8 @@ type commonEndpoint interface { // SocketOperations encapsulates all the state needed to represent a network stack // endpoint in the kernel context. +// +// +stateify savable type SocketOperations struct { socket.ReceiveTimeout fsutil.PipeSeek `state:"nosave"` diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index ec1d96ccb..12b4b4767 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -26,6 +26,8 @@ import ( ) // Stack implements inet.Stack for netstack/tcpip/stack.Stack. +// +// +stateify savable type Stack struct { Stack *stack.Stack `state:"manual"` } diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index 227ca3926..d623718b3 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,24 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "hostinet_state", - srcs = [ - "save_restore.go", - "socket.go", - "stack.go", - ], - out = "hostinet_autogen_state.go", - package = "hostinet", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "hostinet", srcs = [ "device.go", "hostinet.go", - "hostinet_autogen_state.go", "save_restore.go", "socket.go", "socket_unsafe.go", @@ -42,7 +30,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index b23a243f7..b852165f7 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,21 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "netlink_state", - srcs = [ - "socket.go", - ], - out = "netlink_state.go", - package = "netlink", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "netlink", srcs = [ "message.go", - "netlink_state.go", "provider.go", "socket.go", ], @@ -36,7 +26,6 @@ go_library( "//pkg/sentry/socket/netlink/port", "//pkg/sentry/socket/unix", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index ba6f686e4..3a7dbc5ed 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,23 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "port_state", - srcs = ["port.go"], - out = "port_state.go", - package = "port", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "port", - srcs = [ - "port.go", - "port_state.go", - ], + srcs = ["port.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/port", visibility = ["//pkg/sentry:internal"], - deps = ["//pkg/state"], ) go_test( diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 4ccf0b84c..1c5d4c3a5 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -32,6 +32,8 @@ import ( const maxPorts = 10000 // Manager allocates netlink port IDs. +// +// +stateify savable type Manager struct { // mu protects the fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index 726469fc9..e1bcfe252 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,32 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "route_state", - srcs = ["protocol.go"], - out = "route_state.go", - package = "route", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "route", - srcs = [ - "protocol.go", - "route_state.go", - ], + srcs = ["protocol.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/route", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", "//pkg/sentry/context", - "//pkg/sentry/fs", "//pkg/sentry/inet", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/socket/netlink", - "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", ], ) diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index e8030c518..55a76e916 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -43,6 +43,8 @@ func typeKind(typ uint16) commandKind { } // Protocol implements netlink.Protocol. +// +// +stateify savable type Protocol struct{} var _ netlink.Protocol = (*Protocol)(nil) diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 0b8f528d0..e15d1546c 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -51,6 +51,8 @@ var netlinkSocketDevice = device.NewAnonDevice() // to/from the kernel. // // Socket implements socket.Socket. +// +// +stateify savable type Socket struct { socket.ReceiveTimeout fsutil.PipeSeek `state:"nosave"` diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index bd4858a34..54fe64595 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -195,6 +195,8 @@ func NewDirent(ctx context.Context, d *device.Device) *fs.Dirent { // // Care must be taken when copying ReceiveTimeout as it contains atomic // variables. +// +// +stateify savable type ReceiveTimeout struct { // ns is length of the timeout in nanoseconds. // diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index 7d04d6b6b..9fe681e9a 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,15 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "unix_state", - srcs = [ - "unix.go", - ], - out = "unix_state.go", - package = "unix", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "unix", @@ -17,7 +8,6 @@ go_library( "device.go", "io.go", "unix.go", - "unix_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix", visibility = ["//pkg/sentry:internal"], @@ -37,7 +27,6 @@ go_library( "//pkg/sentry/socket/control", "//pkg/sentry/socket/epsocket", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 27bacbbc3..5b6411f97 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -42,6 +42,8 @@ import ( // SocketOperations is a Unix socket. It is similar to an epsocket, except it is backed // by a unix.Endpoint instead of a tcpip.Endpoint. +// +// +stateify savable type SocketOperations struct { refs.AtomicRefCount socket.ReceiveTimeout diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 574621ad2..e4450a093 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,18 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "linux_state", - srcs = [ - "sys_aio.go", - "sys_futex.go", - "sys_poll.go", - "sys_time.go", - ], - out = "linux_state.go", - package = "linux", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "linux", @@ -20,7 +8,6 @@ go_library( "error.go", "flags.go", "linux64.go", - "linux_state.go", "sigset.go", "sys_aio.go", "sys_capability.go", @@ -66,7 +53,6 @@ go_library( "//pkg/abi/linux", "//pkg/binary", "//pkg/bpf", - "//pkg/eventchannel", "//pkg/log", "//pkg/metric", "//pkg/rand", @@ -74,7 +60,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", - "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/lock", "//pkg/sentry/fs/timerfd", "//pkg/sentry/kernel", @@ -85,7 +70,6 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/pipe", "//pkg/sentry/kernel/sched", - "//pkg/sentry/kernel/semaphore", "//pkg/sentry/kernel/shm", "//pkg/sentry/kernel/time", "//pkg/sentry/limits", @@ -97,8 +81,6 @@ go_library( "//pkg/sentry/syscalls", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", - "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index fc3397081..54e4afa9e 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -69,6 +69,8 @@ type ioCallback struct { } // ioEvent describes an I/O result. +// +// +stateify savable type ioEvent struct { Data uint64 Obj uint64 diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index 57762d058..1a0e1f5fb 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -132,6 +132,8 @@ func (f futexChecker) Op(addr uintptr, opIn uint32) (bool, error) { // futexWaitRestartBlock encapsulates the state required to restart futex(2) // via restart_syscall(2). +// +// +stateify savable type futexWaitRestartBlock struct { duration time.Duration diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index d4dbfd285..b9bdefadb 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -274,6 +274,8 @@ func copyOutTimevalRemaining(t *kernel.Task, startNs ktime.Time, timeout time.Du // pollRestartBlock encapsulates the state required to restart poll(2) via // restart_syscall(2). +// +// +stateify savable type pollRestartBlock struct { pfdAddr usermem.Addr nfds uint diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index dcee694b2..8e6683444 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -168,6 +168,8 @@ func Time(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC // clockNanosleepRestartBlock encapsulates the state required to restart // clock_nanosleep(2) via restart_syscall(2). +// +// +stateify savable type clockNanosleepRestartBlock struct { c ktime.Clock duration time.Duration diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index edee44d96..868dfd400 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,17 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "usage_state", - srcs = [ - "cpu.go", - "io.go", - "memory.go", - ], - out = "usage_state.go", - package = "usage", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "usage", @@ -21,7 +10,6 @@ go_library( "memory.go", "memory_unsafe.go", "usage.go", - "usage_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/usage", visibility = [ @@ -29,9 +17,6 @@ go_library( ], deps = [ "//pkg/bits", - "//pkg/log", "//pkg/sentry/memutil", - "//pkg/state", - "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index 1c2cc90e1..ed7b04b9e 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -20,6 +20,8 @@ import ( // CPUStats contains the subset of struct rusage fields that relate to CPU // scheduling. +// +// +stateify savable type CPUStats struct { // UserTime is the amount of time spent executing application code. UserTime time.Duration diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index a05053c32..49faa507d 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -19,6 +19,8 @@ import ( ) // IO contains I/O-related statistics. +// +// +stateify savable type IO struct { // CharsRead is the number of bytes read by read syscalls. CharsRead uint64 diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index 9dd1cd2b5..69ba919e0 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,19 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "usermem_state", - srcs = [ - "access_type.go", - "addr.go", - "addr_range.go", - "addr_range_seq_unsafe.go", - ], - out = "usermem_state.go", - package = "usermem", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "addr_range", @@ -36,7 +24,6 @@ go_library( "bytes_io.go", "bytes_io_unsafe.go", "usermem.go", - "usermem_state.go", "usermem_x86.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/usermem", @@ -47,7 +34,6 @@ go_library( "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/safemem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/buffer", ], diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 7eabecf30..75346d854 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -20,6 +20,8 @@ import ( // AccessType specifies memory access types. This is used for // setting mapping permissions, as well as communicating faults. +// +// +stateify savable type AccessType struct { // Read is read access. Read bool diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index d175fdc74..fc94bee80 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -19,6 +19,8 @@ import ( ) // Addr represents a generic virtual address. +// +// +stateify savable type Addr uintptr // AddLength adds the given length to start and returns the result. ok is true diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 391d801d0..5153bd3b4 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,26 +1,13 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tcpip_state", - srcs = [ - "tcpip.go", - ], - out = "tcpip_state.go", - package = "tcpip", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tcpip", - srcs = [ - "tcpip.go", - "tcpip_state.go", - ], + srcs = ["tcpip.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip", visibility = ["//visibility:public"], deps = [ - "//pkg/state", "//pkg/tcpip/buffer", "//pkg/waiter", ], diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index efeb6a448..11a725423 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,26 +1,15 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "buffer_state", - srcs = [ - "view.go", - ], - out = "buffer_state.go", - package = "buffer", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "buffer", srcs = [ - "buffer_state.go", "prependable.go", "view.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer", visibility = ["//visibility:public"], - deps = ["//pkg/state"], ) go_test( diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index a5774a327..bbb4e1d24 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -54,6 +54,8 @@ func (v *View) ToVectorisedView(views [1]View) VectorisedView { // VectorisedView is a vectorised version of View using non contigous memory. // It supports all the convenience methods supported by View. +// +// +stateify savable type VectorisedView struct { views []View size int diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 3aa2cfb24..8f22ba3a5 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,15 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tcp_header_state", - srcs = [ - "tcp.go", - ], - out = "tcp_header_state.go", - package = "header", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "header", @@ -25,13 +16,11 @@ go_library( "ipv6.go", "ipv6_fragment.go", "tcp.go", - "tcp_header_state.go", "udp.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/header", visibility = ["//visibility:public"], deps = [ - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/seqnum", ], diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index a95d282b0..6689a6dc5 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -120,6 +120,8 @@ type TCPSynOptions struct { } // SACKBlock represents a single contiguous SACK block. +// +// +stateify savable type SACKBlock struct { // Start indicates the lowest sequence number in the block. Start seqnum.Value @@ -131,6 +133,8 @@ type SACKBlock struct { // TCPOptions are used to parse and cache the TCP segment options for a non // syn/syn-ack segment. +// +// +stateify savable type TCPOptions struct { // TS is true if the TimeStamp option is enabled. TS bool diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index ac97ebe43..83b4d253f 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,14 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "fragmentation_state", - srcs = ["reassembler_list.go"], - out = "fragmentation_state.go", - package = "fragmentation", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "reassembler_list", @@ -26,7 +19,6 @@ go_library( srcs = [ "frag_heap.go", "fragmentation.go", - "fragmentation_state.go", "reassembler.go", "reassembler_list.go", ], @@ -34,7 +26,6 @@ go_library( visibility = ["//:sandbox"], deps = [ "//pkg/log", - "//pkg/state", "//pkg/tcpip/buffer", ], ) diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index a75869dac..c5c889239 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,25 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "seqnum_state", - srcs = [ - "seqnum.go", - ], - out = "seqnum_state.go", - package = "seqnum", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "seqnum", - srcs = [ - "seqnum.go", - "seqnum_state.go", - ], + srcs = ["seqnum.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum", visibility = [ "//visibility:public", ], - deps = ["//pkg/state"], ) diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index eb1e4645d..af0aec85c 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -213,6 +213,8 @@ const ( // FullAddress represents a full transport node address, as required by the // Connect() and Bind() methods. +// +// +stateify savable type FullAddress struct { // NIC is the ID of the NIC this address refers to. // @@ -256,6 +258,8 @@ func (s SlicePayload) Size() int { } // A ControlMessages contains socket control messages for IP sockets. +// +// +stateify savable type ControlMessages struct { // HasTimestamp indicates whether Timestamp is valid/set. HasTimestamp bool diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 28e3e1700..117532fea 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,19 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "ping_state", - srcs = [ - "endpoint.go", - "endpoint_state.go", - "ping_packet_list.go", - ], - out = "ping_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], - package = "ping", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "ping_packet_list", @@ -32,14 +20,13 @@ go_library( "endpoint.go", "endpoint_state.go", "ping_packet_list.go", - "ping_state.go", "protocol.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index f15e44b61..a22684de9 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -26,6 +26,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) +// +stateify savable type pingPacket struct { pingPacketEntry senderAddress tcpip.FullAddress diff --git a/pkg/tcpip/transport/queue/BUILD b/pkg/tcpip/transport/queue/BUILD index fb878ad36..6dcec312e 100644 --- a/pkg/tcpip/transport/queue/BUILD +++ b/pkg/tcpip/transport/queue/BUILD @@ -1,27 +1,14 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "queue_state", - srcs = [ - "queue.go", - ], - out = "queue_state.go", - package = "queue", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "queue", - srcs = [ - "queue.go", - "queue_state.go", - ], + srcs = ["queue.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/queue", visibility = ["//:sandbox"], deps = [ "//pkg/ilist", - "//pkg/state", "//pkg/tcpip", "//pkg/waiter", ], diff --git a/pkg/tcpip/transport/queue/queue.go b/pkg/tcpip/transport/queue/queue.go index 6a17441ae..eb9ee8a3f 100644 --- a/pkg/tcpip/transport/queue/queue.go +++ b/pkg/tcpip/transport/queue/queue.go @@ -33,6 +33,8 @@ type Entry interface { } // Queue is a buffer queue. +// +// +stateify savable type Queue struct { ReaderQueue *waiter.Queue WriterQueue *waiter.Queue diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 6a7153e4d..9ebae6cc7 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,27 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tcp_state", - srcs = [ - "endpoint.go", - "endpoint_state.go", - "rcv.go", - "reno.go", - "segment.go", - "segment_heap.go", - "segment_queue.go", - "segment_state.go", - "snd.go", - "snd_state.go", - "tcp_segment_list.go", - ], - out = "tcp_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], - package = "tcp", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "tcp_segment_list", @@ -53,15 +33,14 @@ go_library( "snd.go", "snd_state.go", "tcp_segment_list.go", - "tcp_state.go", "timer.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/rand", "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 5b8a1e20f..de1883d84 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -54,6 +54,8 @@ const ( ) // SACKInfo holds TCP SACK related information for a given endpoint. +// +// +stateify savable type SACKInfo struct { // Blocks is the maximum number of SACK blocks we track // per endpoint. @@ -69,6 +71,8 @@ type SACKInfo struct { // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. The protocol implementation, however, runs in a single // goroutine. +// +// +stateify savable type endpoint struct { // workMu is used to arbitrate which goroutine may perform protocol // work. Only the main protocol goroutine is expected to call Lock() on diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index b22a00ce1..92ef9c6f7 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -22,6 +22,8 @@ import ( // receiver holds the state necessary to receive TCP segments and turn them // into a stream of bytes. +// +// +stateify savable type receiver struct { ep *endpoint diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index 60f170a27..03ae8d747 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -16,6 +16,8 @@ package tcp // renoState stores the variables related to TCP New Reno congestion // control algorithm. +// +// +stateify savable type renoState struct { s *sender } diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 40928ba2c..8dccea2ba 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -36,6 +36,8 @@ const ( // segment represents a TCP segment. It holds the payload and parsed TCP segment // information, and can be added to intrusive lists. // segment is mostly immutable, the only field allowed to change is viewToDeliver. +// +// +stateify savable type segment struct { segmentEntry refCnt int32 diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 2ddcf5f10..6a2d7bc0b 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -21,6 +21,8 @@ import ( ) // segmentQueue is a bounded, thread-safe queue of TCP segments. +// +// +stateify savable type segmentQueue struct { mu sync.Mutex `state:"nosave"` list segmentList `state:"wait"` diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index e38686e1b..376e81846 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -54,6 +54,8 @@ type congestionControl interface { } // sender holds the state necessary to send TCP segments. +// +// +stateify savable type sender struct { ep *endpoint @@ -133,6 +135,8 @@ type sender struct { } // fastRecovery holds information related to fast recovery from a packet loss. +// +// +stateify savable type fastRecovery struct { // active whether the endpoint is in fast recovery. The following fields // are only meaningful when active is true. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index 33c8867f4..d536839af 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -18,6 +18,7 @@ import ( "time" ) +// +stateify savable type unixTime struct { second int64 nano int64 diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 790dd55a3..1a3a62d3d 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,19 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "udp_state", - srcs = [ - "endpoint.go", - "endpoint_state.go", - "udp_packet_list.go", - ], - out = "udp_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], - package = "udp", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "udp_packet_list", @@ -33,13 +21,12 @@ go_library( "endpoint_state.go", "protocol.go", "udp_packet_list.go", - "udp_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 2a32c3a87..03fb76f92 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -25,6 +25,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) +// +stateify savable type udpPacket struct { udpPacketEntry senderAddress tcpip.FullAddress @@ -49,6 +50,8 @@ const ( // between users of the endpoint and the protocol implementation; it is legal to // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. +// +// +stateify savable type endpoint struct { // The following fields are initialized at creation time and do not // change throughout the lifetime of the endpoint. diff --git a/pkg/tcpip/transport/unix/BUILD b/pkg/tcpip/transport/unix/BUILD index 676f2cf92..dae0bd079 100644 --- a/pkg/tcpip/transport/unix/BUILD +++ b/pkg/tcpip/transport/unix/BUILD @@ -1,17 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "unix_state", - srcs = [ - "connectioned.go", - "connectionless.go", - "unix.go", - ], - out = "unix_state.go", - package = "unix", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "unix", @@ -20,14 +9,11 @@ go_library( "connectioned_state.go", "connectionless.go", "unix.go", - "unix_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix", visibility = ["//:sandbox"], deps = [ "//pkg/ilist", - "//pkg/log", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/transport/queue", diff --git a/pkg/tcpip/transport/unix/connectioned.go b/pkg/tcpip/transport/unix/connectioned.go index 0e63186b2..dd7c03cf1 100644 --- a/pkg/tcpip/transport/unix/connectioned.go +++ b/pkg/tcpip/transport/unix/connectioned.go @@ -85,6 +85,8 @@ type ConnectingEndpoint interface { // path != "" && acceptedChan != nil => bound and listening. // // Only one of these will be true at any moment. +// +// +stateify savable type connectionedEndpoint struct { baseEndpoint diff --git a/pkg/tcpip/transport/unix/connectionless.go b/pkg/tcpip/transport/unix/connectionless.go index 3276ddcd0..2a6ec8b4b 100644 --- a/pkg/tcpip/transport/unix/connectionless.go +++ b/pkg/tcpip/transport/unix/connectionless.go @@ -25,6 +25,8 @@ import ( // // Specifically, this means datagram unix sockets not created with // socketpair(2). +// +// +stateify savable type connectionlessEndpoint struct { baseEndpoint } diff --git a/pkg/tcpip/transport/unix/unix.go b/pkg/tcpip/transport/unix/unix.go index 190a1ccdb..8e4af3139 100644 --- a/pkg/tcpip/transport/unix/unix.go +++ b/pkg/tcpip/transport/unix/unix.go @@ -60,6 +60,8 @@ type CredentialsControlMessage interface { } // A ControlMessages represents a collection of socket control messages. +// +// +stateify savable type ControlMessages struct { // Rights is a control message containing FDs. Rights RightsControlMessage @@ -235,6 +237,8 @@ type BoundEndpoint interface { } // message represents a message passed over a Unix domain socket. +// +// +stateify savable type message struct { ilist.Entry @@ -306,6 +310,8 @@ type Receiver interface { } // queueReceiver implements Receiver for datagram sockets. +// +// +stateify savable type queueReceiver struct { readQueue *queue.Queue } @@ -369,6 +375,8 @@ func (q *queueReceiver) RecvMaxQueueSize() int64 { func (*queueReceiver) Release() {} // streamQueueReceiver implements Receiver for stream sockets. +// +// +stateify savable type streamQueueReceiver struct { queueReceiver @@ -579,6 +587,7 @@ type ConnectedEndpoint interface { Release() } +// +stateify savable type connectedEndpoint struct { // endpoint represents the subset of the Endpoint functionality needed by // the connectedEndpoint. It is implemented by both connectionedEndpoint @@ -671,6 +680,8 @@ func (*connectedEndpoint) Release() {} // unix domain socket Endpoint implementations. // // Not to be used on its own. +// +// +stateify savable type baseEndpoint struct { *waiter.Queue diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 8256acdb4..5e611c54f 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,28 +1,13 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "waiter_state", - srcs = [ - "waiter.go", - ], - out = "waiter_state.go", - package = "waiter", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "waiter", - srcs = [ - "waiter.go", - "waiter_state.go", - ], + srcs = ["waiter.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/waiter", visibility = ["//visibility:public"], - deps = [ - "//pkg/ilist", - "//pkg/state", - ], + deps = ["//pkg/ilist"], ) go_test( diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 9b189bb9e..9825880ca 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -157,6 +157,8 @@ func NewChannelEntry(c chan struct{}) (Entry, chan struct{}) { // notifiers can notify them when events happen. // // The zero value for waiter.Queue is an empty queue ready for use. +// +// +stateify savable type Queue struct { list ilist.List `state:"zerovalue"` mu sync.RWMutex `state:"nosave"` -- cgit v1.2.3 From 60add78980737a7330100d98bf6a214892dee3c0 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 1 Aug 2018 19:56:12 -0700 Subject: Automated rollback of changelist 207007153 PiperOrigin-RevId: 207037226 Change-Id: I8b5f1a056d4f3eab17846f2e0193bb737ecb5428 --- pkg/abi/BUILD | 13 +++++- pkg/abi/linux/BUILD | 16 ++++++- pkg/abi/linux/bpf.go | 2 - pkg/abi/linux/tty.go | 2 - pkg/bpf/BUILD | 17 +++++++- pkg/bpf/interpreter.go | 2 - pkg/cpuid/BUILD | 15 ++++++- pkg/cpuid/cpuid.go | 2 - pkg/ilist/BUILD | 15 ++++++- pkg/ilist/list.go | 4 -- pkg/segment/range.go | 2 - pkg/segment/set.go | 5 --- pkg/sentry/arch/BUILD | 18 +++++++- pkg/sentry/arch/arch.go | 2 - pkg/sentry/arch/arch_amd64.go | 2 - pkg/sentry/arch/arch_state_x86.go | 1 - pkg/sentry/arch/arch_x86.go | 2 - pkg/sentry/arch/auxv.go | 2 - pkg/sentry/arch/signal_amd64.go | 6 --- pkg/sentry/context/contexttest/BUILD | 17 +++++++- pkg/sentry/fs/BUILD | 36 +++++++++++++++- pkg/sentry/fs/ashmem/BUILD | 17 +++++++- pkg/sentry/fs/ashmem/area.go | 8 ++-- pkg/sentry/fs/ashmem/device.go | 22 +++++----- pkg/sentry/fs/ashmem/pin_board.go | 2 - pkg/sentry/fs/attr.go | 12 ------ pkg/sentry/fs/binder/BUILD | 13 +++++- pkg/sentry/fs/binder/binder.go | 26 +++++------- pkg/sentry/fs/dentry.go | 4 -- pkg/sentry/fs/dev/BUILD | 20 ++++++++- pkg/sentry/fs/dev/dev.go | 2 - pkg/sentry/fs/dev/fs.go | 2 - pkg/sentry/fs/dev/full.go | 2 - pkg/sentry/fs/dev/null.go | 3 -- pkg/sentry/fs/dev/random.go | 1 - pkg/sentry/fs/dirent.go | 2 - pkg/sentry/fs/dirent_cache.go | 2 - pkg/sentry/fs/fdpipe/BUILD | 31 +++++++++++++- pkg/sentry/fs/fdpipe/pipe.go | 2 - pkg/sentry/fs/file.go | 2 - pkg/sentry/fs/file_overlay.go | 4 -- pkg/sentry/fs/filesystems.go | 2 - pkg/sentry/fs/filetest/BUILD | 18 +++++++- pkg/sentry/fs/flags.go | 2 - pkg/sentry/fs/fsutil/BUILD | 20 ++++++++- pkg/sentry/fs/fsutil/dirty_set.go | 2 - pkg/sentry/fs/fsutil/handle.go | 2 - pkg/sentry/fs/fsutil/host_file_mapper.go | 2 - pkg/sentry/fs/fsutil/inode.go | 6 --- pkg/sentry/fs/fsutil/inode_cached.go | 2 - pkg/sentry/fs/gofer/BUILD | 23 +++++++++- pkg/sentry/fs/gofer/file.go | 2 - pkg/sentry/fs/gofer/fs.go | 2 - pkg/sentry/fs/gofer/inode.go | 4 -- pkg/sentry/fs/gofer/session.go | 3 -- pkg/sentry/fs/host/BUILD | 27 +++++++++++- pkg/sentry/fs/host/descriptor.go | 2 - pkg/sentry/fs/host/file.go | 2 - pkg/sentry/fs/host/fs.go | 6 +-- pkg/sentry/fs/host/inode.go | 4 -- pkg/sentry/fs/inode.go | 4 -- pkg/sentry/fs/inode_inotify.go | 2 - pkg/sentry/fs/inotify.go | 2 - pkg/sentry/fs/inotify_event.go | 2 - pkg/sentry/fs/inotify_watch.go | 2 - pkg/sentry/fs/lock/BUILD | 15 ++++++- pkg/sentry/fs/lock/lock.go | 6 +-- pkg/sentry/fs/mount.go | 4 -- pkg/sentry/fs/mount_overlay.go | 4 -- pkg/sentry/fs/mounts.go | 2 - pkg/sentry/fs/overlay.go | 2 - pkg/sentry/fs/proc/BUILD | 34 ++++++++++++++- pkg/sentry/fs/proc/cpuinfo.go | 2 - pkg/sentry/fs/proc/exec_args.go | 2 - pkg/sentry/fs/proc/fds.go | 6 --- pkg/sentry/fs/proc/file.go | 1 - pkg/sentry/fs/proc/filesystems.go | 2 - pkg/sentry/fs/proc/fs.go | 2 - pkg/sentry/fs/proc/loadavg.go | 2 - pkg/sentry/fs/proc/meminfo.go | 2 - pkg/sentry/fs/proc/mounts.go | 4 -- pkg/sentry/fs/proc/proc.go | 4 -- pkg/sentry/fs/proc/seqfile/BUILD | 30 +++++++++++-- pkg/sentry/fs/proc/seqfile/seqfile.go | 4 -- pkg/sentry/fs/proc/stat.go | 2 - pkg/sentry/fs/proc/sys.go | 5 --- pkg/sentry/fs/proc/sys_net.go | 2 - pkg/sentry/fs/proc/task.go | 20 --------- pkg/sentry/fs/proc/uid_gid_map.go | 3 -- pkg/sentry/fs/proc/uptime.go | 2 - pkg/sentry/fs/proc/version.go | 2 - pkg/sentry/fs/ramfs/BUILD | 21 ++++++++- pkg/sentry/fs/ramfs/dir.go | 2 - pkg/sentry/fs/ramfs/ramfs.go | 2 - pkg/sentry/fs/ramfs/socket.go | 2 - pkg/sentry/fs/ramfs/symlink.go | 2 - pkg/sentry/fs/ramfs/test/BUILD | 18 +++++++- pkg/sentry/fs/sys/BUILD | 14 +++++- pkg/sentry/fs/sys/fs.go | 2 - pkg/sentry/fs/sys/sys.go | 5 +-- pkg/sentry/fs/timerfd/BUILD | 18 +++++++- pkg/sentry/fs/timerfd/timerfd.go | 4 +- pkg/sentry/fs/tmpfs/BUILD | 17 +++++++- pkg/sentry/fs/tmpfs/file_regular.go | 2 - pkg/sentry/fs/tmpfs/fs.go | 2 - pkg/sentry/fs/tmpfs/inode_file.go | 2 - pkg/sentry/fs/tmpfs/tmpfs.go | 8 ---- pkg/sentry/fs/tty/BUILD | 20 ++++++++- pkg/sentry/fs/tty/dir.go | 18 +++----- pkg/sentry/fs/tty/fs.go | 4 -- pkg/sentry/fs/tty/inode.go | 2 - pkg/sentry/fs/tty/line_discipline.go | 6 --- pkg/sentry/fs/tty/master.go | 4 -- pkg/sentry/fs/tty/queue.go | 4 +- pkg/sentry/fs/tty/slave.go | 4 -- pkg/sentry/fs/tty/terminal.go | 2 - pkg/sentry/inet/BUILD | 15 ++++++- pkg/sentry/inet/inet.go | 2 - pkg/sentry/kernel/BUILD | 59 +++++++++++++++++++++++--- pkg/sentry/kernel/abstract_socket_namespace.go | 3 -- pkg/sentry/kernel/auth/BUILD | 17 +++++++- pkg/sentry/kernel/auth/credentials.go | 2 - pkg/sentry/kernel/auth/id_map.go | 2 - pkg/sentry/kernel/auth/user_namespace.go | 2 - pkg/sentry/kernel/epoll/BUILD | 15 ++++++- pkg/sentry/kernel/epoll/epoll.go | 8 +--- pkg/sentry/kernel/eventfd/BUILD | 18 +++++++- pkg/sentry/kernel/eventfd/eventfd.go | 4 +- pkg/sentry/kernel/fd_map.go | 6 --- pkg/sentry/kernel/fs_context.go | 2 - pkg/sentry/kernel/futex/BUILD | 18 +++++++- pkg/sentry/kernel/futex/futex.go | 2 - pkg/sentry/kernel/ipc_namespace.go | 2 - pkg/sentry/kernel/kernel.go | 4 +- pkg/sentry/kernel/pending_signals.go | 5 --- pkg/sentry/kernel/pipe/BUILD | 20 ++++++++- pkg/sentry/kernel/pipe/buffers.go | 2 - pkg/sentry/kernel/pipe/node.go | 2 - pkg/sentry/kernel/pipe/pipe.go | 2 - pkg/sentry/kernel/pipe/reader.go | 2 - pkg/sentry/kernel/pipe/reader_writer.go | 2 - pkg/sentry/kernel/pipe/writer.go | 2 - pkg/sentry/kernel/ptrace.go | 4 -- pkg/sentry/kernel/rseq.go | 2 - pkg/sentry/kernel/semaphore/BUILD | 15 ++++++- pkg/sentry/kernel/semaphore/semaphore.go | 8 ---- pkg/sentry/kernel/sessions.go | 4 -- pkg/sentry/kernel/shm/BUILD | 13 +++++- pkg/sentry/kernel/shm/shm.go | 4 -- pkg/sentry/kernel/signal_handlers.go | 2 - pkg/sentry/kernel/syscalls.go | 2 - pkg/sentry/kernel/syslog.go | 2 - pkg/sentry/kernel/task.go | 2 - pkg/sentry/kernel/task_clone.go | 4 -- pkg/sentry/kernel/task_context.go | 2 - pkg/sentry/kernel/task_exec.go | 4 -- pkg/sentry/kernel/task_exit.go | 6 --- pkg/sentry/kernel/task_resources.go | 2 - pkg/sentry/kernel/task_run.go | 2 - pkg/sentry/kernel/task_sched.go | 2 - pkg/sentry/kernel/task_signals.go | 5 --- pkg/sentry/kernel/task_syscall.go | 4 -- pkg/sentry/kernel/thread_group.go | 2 - pkg/sentry/kernel/threads.go | 8 ---- pkg/sentry/kernel/time/BUILD | 14 +++++- pkg/sentry/kernel/time/time.go | 6 --- pkg/sentry/kernel/timekeeper.go | 2 - pkg/sentry/kernel/timer.go | 8 ---- pkg/sentry/kernel/uts_namespace.go | 2 - pkg/sentry/kernel/vdso.go | 2 - pkg/sentry/limits/BUILD | 13 +++++- pkg/sentry/limits/limits.go | 4 -- pkg/sentry/loader/BUILD | 15 ++++++- pkg/sentry/loader/vdso.go | 2 - pkg/sentry/loader/vdso_state.go | 1 - pkg/sentry/memmap/BUILD | 15 ++++++- pkg/sentry/memmap/mapping_set.go | 2 - pkg/sentry/mm/BUILD | 21 ++++++++- pkg/sentry/mm/aio_context.go | 8 ---- pkg/sentry/mm/mm.go | 7 --- pkg/sentry/mm/special_mappable.go | 2 - pkg/sentry/platform/BUILD | 13 +++++- pkg/sentry/platform/filemem/BUILD | 14 +++++- pkg/sentry/platform/filemem/filemem.go | 2 - pkg/sentry/socket/BUILD | 17 +++++++- pkg/sentry/socket/control/BUILD | 23 +++++++--- pkg/sentry/socket/control/control.go | 4 -- pkg/sentry/socket/epsocket/BUILD | 16 ++++++- pkg/sentry/socket/epsocket/epsocket.go | 2 - pkg/sentry/socket/epsocket/stack.go | 2 - pkg/sentry/socket/hostinet/BUILD | 15 ++++++- pkg/sentry/socket/netlink/BUILD | 13 +++++- pkg/sentry/socket/netlink/port/BUILD | 15 ++++++- pkg/sentry/socket/netlink/port/port.go | 2 - pkg/sentry/socket/netlink/route/BUILD | 17 +++++++- pkg/sentry/socket/netlink/route/protocol.go | 2 - pkg/sentry/socket/netlink/socket.go | 2 - pkg/sentry/socket/socket.go | 2 - pkg/sentry/socket/unix/BUILD | 13 +++++- pkg/sentry/socket/unix/unix.go | 2 - pkg/sentry/syscalls/linux/BUILD | 20 ++++++++- pkg/sentry/syscalls/linux/sys_aio.go | 2 - pkg/sentry/syscalls/linux/sys_futex.go | 2 - pkg/sentry/syscalls/linux/sys_poll.go | 2 - pkg/sentry/syscalls/linux/sys_time.go | 2 - pkg/sentry/usage/BUILD | 17 +++++++- pkg/sentry/usage/cpu.go | 2 - pkg/sentry/usage/io.go | 2 - pkg/sentry/usermem/BUILD | 16 ++++++- pkg/sentry/usermem/access_type.go | 2 - pkg/sentry/usermem/addr.go | 2 - pkg/tcpip/BUILD | 17 +++++++- pkg/tcpip/buffer/BUILD | 13 +++++- pkg/tcpip/buffer/view.go | 2 - pkg/tcpip/header/BUILD | 13 +++++- pkg/tcpip/header/tcp.go | 4 -- pkg/tcpip/network/fragmentation/BUILD | 11 ++++- pkg/tcpip/seqnum/BUILD | 17 +++++++- pkg/tcpip/tcpip.go | 4 -- pkg/tcpip/transport/ping/BUILD | 17 +++++++- pkg/tcpip/transport/ping/endpoint.go | 1 - pkg/tcpip/transport/queue/BUILD | 17 +++++++- pkg/tcpip/transport/queue/queue.go | 2 - pkg/tcpip/transport/tcp/BUILD | 25 ++++++++++- pkg/tcpip/transport/tcp/endpoint.go | 4 -- pkg/tcpip/transport/tcp/rcv.go | 2 - pkg/tcpip/transport/tcp/reno.go | 2 - pkg/tcpip/transport/tcp/segment.go | 2 - pkg/tcpip/transport/tcp/segment_queue.go | 2 - pkg/tcpip/transport/tcp/snd.go | 4 -- pkg/tcpip/transport/tcp/snd_state.go | 1 - pkg/tcpip/transport/udp/BUILD | 17 +++++++- pkg/tcpip/transport/udp/endpoint.go | 3 -- pkg/tcpip/transport/unix/BUILD | 16 ++++++- pkg/tcpip/transport/unix/connectioned.go | 2 - pkg/tcpip/transport/unix/connectionless.go | 2 - pkg/tcpip/transport/unix/unix.go | 11 ----- pkg/waiter/BUILD | 21 +++++++-- pkg/waiter/waiter.go | 2 - 239 files changed, 1108 insertions(+), 662 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index c014d2c4b..f1e6bac67 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,13 +1,24 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "abi_state", + srcs = [ + "abi.go", + ], + out = "abi_state.go", + package = "abi", +) go_library( name = "abi", srcs = [ "abi.go", + "abi_state.go", "flag.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/abi", visibility = ["//:sandbox"], + deps = ["//pkg/state"], ) diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index ac4ceefbc..38b4829c9 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -4,7 +4,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "linux_state", + srcs = [ + "binder.go", + "bpf.go", + "time.go", + "tty.go", + ], + out = "linux_state.go", + package = "linux", +) go_library( name = "linux", @@ -29,6 +41,7 @@ go_library( "ipc.go", "limits.go", "linux.go", + "linux_state.go", "mm.go", "netdevice.go", "netlink.go", @@ -54,5 +67,6 @@ go_library( "//pkg/abi", "//pkg/binary", "//pkg/bits", + "//pkg/state", ], ) diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index 80e5b1af1..f597ef4f5 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -15,8 +15,6 @@ package linux // BPFInstruction is a raw BPF virtual machine instruction. -// -// +stateify savable type BPFInstruction struct { // OpCode is the operation to execute. OpCode uint16 diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index b640f7627..84b6ccc87 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -38,8 +38,6 @@ type Termios struct { // KernelTermios is struct ktermios/struct termios2, defined in // uapi/asm-generic/termbits.h. -// -// +stateify savable type KernelTermios struct { InputFlags uint32 OutputFlags uint32 diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index 564df3af5..403270049 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,11 +1,21 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "bpf_state", + srcs = [ + "interpreter.go", + ], + out = "bpf_state.go", + package = "bpf", +) go_library( name = "bpf", srcs = [ "bpf.go", + "bpf_state.go", "decoder.go", "input_bytes.go", "interpreter.go", @@ -13,7 +23,10 @@ go_library( ], importpath = "gvisor.googlesource.com/gvisor/pkg/bpf", visibility = ["//visibility:public"], - deps = ["//pkg/abi/linux"], + deps = [ + "//pkg/abi/linux", + "//pkg/state", + ], ) go_test( diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index 111ada9d1..b7dee86a8 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -88,8 +88,6 @@ func (e Error) Error() string { } // Program is a BPF program that has been validated for consistency. -// -// +stateify savable type Program struct { instructions []linux.BPFInstruction } diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index 46fc4703b..9a0ca1b33 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,16 +1,27 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "cpuid_state", + srcs = ["cpuid.go"], + out = "cpuid_state.go", + package = "cpuid", +) go_library( name = "cpuid", srcs = [ "cpu_amd64.s", "cpuid.go", + "cpuid_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/cpuid", visibility = ["//:sandbox"], - deps = ["//pkg/log"], + deps = [ + "//pkg/log", + "//pkg/state", + ], ) go_test( diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index e91e34dc7..b486ab037 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -409,8 +409,6 @@ func (f Feature) flagString(cpuinfoOnly bool) string { } // FeatureSet is a set of Features for a cpu. -// -// +stateify savable type FeatureSet struct { // Set is the set of features that are enabled in this FeatureSet. Set map[Feature]bool diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index b26a39132..e32f26ffa 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,15 +1,28 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "list_state", + srcs = [ + "interface_list.go", + ], + out = "interface_list_state.go", + package = "ilist", +) go_library( name = "ilist", srcs = [ "interface_list.go", + "interface_list_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/ilist", visibility = ["//visibility:public"], + deps = [ + "//pkg/state", + ], ) go_template_instance( diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index a88b82196..5efb6c072 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -36,8 +36,6 @@ type Linker interface { // for e := l.Front(); e != nil; e = e.Next() { // // do something with e. // } -// -// +stateify savable type List struct { head Linker tail Linker @@ -157,8 +155,6 @@ func (l *List) Remove(e Linker) { // Entry is a default implementation of Linker. Users can add anonymous fields // of this type to their structs to make them automatically implement the // methods needed by List. -// -// +stateify savable type Entry struct { next Linker prev Linker diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 34c067265..5ff30d489 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -18,8 +18,6 @@ package segment type T uint64 // A Range represents a contiguous range of T. -// -// +stateify savable type Range struct { // Start is the inclusive start of the range. Start T diff --git a/pkg/segment/set.go b/pkg/segment/set.go index cffec2a2c..6eed1d930 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -88,8 +88,6 @@ const ( // A Set is a mapping of segments with non-overlapping Range keys. The zero // value for a Set is an empty set. Set values are not safely movable nor // copyable. Set is thread-compatible. -// -// +stateify savable type Set struct { root node `state:".(*SegmentDataSlices)"` } @@ -598,7 +596,6 @@ func (s *Set) ApplyContiguous(r Range, fn func(seg Iterator)) GapIterator { } } -// +stateify savable type node struct { // An internal binary tree node looks like: // @@ -1320,8 +1317,6 @@ func (n *node) writeDebugString(buf *bytes.Buffer, prefix string) { // SegmentDataSlices represents segments from a set as slices of start, end, and // values. SegmentDataSlices is primarily used as an intermediate representation // for save/restore and the layout here is optimized for that. -// -// +stateify savable type SegmentDataSlices struct { Start []Key End []Key diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index 314b3e962..0a2a35400 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,7 +1,21 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "arch_state", + srcs = [ + "arch.go", + "arch_amd64.go", + "arch_state_x86.go", + "arch_x86.go", + "auxv.go", + "signal_amd64.go", + ], + out = "arch_state.go", + package = "arch", +) go_library( name = "arch", @@ -10,6 +24,7 @@ go_library( "arch.go", "arch_amd64.go", "arch_amd64.s", + "arch_state.go", "arch_state_x86.go", "arch_x86.go", "auxv.go", @@ -31,6 +46,7 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/limits", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 21cb84502..0189e958d 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -254,8 +254,6 @@ const ( // MemoryManager. // // Note that "highest address" below is always exclusive. -// -// +stateify savable type MmapLayout struct { // MinAddr is the lowest mappable address. MinAddr usermem.Addr diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index f1e408af9..23526fe8e 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -95,8 +95,6 @@ const ( ) // context64 represents an AMD64 context. -// -// +stateify savable type context64 struct { State sigFPState []x86FPState // fpstate to be restored on sigreturn. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index e9c23a06b..cb38d098a 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -56,7 +56,6 @@ func (s *State) afterLoad() { copy(s.x86FPState, old) } -// +stateify savable type syscallPtraceRegs struct { R15 uint64 R14 uint64 diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index b35eec53c..5cc4f8377 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -153,8 +153,6 @@ func NewFloatingPointData() *FloatingPointData { // State contains the common architecture bits for X86 (the build tag of this // file ensures it's only built on x86). -// -// +stateify savable type State struct { // The system registers. Regs syscall.PtraceRegs `state:".(syscallPtraceRegs)"` diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 81cfb4a01..70e0e35b7 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -19,8 +19,6 @@ import ( ) // An AuxEntry represents an entry in an ELF auxiliary vector. -// -// +stateify savable type AuxEntry struct { Key uint64 Value usermem.Addr diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index e81717e8b..c1d743f38 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -28,8 +28,6 @@ import ( // SignalAct represents the action that should be taken when a signal is // delivered, and is equivalent to struct sigaction on 64-bit x86. -// -// +stateify savable type SignalAct struct { Handler uint64 Flags uint64 @@ -49,8 +47,6 @@ func (s *SignalAct) DeserializeTo(other *SignalAct) { // SignalStack represents information about a user stack, and is equivalent to // stack_t on 64-bit x86. -// -// +stateify savable type SignalStack struct { Addr uint64 Flags uint32 @@ -70,8 +66,6 @@ func (s *SignalStack) DeserializeTo(other *SignalStack) { // SignalInfo represents information about a signal being delivered, and is // equivalent to struct siginfo on 64-bit x86. -// -// +stateify savable type SignalInfo struct { Signo int32 // Signal number Errno int32 // Errno value diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 01bb40b04..591b11a4d 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,11 +1,23 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "contexttest_state", + srcs = [ + "contexttest.go", + ], + out = "contexttest_state.go", + package = "contexttest", +) go_library( name = "contexttest", testonly = 1, - srcs = ["contexttest.go"], + srcs = [ + "contexttest.go", + "contexttest_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest", visibility = ["//pkg/sentry:internal"], deps = [ @@ -16,5 +28,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/platform/ptrace", "//pkg/sentry/uniqueid", + "//pkg/state", ], ) diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 18cd5ae8e..e3c9a9b70 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,7 +1,40 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "fs_state", + srcs = [ + "attr.go", + "dentry.go", + "dirent.go", + "dirent_cache.go", + "dirent_list.go", + "dirent_state.go", + "file.go", + "file_overlay.go", + "file_state.go", + "filesystems.go", + "flags.go", + "inode.go", + "inode_inotify.go", + "inode_operations.go", + "inode_overlay.go", + "inotify.go", + "inotify_event.go", + "inotify_watch.go", + "mock.go", + "mount.go", + "mount_overlay.go", + "mount_state.go", + "mounts.go", + "overlay.go", + "path.go", + ], + out = "fs_state.go", + package = "fs", +) go_library( name = "fs", @@ -21,6 +54,7 @@ go_library( "filesystems.go", "flags.go", "fs.go", + "fs_state.go", "inode.go", "inode_inotify.go", "inode_operations.go", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index dc893d22f..9f166799a 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,12 +1,26 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") +go_stateify( + name = "ashmem_state", + srcs = [ + "area.go", + "device.go", + "pin_board.go", + "uint64_range.go", + "uint64_set.go", + ], + out = "ashmem_state.go", + package = "ashmem", +) + go_library( name = "ashmem", srcs = [ "area.go", + "ashmem_state.go", "device.go", "pin_board.go", "uint64_range.go", @@ -27,6 +41,7 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", ], diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index bfd7f2762..e4f76f0d0 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -39,12 +39,10 @@ const ( ) // Area implements fs.FileOperations. -// -// +stateify savable type Area struct { - fsutil.NoFsync `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` + fsutil.NoFsync + fsutil.DeprecatedFileOperations + fsutil.NotDirReaddir ad *Device diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index d0986fa11..c5b51d4a7 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -27,19 +27,17 @@ import ( ) // Device implements fs.InodeOperations. -// -// +stateify savable type Device struct { - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.InodeNotDirectory `state:"nosave"` - fsutil.InodeNotRenameable `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` - fsutil.InodeNotSymlink `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` + fsutil.DeprecatedFileOperations + fsutil.InodeNoExtendedAttributes + fsutil.InodeNotDirectory + fsutil.InodeNotRenameable + fsutil.InodeNotSocket + fsutil.InodeNotSymlink + fsutil.NoFsync + fsutil.NoMappable + fsutil.NoopWriteOut + fsutil.NotDirReaddir mu sync.Mutex `state:"nosave"` unstable fs.UnstableAttr diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index ecba395a0..c7fb3822c 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -56,8 +56,6 @@ func (setFunctions) Split(Range, noValue, uint64) (noValue, noValue) { // segment.Set is used for implementation where segments represent // ranges of pinned bytes, while gaps represent ranges of unpinned // bytes. All ranges are page-aligned. -// -// +stateify savable type PinBoard struct { Set } diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 4178f18b2..56a2ad6f7 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -91,8 +91,6 @@ func (n InodeType) String() string { // StableAttr contains Inode attributes that will be stable throughout the // lifetime of the Inode. -// -// +stateify savable type StableAttr struct { // Type is the InodeType of a InodeOperations. Type InodeType @@ -152,8 +150,6 @@ func IsCharDevice(s StableAttr) bool { // UnstableAttr contains Inode attributes that may change over the lifetime // of the Inode. -// -// +stateify savable type UnstableAttr struct { // Size is the file size in bytes. Size int64 @@ -190,8 +186,6 @@ func WithCurrentTime(ctx context.Context, u UnstableAttr) UnstableAttr { } // AttrMask contains fields to mask StableAttr and UnstableAttr. -// -// +stateify savable type AttrMask struct { Type bool DeviceID bool @@ -233,8 +227,6 @@ func (a AttrMask) Union(b AttrMask) AttrMask { } // PermMask are file access permissions. -// -// +stateify savable type PermMask struct { // Read indicates reading is permitted. Read bool @@ -288,8 +280,6 @@ func (p PermMask) SupersetOf(other PermMask) bool { // FilePermissions represents the permissions of a file, with // Read/Write/Execute bits for user, group, and other. -// -// +stateify savable type FilePermissions struct { User PermMask Group PermMask @@ -380,8 +370,6 @@ func (f FilePermissions) AnyRead() bool { } // FileOwner represents ownership of a file. -// -// +stateify savable type FileOwner struct { UID auth.KUID GID auth.KGID diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index a077b91d2..ec3928baf 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,16 +1,25 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "binder_state", + srcs = ["binder.go"], + out = "binder_state.go", + package = "binder", +) go_library( name = "binder", srcs = [ "binder.go", + "binder_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/binder", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/log", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -21,6 +30,8 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", + "//pkg/tcpip/transport/unix", ], ) diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index 502a262dd..3f87b6b08 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -40,17 +40,15 @@ const ( ) // Device implements fs.InodeOperations. -// -// +stateify savable type Device struct { - fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.InodeNotDirectory `state:"nosave"` - fsutil.InodeNotRenameable `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` - fsutil.InodeNotSymlink `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeNoExtendedAttributes + fsutil.InodeNotDirectory + fsutil.InodeNotRenameable + fsutil.InodeNotSocket + fsutil.InodeNotSymlink + fsutil.NoMappable + fsutil.NoopWriteOut + fsutil.DeprecatedFileOperations // mu protects unstable. mu sync.Mutex `state:"nosave"` @@ -188,12 +186,10 @@ func (bd *Device) StatFS(context.Context) (fs.Info, error) { } // Proc implements fs.FileOperations and fs.IoctlGetter. -// -// +stateify savable type Proc struct { - fsutil.NoFsync `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` + fsutil.NoFsync + fsutil.DeprecatedFileOperations + fsutil.NotDirReaddir bd *Device task *kernel.Task diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index b347468ff..d42e8da81 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -21,8 +21,6 @@ import ( ) // DentAttr is the metadata of a directory entry. It is a subset of StableAttr. -// -// +stateify savable type DentAttr struct { // Type is the InodeType of an Inode. Type InodeType @@ -156,8 +154,6 @@ func GenericReaddir(ctx *DirCtx, s *SortedDentryMap) (int, error) { } // SortedDentryMap is a sorted map of names and fs.DentAttr entries. -// -// +stateify savable type SortedDentryMap struct { // names is always kept in sorted-order. names []string diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index fc069bb5f..ea41615fd 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,11 +1,25 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "dev_state", + srcs = [ + "dev.go", + "fs.go", + "full.go", + "null.go", + "random.go", + ], + out = "dev_state.go", + package = "dev", +) go_library( name = "dev", srcs = [ "dev.go", + "dev_state.go", "device.go", "fs.go", "full.go", @@ -16,6 +30,8 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/amutex", + "//pkg/log", "//pkg/rand", "//pkg/sentry/context", "//pkg/sentry/device", @@ -29,7 +45,9 @@ go_library( "//pkg/sentry/mm", "//pkg/sentry/platform", "//pkg/sentry/safemem", + "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index 3f4f2a40a..36c61bfc2 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -27,8 +27,6 @@ import ( ) // Dev is the root node. -// -// +stateify savable type Dev struct { ramfs.Dir } diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index 2ae49be4e..3c79f3782 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -29,8 +29,6 @@ const binderEnabledKey = "binder_enabled" const ashmemEnabledKey = "ashmem_enabled" // filesystem is a devtmpfs. -// -// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 492b8eb3a..e13eb6c03 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -26,8 +26,6 @@ import ( ) // fullDevice is used to implement /dev/full. -// -// +stateify savable type fullDevice struct { ramfs.Entry } diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 2977c8670..66b8ba967 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -29,7 +29,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// +stateify savable type nullDevice struct { ramfs.Entry } @@ -55,7 +54,6 @@ func (n *nullDevice) Truncate(context.Context, *fs.Inode, int64) error { return nil } -// +stateify savable type zeroDevice struct { nullDevice } @@ -82,7 +80,6 @@ func (zd *zeroDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.F }), nil } -// +stateify savable type zeroFileOperations struct { fs.FileOperations } diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index 47b76218f..33a045a05 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -24,7 +24,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// +stateify savable type randomDevice struct { ramfs.Entry } diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 4658d044f..f9bf2fba6 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -81,8 +81,6 @@ var renameMu sync.RWMutex // // Dirents currently do not attempt to free entries that lack application references under // memory pressure. -// -// +stateify savable type Dirent struct { // AtomicRefCount is our reference count. refs.AtomicRefCount diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index c680e4828..e786e4f65 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -25,8 +25,6 @@ import ( // // A nil DirentCache corresponds to a cache with size 0. All methods can be // called, but nothing is actually cached. -// -// +stateify savable type DirentCache struct { // Maximum size of the cache. This must be saved manually, to handle the case // when cache is nil. diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index ffe4204bc..4fcb06f1f 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,27 +1,54 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "pipe_state", + srcs = [ + "pipe.go", + "pipe_state.go", + ], + out = "pipe_autogen_state.go", + imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], + package = "fdpipe", +) go_library( name = "fdpipe", srcs = [ "pipe.go", + "pipe_autogen_state.go", "pipe_opener.go", "pipe_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fdpipe", - imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/abi/linux", + "//pkg/amutex", "//pkg/fd", "//pkg/log", + "//pkg/metric", + "//pkg/p9", + "//pkg/refs", "//pkg/secio", "//pkg/sentry/context", + "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", + "//pkg/sentry/fs/lock", + "//pkg/sentry/kernel/auth", + "//pkg/sentry/kernel/time", + "//pkg/sentry/memmap", + "//pkg/sentry/platform", "//pkg/sentry/safemem", + "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", + "//pkg/tcpip", + "//pkg/tcpip/transport/unix", + "//pkg/unet", "//pkg/waiter", "//pkg/waiter/fdnotifier", ], diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 2e34604e6..7b318e35f 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -34,8 +34,6 @@ import ( ) // pipeOperations are the fs.FileOperations of a host pipe. -// -// +stateify savable type pipeOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 8e535a618..6d93ef760 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -47,8 +47,6 @@ const FileMaxOffset = math.MaxInt64 // and write(2). // // FIXME: Split synchronization from cancellation. -// -// +stateify savable type File struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 113962368..36b2cf75e 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -60,8 +60,6 @@ func overlayFile(ctx context.Context, inode *Inode, flags FileFlags) (*File, err } // overlayFileOperations implements FileOperations for a file in an overlay. -// -// +stateify savable type overlayFileOperations struct { // upperMu protects upper below. In contrast lower is stable. upperMu sync.Mutex `state:"nosave"` @@ -377,8 +375,6 @@ func readdirOne(ctx context.Context, d *Dirent) (map[string]DentAttr, error) { // overlayMappingIdentity wraps a MappingIdentity, and also holds a reference // on a file during its lifetime. -// -// +stateify savable type overlayMappingIdentity struct { refs.AtomicRefCount id memmap.MappingIdentity diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index 5a1e7a270..200e792f4 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -125,8 +125,6 @@ func GetFilesystems() []Filesystem { } // MountSourceFlags represents all mount option flags as a struct. -// -// +stateify savable type MountSourceFlags struct { // ReadOnly corresponds to mount(2)'s "MS_RDONLY" and indicates that // the filesystem should be mounted read-only. diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index d137fee4c..f481c57fb 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,20 +1,34 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "filetest_state", + srcs = [ + "filetest.go", + ], + out = "filetest_state.go", + package = "filetest", +) go_library( name = "filetest", testonly = 1, - srcs = ["filetest.go"], + srcs = [ + "filetest.go", + "filetest_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/filetest", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index 1aa271560..da0ff58af 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -19,8 +19,6 @@ import ( ) // FileFlags encodes file flags. -// -// +stateify savable type FileFlags struct { // Direct indicates that I/O should be done directly. Direct bool diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 3512bae6f..6eea64298 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,7 +1,24 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "fsutil_state", + srcs = [ + "dirty_set_impl.go", + "file.go", + "file_range_set_impl.go", + "frame_ref_set_impl.go", + "handle.go", + "host_file_mapper.go", + "host_file_mapper_state.go", + "inode.go", + "inode_cached.go", + ], + out = "fsutil_state.go", + package = "fsutil", +) go_template_instance( name = "dirty_set_impl", @@ -67,6 +84,7 @@ go_library( "frame_ref_set.go", "frame_ref_set_impl.go", "fsutil.go", + "fsutil_state.go", "handle.go", "host_file_mapper.go", "host_file_mapper_state.go", diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 8e31e48fd..9c6c98542 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -32,8 +32,6 @@ import ( // DirtyInfo is the value type of DirtySet, and represents information about a // Mappable offset that is dirty (the cached data for that offset is newer than // its source). -// -// +stateify savable type DirtyInfo struct { // Keep is true if the represented offset is concurrently writable, such // that writing the data for that offset back to the source does not diff --git a/pkg/sentry/fs/fsutil/handle.go b/pkg/sentry/fs/fsutil/handle.go index e7efd3c0f..149c0f84a 100644 --- a/pkg/sentry/fs/fsutil/handle.go +++ b/pkg/sentry/fs/fsutil/handle.go @@ -27,8 +27,6 @@ import ( // // FIXME: Remove Handle entirely in favor of individual fs.File // implementations using simple generic utilities. -// -// +stateify savable type Handle struct { NoopRelease `state:"nosave"` NoIoctl `state:"nosave"` diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index 9c1e2f76f..d0a27fc1c 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -29,8 +29,6 @@ import ( // HostFileMapper caches mappings of an arbitrary host file descriptor. It is // used by implementations of memmap.Mappable that represent a host file // descriptor. -// -// +stateify savable type HostFileMapper struct { // HostFile conceptually breaks the file into pieces called chunks, of // size and alignment chunkSize, and caches mappings of the file on a chunk diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index 177396fdc..e1ad07df2 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -31,8 +31,6 @@ func NewSimpleInodeOperations(i InodeSimpleAttributes) fs.InodeOperations { } // simpleInodeOperations is a simple implementation of Inode. -// -// +stateify savable type simpleInodeOperations struct { DeprecatedFileOperations `state:"nosave"` InodeNotDirectory `state:"nosave"` @@ -50,8 +48,6 @@ type simpleInodeOperations struct { // InodeSimpleAttributes implements a subset of the Inode interface. It provides // read-only access to attributes. -// -// +stateify savable type InodeSimpleAttributes struct { // FSType is the filesystem type reported by StatFS. FSType uint64 @@ -114,8 +110,6 @@ func (*InodeSimpleAttributes) Truncate(context.Context, *fs.Inode, int64) error // // Users need not initialize Xattrs to non-nil (it will be initialized // when the first extended attribute is set. -// -// +stateify savable type InMemoryAttributes struct { Unstable fs.UnstableAttr Xattrs map[string][]byte diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index 0a320e2d8..cba642a8f 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -55,8 +55,6 @@ import ( // // Implementations of InodeOperations.WriteOut must call Sync to write out // in-memory modifications of data and metadata to the CachedFileObject. -// -// +stateify savable type CachingInodeOperations struct { // backingFile is a handle to a cached file object. backingFile CachedFileObject diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index cb17339c9..1277379e7 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,6 +1,21 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "gofer_state", + srcs = [ + "file.go", + "file_state.go", + "fs.go", + "inode.go", + "inode_state.go", + "session.go", + "session_state.go", + ], + out = "gofer_state.go", + package = "gofer", +) go_library( name = "gofer", @@ -12,6 +27,7 @@ go_library( "file.go", "file_state.go", "fs.go", + "gofer_state.go", "handles.go", "inode.go", "inode_state.go", @@ -25,6 +41,7 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/amutex", "//pkg/fd", "//pkg/log", "//pkg/metric", @@ -37,11 +54,15 @@ go_library( "//pkg/sentry/fs/fdpipe", "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/host", + "//pkg/sentry/fs/lock", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", + "//pkg/sentry/platform", "//pkg/sentry/safemem", + "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 46a6bbd5d..039618808 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -33,8 +33,6 @@ import ( var openedWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.") // fileOperations implements fs.FileOperations for a remote file system. -// -// +stateify savable type fileOperations struct { fsutil.NoIoctl `state:"nosave"` waiter.AlwaysReady `state:"nosave"` diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index 3ae93f059..dd5d43c47 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -83,8 +83,6 @@ var ( ) // filesystem is a 9p client. -// -// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 7fc8f77b0..df584c382 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -35,8 +35,6 @@ import ( ) // inodeOperations implements fs.InodeOperations. -// -// +stateify savable type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` @@ -70,8 +68,6 @@ type inodeOperations struct { // circular load dependency between it and inodeOperations). Even with // lazy loading, this approach defines the dependencies between objects // and the expected load behavior more concretely. -// -// +stateify savable type inodeFileState struct { // s is common file system state for Gofers. s *session `state:"wait"` diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index 648a11435..b6841526a 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -27,7 +27,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/unet" ) -// +stateify savable type endpointMap struct { mu sync.RWMutex `state:"nosave"` // TODO: Make map with private unix sockets savable. @@ -64,8 +63,6 @@ func (e *endpointMap) get(key device.MultiDeviceKey) unix.BoundEndpoint { } // session holds state for each 9p session established during sys_mount. -// -// +stateify savable type session struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 29c79284a..23ec66f50 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,6 +1,23 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "host_state", + srcs = [ + "control.go", + "descriptor.go", + "descriptor_state.go", + "file.go", + "fs.go", + "inode.go", + "inode_state.go", + "socket.go", + "socket_state.go", + ], + out = "host_state.go", + package = "host", +) go_library( name = "host", @@ -11,6 +28,7 @@ go_library( "device.go", "file.go", "fs.go", + "host_state.go", "inode.go", "inode_state.go", "ioctl_unsafe.go", @@ -24,6 +42,7 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/amutex", "//pkg/fd", "//pkg/log", "//pkg/refs", @@ -33,14 +52,20 @@ go_library( "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", + "//pkg/sentry/fs/lock", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", + "//pkg/sentry/platform", "//pkg/sentry/safemem", + "//pkg/sentry/socket", "//pkg/sentry/socket/control", "//pkg/sentry/socket/unix", + "//pkg/sentry/uniqueid", + "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/link/rawfile", diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 3aee4d11c..613bd06e8 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -25,8 +25,6 @@ import ( ) // descriptor wraps a host fd. -// -// +stateify savable type descriptor struct { // donated is true if the host fd was donated by another process. donated bool diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index f9bef6d93..bdf844337 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -37,8 +37,6 @@ import ( ) // fileOperations implements fs.FileOperations for a host file descriptor. -// -// +stateify savable type fileOperations struct { fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index e46ae433c..974700636 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -51,8 +51,6 @@ const maxTraversals = 10 // to lock down the configurations. This filesystem should only be mounted at root. // // Think twice before exposing this to applications. -// -// +stateify savable type Filesystem struct { // whitelist is a set of host paths to whitelist. paths []string @@ -268,10 +266,8 @@ func newMountSource(ctx context.Context, root string, mounter fs.FileOwner, file } // superOperations implements fs.MountSourceOperations. -// -// +stateify savable type superOperations struct { - fs.SimpleMountSourceOperations + fs.SimpleMountSourceOperations `state:"nosave"` // root is the path of the mount point. All inode mappings // are relative to this root. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 761ccde33..226bc5164 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -34,8 +34,6 @@ import ( // inodeOperations implements fs.InodeOperations for an fs.Inodes backed // by a host file descriptor. -// -// +stateify savable type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` @@ -67,8 +65,6 @@ type inodeOperations struct { // circular load dependency between it and inodeOperations). Even with // lazy loading, this approach defines the dependencies between objects // and the expected load behavior more concretely. -// -// +stateify savable type inodeFileState struct { // Common file system state. mops *superOperations `state:"wait"` diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index d0dbce5dd..6c8e6f188 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -28,8 +28,6 @@ import ( // Inode is a file system object that can be simultaneously referenced by different // components of the VFS (Dirent, fs.File, etc). -// -// +stateify savable type Inode struct { // AtomicRefCount is our reference count. refs.AtomicRefCount @@ -60,8 +58,6 @@ type Inode struct { // Note that in Linux fcntl(2) and flock(2) locks are _not_ cooperative, because race and // deadlock conditions make merging them prohibitive. We do the same and keep them oblivious // to each other but provide a "context" as a convenient container. -// -// +stateify savable type LockCtx struct { // Posix is a set of POSIX-style regional advisory locks, see fcntl(2). Posix lock.Locks diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index 683140afe..358bbecdf 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -20,8 +20,6 @@ import ( ) // Watches is the collection of inotify watches on an inode. -// -// +stateify savable type Watches struct { // mu protects the fields below. mu sync.RWMutex `state:"nosave"` diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 2aabdded8..6f5e8ce5e 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -34,8 +34,6 @@ import ( // // Lock ordering: // Inotify.mu -> Inode.Watches.mu -> Watch.mu -> Inotify.evMu -// -// +stateify savable type Inotify struct { // Unique identifier for this inotify instance. We don't just reuse the // inotify fd because fds can be duped. These should not be exposed to the diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index e9b5e0f56..217915ba4 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -28,8 +28,6 @@ import ( const inotifyEventBaseSize = 16 // Event represents a struct inotify_event from linux. -// -// +stateify savable type Event struct { ilist.Entry diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index 3e1959e83..8904ef544 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -27,8 +27,6 @@ import ( // holding an extra ref on each dirent known (by inotify) to point to the // inode. These are known as pins. For a full discussion, see // fs/g3doc/inotify.md. -// -// +stateify savable type Watch struct { // Inotify instance which owns this watch. owner *Inotify diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index 3159ff1da..2607d7ed3 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,7 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "lock_state", + srcs = [ + "lock.go", + "lock_range.go", + "lock_set.go", + ], + out = "lock_state.go", + package = "lock", +) go_template_instance( name = "lock_range", @@ -38,11 +49,13 @@ go_library( "lock_range.go", "lock_set.go", "lock_set_functions.go", + "lock_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/lock", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/log", + "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index e9b376eb6..24d54c989 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -88,8 +88,6 @@ const LockEOF = math.MaxUint64 // // A Lock may be downgraded from a write lock to a read lock only if // the write lock's uid is the same as the read lock. -// -// +stateify savable type Lock struct { // Readers are the set of read lock holders identified by UniqueID. // If len(Readers) > 0 then HasWriter must be false. @@ -105,8 +103,6 @@ type Lock struct { } // Locks is a thread-safe wrapper around a LockSet. -// -// +stateify savable type Locks struct { // mu protects locks below. mu sync.Mutex `state:"nosave"` @@ -115,7 +111,7 @@ type Locks struct { locks LockSet // blockedQueue is the queue of waiters that are waiting on a lock. - blockedQueue waiter.Queue `state:"zerovalue"` + blockedQueue waiter.Queue } // Blocker is the interface used for blocking locks. Passing a nil Blocker diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 4ede767f9..eb1897174 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -101,8 +101,6 @@ func (i InodeMappings) String() string { // (e.g. cannot be mounted at different locations). // // TODO: Move mount-specific information out of MountSource. -// -// +stateify savable type MountSource struct { refs.AtomicRefCount @@ -262,8 +260,6 @@ func NewNonCachingMountSource(filesystem Filesystem, flags MountSourceFlags) *Mo } // SimpleMountSourceOperations implements MountSourceOperations. -// -// +stateify savable type SimpleMountSourceOperations struct { keep bool } diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index d135e8a37..1be81e3a1 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -18,8 +18,6 @@ import "gvisor.googlesource.com/gvisor/pkg/sentry/context" // overlayMountSourceOperations implements MountSourceOperations for an overlay // mount point. -// -// +stateify savable type overlayMountSourceOperations struct { upper *MountSource lower *MountSource @@ -74,8 +72,6 @@ func (o *overlayMountSourceOperations) Destroy() { } // type overlayFilesystem is the filesystem for overlay mounts. -// -// +stateify savable type overlayFilesystem struct{} // Name implements Filesystem.Name. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index 144d3427d..87da4ee0e 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -32,8 +32,6 @@ import ( const DefaultTraversalLimit = 10 // MountNamespace defines a collection of mounts. -// -// +stateify savable type MountNamespace struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index af13dc8c7..7357d6401 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -145,8 +145,6 @@ func newOverlayInode(ctx context.Context, o *overlayEntry, msrc *MountSource) *I } // overlayEntry is the overlay metadata of an Inode. It implements Mappable. -// -// +stateify savable type overlayEntry struct { // lowerExists is true if an Inode exists for this file in the lower // filesystem. If lowerExists is true, then the overlay must create diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 2d9f07f2f..870df47b2 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,6 +1,32 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "proc_state", + srcs = [ + "cpuinfo.go", + "exec_args.go", + "fds.go", + "file.go", + "filesystems.go", + "fs.go", + "loadavg.go", + "meminfo.go", + "mounts.go", + "net.go", + "proc.go", + "stat.go", + "sys.go", + "sys_net.go", + "task.go", + "uid_gid_map.go", + "uptime.go", + "version.go", + ], + out = "proc_state.go", + package = "proc", +) go_library( name = "proc", @@ -16,6 +42,7 @@ go_library( "mounts.go", "net.go", "proc.go", + "proc_state.go", "rpcinet_proc.go", "stat.go", "sys.go", @@ -29,6 +56,9 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/amutex", + "//pkg/log", + "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/device", @@ -43,6 +73,8 @@ go_library( "//pkg/sentry/socket/rpcinet", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", + "//pkg/syserr", "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index 4dfec03a4..f80aaa5b1 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -27,8 +27,6 @@ import ( // cpuinfo is a file describing the CPU capabilities. // // Presently cpuinfo never changes, so it doesn't need to be a SeqFile. -// -// +stateify savable type cpuinfo struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index a69cbaa0e..0e1523bf1 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -37,8 +37,6 @@ const ( // execArgFile is a file containing the exec args (either cmdline or environ) // for a given task. -// -// +stateify savable type execArgFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index cca8f874c..194a9c12a 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -138,8 +138,6 @@ func (f *fd) Close() error { } // fdDir implements /proc/TID/fd. -// -// +stateify savable type fdDir struct { ramfs.Dir @@ -199,8 +197,6 @@ func (f *fdDir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset } // fdInfo is a single file in /proc/TID/fdinfo/. -// -// +stateify savable type fdInfo struct { ramfs.File @@ -233,8 +229,6 @@ func (*fdInfo) Truncate(ctx context.Context, inode *fs.Inode, size int64) error // fdInfoDir implements /proc/TID/fdinfo. It embeds an fdDir, but overrides // Lookup and Readdir. -// -// +stateify savable type fdInfoDir struct { ramfs.Dir diff --git a/pkg/sentry/fs/proc/file.go b/pkg/sentry/fs/proc/file.go index 4b2d08e75..9a433cdf8 100644 --- a/pkg/sentry/fs/proc/file.go +++ b/pkg/sentry/fs/proc/file.go @@ -22,7 +22,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// +stateify savable type file struct { fs.InodeOperations diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index 49b92fd8a..37db9cf9c 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -24,8 +24,6 @@ import ( ) // filesystemsData backs /proc/filesystems. -// -// +stateify savable type filesystemsData struct{} // NeedsUpdate returns true on the first generation. The set of registered file diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 061824b8c..3aadd6ac4 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -22,8 +22,6 @@ import ( ) // filesystem is a procfs. -// -// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 6fac251d2..7583b6ccd 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -23,8 +23,6 @@ import ( ) // loadavgData backs /proc/loadavg. -// -// +stateify savable type loadavgData struct{} // NeedsUpdate implements seqfile.SeqSource.NeedsUpdate. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 53dfd59ef..49cb0faed 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -26,8 +26,6 @@ import ( ) // meminfoData backs /proc/meminfo. -// -// +stateify savable type meminfoData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index 2b8167c28..108432f4e 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -71,8 +71,6 @@ func forEachMountSource(t *kernel.Task, fn func(string, *fs.MountSource)) { } // mountInfoFile is used to implement /proc/[pid]/mountinfo. -// -// +stateify savable type mountInfoFile struct { t *kernel.Task } @@ -154,8 +152,6 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se } // mountsFile is used to implement /proc/[pid]/mountinfo. -// -// +stateify savable type mountsFile struct { t *kernel.Task } diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index 07029a7bb..b2a8d639c 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -33,8 +33,6 @@ import ( ) // proc is a root proc node. -// -// +stateify savable type proc struct { ramfs.Dir @@ -49,8 +47,6 @@ type proc struct { // stubProcFSFile is a file type that can be used to return file contents // which are constant. This file is not writable and will always have mode // 0444. -// -// +stateify savable type stubProcFSFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index 53c475652..c84f7e20d 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,10 +1,22 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "seqfile_state", + srcs = [ + "seqfile.go", + ], + out = "seqfile_state.go", + package = "seqfile", +) go_library( name = "seqfile", - srcs = ["seqfile.go"], + srcs = [ + "seqfile.go", + "seqfile_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile", visibility = ["//pkg/sentry:internal"], deps = [ @@ -14,16 +26,26 @@ go_library( "//pkg/sentry/fs/ramfs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", + "//pkg/state", ], ) +go_stateify( + name = "seqfile_test_state", + srcs = ["seqfile_test.go"], + out = "seqfile_test_state.go", + package = "seqfile", +) + go_test( name = "seqfile_test", size = "small", - srcs = ["seqfile_test.go"], + srcs = [ + "seqfile_test.go", + "seqfile_test_state.go", + ], embed = [":seqfile"], deps = [ - "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs/test", diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 51cae5e37..c08565f8a 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -30,8 +30,6 @@ import ( type SeqHandle interface{} // SeqData holds the data for one unit in the file. -// -// +stateify savable type SeqData struct { // The data to be returned to the user. Buf []byte @@ -84,8 +82,6 @@ func (s *SeqGenerationCounter) IsCurrent(generation int64) bool { } // SeqFile is used to provide dynamic files that can be ordered by record. -// -// +stateify savable type SeqFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index bf7650211..284f3e52b 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -25,8 +25,6 @@ import ( ) // statData backs /proc/stat. -// -// +stateify savable type statData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index a2d36ca23..aab891c53 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -28,8 +28,6 @@ import ( ) // hostname is a file containing the system hostname. -// -// +stateify savable type hostname struct { ramfs.Entry } @@ -54,8 +52,6 @@ func (p *proc) newHostname(ctx context.Context, msrc *fs.MountSource) *fs.Inode } // mmapMinAddrData backs /proc/sys/vm/mmap_min_addr. -// -// +stateify savable type mmapMinAddrData struct { k *kernel.Kernel } @@ -78,7 +74,6 @@ func (d *mmapMinAddrData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHand }, 0 } -// +stateify savable type overcommitMemory struct{} func (*overcommitMemory) NeedsUpdate(generation int64) bool { diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index beb25be20..f3a5043f8 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -33,7 +33,6 @@ const ( tcpWMem ) -// +stateify savable type tcpMem struct { ramfs.Entry s inet.Stack @@ -101,7 +100,6 @@ func (m *tcpMem) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, return n, cperr } -// +stateify savable type tcpSack struct { ramfs.Entry s inet.Stack diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 748ca4320..efc635946 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -52,8 +52,6 @@ func getTaskMM(t *kernel.Task) (*mm.MemoryManager, error) { } // taskDir represents a task-level directory. -// -// +stateify savable type taskDir struct { ramfs.Dir @@ -94,8 +92,6 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace } // subtasks represents a /proc/TID/task directory. -// -// +stateify savable type subtasks struct { ramfs.Dir @@ -171,8 +167,6 @@ func (s *subtasks) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, off } // exe is an fs.InodeOperations symlink for the /proc/PID/exe file. -// -// +stateify savable type exe struct { ramfs.Symlink @@ -232,8 +226,6 @@ func (e *exe) Readlink(ctx context.Context, inode *fs.Inode) (string, error) { // namespaceFile represents a file in the namespacefs, such as the files in // /proc//ns. -// -// +stateify savable type namespaceFile struct { ramfs.Symlink @@ -282,8 +274,6 @@ func newNamespaceDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { } // mapsData implements seqfile.SeqSource for /proc/[pid]/maps. -// -// +stateify savable type mapsData struct { t *kernel.Task } @@ -321,7 +311,6 @@ func (md *mapsData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([ return []seqfile.SeqData{}, 0 } -// +stateify savable type taskStatData struct { t *kernel.Task @@ -402,8 +391,6 @@ func (s *taskStatData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) } // statmData implements seqfile.SeqSource for /proc/[pid]/statm. -// -// +stateify savable type statmData struct { t *kernel.Task } @@ -438,8 +425,6 @@ func (s *statmData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([ } // statusData implements seqfile.SeqSource for /proc/[pid]/status. -// -// +stateify savable type statusData struct { t *kernel.Task pidns *kernel.PIDNamespace @@ -505,7 +490,6 @@ type ioUsage interface { IOUsage() *usage.IO } -// +stateify savable type ioData struct { ioUsage } @@ -546,8 +530,6 @@ func (i *ioData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se // On Linux, /proc/[pid]/comm is writable, and writing to the comm file changes // the thread name. We don't implement this yet as there are no known users of // this feature. -// -// +stateify savable type comm struct { ramfs.Entry @@ -577,8 +559,6 @@ func (c *comm) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, off } // auxvec is a file containing the auxiliary vector for a task. -// -// +stateify savable type auxvec struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index 9811d9c9d..85acb5163 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -29,8 +29,6 @@ import ( // An idMapSeqSource is a seqfile.SeqSource that returns UID or GID mappings // from a task's user namespace. -// -// +stateify savable type idMapSeqSource struct { t *kernel.Task gids bool @@ -72,7 +70,6 @@ type idMapSeqHandle struct { value int } -// +stateify savable type idMapSeqFile struct { seqfile.SeqFile } diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index f3a9b81df..4679d5821 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -27,8 +27,6 @@ import ( ) // uptime is a file containing the system uptime. -// -// +stateify savable type uptime struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index 00f6a2afd..c0f2e87e3 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -23,8 +23,6 @@ import ( ) // versionData backs /proc/version. -// -// +stateify savable type versionData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index 5230157fe..d84f2c624 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,6 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "ramfs_state", + srcs = [ + "dir.go", + "file.go", + "ramfs.go", + "socket.go", + "symlink.go", + ], + out = "ramfs_state.go", + package = "ramfs", +) go_library( name = "ramfs", @@ -8,6 +21,7 @@ go_library( "dir.go", "file.go", "ramfs.go", + "ramfs_state.go", "socket.go", "symlink.go", "tree.go", @@ -15,8 +29,12 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/amutex", + "//pkg/log", + "//pkg/refs", "//pkg/secio", "//pkg/sentry/context", + "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", @@ -24,6 +42,7 @@ go_library( "//pkg/sentry/memmap", "//pkg/sentry/safemem", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 04432f28c..19d5612ed 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -44,8 +44,6 @@ type CreateOps struct { } // Dir represents a single directory in the filesystem. -// -// +stateify savable type Dir struct { Entry diff --git a/pkg/sentry/fs/ramfs/ramfs.go b/pkg/sentry/fs/ramfs/ramfs.go index 13e72e775..d6cfaf753 100644 --- a/pkg/sentry/fs/ramfs/ramfs.go +++ b/pkg/sentry/fs/ramfs/ramfs.go @@ -60,8 +60,6 @@ var ( // Entry represents common internal state for file and directory nodes. // This may be used by other packages to easily create ramfs files. -// -// +stateify savable type Entry struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoMappable `state:"nosave"` diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 93427a1ff..b0c79325f 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -21,8 +21,6 @@ import ( ) // Socket represents a socket. -// -// +stateify savable type Socket struct { Entry diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 1c54d9991..9bbf78619 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -22,8 +22,6 @@ import ( ) // Symlink represents a symlink. -// -// +stateify savable type Symlink struct { Entry diff --git a/pkg/sentry/fs/ramfs/test/BUILD b/pkg/sentry/fs/ramfs/test/BUILD index 187eac49d..57fee45e2 100644 --- a/pkg/sentry/fs/ramfs/test/BUILD +++ b/pkg/sentry/fs/ramfs/test/BUILD @@ -1,16 +1,30 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "test_state", + srcs = [ + "test.go", + ], + out = "test_state.go", + package = "test", +) go_library( name = "test", testonly = 1, - srcs = ["test.go"], + srcs = [ + "test.go", + "test_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/sentry/context", + "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs", + "//pkg/state", ], ) diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index bc24e980e..095ff1f25 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,6 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "sys_state", + srcs = [ + "fs.go", + "sys.go", + ], + out = "sys_state.go", + package = "sys", +) go_library( name = "sys", @@ -8,6 +18,7 @@ go_library( "device.go", "fs.go", "sys.go", + "sys_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/sys", visibility = ["//pkg/sentry:internal"], @@ -17,5 +28,6 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs", "//pkg/sentry/usermem", + "//pkg/state", ], ) diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index 625525540..c6d5f7fd8 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -20,8 +20,6 @@ import ( ) // filesystem is a sysfs. -// -// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index b9b2fb4a1..ccf56f644 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -22,13 +22,12 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// +stateify savable -type dir struct { +type Dir struct { ramfs.Dir } func newDir(ctx context.Context, msrc *fs.MountSource, contents map[string]*fs.Inode) *fs.Inode { - d := &dir{} + d := &Dir{} d.InitDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(d, msrc, fs.StableAttr{ DeviceID: sysfsDevice.DeviceID(), diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index ffdd7e0dc..8b1b7872e 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,19 +1,33 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "timerfd_state", + srcs = [ + "timerfd.go", + ], + out = "timerfd_state.go", + package = "timerfd", +) go_library( name = "timerfd", - srcs = ["timerfd.go"], + srcs = [ + "timerfd.go", + "timerfd_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/timerfd", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index 767db95a0..ae58f6fd7 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -30,8 +30,6 @@ import ( ) // TimerOperations implements fs.FileOperations for timerfds. -// -// +stateify savable type TimerOperations struct { fsutil.ZeroSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` @@ -40,7 +38,7 @@ type TimerOperations struct { fsutil.NoMMap `state:"nosave"` fsutil.NoIoctl `state:"nosave"` - events waiter.Queue `state:"zerovalue"` + events waiter.Queue `state:"nosave"` timer *ktime.Timer // val is the number of timer expirations since the last successful call to diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index cfe11ab02..473ab4296 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,6 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "tmpfs_state", + srcs = [ + "file_regular.go", + "fs.go", + "inode_file.go", + "tmpfs.go", + ], + out = "tmpfs_state.go", + package = "tmpfs", +) go_library( name = "tmpfs", @@ -10,11 +22,13 @@ go_library( "fs.go", "inode_file.go", "tmpfs.go", + "tmpfs_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tmpfs", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", @@ -27,6 +41,7 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/tcpip/transport/unix", "//pkg/waiter", ], diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 342688f81..9811d90bc 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -25,8 +25,6 @@ import ( // regularFileOperations implements fs.FileOperations for a regular // tmpfs file. -// -// +stateify savable type regularFileOperations struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index ca620e65e..5bd9ade52 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -47,8 +47,6 @@ const ( var modeRegexp = regexp.MustCompile("0[0-7][0-7][0-7]") // Filesystem is a tmpfs. -// -// +stateify savable type Filesystem struct{} func init() { diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 1e4fe47d2..4e803c9ff 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -43,8 +43,6 @@ import ( // include an InvalidatorRegion associated with that reference. When the // referenced portion of the file is removed (with Truncate), the associated // InvalidatorRegion is invalidated. -// -// +stateify savable type fileInodeOperations struct { fsutil.DeprecatedFileOperations `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 10cb5451d..1cc7ae491 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -49,8 +49,6 @@ func rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent } // Dir is a directory. -// -// +stateify savable type Dir struct { ramfs.Dir @@ -124,8 +122,6 @@ func (*Dir) StatFS(context.Context) (fs.Info, error) { } // Symlink is a symlink. -// -// +stateify savable type Symlink struct { ramfs.Symlink } @@ -153,8 +149,6 @@ func (s *Symlink) StatFS(context.Context) (fs.Info, error) { } // Socket is a socket. -// -// +stateify savable type Socket struct { ramfs.Socket } @@ -182,8 +176,6 @@ func (s *Socket) StatFS(context.Context) (fs.Info, error) { } // Fifo is a tmpfs named pipe. -// -// +stateify savable type Fifo struct { ramfs.Entry } diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index 3c446eef4..363897b2c 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,6 +1,22 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "tty_state", + srcs = [ + "dir.go", + "fs.go", + "inode.go", + "line_discipline.go", + "master.go", + "queue.go", + "slave.go", + "terminal.go", + ], + out = "tty_state.go", + package = "tty", +) go_library( name = "tty", @@ -13,6 +29,7 @@ go_library( "queue.go", "slave.go", "terminal.go", + "tty_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tty", visibility = ["//pkg/sentry:internal"], @@ -27,6 +44,7 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index c91091db4..2c5b2aed6 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -49,16 +49,14 @@ import ( // corresponding Dirents hold on their parent (this directory). // // dirInodeOperations implements fs.InodeOperations. -// -// +stateify savable type dirInodeOperations struct { - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` - fsutil.InodeNotRenameable `state:"nosave"` - fsutil.InodeNotSymlink `state:"nosave"` - fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` + fsutil.DeprecatedFileOperations + fsutil.InodeNotSocket + fsutil.InodeNotRenameable + fsutil.InodeNotSymlink + fsutil.InodeNoExtendedAttributes + fsutil.NoMappable + fsutil.NoopWriteOut // msrc is the super block this directory is on. // @@ -350,8 +348,6 @@ func (d *dirInodeOperations) masterClose(t *Terminal) { // // This is nearly identical to fsutil.DirFileOperations, except that it takes // df.di.mu in IterateDir. -// -// +stateify savable type dirFileOperations struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index e28635607..dbaffe95e 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -28,8 +28,6 @@ var ptsDevice = device.NewAnonDevice() // // This devpts is always in the new "multi-instance" mode. i.e., it contains a // ptmx device tied to this mount. -// -// +stateify savable type filesystem struct{} func init() { @@ -71,8 +69,6 @@ func (f *filesystem) Mount(ctx context.Context, device string, flags fs.MountSou } // superOperations implements fs.MountSourceOperations, preventing caching. -// -// +stateify savable type superOperations struct{} // Revalidate implements fs.DirentOperations.Revalidate. diff --git a/pkg/sentry/fs/tty/inode.go b/pkg/sentry/fs/tty/inode.go index c0fa2b407..04b9a7727 100644 --- a/pkg/sentry/fs/tty/inode.go +++ b/pkg/sentry/fs/tty/inode.go @@ -31,8 +31,6 @@ import ( // // * fs.InodeOperations.Release // * fs.InodeOperations.GetFile -// -// +stateify savable type inodeOperations struct { fsutil.DeprecatedFileOperations `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index d243ee40e..f094635f5 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -72,8 +72,6 @@ const ( // termiosMu // inQueue.mu // outQueue.mu -// -// +stateify savable type lineDiscipline struct { // inQueue is the input queue of the terminal. inQueue queue @@ -185,8 +183,6 @@ type transformer interface { // outputQueueTransformer implements transformer. It performs line discipline // transformations on the output queue. -// -// +stateify savable type outputQueueTransformer struct{} // transform does output processing for one end of the pty. See @@ -258,8 +254,6 @@ func (*outputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte // inputQueueTransformer implements transformer. It performs line discipline // transformations on the input queue. -// -// +stateify savable type inputQueueTransformer struct{} // transform does input processing for one end of the pty. Characters read are diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index c7198e218..74cdbe874 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -27,8 +27,6 @@ import ( // masterInodeOperations are the fs.InodeOperations for the master end of the // Terminal (ptmx file). -// -// +stateify savable type masterInodeOperations struct { inodeOperations @@ -98,8 +96,6 @@ func (mi *masterInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flag } // masterFileOperations are the fs.FileOperations for the master end of a terminal. -// -// +stateify savable type masterFileOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 42c105abc..026d5e077 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -32,13 +32,11 @@ import ( // processed (i.e. undergo termios transformations) as they are added to the // read buffer. The read buffer is readable when its length is nonzero and // readable is true. -// -// +stateify savable type queue struct { // mu protects everything in queue. mu sync.Mutex `state:"nosave"` - waiter.Queue `state:"zerovalue"` + waiter.Queue `state:"nosave"` // readBuf is buffer of data ready to be read when readable is true. // This data has been processed. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 1c562b172..f5eec726e 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -27,8 +27,6 @@ import ( // slaveInodeOperations are the fs.InodeOperations for the slave end of the // Terminal (pts file). -// -// +stateify savable type slaveInodeOperations struct { inodeOperations @@ -88,8 +86,6 @@ func (si *slaveInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags } // slaveFileOperations are the fs.FileOperations for the slave end of a terminal. -// -// +stateify savable type slaveFileOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index 3cb135124..fa5b00409 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -21,8 +21,6 @@ import ( ) // Terminal is a pseudoterminal. -// -// +stateify savable type Terminal struct { refs.AtomicRefCount diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index 159c50efb..eaf8f15b2 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -3,15 +3,26 @@ package( licenses = ["notice"], # Apache 2.0 ) -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "inet_state", + srcs = ["inet.go"], + out = "inet_state.go", + package = "inet", +) go_library( name = "inet", srcs = [ "context.go", "inet.go", + "inet_state.go", "test_stack.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/inet", - deps = ["//pkg/sentry/context"], + deps = [ + "//pkg/sentry/context", + "//pkg/state", + ], ) diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index e54a61196..e4b326993 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -87,8 +87,6 @@ type InterfaceAddr struct { } // TCPBufferSize contains settings controlling TCP buffer sizing. -// -// +stateify savable type TCPBufferSize struct { // Min is the minimum size. Min int diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 0ebacefa6..c4a7dacb2 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,7 +1,58 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "kernel_state", + srcs = [ + "abstract_socket_namespace.go", + "fd_map.go", + "fs_context.go", + "ipc_namespace.go", + "kernel.go", + "kernel_state.go", + "pending_signals.go", + "pending_signals_state.go", + "process_group_list.go", + "ptrace.go", + "rseq.go", + "session_list.go", + "sessions.go", + "signal.go", + "signal_handlers.go", + "syscalls.go", + "syscalls_state.go", + "syslog.go", + "task.go", + "task_clone.go", + "task_context.go", + "task_exec.go", + "task_exit.go", + "task_list.go", + "task_resources.go", + "task_run.go", + "task_sched.go", + "task_signals.go", + "task_start.go", + "task_syscall.go", + "thread_group.go", + "threads.go", + "timekeeper.go", + "timekeeper_state.go", + "timer.go", + "uts_namespace.go", + "vdso.go", + "version.go", + ], + out = "kernel_autogen_state.go", + imports = [ + "gvisor.googlesource.com/gvisor/pkg/sentry/arch", + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", + "gvisor.googlesource.com/gvisor/pkg/tcpip", + ], + package = "kernel", +) go_template_instance( name = "pending_signals_list", @@ -67,6 +118,7 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", + "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", @@ -112,11 +164,6 @@ go_library( "version.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel", - imports = [ - "gvisor.googlesource.com/gvisor/pkg/sentry/arch", - # "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", - "gvisor.googlesource.com/gvisor/pkg/tcpip", - ], visibility = ["//:sandbox"], deps = [ "//pkg/abi", diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index d6d1d341d..014c4a3bf 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -22,7 +22,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" ) -// +stateify savable type abstractEndpoint struct { ep unix.BoundEndpoint wr *refs.WeakRef @@ -40,8 +39,6 @@ func (e *abstractEndpoint) WeakRefGone() { } // AbstractSocketNamespace is used to implement the Linux abstract socket functionality. -// -// +stateify savable type AbstractSocketNamespace struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index a81085372..5b7b30557 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,7 +1,20 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "auth_state", + srcs = [ + "credentials.go", + "id.go", + "id_map_range.go", + "id_map_set.go", + "user_namespace.go", + ], + out = "auth_state.go", + package = "auth", +) go_template_instance( name = "id_map_range", @@ -35,6 +48,7 @@ go_library( name = "auth", srcs = [ "auth.go", + "auth_state.go", "capability_set.go", "context.go", "credentials.go", @@ -52,6 +66,7 @@ go_library( "//pkg/bits", "//pkg/log", "//pkg/sentry/context", + "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index f18f7dac9..f6fb05285 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -21,8 +21,6 @@ import ( // Credentials contains information required to authorize privileged operations // in a user namespace. -// -// +stateify savable type Credentials struct { // Real/effective/saved user/group IDs in the root user namespace. None of // these should ever be NoID. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index bd0090e0f..6adb33530 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -77,8 +77,6 @@ func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool { // An IDMapEntry represents a mapping from a range of contiguous IDs in a user // namespace to an equally-sized range of contiguous IDs in the namespace's // parent. -// -// +stateify savable type IDMapEntry struct { // FirstID is the first ID in the range in the namespace. FirstID uint32 diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index d359f3f31..0980aeadf 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -23,8 +23,6 @@ import ( // A UserNamespace represents a user namespace. See user_namespaces(7) for // details. -// -// +stateify savable type UserNamespace struct { // parent is this namespace's parent. If this is the root namespace, parent // is nil. The parent pointer is immutable. diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 5e8b36ed6..7d491efbc 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,11 +1,22 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "epoll_autogen_state", + srcs = [ + "epoll.go", + "epoll_state.go", + ], + out = "epoll_autogen_state.go", + package = "epoll", +) go_library( name = "epoll", srcs = [ "epoll.go", + "epoll_autogen_state.go", "epoll_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/epoll", @@ -18,7 +29,9 @@ go_library( "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/kdefs", + "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index d87e64a1c..b572fcd7e 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -58,8 +58,6 @@ const ( // potentially be reassigned. We also cannot use just the file pointer because // it is possible to have multiple entries for the same file object as long as // they are created with different FDs (i.e., the FDs point to the same file). -// -// +stateify savable type FileIdentifier struct { File *fs.File Fd kdefs.FD @@ -67,8 +65,6 @@ type FileIdentifier struct { // pollEntry holds all the state associated with an event poll entry, that is, // a file being observed by an event poll object. -// -// +stateify savable type pollEntry struct { ilist.Entry file *refs.WeakRef `state:"manual"` @@ -96,8 +92,6 @@ func (p *pollEntry) WeakRefGone() { // EventPoll holds all the state associated with an event poll object, that is, // collection of files to observe and their current state. -// -// +stateify savable type EventPoll struct { fsutil.PipeSeek `state:"zerovalue"` fsutil.NotDirReaddir `state:"zerovalue"` @@ -108,7 +102,7 @@ type EventPoll struct { // Wait queue is used to notify interested parties when the event poll // object itself becomes readable or writable. - waiter.Queue `state:"zerovalue"` + waiter.Queue // files is the map of all the files currently being observed, it is // protected by mu. diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index cc1120b4f..7ec179bd8 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,19 +1,33 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "eventfd_state", + srcs = [ + "eventfd.go", + ], + out = "eventfd_state.go", + package = "eventfd", +) go_library( name = "eventfd", - srcs = ["eventfd.go"], + srcs = [ + "eventfd.go", + "eventfd_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/eventfd", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/waiter", "//pkg/waiter/fdnotifier", diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index a4ada0e78..bd50bd9fe 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -35,8 +35,6 @@ import ( // EventOperations represents an event with the semantics of Linux's file-based event // notification (eventfd). Eventfds are usually internal to the Sentry but in certain // situations they may be converted into a host-backed eventfd. -// -// +stateify savable type EventOperations struct { fsutil.NoopRelease `state:"nosave"` fsutil.PipeSeek `state:"nosave"` @@ -51,7 +49,7 @@ type EventOperations struct { // Queue is used to notify interested parties when the event object // becomes readable or writable. - wq waiter.Queue `state:"zerovalue"` + wq waiter.Queue `state:"nosave"` // val is the current value of the event counter. val uint64 diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index d5d4aaacb..299506330 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -46,8 +46,6 @@ func (f FDs) Less(i, j int) bool { } // FDFlags define flags for an individual descriptor. -// -// +stateify savable type FDFlags struct { // CloseOnExec indicates the descriptor should be closed on exec. CloseOnExec bool @@ -71,16 +69,12 @@ func (f FDFlags) ToLinuxFDFlags() (mask uint) { // descriptor holds the details about a file descriptor, namely a pointer the // file itself and the descriptor flags. -// -// +stateify savable type descriptor struct { file *fs.File flags FDFlags } // FDMap is used to manage File references and flags. -// -// +stateify savable type FDMap struct { refs.AtomicRefCount k *Kernel diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index f3f05e8f5..dbc097696 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -25,8 +25,6 @@ import ( // FSContext contains filesystem context. // // This includes umask and working directory. -// -// +stateify savable type FSContext struct { refs.AtomicRefCount diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index b44a26974..a97a43549 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_template_instance( name = "waiter_list", @@ -14,15 +14,29 @@ go_template_instance( }, ) +go_stateify( + name = "futex_state", + srcs = [ + "futex.go", + "waiter_list.go", + ], + out = "futex_state.go", + package = "futex", +) + go_library( name = "futex", srcs = [ "futex.go", + "futex_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex", visibility = ["//pkg/sentry:internal"], - deps = ["//pkg/syserror"], + deps = [ + "//pkg/state", + "//pkg/syserror", + ], ) go_test( diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 4a1f2a0ef..15e3e5e2c 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -196,8 +196,6 @@ func bucketIndexForAddr(addr uintptr) uintptr { } // Manager holds futex state for a single virtual address space. -// -// +stateify savable type Manager struct { buckets [bucketCount]bucket `state:"zerovalue"` } diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 5eef49f59..a86bda77b 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -21,8 +21,6 @@ import ( ) // IPCNamespace represents an IPC namespace. -// -// +stateify savable type IPCNamespace struct { // User namespace which owns this IPC namespace. Immutable. userNS *auth.UserNamespace diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 419a1d473..64439cd9d 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -62,8 +62,6 @@ import ( // Kernel represents an emulated Linux kernel. It must be initialized by calling // Init() or LoadFrom(). -// -// +stateify savable type Kernel struct { // extMu serializes external changes to the Kernel with calls to // Kernel.SaveTo. (Kernel.SaveTo requires that the state of the Kernel @@ -160,7 +158,7 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. - exitErr error `state:"nosave"` + exitErr error // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index 06be5a7e1..5dc0f266c 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -38,8 +38,6 @@ const ( // pendingSignals holds a collection of pending signals. The zero value of // pendingSignals is a valid empty collection. pendingSignals is thread-unsafe; // users must provide synchronization. -// -// +stateify savable type pendingSignals struct { // signals contains all pending signals. // @@ -54,14 +52,11 @@ type pendingSignals struct { } // pendingSignalQueue holds a pendingSignalList for a single signal number. -// -// +stateify savable type pendingSignalQueue struct { pendingSignalList length int } -// +stateify savable type pendingSignal struct { // pendingSignalEntry links into a pendingSignalList. pendingSignalEntry diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 19b23c6d2..4600d19bd 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,6 +1,20 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "pipe_state", + srcs = [ + "buffers.go", + "node.go", + "pipe.go", + "reader.go", + "reader_writer.go", + "writer.go", + ], + out = "pipe_state.go", + package = "pipe", +) go_library( name = "pipe", @@ -9,6 +23,7 @@ go_library( "device.go", "node.go", "pipe.go", + "pipe_state.go", "reader.go", "reader_writer.go", "writer.go", @@ -19,12 +34,15 @@ go_library( "//pkg/abi/linux", "//pkg/amutex", "//pkg/ilist", + "//pkg/log", + "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index a82e45c3f..f300537c5 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -20,8 +20,6 @@ import ( // Buffer encapsulates a queueable byte buffer that can // easily be truncated. It is designed only for use with pipes. -// -// +stateify savable type Buffer struct { ilist.Entry data []byte diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 23d692da1..e418cf174 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -24,8 +24,6 @@ import ( ) // inodeOperations wraps fs.InodeOperations operations with common pipe opening semantics. -// -// +stateify savable type inodeOperations struct { fs.InodeOperations diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index ced2559a7..9a21df5b4 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -41,8 +41,6 @@ const DefaultPipeSize = 65536 // Pipe is an encapsulation of a platform-independent pipe. // It manages a buffered byte queue shared between a reader/writer // pair. -// -// +stateify savable type Pipe struct { waiter.Queue `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 1fa5e9a32..40d5e4943 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -20,8 +20,6 @@ import ( // Reader satisfies the fs.FileOperations interface for read-only pipes. // Reader should be used with !fs.FileFlags.Write to reject writes. -// -// +stateify savable type Reader struct { ReaderWriter } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 82607367b..dc642a3a6 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -31,8 +31,6 @@ import ( // read and write requests. This should only be used directly for named pipes. // pipe(2) and pipe2(2) only support unidirectional pipes and should use // either pipe.Reader or pipe.Writer. -// -// +stateify savable type ReaderWriter struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index d93324b53..fd13008ac 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -20,8 +20,6 @@ import ( // Writer satisfies the fs.FileOperations interface for write-only pipes. // Writer should be used with !fs.FileFlags.Read to reject reads. -// -// +stateify savable type Writer struct { ReaderWriter } diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index e9e69004d..f1c2c4bf0 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -25,8 +25,6 @@ import ( // ptraceOptions are the subset of options controlling a task's ptrace behavior // that are set by ptrace(PTRACE_SETOPTIONS). -// -// +stateify savable type ptraceOptions struct { // ExitKill is true if the tracee should be sent SIGKILL when the tracer // exits. @@ -187,8 +185,6 @@ func (t *Task) hasTracer() bool { } // ptraceStop is a TaskStop placed on tasks in a ptrace-stop. -// -// +stateify savable type ptraceStop struct { // If frozen is true, the stopped task's tracer is currently operating on // it, so Task.Kill should not remove the stop. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 1f3de58e3..635372993 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -23,8 +23,6 @@ import ( // Restartable sequences, as described in https://lwn.net/Articles/650333/. // RSEQCriticalRegion describes a restartable sequence critical region. -// -// +stateify savable type RSEQCriticalRegion struct { // When a task in this thread group has its CPU preempted (as defined by // platform.ErrContextCPUPreempted) or has a signal delivered to an diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index e7fa44e2c..969145fe1 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") go_template_instance( name = "waiter_list", @@ -14,10 +14,21 @@ go_template_instance( }, ) +go_stateify( + name = "semaphore_state", + srcs = [ + "semaphore.go", + "waiter_list.go", + ], + out = "semaphore_autogen_state.go", + package = "semaphore", +) + go_library( name = "semaphore", srcs = [ "semaphore.go", + "semaphore_autogen_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/semaphore", @@ -29,6 +40,8 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", + "//pkg/state", + "//pkg/state/statefile", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index aa07946cf..a1ee83ce5 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -42,8 +42,6 @@ const ( ) // Registry maintains a set of semaphores that can be found by key or ID. -// -// +stateify savable type Registry struct { // userNS owning the ipc name this registry belongs to. Immutable. userNS *auth.UserNamespace @@ -54,8 +52,6 @@ type Registry struct { } // Set represents a set of semaphores that can be operated atomically. -// -// +stateify savable type Set struct { // registry owning this sem set. Immutable. registry *Registry @@ -83,8 +79,6 @@ type Set struct { } // sem represents a single semanphore from a set. -// -// +stateify savable type sem struct { value int16 waiters waiterList `state:"zerovalue"` @@ -92,8 +86,6 @@ type sem struct { // waiter represents a caller that is waiting for the semaphore value to // become positive or zero. -// -// +stateify savable type waiter struct { waiterEntry diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index cf4e18805..fa4c7b8f6 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -27,8 +27,6 @@ type SessionID ThreadID type ProcessGroupID ThreadID // Session contains a leader threadgroup and a list of ProcessGroups. -// -// +stateify savable type Session struct { refs refs.AtomicRefCount @@ -78,8 +76,6 @@ func (s *Session) decRef() { } // ProcessGroup contains an originator threadgroup and a parent Session. -// -// +stateify savable type ProcessGroup struct { refs refs.AtomicRefCount // not exported. diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 40e641355..0f88eb0ac 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,12 +1,22 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "shm_state", + srcs = [ + "shm.go", + ], + out = "shm_autogen_state.go", + package = "shm", +) go_library( name = "shm", srcs = [ "device.go", "shm.go", + "shm_autogen_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm", visibility = ["//pkg/sentry:internal"], @@ -23,6 +33,7 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 1ac444094..7217e8103 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -72,8 +72,6 @@ const ( // Registry tracks all shared memory segments in an IPC namespace. The registry // provides the mechanisms for creating and finding segments, and reporting // global shm parameters. -// -// +stateify savable type Registry struct { // userNS owns the IPC namespace this registry belong to. Immutable. userNS *auth.UserNamespace @@ -290,8 +288,6 @@ func (r *Registry) remove(s *Shm) { // shmctl(SHM_RMID). // // Shm implements memmap.Mappable and memmap.MappingIdentity. -// -// +stateify savable type Shm struct { // AtomicRefCount tracks the number of references to this segment from // maps. A segment always holds a reference to itself, until it's marked for diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 3649f5e4d..21ba4ee70 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -22,8 +22,6 @@ import ( ) // SignalHandlers holds information about signal actions. -// -// +stateify savable type SignalHandlers struct { // mu protects actions, as well as the signal state of all tasks and thread // groups using this SignalHandlers object. (See comment on diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 4c7811b6c..e20fa3eb6 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -176,8 +176,6 @@ type Stracer interface { // SyscallTable is a lookup table of system calls. Critically, a SyscallTable // is *immutable*. In order to make supporting suspend and resume sane, they // must be uniquely registered and may not change during operation. -// -// +stateify savable type SyscallTable struct { // OS is the operating system that this syscall table implements. OS abi.OS `state:"wait"` diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 125312b6a..31541749e 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -23,8 +23,6 @@ import ( // syslog represents a sentry-global kernel log. // // Currently, it contains only fun messages for a dmesg easter egg. -// -// +stateify savable type syslog struct { // mu protects the below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index ae9b3d175..7f6735320 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -52,8 +52,6 @@ import ( // All fields that are "exclusive to the task goroutine" can only be accessed // by the task goroutine while it is running. The task goroutine does not // require synchronization to read or write these fields. -// -// +stateify savable type Task struct { taskNode diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index 38f7826e2..a61283267 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -349,7 +349,6 @@ func (t *Task) unstopVforkParent() { } } -// +stateify savable type runSyscallAfterPtraceEventClone struct { vforkChild *Task @@ -367,7 +366,6 @@ func (r *runSyscallAfterPtraceEventClone) execute(t *Task) taskRunState { return (*runSyscallExit)(nil) } -// +stateify savable type runSyscallAfterVforkStop struct { // childTID has the same meaning as // runSyscallAfterPtraceEventClone.vforkChildTID. @@ -473,8 +471,6 @@ func (t *Task) Unshare(opts *SharingOptions) error { // current MM. (Normally, CLONE_VFORK is used in conjunction with CLONE_VM, so // that the child and parent share mappings until the child execve()s into a // new process image or exits.) -// -// +stateify savable type vforkStop struct{} // StopIgnoresKill implements TaskStop.Killable. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index 9a59cbd33..5c563ba08 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -35,8 +35,6 @@ var ErrNoSyscalls = errors.New("no syscall table found") type Auxmap map[string]interface{} // TaskContext is the subset of a task's data that is provided by the loader. -// -// +stateify savable type TaskContext struct { // Name is the thread name set by the prctl(PR_SET_NAME) system call. Name string diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 385299b24..2285847a2 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -73,8 +73,6 @@ import ( // execStop is a TaskStop that a task sets on itself when it wants to execve // and is waiting for the other tasks in its thread group to exit first. -// -// +stateify savable type execStop struct{} // Killable implements TaskStop.Killable. @@ -121,8 +119,6 @@ func (t *Task) Execve(newTC *TaskContext) (*SyscallControl, error) { // The runSyscallAfterExecStop state continues execve(2) after all siblings of // a thread in the execve syscall have exited. -// -// +stateify savable type runSyscallAfterExecStop struct { tc *TaskContext } diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index b16844e91..d6604f37b 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -38,8 +38,6 @@ import ( // An ExitStatus is a value communicated from an exiting task or thread group // to the party that reaps it. -// -// +stateify savable type ExitStatus struct { // Code is the numeric value passed to the call to exit or exit_group that // caused the exit. If the exit was not caused by such a call, Code is 0. @@ -224,8 +222,6 @@ func (t *Task) advanceExitStateLocked(oldExit, newExit TaskExitState) { } // runExit is the entry point into the task exit path. -// -// +stateify savable type runExit struct{} func (*runExit) execute(t *Task) taskRunState { @@ -233,7 +229,6 @@ func (*runExit) execute(t *Task) taskRunState { return (*runExitMain)(nil) } -// +stateify savable type runExitMain struct{} func (*runExitMain) execute(t *Task) taskRunState { @@ -536,7 +531,6 @@ func (t *Task) reparentLocked(parent *Task) { // tracer (if one exists) and reaps the leader immediately. In Linux, this is // in fs/exec.c:de_thread(); in the sentry, this is in Task.promoteLocked(). -// +stateify savable type runExitNotify struct{} func (*runExitNotify) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_resources.go b/pkg/sentry/kernel/task_resources.go index 0832bf989..4ca25664a 100644 --- a/pkg/sentry/kernel/task_resources.go +++ b/pkg/sentry/kernel/task_resources.go @@ -21,8 +21,6 @@ import ( // TaskResources is the subset of a task's data provided by its creator that is // not provided by the loader. -// -// +stateify savable type TaskResources struct { // SignalMask is the set of signals whose delivery is currently blocked. // diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 8dd0ef6ea..a03fa6ac0 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -131,8 +131,6 @@ func (t *Task) doStop() { // The runApp state checks for interrupts before executing untrusted // application code. -// -// +stateify savable type runApp struct{} func (*runApp) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index 49141ab74..b50139077 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -65,8 +65,6 @@ const ( // TaskGoroutineSchedInfo contains task goroutine scheduling state which must // be read and updated atomically. -// -// +stateify savable type TaskGoroutineSchedInfo struct { // Timestamp was the value of Kernel.cpuClock when this // TaskGoroutineSchedInfo was last updated. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 62ec530be..91f6c0874 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -748,8 +748,6 @@ func (t *Task) CopyInSignalStack(addr usermem.Addr) (arch.SignalStack, error) { // groupStop is a TaskStop placed on tasks that have received a stop signal // (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU). (The term "group-stop" originates from // the ptrace man page.) -// -// +stateify savable type groupStop struct{} // Killable implements TaskStop.Killable. @@ -883,8 +881,6 @@ func (t *Task) signalStop(target *Task, code int32, status int32) { } // The runInterrupt state handles conditions indicated by interrupts. -// -// +stateify savable type runInterrupt struct{} func (*runInterrupt) execute(t *Task) taskRunState { @@ -1024,7 +1020,6 @@ func (*runInterrupt) execute(t *Task) taskRunState { return (*runApp)(nil) } -// +stateify savable type runInterruptAfterSignalDeliveryStop struct{} func (*runInterruptAfterSignalDeliveryStop) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 3b9652504..79f4ff60c 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -241,7 +241,6 @@ func (t *Task) doSyscallEnter(sysno uintptr, args arch.SyscallArguments) taskRun return t.doSyscallInvoke(sysno, args) } -// +stateify savable type runSyscallAfterSyscallEnterStop struct{} func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { @@ -261,7 +260,6 @@ func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } -// +stateify savable type runSyscallAfterSysemuStop struct{} func (*runSyscallAfterSysemuStop) execute(t *Task) taskRunState { @@ -296,7 +294,6 @@ func (t *Task) doSyscallInvoke(sysno uintptr, args arch.SyscallArguments) taskRu return (*runSyscallExit)(nil).execute(t) } -// +stateify savable type runSyscallReinvoke struct{} func (*runSyscallReinvoke) execute(t *Task) taskRunState { @@ -313,7 +310,6 @@ func (*runSyscallReinvoke) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } -// +stateify savable type runSyscallExit struct{} func (*runSyscallExit) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 441b8a822..8fffd3446 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -28,8 +28,6 @@ import ( // groups" are usually called "processes" in userspace documentation.) // // ThreadGroup is a superset of Linux's struct signal_struct. -// -// +stateify savable type ThreadGroup struct { threadGroupNode diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 844213c35..440da9dad 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -50,8 +50,6 @@ func (tid ThreadID) String() string { const InitTID ThreadID = 1 // A TaskSet comprises all tasks in a system. -// -// +stateify savable type TaskSet struct { // mu protects all relationships betweens tasks and thread groups in the // TaskSet. (mu is approximately equivalent to Linux's tasklist_lock.) @@ -112,8 +110,6 @@ func (ts *TaskSet) forEachThreadGroupLocked(f func(tg *ThreadGroup)) { // // N.B. A task is said to be visible in a PID namespace if the PID namespace // contains a thread ID that maps to that task. -// -// +stateify savable type PIDNamespace struct { // owner is the TaskSet that this PID namespace belongs to. The owner // pointer is immutable. @@ -267,8 +263,6 @@ func (ns *PIDNamespace) UserNamespace() *auth.UserNamespace { // (threadGroupNode is an anonymous field in ThreadGroup; this is to expose // threadGroupEntry's methods on ThreadGroup to make it implement // threadGroupLinker.) -// -// +stateify savable type threadGroupNode struct { // pidns is the PID namespace containing the thread group and all of its // member tasks. The pidns pointer is immutable. @@ -388,8 +382,6 @@ func (tg *ThreadGroup) ID() ThreadID { // A taskNode defines the relationship between a task and the rest of the // system. The comments on threadGroupNode also apply to taskNode. -// -// +stateify savable type taskNode struct { // tg is the thread group that this task belongs to. The tg pointer is // immutable. diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index 5d8db2273..b3ed42aa4 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,18 +1,30 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "time_state", + srcs = [ + "time.go", + ], + out = "time_state.go", + package = "time", +) go_library( name = "time", srcs = [ "context.go", "time.go", + "time_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/log", "//pkg/sentry/context", + "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index 6eadd2878..c223c2f19 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -42,8 +42,6 @@ const ( // // Time may represent time with respect to any clock and may not have any // meaning in the real world. -// -// +stateify savable type Time struct { ns int64 } @@ -288,8 +286,6 @@ type TimerListener interface { } // Setting contains user-controlled mutable Timer properties. -// -// +stateify savable type Setting struct { // Enabled is true if the timer is running. Enabled bool @@ -375,8 +371,6 @@ func (s Setting) advancedTo(now Time) (Setting, uint64) { // // Timers should be created using NewTimer and must be cleaned up by calling // Timer.Destroy when no longer used. -// -// +stateify savable type Timer struct { // clock is the time source. clock is immutable. clock Clock diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index df5dbe128..4de8ac13b 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -25,8 +25,6 @@ import ( ) // Timekeeper manages all of the kernel clocks. -// -// +stateify savable type Timekeeper struct { // clocks are the clock sources. // diff --git a/pkg/sentry/kernel/timer.go b/pkg/sentry/kernel/timer.go index 534d03d0f..03a3310be 100644 --- a/pkg/sentry/kernel/timer.go +++ b/pkg/sentry/kernel/timer.go @@ -26,8 +26,6 @@ import ( // timekeeperClock is a ktime.Clock that reads time from a // kernel.Timekeeper-managed clock. -// -// +stateify savable type timekeeperClock struct { tk *Timekeeper c sentrytime.ClockID @@ -51,8 +49,6 @@ func (tc *timekeeperClock) Now() ktime.Time { // tgClock is a ktime.Clock that measures the time a thread group has spent // executing. -// -// +stateify savable type tgClock struct { tg *ThreadGroup @@ -159,8 +155,6 @@ func (tc *taskClock) Now() ktime.Time { } // signalNotifier is a ktime.Listener that sends signals to a ThreadGroup. -// -// +stateify savable type signalNotifier struct { tg *ThreadGroup signal linux.Signal @@ -185,8 +179,6 @@ func (s *signalNotifier) Notify(exp uint64) { func (s *signalNotifier) Destroy() {} // TimerManager is a collection of supported process cpu timers. -// -// +stateify savable type TimerManager struct { // Clocks used to drive thread group execution time timers. virtClock *tgClock diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index 7e0fe0d21..58e9b4d1b 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -22,8 +22,6 @@ import ( // UTSNamespace represents a UTS namespace, a holder of two system identifiers: // the hostname and domain name. -// -// +stateify savable type UTSNamespace struct { // mu protects all fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 971e8bc59..0bacbea49 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -52,8 +52,6 @@ type vdsoParams struct { // Everything in the struct is 8 bytes for easy alignment. // // It must be kept in sync with params in vdso/vdso_time.cc. -// -// +stateify savable type VDSOParamPage struct { // The parameter page is fr, allocated from platform.Memory(). platform platform.Platform diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 90f4395d4..3ce41cacc 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,12 +1,22 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "limits_state", + srcs = [ + "limits.go", + ], + out = "limits_state.go", + package = "limits", +) go_library( name = "limits", srcs = [ "context.go", "limits.go", + "limits_state.go", "linux.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/limits", @@ -14,6 +24,7 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/sentry/context", + "//pkg/state", ], ) diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index 02c8b60e3..4230ba958 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -47,8 +47,6 @@ const ( const Infinity = ^uint64(0) // Limit specifies a system limit. -// -// +stateify savable type Limit struct { // Cur specifies the current limit. Cur uint64 @@ -57,8 +55,6 @@ type Limit struct { } // LimitSet represents the Limits that correspond to each LimitType. -// -// +stateify savable type LimitSet struct { mu sync.Mutex `state:"nosave"` data map[LimitType]Limit diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 0beb4561b..e63052c6d 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") go_embed_data( name = "vdso_bin", @@ -10,12 +10,23 @@ go_embed_data( var = "vdsoBin", ) +go_stateify( + name = "loader_state", + srcs = [ + "vdso.go", + "vdso_state.go", + ], + out = "loader_state.go", + package = "loader", +) + go_library( name = "loader", srcs = [ "elf.go", "interpreter.go", "loader.go", + "loader_state.go", "vdso.go", "vdso_state.go", ":vdso_bin", @@ -29,6 +40,7 @@ go_library( "//pkg/cpuid", "//pkg/log", "//pkg/rand", + "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -43,6 +55,7 @@ go_library( "//pkg/sentry/uniqueid", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index a06e27ac9..2e8693f8e 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -193,8 +193,6 @@ func validateVDSO(ctx context.Context, f *fs.File, size uint64) (elfInfo, error) // // NOTE: to support multiple architectures or operating systems, this // would need to contain a VDSO for each. -// -// +stateify savable type VDSO struct { // ParamPage is the VDSO parameter page. This page should be updated to // inform the VDSO for timekeeping data. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index dc71e1c2d..92004ad9e 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -18,7 +18,6 @@ import ( "debug/elf" ) -// +stateify savable type elfProgHeader struct { Type elf.ProgType Flags elf.ProgFlag diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index c9e0b95a0..2e367e189 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,7 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "memmap_state", + srcs = [ + "mappable_range.go", + "mapping_set.go", + "mapping_set_impl.go", + ], + out = "memmap_state.go", + package = "memmap", +) go_template_instance( name = "mappable_range", @@ -35,6 +46,7 @@ go_library( "mapping_set.go", "mapping_set_impl.go", "memmap.go", + "memmap_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/memmap", visibility = ["//pkg/sentry:internal"], @@ -44,6 +56,7 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/platform", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index c9483905d..0cd42ffbf 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -35,8 +35,6 @@ import ( type MappingsOfRange map[MappingOfRange]struct{} // MappingOfRange represents a mapping of a MappableRange. -// -// +stateify savable type MappingOfRange struct { MappingSpace MappingSpace AddrRange usermem.AddrRange diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index bbdfae247..3f396986a 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,7 +1,24 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "mm_state", + srcs = [ + "aio_context.go", + "aio_context_state.go", + "file_refcount_set.go", + "io_list.go", + "mm.go", + "pma_set.go", + "save_restore.go", + "special_mappable.go", + "vma_set.go", + ], + out = "mm_state.go", + package = "mm", +) go_template_instance( name = "file_refcount_set", @@ -84,6 +101,7 @@ go_library( "lifecycle.go", "metadata.go", "mm.go", + "mm_state.go", "pma.go", "pma_set.go", "proc_pid_maps.go", @@ -113,6 +131,7 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/sync", "//pkg/syserror", "//pkg/tcpip/buffer", diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index b42156d45..992bde5a5 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -28,8 +28,6 @@ import ( ) // aioManager creates and manages asynchronous I/O contexts. -// -// +stateify savable type aioManager struct { // mu protects below. mu sync.Mutex `state:"nosave"` @@ -91,16 +89,12 @@ func (a *aioManager) lookupAIOContext(id uint64) (*AIOContext, bool) { } // ioResult is a completed I/O operation. -// -// +stateify savable type ioResult struct { data interface{} ioEntry } // AIOContext is a single asynchronous I/O context. -// -// +stateify savable type AIOContext struct { // done is the notification channel used for all requests. done chan struct{} `state:"nosave"` @@ -196,8 +190,6 @@ func (ctx *AIOContext) WaitChannel() (chan struct{}, bool) { // aioMappable implements memmap.MappingIdentity and memmap.Mappable for AIO // ring buffers. -// -// +stateify savable type aioMappable struct { refs.AtomicRefCount diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index 3299ae164..ce8097b7f 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -46,8 +46,6 @@ import ( ) // MemoryManager implements a virtual address space. -// -// +stateify savable type MemoryManager struct { // p is the platform. // @@ -209,8 +207,6 @@ type MemoryManager struct { } // vma represents a virtual memory area. -// -// +stateify savable type vma struct { // mappable is the virtual memory object mapped by this vma. If mappable is // nil, the vma represents a private anonymous mapping. @@ -350,8 +346,6 @@ func (v *vma) loadRealPerms(b int) { } // pma represents a platform mapping area. -// -// +stateify savable type pma struct { // file is the file mapped by this pma. Only pmas for which file == // platform.Platform.Memory() may be saved. pmas hold a reference to the @@ -386,7 +380,6 @@ type pma struct { internalMappings safemem.BlockSeq `state:"nosave"` } -// +stateify savable type privateRefs struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index aa2f87107..9d3614034 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -28,8 +28,6 @@ import ( // semantics similar to Linux's mm/mmap.c:_install_special_mapping(), except // that SpecialMappable takes ownership of the memory that it represents // (_install_special_mapping() does not.) -// -// +stateify savable type SpecialMappable struct { refs.AtomicRefCount diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index af9ba5394..15a7fbbc3 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,7 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "platform_state", + srcs = [ + "file_range.go", + ], + out = "platform_state.go", + package = "platform", +) go_template_instance( name = "file_range", @@ -21,6 +30,7 @@ go_library( "file_range.go", "mmap_min_addr.go", "platform.go", + "platform_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/platform", visibility = ["//pkg/sentry:internal"], @@ -34,6 +44,7 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index 2a5982763..dadba1d38 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,7 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "filemem_autogen_state", + srcs = [ + "filemem.go", + "filemem_state.go", + "usage_set.go", + ], + out = "filemem_autogen_state.go", + package = "filemem", +) go_template_instance( name = "usage_set", @@ -27,6 +38,7 @@ go_library( name = "filemem", srcs = [ "filemem.go", + "filemem_autogen_state.go", "filemem_state.go", "filemem_unsafe.go", "usage_set.go", diff --git a/pkg/sentry/platform/filemem/filemem.go b/pkg/sentry/platform/filemem/filemem.go index feb020ef8..870274ae1 100644 --- a/pkg/sentry/platform/filemem/filemem.go +++ b/pkg/sentry/platform/filemem/filemem.go @@ -155,8 +155,6 @@ type FileMem struct { } // usage tracks usage information. -// -// +stateify savable type usageInfo struct { // kind is the usage kind. kind usage.MemoryKind diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index a320fca0b..929787aa0 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,10 +1,22 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "socket_state", + srcs = [ + "socket.go", + ], + out = "socket_state_autogen.go", + package = "socket", +) go_library( name = "socket", - srcs = ["socket.go"], + srcs = [ + "socket.go", + "socket_state_autogen.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket", visibility = ["//pkg/sentry:internal"], deps = [ @@ -17,6 +29,7 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserr", "//pkg/tcpip", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index c4874fdfb..faf2b4c27 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,14 +1,26 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") -go_library( - name = "control", - srcs = ["control.go"], - importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/control", +go_stateify( + name = "control_state", + srcs = [ + "control.go", + ], + out = "control_state.go", imports = [ "gvisor.googlesource.com/gvisor/pkg/sentry/fs", ], + package = "control", +) + +go_library( + name = "control", + srcs = [ + "control.go", + "control_state.go", + ], + importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/control", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", @@ -19,6 +31,7 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/kdefs", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", ], diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index c31182e69..17ecdd11c 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -51,8 +51,6 @@ type SCMRights interface { // RightsFiles represents a SCM_RIGHTS socket control message. A reference is // maintained for each fs.File and is release either when an FD is created or // when the Release method is called. -// -// +stateify savable type RightsFiles []*fs.File // NewSCMRights creates a new SCM_RIGHTS socket control message representation @@ -130,8 +128,6 @@ func PackRights(t *kernel.Task, rights SCMRights, cloexec bool, buf []byte) []by } // scmCredentials represents an SCM_CREDENTIALS socket control message. -// -// +stateify savable type scmCredentials struct { t *kernel.Task kuid auth.KUID diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index 49af8db85..7ad5e88c5 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,12 +1,24 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "epsocket_state", + srcs = [ + "epsocket.go", + "save_restore.go", + "stack.go", + ], + out = "epsocket_state.go", + package = "epsocket", +) go_library( name = "epsocket", srcs = [ "device.go", "epsocket.go", + "epsocket_state.go", "provider.go", "save_restore.go", "stack.go", @@ -19,6 +31,7 @@ go_library( "//pkg/abi/linux", "//pkg/binary", "//pkg/log", + "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", @@ -31,6 +44,7 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index f969a1d7c..a2927e1b9 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -95,8 +95,6 @@ type commonEndpoint interface { // SocketOperations encapsulates all the state needed to represent a network stack // endpoint in the kernel context. -// -// +stateify savable type SocketOperations struct { socket.ReceiveTimeout fsutil.PipeSeek `state:"nosave"` diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 12b4b4767..ec1d96ccb 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -26,8 +26,6 @@ import ( ) // Stack implements inet.Stack for netstack/tcpip/stack.Stack. -// -// +stateify savable type Stack struct { Stack *stack.Stack `state:"manual"` } diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index d623718b3..227ca3926 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,12 +1,24 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "hostinet_state", + srcs = [ + "save_restore.go", + "socket.go", + "stack.go", + ], + out = "hostinet_autogen_state.go", + package = "hostinet", +) go_library( name = "hostinet", srcs = [ "device.go", "hostinet.go", + "hostinet_autogen_state.go", "save_restore.go", "socket.go", "socket_unsafe.go", @@ -30,6 +42,7 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index b852165f7..b23a243f7 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,11 +1,21 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "netlink_state", + srcs = [ + "socket.go", + ], + out = "netlink_state.go", + package = "netlink", +) go_library( name = "netlink", srcs = [ "message.go", + "netlink_state.go", "provider.go", "socket.go", ], @@ -26,6 +36,7 @@ go_library( "//pkg/sentry/socket/netlink/port", "//pkg/sentry/socket/unix", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index 3a7dbc5ed..ba6f686e4 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,12 +1,23 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "port_state", + srcs = ["port.go"], + out = "port_state.go", + package = "port", +) go_library( name = "port", - srcs = ["port.go"], + srcs = [ + "port.go", + "port_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/port", visibility = ["//pkg/sentry:internal"], + deps = ["//pkg/state"], ) go_test( diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 1c5d4c3a5..4ccf0b84c 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -32,8 +32,6 @@ import ( const maxPorts = 10000 // Manager allocates netlink port IDs. -// -// +stateify savable type Manager struct { // mu protects the fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index e1bcfe252..726469fc9 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,19 +1,32 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "route_state", + srcs = ["protocol.go"], + out = "route_state.go", + package = "route", +) go_library( name = "route", - srcs = ["protocol.go"], + srcs = [ + "protocol.go", + "route_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/route", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", "//pkg/sentry/context", + "//pkg/sentry/fs", "//pkg/sentry/inet", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/socket/netlink", + "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserr", ], ) diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 55a76e916..e8030c518 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -43,8 +43,6 @@ func typeKind(typ uint16) commandKind { } // Protocol implements netlink.Protocol. -// -// +stateify savable type Protocol struct{} var _ netlink.Protocol = (*Protocol)(nil) diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index e15d1546c..0b8f528d0 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -51,8 +51,6 @@ var netlinkSocketDevice = device.NewAnonDevice() // to/from the kernel. // // Socket implements socket.Socket. -// -// +stateify savable type Socket struct { socket.ReceiveTimeout fsutil.PipeSeek `state:"nosave"` diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 54fe64595..bd4858a34 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -195,8 +195,6 @@ func NewDirent(ctx context.Context, d *device.Device) *fs.Dirent { // // Care must be taken when copying ReceiveTimeout as it contains atomic // variables. -// -// +stateify savable type ReceiveTimeout struct { // ns is length of the timeout in nanoseconds. // diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index 9fe681e9a..7d04d6b6b 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,6 +1,15 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "unix_state", + srcs = [ + "unix.go", + ], + out = "unix_state.go", + package = "unix", +) go_library( name = "unix", @@ -8,6 +17,7 @@ go_library( "device.go", "io.go", "unix.go", + "unix_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix", visibility = ["//pkg/sentry:internal"], @@ -27,6 +37,7 @@ go_library( "//pkg/sentry/socket/control", "//pkg/sentry/socket/epsocket", "//pkg/sentry/usermem", + "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 5b6411f97..27bacbbc3 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -42,8 +42,6 @@ import ( // SocketOperations is a Unix socket. It is similar to an epsocket, except it is backed // by a unix.Endpoint instead of a tcpip.Endpoint. -// -// +stateify savable type SocketOperations struct { refs.AtomicRefCount socket.ReceiveTimeout diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index e4450a093..574621ad2 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,6 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "linux_state", + srcs = [ + "sys_aio.go", + "sys_futex.go", + "sys_poll.go", + "sys_time.go", + ], + out = "linux_state.go", + package = "linux", +) go_library( name = "linux", @@ -8,6 +20,7 @@ go_library( "error.go", "flags.go", "linux64.go", + "linux_state.go", "sigset.go", "sys_aio.go", "sys_capability.go", @@ -53,6 +66,7 @@ go_library( "//pkg/abi/linux", "//pkg/binary", "//pkg/bpf", + "//pkg/eventchannel", "//pkg/log", "//pkg/metric", "//pkg/rand", @@ -60,6 +74,7 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", + "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/lock", "//pkg/sentry/fs/timerfd", "//pkg/sentry/kernel", @@ -70,6 +85,7 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/pipe", "//pkg/sentry/kernel/sched", + "//pkg/sentry/kernel/semaphore", "//pkg/sentry/kernel/shm", "//pkg/sentry/kernel/time", "//pkg/sentry/limits", @@ -81,6 +97,8 @@ go_library( "//pkg/sentry/syscalls", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/state", + "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index 54e4afa9e..fc3397081 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -69,8 +69,6 @@ type ioCallback struct { } // ioEvent describes an I/O result. -// -// +stateify savable type ioEvent struct { Data uint64 Obj uint64 diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index 1a0e1f5fb..57762d058 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -132,8 +132,6 @@ func (f futexChecker) Op(addr uintptr, opIn uint32) (bool, error) { // futexWaitRestartBlock encapsulates the state required to restart futex(2) // via restart_syscall(2). -// -// +stateify savable type futexWaitRestartBlock struct { duration time.Duration diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index b9bdefadb..d4dbfd285 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -274,8 +274,6 @@ func copyOutTimevalRemaining(t *kernel.Task, startNs ktime.Time, timeout time.Du // pollRestartBlock encapsulates the state required to restart poll(2) via // restart_syscall(2). -// -// +stateify savable type pollRestartBlock struct { pfdAddr usermem.Addr nfds uint diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index 8e6683444..dcee694b2 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -168,8 +168,6 @@ func Time(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC // clockNanosleepRestartBlock encapsulates the state required to restart // clock_nanosleep(2) via restart_syscall(2). -// -// +stateify savable type clockNanosleepRestartBlock struct { c ktime.Clock duration time.Duration diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index 868dfd400..edee44d96 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,6 +1,17 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "usage_state", + srcs = [ + "cpu.go", + "io.go", + "memory.go", + ], + out = "usage_state.go", + package = "usage", +) go_library( name = "usage", @@ -10,6 +21,7 @@ go_library( "memory.go", "memory_unsafe.go", "usage.go", + "usage_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/usage", visibility = [ @@ -17,6 +29,9 @@ go_library( ], deps = [ "//pkg/bits", + "//pkg/log", "//pkg/sentry/memutil", + "//pkg/state", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index ed7b04b9e..1c2cc90e1 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -20,8 +20,6 @@ import ( // CPUStats contains the subset of struct rusage fields that relate to CPU // scheduling. -// -// +stateify savable type CPUStats struct { // UserTime is the amount of time spent executing application code. UserTime time.Duration diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index 49faa507d..a05053c32 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -19,8 +19,6 @@ import ( ) // IO contains I/O-related statistics. -// -// +stateify savable type IO struct { // CharsRead is the number of bytes read by read syscalls. CharsRead uint64 diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index 69ba919e0..9dd1cd2b5 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,7 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "usermem_state", + srcs = [ + "access_type.go", + "addr.go", + "addr_range.go", + "addr_range_seq_unsafe.go", + ], + out = "usermem_state.go", + package = "usermem", +) go_template_instance( name = "addr_range", @@ -24,6 +36,7 @@ go_library( "bytes_io.go", "bytes_io_unsafe.go", "usermem.go", + "usermem_state.go", "usermem_x86.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/usermem", @@ -34,6 +47,7 @@ go_library( "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/safemem", + "//pkg/state", "//pkg/syserror", "//pkg/tcpip/buffer", ], diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 75346d854..7eabecf30 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -20,8 +20,6 @@ import ( // AccessType specifies memory access types. This is used for // setting mapping permissions, as well as communicating faults. -// -// +stateify savable type AccessType struct { // Read is read access. Read bool diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index fc94bee80..d175fdc74 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -19,8 +19,6 @@ import ( ) // Addr represents a generic virtual address. -// -// +stateify savable type Addr uintptr // AddLength adds the given length to start and returns the result. ok is true diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 5153bd3b4..391d801d0 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,13 +1,26 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "tcpip_state", + srcs = [ + "tcpip.go", + ], + out = "tcpip_state.go", + package = "tcpip", +) go_library( name = "tcpip", - srcs = ["tcpip.go"], + srcs = [ + "tcpip.go", + "tcpip_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip", visibility = ["//visibility:public"], deps = [ + "//pkg/state", "//pkg/tcpip/buffer", "//pkg/waiter", ], diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index 11a725423..efeb6a448 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,15 +1,26 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "buffer_state", + srcs = [ + "view.go", + ], + out = "buffer_state.go", + package = "buffer", +) go_library( name = "buffer", srcs = [ + "buffer_state.go", "prependable.go", "view.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer", visibility = ["//visibility:public"], + deps = ["//pkg/state"], ) go_test( diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index bbb4e1d24..a5774a327 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -54,8 +54,6 @@ func (v *View) ToVectorisedView(views [1]View) VectorisedView { // VectorisedView is a vectorised version of View using non contigous memory. // It supports all the convenience methods supported by View. -// -// +stateify savable type VectorisedView struct { views []View size int diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 8f22ba3a5..3aa2cfb24 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,6 +1,15 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "tcp_header_state", + srcs = [ + "tcp.go", + ], + out = "tcp_header_state.go", + package = "header", +) go_library( name = "header", @@ -16,11 +25,13 @@ go_library( "ipv6.go", "ipv6_fragment.go", "tcp.go", + "tcp_header_state.go", "udp.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/header", visibility = ["//visibility:public"], deps = [ + "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/seqnum", ], diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 6689a6dc5..a95d282b0 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -120,8 +120,6 @@ type TCPSynOptions struct { } // SACKBlock represents a single contiguous SACK block. -// -// +stateify savable type SACKBlock struct { // Start indicates the lowest sequence number in the block. Start seqnum.Value @@ -133,8 +131,6 @@ type SACKBlock struct { // TCPOptions are used to parse and cache the TCP segment options for a non // syn/syn-ack segment. -// -// +stateify savable type TCPOptions struct { // TS is true if the TimeStamp option is enabled. TS bool diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index 83b4d253f..ac97ebe43 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,7 +1,14 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "fragmentation_state", + srcs = ["reassembler_list.go"], + out = "fragmentation_state.go", + package = "fragmentation", +) go_template_instance( name = "reassembler_list", @@ -19,6 +26,7 @@ go_library( srcs = [ "frag_heap.go", "fragmentation.go", + "fragmentation_state.go", "reassembler.go", "reassembler_list.go", ], @@ -26,6 +34,7 @@ go_library( visibility = ["//:sandbox"], deps = [ "//pkg/log", + "//pkg/state", "//pkg/tcpip/buffer", ], ) diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index c5c889239..a75869dac 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,12 +1,25 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "seqnum_state", + srcs = [ + "seqnum.go", + ], + out = "seqnum_state.go", + package = "seqnum", +) go_library( name = "seqnum", - srcs = ["seqnum.go"], + srcs = [ + "seqnum.go", + "seqnum_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum", visibility = [ "//visibility:public", ], + deps = ["//pkg/state"], ) diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index af0aec85c..eb1e4645d 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -213,8 +213,6 @@ const ( // FullAddress represents a full transport node address, as required by the // Connect() and Bind() methods. -// -// +stateify savable type FullAddress struct { // NIC is the ID of the NIC this address refers to. // @@ -258,8 +256,6 @@ func (s SlicePayload) Size() int { } // A ControlMessages contains socket control messages for IP sockets. -// -// +stateify savable type ControlMessages struct { // HasTimestamp indicates whether Timestamp is valid/set. HasTimestamp bool diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 117532fea..28e3e1700 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,7 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "ping_state", + srcs = [ + "endpoint.go", + "endpoint_state.go", + "ping_packet_list.go", + ], + out = "ping_state.go", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], + package = "ping", +) go_template_instance( name = "ping_packet_list", @@ -20,13 +32,14 @@ go_library( "endpoint.go", "endpoint_state.go", "ping_packet_list.go", + "ping_state.go", "protocol.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/sleep", + "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index a22684de9..f15e44b61 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -26,7 +26,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// +stateify savable type pingPacket struct { pingPacketEntry senderAddress tcpip.FullAddress diff --git a/pkg/tcpip/transport/queue/BUILD b/pkg/tcpip/transport/queue/BUILD index 6dcec312e..fb878ad36 100644 --- a/pkg/tcpip/transport/queue/BUILD +++ b/pkg/tcpip/transport/queue/BUILD @@ -1,14 +1,27 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "queue_state", + srcs = [ + "queue.go", + ], + out = "queue_state.go", + package = "queue", +) go_library( name = "queue", - srcs = ["queue.go"], + srcs = [ + "queue.go", + "queue_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/queue", visibility = ["//:sandbox"], deps = [ "//pkg/ilist", + "//pkg/state", "//pkg/tcpip", "//pkg/waiter", ], diff --git a/pkg/tcpip/transport/queue/queue.go b/pkg/tcpip/transport/queue/queue.go index eb9ee8a3f..6a17441ae 100644 --- a/pkg/tcpip/transport/queue/queue.go +++ b/pkg/tcpip/transport/queue/queue.go @@ -33,8 +33,6 @@ type Entry interface { } // Queue is a buffer queue. -// -// +stateify savable type Queue struct { ReaderQueue *waiter.Queue WriterQueue *waiter.Queue diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 9ebae6cc7..6a7153e4d 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,7 +1,27 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "tcp_state", + srcs = [ + "endpoint.go", + "endpoint_state.go", + "rcv.go", + "reno.go", + "segment.go", + "segment_heap.go", + "segment_queue.go", + "segment_state.go", + "snd.go", + "snd_state.go", + "tcp_segment_list.go", + ], + out = "tcp_state.go", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], + package = "tcp", +) go_template_instance( name = "tcp_segment_list", @@ -33,14 +53,15 @@ go_library( "snd.go", "snd_state.go", "tcp_segment_list.go", + "tcp_state.go", "timer.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/rand", "//pkg/sleep", + "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index de1883d84..5b8a1e20f 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -54,8 +54,6 @@ const ( ) // SACKInfo holds TCP SACK related information for a given endpoint. -// -// +stateify savable type SACKInfo struct { // Blocks is the maximum number of SACK blocks we track // per endpoint. @@ -71,8 +69,6 @@ type SACKInfo struct { // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. The protocol implementation, however, runs in a single // goroutine. -// -// +stateify savable type endpoint struct { // workMu is used to arbitrate which goroutine may perform protocol // work. Only the main protocol goroutine is expected to call Lock() on diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index 92ef9c6f7..b22a00ce1 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -22,8 +22,6 @@ import ( // receiver holds the state necessary to receive TCP segments and turn them // into a stream of bytes. -// -// +stateify savable type receiver struct { ep *endpoint diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index 03ae8d747..60f170a27 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -16,8 +16,6 @@ package tcp // renoState stores the variables related to TCP New Reno congestion // control algorithm. -// -// +stateify savable type renoState struct { s *sender } diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 8dccea2ba..40928ba2c 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -36,8 +36,6 @@ const ( // segment represents a TCP segment. It holds the payload and parsed TCP segment // information, and can be added to intrusive lists. // segment is mostly immutable, the only field allowed to change is viewToDeliver. -// -// +stateify savable type segment struct { segmentEntry refCnt int32 diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 6a2d7bc0b..2ddcf5f10 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -21,8 +21,6 @@ import ( ) // segmentQueue is a bounded, thread-safe queue of TCP segments. -// -// +stateify savable type segmentQueue struct { mu sync.Mutex `state:"nosave"` list segmentList `state:"wait"` diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 376e81846..e38686e1b 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -54,8 +54,6 @@ type congestionControl interface { } // sender holds the state necessary to send TCP segments. -// -// +stateify savable type sender struct { ep *endpoint @@ -135,8 +133,6 @@ type sender struct { } // fastRecovery holds information related to fast recovery from a packet loss. -// -// +stateify savable type fastRecovery struct { // active whether the endpoint is in fast recovery. The following fields // are only meaningful when active is true. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index d536839af..33c8867f4 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -18,7 +18,6 @@ import ( "time" ) -// +stateify savable type unixTime struct { second int64 nano int64 diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 1a3a62d3d..790dd55a3 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,7 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "udp_state", + srcs = [ + "endpoint.go", + "endpoint_state.go", + "udp_packet_list.go", + ], + out = "udp_state.go", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], + package = "udp", +) go_template_instance( name = "udp_packet_list", @@ -21,12 +33,13 @@ go_library( "endpoint_state.go", "protocol.go", "udp_packet_list.go", + "udp_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/sleep", + "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 03fb76f92..2a32c3a87 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -25,7 +25,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// +stateify savable type udpPacket struct { udpPacketEntry senderAddress tcpip.FullAddress @@ -50,8 +49,6 @@ const ( // between users of the endpoint and the protocol implementation; it is legal to // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. -// -// +stateify savable type endpoint struct { // The following fields are initialized at creation time and do not // change throughout the lifetime of the endpoint. diff --git a/pkg/tcpip/transport/unix/BUILD b/pkg/tcpip/transport/unix/BUILD index dae0bd079..676f2cf92 100644 --- a/pkg/tcpip/transport/unix/BUILD +++ b/pkg/tcpip/transport/unix/BUILD @@ -1,6 +1,17 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") + +go_stateify( + name = "unix_state", + srcs = [ + "connectioned.go", + "connectionless.go", + "unix.go", + ], + out = "unix_state.go", + package = "unix", +) go_library( name = "unix", @@ -9,11 +20,14 @@ go_library( "connectioned_state.go", "connectionless.go", "unix.go", + "unix_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix", visibility = ["//:sandbox"], deps = [ "//pkg/ilist", + "//pkg/log", + "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/transport/queue", diff --git a/pkg/tcpip/transport/unix/connectioned.go b/pkg/tcpip/transport/unix/connectioned.go index dd7c03cf1..0e63186b2 100644 --- a/pkg/tcpip/transport/unix/connectioned.go +++ b/pkg/tcpip/transport/unix/connectioned.go @@ -85,8 +85,6 @@ type ConnectingEndpoint interface { // path != "" && acceptedChan != nil => bound and listening. // // Only one of these will be true at any moment. -// -// +stateify savable type connectionedEndpoint struct { baseEndpoint diff --git a/pkg/tcpip/transport/unix/connectionless.go b/pkg/tcpip/transport/unix/connectionless.go index 2a6ec8b4b..3276ddcd0 100644 --- a/pkg/tcpip/transport/unix/connectionless.go +++ b/pkg/tcpip/transport/unix/connectionless.go @@ -25,8 +25,6 @@ import ( // // Specifically, this means datagram unix sockets not created with // socketpair(2). -// -// +stateify savable type connectionlessEndpoint struct { baseEndpoint } diff --git a/pkg/tcpip/transport/unix/unix.go b/pkg/tcpip/transport/unix/unix.go index 8e4af3139..190a1ccdb 100644 --- a/pkg/tcpip/transport/unix/unix.go +++ b/pkg/tcpip/transport/unix/unix.go @@ -60,8 +60,6 @@ type CredentialsControlMessage interface { } // A ControlMessages represents a collection of socket control messages. -// -// +stateify savable type ControlMessages struct { // Rights is a control message containing FDs. Rights RightsControlMessage @@ -237,8 +235,6 @@ type BoundEndpoint interface { } // message represents a message passed over a Unix domain socket. -// -// +stateify savable type message struct { ilist.Entry @@ -310,8 +306,6 @@ type Receiver interface { } // queueReceiver implements Receiver for datagram sockets. -// -// +stateify savable type queueReceiver struct { readQueue *queue.Queue } @@ -375,8 +369,6 @@ func (q *queueReceiver) RecvMaxQueueSize() int64 { func (*queueReceiver) Release() {} // streamQueueReceiver implements Receiver for stream sockets. -// -// +stateify savable type streamQueueReceiver struct { queueReceiver @@ -587,7 +579,6 @@ type ConnectedEndpoint interface { Release() } -// +stateify savable type connectedEndpoint struct { // endpoint represents the subset of the Endpoint functionality needed by // the connectedEndpoint. It is implemented by both connectionedEndpoint @@ -680,8 +671,6 @@ func (*connectedEndpoint) Release() {} // unix domain socket Endpoint implementations. // // Not to be used on its own. -// -// +stateify savable type baseEndpoint struct { *waiter.Queue diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 5e611c54f..8256acdb4 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,13 +1,28 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") + +go_stateify( + name = "waiter_state", + srcs = [ + "waiter.go", + ], + out = "waiter_state.go", + package = "waiter", +) go_library( name = "waiter", - srcs = ["waiter.go"], + srcs = [ + "waiter.go", + "waiter_state.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/waiter", visibility = ["//visibility:public"], - deps = ["//pkg/ilist"], + deps = [ + "//pkg/ilist", + "//pkg/state", + ], ) go_test( diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 9825880ca..9b189bb9e 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -157,8 +157,6 @@ func NewChannelEntry(c chan struct{}) (Entry, chan struct{}) { // notifiers can notify them when events happen. // // The zero value for waiter.Queue is an empty queue ready for use. -// -// +stateify savable type Queue struct { list ilist.List `state:"zerovalue"` mu sync.RWMutex `state:"nosave"` -- cgit v1.2.3 From 57d0fcbdbf7e9d2d573ce8d4ca2f72b82f778d63 Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Thu, 2 Aug 2018 10:41:44 -0700 Subject: Automated rollback of changelist 207037226 PiperOrigin-RevId: 207125440 Change-Id: I6c572afb4d693ee72a0c458a988b0e96d191cd49 --- pkg/abi/BUILD | 13 +----- pkg/abi/linux/BUILD | 16 +------ pkg/abi/linux/bpf.go | 2 + pkg/abi/linux/tty.go | 2 + pkg/bpf/BUILD | 17 +------- pkg/bpf/interpreter.go | 2 + pkg/cpuid/BUILD | 15 +------ pkg/cpuid/cpuid.go | 2 + pkg/ilist/BUILD | 15 +------ pkg/ilist/list.go | 4 ++ pkg/segment/range.go | 2 + pkg/segment/set.go | 5 +++ pkg/sentry/arch/BUILD | 18 +------- pkg/sentry/arch/arch.go | 2 + pkg/sentry/arch/arch_amd64.go | 2 + pkg/sentry/arch/arch_state_x86.go | 1 + pkg/sentry/arch/arch_x86.go | 2 + pkg/sentry/arch/auxv.go | 2 + pkg/sentry/arch/signal_amd64.go | 6 +++ pkg/sentry/context/contexttest/BUILD | 17 +------- pkg/sentry/fs/BUILD | 36 +--------------- pkg/sentry/fs/ashmem/BUILD | 17 +------- pkg/sentry/fs/ashmem/area.go | 8 ++-- pkg/sentry/fs/ashmem/device.go | 22 +++++----- pkg/sentry/fs/ashmem/pin_board.go | 2 + pkg/sentry/fs/attr.go | 12 ++++++ pkg/sentry/fs/binder/BUILD | 13 +----- pkg/sentry/fs/binder/binder.go | 26 ++++++----- pkg/sentry/fs/dentry.go | 4 ++ pkg/sentry/fs/dev/BUILD | 20 +-------- pkg/sentry/fs/dev/dev.go | 2 + pkg/sentry/fs/dev/fs.go | 2 + pkg/sentry/fs/dev/full.go | 2 + pkg/sentry/fs/dev/null.go | 3 ++ pkg/sentry/fs/dev/random.go | 1 + pkg/sentry/fs/dirent.go | 2 + pkg/sentry/fs/dirent_cache.go | 2 + pkg/sentry/fs/fdpipe/BUILD | 31 +------------ pkg/sentry/fs/fdpipe/pipe.go | 2 + pkg/sentry/fs/file.go | 2 + pkg/sentry/fs/file_overlay.go | 4 ++ pkg/sentry/fs/filesystems.go | 2 + pkg/sentry/fs/filetest/BUILD | 18 +------- pkg/sentry/fs/flags.go | 2 + pkg/sentry/fs/fsutil/BUILD | 20 +-------- pkg/sentry/fs/fsutil/dirty_set.go | 2 + pkg/sentry/fs/fsutil/handle.go | 2 + pkg/sentry/fs/fsutil/host_file_mapper.go | 2 + pkg/sentry/fs/fsutil/inode.go | 6 +++ pkg/sentry/fs/fsutil/inode_cached.go | 2 + pkg/sentry/fs/gofer/BUILD | 23 +--------- pkg/sentry/fs/gofer/file.go | 2 + pkg/sentry/fs/gofer/fs.go | 2 + pkg/sentry/fs/gofer/inode.go | 4 ++ pkg/sentry/fs/gofer/session.go | 3 ++ pkg/sentry/fs/host/BUILD | 27 +----------- pkg/sentry/fs/host/descriptor.go | 2 + pkg/sentry/fs/host/file.go | 2 + pkg/sentry/fs/host/fs.go | 6 ++- pkg/sentry/fs/host/inode.go | 4 ++ pkg/sentry/fs/host/socket.go | 2 + pkg/sentry/fs/inode.go | 4 ++ pkg/sentry/fs/inode_inotify.go | 2 + pkg/sentry/fs/inotify.go | 2 + pkg/sentry/fs/inotify_event.go | 2 + pkg/sentry/fs/inotify_watch.go | 2 + pkg/sentry/fs/lock/BUILD | 15 +------ pkg/sentry/fs/lock/lock.go | 6 ++- pkg/sentry/fs/mount.go | 4 ++ pkg/sentry/fs/mount_overlay.go | 4 ++ pkg/sentry/fs/mounts.go | 2 + pkg/sentry/fs/overlay.go | 2 + pkg/sentry/fs/proc/BUILD | 34 +-------------- pkg/sentry/fs/proc/cpuinfo.go | 2 + pkg/sentry/fs/proc/exec_args.go | 2 + pkg/sentry/fs/proc/fds.go | 6 +++ pkg/sentry/fs/proc/file.go | 1 + pkg/sentry/fs/proc/filesystems.go | 2 + pkg/sentry/fs/proc/fs.go | 2 + pkg/sentry/fs/proc/loadavg.go | 2 + pkg/sentry/fs/proc/meminfo.go | 2 + pkg/sentry/fs/proc/mounts.go | 4 ++ pkg/sentry/fs/proc/proc.go | 4 ++ pkg/sentry/fs/proc/seqfile/BUILD | 30 ++----------- pkg/sentry/fs/proc/seqfile/seqfile.go | 4 ++ pkg/sentry/fs/proc/stat.go | 2 + pkg/sentry/fs/proc/sys.go | 5 +++ pkg/sentry/fs/proc/sys_net.go | 2 + pkg/sentry/fs/proc/task.go | 20 +++++++++ pkg/sentry/fs/proc/uid_gid_map.go | 3 ++ pkg/sentry/fs/proc/uptime.go | 2 + pkg/sentry/fs/proc/version.go | 2 + pkg/sentry/fs/ramfs/BUILD | 21 +-------- pkg/sentry/fs/ramfs/dir.go | 2 + pkg/sentry/fs/ramfs/ramfs.go | 2 + pkg/sentry/fs/ramfs/socket.go | 2 + pkg/sentry/fs/ramfs/symlink.go | 2 + pkg/sentry/fs/ramfs/test/BUILD | 18 +------- pkg/sentry/fs/sys/BUILD | 14 +----- pkg/sentry/fs/sys/fs.go | 2 + pkg/sentry/fs/sys/sys.go | 5 ++- pkg/sentry/fs/timerfd/BUILD | 18 +------- pkg/sentry/fs/timerfd/timerfd.go | 4 +- pkg/sentry/fs/tmpfs/BUILD | 17 +------- pkg/sentry/fs/tmpfs/file_regular.go | 2 + pkg/sentry/fs/tmpfs/fs.go | 2 + pkg/sentry/fs/tmpfs/inode_file.go | 2 + pkg/sentry/fs/tmpfs/tmpfs.go | 8 ++++ pkg/sentry/fs/tty/BUILD | 20 +-------- pkg/sentry/fs/tty/dir.go | 18 +++++--- pkg/sentry/fs/tty/fs.go | 4 ++ pkg/sentry/fs/tty/inode.go | 2 + pkg/sentry/fs/tty/line_discipline.go | 6 +++ pkg/sentry/fs/tty/master.go | 4 ++ pkg/sentry/fs/tty/queue.go | 4 +- pkg/sentry/fs/tty/slave.go | 4 ++ pkg/sentry/fs/tty/terminal.go | 2 + pkg/sentry/inet/BUILD | 15 +------ pkg/sentry/inet/inet.go | 2 + pkg/sentry/kernel/BUILD | 60 +++----------------------- pkg/sentry/kernel/abstract_socket_namespace.go | 3 ++ pkg/sentry/kernel/auth/BUILD | 17 +------- pkg/sentry/kernel/auth/credentials.go | 2 + pkg/sentry/kernel/auth/id_map.go | 2 + pkg/sentry/kernel/auth/user_namespace.go | 2 + pkg/sentry/kernel/epoll/BUILD | 15 +------ pkg/sentry/kernel/epoll/epoll.go | 8 +++- pkg/sentry/kernel/eventfd/BUILD | 18 +------- pkg/sentry/kernel/eventfd/eventfd.go | 4 +- pkg/sentry/kernel/fd_map.go | 6 +++ pkg/sentry/kernel/fs_context.go | 2 + pkg/sentry/kernel/futex/BUILD | 18 +------- pkg/sentry/kernel/futex/futex.go | 2 + pkg/sentry/kernel/ipc_namespace.go | 2 + pkg/sentry/kernel/kernel.go | 4 +- pkg/sentry/kernel/pending_signals.go | 5 +++ pkg/sentry/kernel/pipe/BUILD | 20 +-------- pkg/sentry/kernel/pipe/buffers.go | 2 + pkg/sentry/kernel/pipe/node.go | 2 + pkg/sentry/kernel/pipe/pipe.go | 2 + pkg/sentry/kernel/pipe/reader.go | 2 + pkg/sentry/kernel/pipe/reader_writer.go | 2 + pkg/sentry/kernel/pipe/writer.go | 2 + pkg/sentry/kernel/ptrace.go | 4 ++ pkg/sentry/kernel/rseq.go | 2 + pkg/sentry/kernel/semaphore/BUILD | 15 +------ pkg/sentry/kernel/semaphore/semaphore.go | 8 ++++ pkg/sentry/kernel/sessions.go | 4 ++ pkg/sentry/kernel/shm/BUILD | 13 +----- pkg/sentry/kernel/shm/shm.go | 4 ++ pkg/sentry/kernel/signal_handlers.go | 2 + pkg/sentry/kernel/syscalls.go | 2 + pkg/sentry/kernel/syslog.go | 2 + pkg/sentry/kernel/task.go | 2 + pkg/sentry/kernel/task_clone.go | 4 ++ pkg/sentry/kernel/task_context.go | 2 + pkg/sentry/kernel/task_exec.go | 4 ++ pkg/sentry/kernel/task_exit.go | 6 +++ pkg/sentry/kernel/task_resources.go | 2 + pkg/sentry/kernel/task_run.go | 2 + pkg/sentry/kernel/task_sched.go | 2 + pkg/sentry/kernel/task_signals.go | 5 +++ pkg/sentry/kernel/task_syscall.go | 4 ++ pkg/sentry/kernel/thread_group.go | 2 + pkg/sentry/kernel/threads.go | 8 ++++ pkg/sentry/kernel/time/BUILD | 14 +----- pkg/sentry/kernel/time/time.go | 6 +++ pkg/sentry/kernel/timekeeper.go | 2 + pkg/sentry/kernel/timer.go | 8 ++++ pkg/sentry/kernel/uts_namespace.go | 2 + pkg/sentry/kernel/vdso.go | 2 + pkg/sentry/limits/BUILD | 13 +----- pkg/sentry/limits/limits.go | 4 ++ pkg/sentry/loader/BUILD | 15 +------ pkg/sentry/loader/vdso.go | 2 + pkg/sentry/loader/vdso_state.go | 1 + pkg/sentry/memmap/BUILD | 15 +------ pkg/sentry/memmap/mapping_set.go | 2 + pkg/sentry/mm/BUILD | 21 +-------- pkg/sentry/mm/aio_context.go | 8 ++++ pkg/sentry/mm/mm.go | 7 +++ pkg/sentry/mm/special_mappable.go | 2 + pkg/sentry/platform/BUILD | 13 +----- pkg/sentry/platform/filemem/BUILD | 14 +----- pkg/sentry/platform/filemem/filemem.go | 2 + pkg/sentry/socket/BUILD | 17 +------- pkg/sentry/socket/control/BUILD | 23 +++------- pkg/sentry/socket/control/control.go | 4 ++ pkg/sentry/socket/epsocket/BUILD | 16 +------ pkg/sentry/socket/epsocket/epsocket.go | 2 + pkg/sentry/socket/epsocket/stack.go | 2 + pkg/sentry/socket/hostinet/BUILD | 15 +------ pkg/sentry/socket/netlink/BUILD | 13 +----- pkg/sentry/socket/netlink/port/BUILD | 15 +------ pkg/sentry/socket/netlink/port/port.go | 2 + pkg/sentry/socket/netlink/route/BUILD | 17 +------- pkg/sentry/socket/netlink/route/protocol.go | 2 + pkg/sentry/socket/netlink/socket.go | 2 + pkg/sentry/socket/socket.go | 2 + pkg/sentry/socket/unix/BUILD | 13 +----- pkg/sentry/socket/unix/unix.go | 2 + pkg/sentry/syscalls/linux/BUILD | 20 +-------- pkg/sentry/syscalls/linux/sys_aio.go | 2 + pkg/sentry/syscalls/linux/sys_futex.go | 2 + pkg/sentry/syscalls/linux/sys_poll.go | 2 + pkg/sentry/syscalls/linux/sys_time.go | 2 + pkg/sentry/usage/BUILD | 17 +------- pkg/sentry/usage/cpu.go | 2 + pkg/sentry/usage/io.go | 2 + pkg/sentry/usermem/BUILD | 16 +------ pkg/sentry/usermem/access_type.go | 2 + pkg/sentry/usermem/addr.go | 2 + pkg/tcpip/BUILD | 17 +------- pkg/tcpip/buffer/BUILD | 13 +----- pkg/tcpip/buffer/view.go | 2 + pkg/tcpip/header/BUILD | 13 +----- pkg/tcpip/header/tcp.go | 4 ++ pkg/tcpip/network/fragmentation/BUILD | 11 +---- pkg/tcpip/seqnum/BUILD | 17 +------- pkg/tcpip/tcpip.go | 4 ++ pkg/tcpip/transport/ping/BUILD | 17 +------- pkg/tcpip/transport/ping/endpoint.go | 1 + pkg/tcpip/transport/queue/BUILD | 17 +------- pkg/tcpip/transport/queue/queue.go | 2 + pkg/tcpip/transport/tcp/BUILD | 25 +---------- pkg/tcpip/transport/tcp/endpoint.go | 4 ++ pkg/tcpip/transport/tcp/rcv.go | 2 + pkg/tcpip/transport/tcp/reno.go | 2 + pkg/tcpip/transport/tcp/segment.go | 2 + pkg/tcpip/transport/tcp/segment_queue.go | 2 + pkg/tcpip/transport/tcp/snd.go | 4 ++ pkg/tcpip/transport/tcp/snd_state.go | 1 + pkg/tcpip/transport/udp/BUILD | 17 +------- pkg/tcpip/transport/udp/endpoint.go | 3 ++ pkg/tcpip/transport/unix/BUILD | 16 +------ pkg/tcpip/transport/unix/connectioned.go | 2 + pkg/tcpip/transport/unix/connectionless.go | 2 + pkg/tcpip/transport/unix/unix.go | 11 +++++ pkg/waiter/BUILD | 21 ++------- pkg/waiter/waiter.go | 2 + 240 files changed, 664 insertions(+), 1109 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index f1e6bac67..c014d2c4b 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,24 +1,13 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "abi_state", - srcs = [ - "abi.go", - ], - out = "abi_state.go", - package = "abi", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "abi", srcs = [ "abi.go", - "abi_state.go", "flag.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/abi", visibility = ["//:sandbox"], - deps = ["//pkg/state"], ) diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 38b4829c9..ac4ceefbc 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -4,19 +4,7 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "linux_state", - srcs = [ - "binder.go", - "bpf.go", - "time.go", - "tty.go", - ], - out = "linux_state.go", - package = "linux", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "linux", @@ -41,7 +29,6 @@ go_library( "ipc.go", "limits.go", "linux.go", - "linux_state.go", "mm.go", "netdevice.go", "netlink.go", @@ -67,6 +54,5 @@ go_library( "//pkg/abi", "//pkg/binary", "//pkg/bits", - "//pkg/state", ], ) diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index f597ef4f5..80e5b1af1 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -15,6 +15,8 @@ package linux // BPFInstruction is a raw BPF virtual machine instruction. +// +// +stateify savable type BPFInstruction struct { // OpCode is the operation to execute. OpCode uint16 diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index 84b6ccc87..b640f7627 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -38,6 +38,8 @@ type Termios struct { // KernelTermios is struct ktermios/struct termios2, defined in // uapi/asm-generic/termbits.h. +// +// +stateify savable type KernelTermios struct { InputFlags uint32 OutputFlags uint32 diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index 403270049..564df3af5 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,21 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "bpf_state", - srcs = [ - "interpreter.go", - ], - out = "bpf_state.go", - package = "bpf", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "bpf", srcs = [ "bpf.go", - "bpf_state.go", "decoder.go", "input_bytes.go", "interpreter.go", @@ -23,10 +13,7 @@ go_library( ], importpath = "gvisor.googlesource.com/gvisor/pkg/bpf", visibility = ["//visibility:public"], - deps = [ - "//pkg/abi/linux", - "//pkg/state", - ], + deps = ["//pkg/abi/linux"], ) go_test( diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index b7dee86a8..111ada9d1 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -88,6 +88,8 @@ func (e Error) Error() string { } // Program is a BPF program that has been validated for consistency. +// +// +stateify savable type Program struct { instructions []linux.BPFInstruction } diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index 9a0ca1b33..46fc4703b 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,27 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "cpuid_state", - srcs = ["cpuid.go"], - out = "cpuid_state.go", - package = "cpuid", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "cpuid", srcs = [ "cpu_amd64.s", "cpuid.go", - "cpuid_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/cpuid", visibility = ["//:sandbox"], - deps = [ - "//pkg/log", - "//pkg/state", - ], + deps = ["//pkg/log"], ) go_test( diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index b486ab037..e91e34dc7 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -409,6 +409,8 @@ func (f Feature) flagString(cpuinfoOnly bool) string { } // FeatureSet is a set of Features for a cpu. +// +// +stateify savable type FeatureSet struct { // Set is the set of features that are enabled in this FeatureSet. Set map[Feature]bool diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index e32f26ffa..b26a39132 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,28 +1,15 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "list_state", - srcs = [ - "interface_list.go", - ], - out = "interface_list_state.go", - package = "ilist", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ilist", srcs = [ "interface_list.go", - "interface_list_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/ilist", visibility = ["//visibility:public"], - deps = [ - "//pkg/state", - ], ) go_template_instance( diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 5efb6c072..a88b82196 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -36,6 +36,8 @@ type Linker interface { // for e := l.Front(); e != nil; e = e.Next() { // // do something with e. // } +// +// +stateify savable type List struct { head Linker tail Linker @@ -155,6 +157,8 @@ func (l *List) Remove(e Linker) { // Entry is a default implementation of Linker. Users can add anonymous fields // of this type to their structs to make them automatically implement the // methods needed by List. +// +// +stateify savable type Entry struct { next Linker prev Linker diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 5ff30d489..34c067265 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -18,6 +18,8 @@ package segment type T uint64 // A Range represents a contiguous range of T. +// +// +stateify savable type Range struct { // Start is the inclusive start of the range. Start T diff --git a/pkg/segment/set.go b/pkg/segment/set.go index 6eed1d930..cffec2a2c 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -88,6 +88,8 @@ const ( // A Set is a mapping of segments with non-overlapping Range keys. The zero // value for a Set is an empty set. Set values are not safely movable nor // copyable. Set is thread-compatible. +// +// +stateify savable type Set struct { root node `state:".(*SegmentDataSlices)"` } @@ -596,6 +598,7 @@ func (s *Set) ApplyContiguous(r Range, fn func(seg Iterator)) GapIterator { } } +// +stateify savable type node struct { // An internal binary tree node looks like: // @@ -1317,6 +1320,8 @@ func (n *node) writeDebugString(buf *bytes.Buffer, prefix string) { // SegmentDataSlices represents segments from a set as slices of start, end, and // values. SegmentDataSlices is primarily used as an intermediate representation // for save/restore and the layout here is optimized for that. +// +// +stateify savable type SegmentDataSlices struct { Start []Key End []Key diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index 0a2a35400..314b3e962 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,21 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "arch_state", - srcs = [ - "arch.go", - "arch_amd64.go", - "arch_state_x86.go", - "arch_x86.go", - "auxv.go", - "signal_amd64.go", - ], - out = "arch_state.go", - package = "arch", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "arch", @@ -24,7 +10,6 @@ go_library( "arch.go", "arch_amd64.go", "arch_amd64.s", - "arch_state.go", "arch_state_x86.go", "arch_x86.go", "auxv.go", @@ -46,7 +31,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/limits", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 0189e958d..21cb84502 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -254,6 +254,8 @@ const ( // MemoryManager. // // Note that "highest address" below is always exclusive. +// +// +stateify savable type MmapLayout struct { // MinAddr is the lowest mappable address. MinAddr usermem.Addr diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 23526fe8e..f1e408af9 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -95,6 +95,8 @@ const ( ) // context64 represents an AMD64 context. +// +// +stateify savable type context64 struct { State sigFPState []x86FPState // fpstate to be restored on sigreturn. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index cb38d098a..e9c23a06b 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -56,6 +56,7 @@ func (s *State) afterLoad() { copy(s.x86FPState, old) } +// +stateify savable type syscallPtraceRegs struct { R15 uint64 R14 uint64 diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index 5cc4f8377..b35eec53c 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -153,6 +153,8 @@ func NewFloatingPointData() *FloatingPointData { // State contains the common architecture bits for X86 (the build tag of this // file ensures it's only built on x86). +// +// +stateify savable type State struct { // The system registers. Regs syscall.PtraceRegs `state:".(syscallPtraceRegs)"` diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 70e0e35b7..81cfb4a01 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -19,6 +19,8 @@ import ( ) // An AuxEntry represents an entry in an ELF auxiliary vector. +// +// +stateify savable type AuxEntry struct { Key uint64 Value usermem.Addr diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index c1d743f38..e81717e8b 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -28,6 +28,8 @@ import ( // SignalAct represents the action that should be taken when a signal is // delivered, and is equivalent to struct sigaction on 64-bit x86. +// +// +stateify savable type SignalAct struct { Handler uint64 Flags uint64 @@ -47,6 +49,8 @@ func (s *SignalAct) DeserializeTo(other *SignalAct) { // SignalStack represents information about a user stack, and is equivalent to // stack_t on 64-bit x86. +// +// +stateify savable type SignalStack struct { Addr uint64 Flags uint32 @@ -66,6 +70,8 @@ func (s *SignalStack) DeserializeTo(other *SignalStack) { // SignalInfo represents information about a signal being delivered, and is // equivalent to struct siginfo on 64-bit x86. +// +// +stateify savable type SignalInfo struct { Signo int32 // Signal number Errno int32 // Errno value diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 591b11a4d..01bb40b04 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,23 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "contexttest_state", - srcs = [ - "contexttest.go", - ], - out = "contexttest_state.go", - package = "contexttest", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "contexttest", testonly = 1, - srcs = [ - "contexttest.go", - "contexttest_state.go", - ], + srcs = ["contexttest.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest", visibility = ["//pkg/sentry:internal"], deps = [ @@ -28,6 +16,5 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/platform/ptrace", "//pkg/sentry/uniqueid", - "//pkg/state", ], ) diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index e3c9a9b70..18cd5ae8e 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,40 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "fs_state", - srcs = [ - "attr.go", - "dentry.go", - "dirent.go", - "dirent_cache.go", - "dirent_list.go", - "dirent_state.go", - "file.go", - "file_overlay.go", - "file_state.go", - "filesystems.go", - "flags.go", - "inode.go", - "inode_inotify.go", - "inode_operations.go", - "inode_overlay.go", - "inotify.go", - "inotify_event.go", - "inotify_watch.go", - "mock.go", - "mount.go", - "mount_overlay.go", - "mount_state.go", - "mounts.go", - "overlay.go", - "path.go", - ], - out = "fs_state.go", - package = "fs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fs", @@ -54,7 +21,6 @@ go_library( "filesystems.go", "flags.go", "fs.go", - "fs_state.go", "inode.go", "inode_inotify.go", "inode_operations.go", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index 9f166799a..dc893d22f 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,26 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") -go_stateify( - name = "ashmem_state", - srcs = [ - "area.go", - "device.go", - "pin_board.go", - "uint64_range.go", - "uint64_set.go", - ], - out = "ashmem_state.go", - package = "ashmem", -) - go_library( name = "ashmem", srcs = [ "area.go", - "ashmem_state.go", "device.go", "pin_board.go", "uint64_range.go", @@ -41,7 +27,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", ], diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index e4f76f0d0..bfd7f2762 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -39,10 +39,12 @@ const ( ) // Area implements fs.FileOperations. +// +// +stateify savable type Area struct { - fsutil.NoFsync - fsutil.DeprecatedFileOperations - fsutil.NotDirReaddir + fsutil.NoFsync `state:"nosave"` + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.NotDirReaddir `state:"nosave"` ad *Device diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index c5b51d4a7..d0986fa11 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -27,17 +27,19 @@ import ( ) // Device implements fs.InodeOperations. +// +// +stateify savable type Device struct { - fsutil.DeprecatedFileOperations - fsutil.InodeNoExtendedAttributes - fsutil.InodeNotDirectory - fsutil.InodeNotRenameable - fsutil.InodeNotSocket - fsutil.InodeNotSymlink - fsutil.NoFsync - fsutil.NoMappable - fsutil.NoopWriteOut - fsutil.NotDirReaddir + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.NoFsync `state:"nosave"` + fsutil.NoMappable `state:"nosave"` + fsutil.NoopWriteOut `state:"nosave"` + fsutil.NotDirReaddir `state:"nosave"` mu sync.Mutex `state:"nosave"` unstable fs.UnstableAttr diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index c7fb3822c..ecba395a0 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -56,6 +56,8 @@ func (setFunctions) Split(Range, noValue, uint64) (noValue, noValue) { // segment.Set is used for implementation where segments represent // ranges of pinned bytes, while gaps represent ranges of unpinned // bytes. All ranges are page-aligned. +// +// +stateify savable type PinBoard struct { Set } diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 56a2ad6f7..4178f18b2 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -91,6 +91,8 @@ func (n InodeType) String() string { // StableAttr contains Inode attributes that will be stable throughout the // lifetime of the Inode. +// +// +stateify savable type StableAttr struct { // Type is the InodeType of a InodeOperations. Type InodeType @@ -150,6 +152,8 @@ func IsCharDevice(s StableAttr) bool { // UnstableAttr contains Inode attributes that may change over the lifetime // of the Inode. +// +// +stateify savable type UnstableAttr struct { // Size is the file size in bytes. Size int64 @@ -186,6 +190,8 @@ func WithCurrentTime(ctx context.Context, u UnstableAttr) UnstableAttr { } // AttrMask contains fields to mask StableAttr and UnstableAttr. +// +// +stateify savable type AttrMask struct { Type bool DeviceID bool @@ -227,6 +233,8 @@ func (a AttrMask) Union(b AttrMask) AttrMask { } // PermMask are file access permissions. +// +// +stateify savable type PermMask struct { // Read indicates reading is permitted. Read bool @@ -280,6 +288,8 @@ func (p PermMask) SupersetOf(other PermMask) bool { // FilePermissions represents the permissions of a file, with // Read/Write/Execute bits for user, group, and other. +// +// +stateify savable type FilePermissions struct { User PermMask Group PermMask @@ -370,6 +380,8 @@ func (f FilePermissions) AnyRead() bool { } // FileOwner represents ownership of a file. +// +// +stateify savable type FileOwner struct { UID auth.KUID GID auth.KGID diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index ec3928baf..a077b91d2 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,25 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "binder_state", - srcs = ["binder.go"], - out = "binder_state.go", - package = "binder", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "binder", srcs = [ "binder.go", - "binder_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/binder", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -30,8 +21,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", - "//pkg/tcpip/transport/unix", ], ) diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index 3f87b6b08..502a262dd 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -40,15 +40,17 @@ const ( ) // Device implements fs.InodeOperations. +// +// +stateify savable type Device struct { - fsutil.InodeNoExtendedAttributes - fsutil.InodeNotDirectory - fsutil.InodeNotRenameable - fsutil.InodeNotSocket - fsutil.InodeNotSymlink - fsutil.NoMappable - fsutil.NoopWriteOut - fsutil.DeprecatedFileOperations + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.NoMappable `state:"nosave"` + fsutil.NoopWriteOut `state:"nosave"` + fsutil.DeprecatedFileOperations `state:"nosave"` // mu protects unstable. mu sync.Mutex `state:"nosave"` @@ -186,10 +188,12 @@ func (bd *Device) StatFS(context.Context) (fs.Info, error) { } // Proc implements fs.FileOperations and fs.IoctlGetter. +// +// +stateify savable type Proc struct { - fsutil.NoFsync - fsutil.DeprecatedFileOperations - fsutil.NotDirReaddir + fsutil.NoFsync `state:"nosave"` + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.NotDirReaddir `state:"nosave"` bd *Device task *kernel.Task diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index d42e8da81..b347468ff 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -21,6 +21,8 @@ import ( ) // DentAttr is the metadata of a directory entry. It is a subset of StableAttr. +// +// +stateify savable type DentAttr struct { // Type is the InodeType of an Inode. Type InodeType @@ -154,6 +156,8 @@ func GenericReaddir(ctx *DirCtx, s *SortedDentryMap) (int, error) { } // SortedDentryMap is a sorted map of names and fs.DentAttr entries. +// +// +stateify savable type SortedDentryMap struct { // names is always kept in sorted-order. names []string diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index ea41615fd..fc069bb5f 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,25 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "dev_state", - srcs = [ - "dev.go", - "fs.go", - "full.go", - "null.go", - "random.go", - ], - out = "dev_state.go", - package = "dev", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "dev", srcs = [ "dev.go", - "dev_state.go", "device.go", "fs.go", "full.go", @@ -30,8 +16,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", - "//pkg/log", "//pkg/rand", "//pkg/sentry/context", "//pkg/sentry/device", @@ -45,9 +29,7 @@ go_library( "//pkg/sentry/mm", "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index 36c61bfc2..3f4f2a40a 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -27,6 +27,8 @@ import ( ) // Dev is the root node. +// +// +stateify savable type Dev struct { ramfs.Dir } diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index 3c79f3782..2ae49be4e 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -29,6 +29,8 @@ const binderEnabledKey = "binder_enabled" const ashmemEnabledKey = "ashmem_enabled" // filesystem is a devtmpfs. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index e13eb6c03..492b8eb3a 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -26,6 +26,8 @@ import ( ) // fullDevice is used to implement /dev/full. +// +// +stateify savable type fullDevice struct { ramfs.Entry } diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 66b8ba967..2977c8670 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -29,6 +29,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// +stateify savable type nullDevice struct { ramfs.Entry } @@ -54,6 +55,7 @@ func (n *nullDevice) Truncate(context.Context, *fs.Inode, int64) error { return nil } +// +stateify savable type zeroDevice struct { nullDevice } @@ -80,6 +82,7 @@ func (zd *zeroDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.F }), nil } +// +stateify savable type zeroFileOperations struct { fs.FileOperations } diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index 33a045a05..47b76218f 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -24,6 +24,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// +stateify savable type randomDevice struct { ramfs.Entry } diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index f9bf2fba6..4658d044f 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -81,6 +81,8 @@ var renameMu sync.RWMutex // // Dirents currently do not attempt to free entries that lack application references under // memory pressure. +// +// +stateify savable type Dirent struct { // AtomicRefCount is our reference count. refs.AtomicRefCount diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index e786e4f65..c680e4828 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -25,6 +25,8 @@ import ( // // A nil DirentCache corresponds to a cache with size 0. All methods can be // called, but nothing is actually cached. +// +// +stateify savable type DirentCache struct { // Maximum size of the cache. This must be saved manually, to handle the case // when cache is nil. diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 4fcb06f1f..ffe4204bc 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,54 +1,27 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "pipe_state", - srcs = [ - "pipe.go", - "pipe_state.go", - ], - out = "pipe_autogen_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], - package = "fdpipe", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "fdpipe", srcs = [ "pipe.go", - "pipe_autogen_state.go", "pipe_opener.go", "pipe_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fdpipe", + imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/abi/linux", - "//pkg/amutex", "//pkg/fd", "//pkg/log", - "//pkg/metric", - "//pkg/p9", - "//pkg/refs", "//pkg/secio", "//pkg/sentry/context", - "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", - "//pkg/sentry/fs/lock", - "//pkg/sentry/kernel/auth", - "//pkg/sentry/kernel/time", - "//pkg/sentry/memmap", - "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", - "//pkg/tcpip", - "//pkg/tcpip/transport/unix", - "//pkg/unet", "//pkg/waiter", "//pkg/waiter/fdnotifier", ], diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 7b318e35f..2e34604e6 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -34,6 +34,8 @@ import ( ) // pipeOperations are the fs.FileOperations of a host pipe. +// +// +stateify savable type pipeOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 6d93ef760..8e535a618 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -47,6 +47,8 @@ const FileMaxOffset = math.MaxInt64 // and write(2). // // FIXME: Split synchronization from cancellation. +// +// +stateify savable type File struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 36b2cf75e..113962368 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -60,6 +60,8 @@ func overlayFile(ctx context.Context, inode *Inode, flags FileFlags) (*File, err } // overlayFileOperations implements FileOperations for a file in an overlay. +// +// +stateify savable type overlayFileOperations struct { // upperMu protects upper below. In contrast lower is stable. upperMu sync.Mutex `state:"nosave"` @@ -375,6 +377,8 @@ func readdirOne(ctx context.Context, d *Dirent) (map[string]DentAttr, error) { // overlayMappingIdentity wraps a MappingIdentity, and also holds a reference // on a file during its lifetime. +// +// +stateify savable type overlayMappingIdentity struct { refs.AtomicRefCount id memmap.MappingIdentity diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index 200e792f4..5a1e7a270 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -125,6 +125,8 @@ func GetFilesystems() []Filesystem { } // MountSourceFlags represents all mount option flags as a struct. +// +// +stateify savable type MountSourceFlags struct { // ReadOnly corresponds to mount(2)'s "MS_RDONLY" and indicates that // the filesystem should be mounted read-only. diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index f481c57fb..d137fee4c 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,34 +1,20 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "filetest_state", - srcs = [ - "filetest.go", - ], - out = "filetest_state.go", - package = "filetest", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "filetest", testonly = 1, - srcs = [ - "filetest.go", - "filetest_state.go", - ], + srcs = ["filetest.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/filetest", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index da0ff58af..1aa271560 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -19,6 +19,8 @@ import ( ) // FileFlags encodes file flags. +// +// +stateify savable type FileFlags struct { // Direct indicates that I/O should be done directly. Direct bool diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 6eea64298..3512bae6f 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,24 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "fsutil_state", - srcs = [ - "dirty_set_impl.go", - "file.go", - "file_range_set_impl.go", - "frame_ref_set_impl.go", - "handle.go", - "host_file_mapper.go", - "host_file_mapper_state.go", - "inode.go", - "inode_cached.go", - ], - out = "fsutil_state.go", - package = "fsutil", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "dirty_set_impl", @@ -84,7 +67,6 @@ go_library( "frame_ref_set.go", "frame_ref_set_impl.go", "fsutil.go", - "fsutil_state.go", "handle.go", "host_file_mapper.go", "host_file_mapper_state.go", diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 9c6c98542..8e31e48fd 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -32,6 +32,8 @@ import ( // DirtyInfo is the value type of DirtySet, and represents information about a // Mappable offset that is dirty (the cached data for that offset is newer than // its source). +// +// +stateify savable type DirtyInfo struct { // Keep is true if the represented offset is concurrently writable, such // that writing the data for that offset back to the source does not diff --git a/pkg/sentry/fs/fsutil/handle.go b/pkg/sentry/fs/fsutil/handle.go index 149c0f84a..e7efd3c0f 100644 --- a/pkg/sentry/fs/fsutil/handle.go +++ b/pkg/sentry/fs/fsutil/handle.go @@ -27,6 +27,8 @@ import ( // // FIXME: Remove Handle entirely in favor of individual fs.File // implementations using simple generic utilities. +// +// +stateify savable type Handle struct { NoopRelease `state:"nosave"` NoIoctl `state:"nosave"` diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index d0a27fc1c..9c1e2f76f 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -29,6 +29,8 @@ import ( // HostFileMapper caches mappings of an arbitrary host file descriptor. It is // used by implementations of memmap.Mappable that represent a host file // descriptor. +// +// +stateify savable type HostFileMapper struct { // HostFile conceptually breaks the file into pieces called chunks, of // size and alignment chunkSize, and caches mappings of the file on a chunk diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index e1ad07df2..177396fdc 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -31,6 +31,8 @@ func NewSimpleInodeOperations(i InodeSimpleAttributes) fs.InodeOperations { } // simpleInodeOperations is a simple implementation of Inode. +// +// +stateify savable type simpleInodeOperations struct { DeprecatedFileOperations `state:"nosave"` InodeNotDirectory `state:"nosave"` @@ -48,6 +50,8 @@ type simpleInodeOperations struct { // InodeSimpleAttributes implements a subset of the Inode interface. It provides // read-only access to attributes. +// +// +stateify savable type InodeSimpleAttributes struct { // FSType is the filesystem type reported by StatFS. FSType uint64 @@ -110,6 +114,8 @@ func (*InodeSimpleAttributes) Truncate(context.Context, *fs.Inode, int64) error // // Users need not initialize Xattrs to non-nil (it will be initialized // when the first extended attribute is set. +// +// +stateify savable type InMemoryAttributes struct { Unstable fs.UnstableAttr Xattrs map[string][]byte diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index cba642a8f..0a320e2d8 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -55,6 +55,8 @@ import ( // // Implementations of InodeOperations.WriteOut must call Sync to write out // in-memory modifications of data and metadata to the CachedFileObject. +// +// +stateify savable type CachingInodeOperations struct { // backingFile is a handle to a cached file object. backingFile CachedFileObject diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index 1277379e7..cb17339c9 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,21 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "gofer_state", - srcs = [ - "file.go", - "file_state.go", - "fs.go", - "inode.go", - "inode_state.go", - "session.go", - "session_state.go", - ], - out = "gofer_state.go", - package = "gofer", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "gofer", @@ -27,7 +12,6 @@ go_library( "file.go", "file_state.go", "fs.go", - "gofer_state.go", "handles.go", "inode.go", "inode_state.go", @@ -41,7 +25,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", "//pkg/fd", "//pkg/log", "//pkg/metric", @@ -54,15 +37,11 @@ go_library( "//pkg/sentry/fs/fdpipe", "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/host", - "//pkg/sentry/fs/lock", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", - "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 039618808..46a6bbd5d 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -33,6 +33,8 @@ import ( var openedWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.") // fileOperations implements fs.FileOperations for a remote file system. +// +// +stateify savable type fileOperations struct { fsutil.NoIoctl `state:"nosave"` waiter.AlwaysReady `state:"nosave"` diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index dd5d43c47..3ae93f059 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -83,6 +83,8 @@ var ( ) // filesystem is a 9p client. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index df584c382..7fc8f77b0 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -35,6 +35,8 @@ import ( ) // inodeOperations implements fs.InodeOperations. +// +// +stateify savable type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` @@ -68,6 +70,8 @@ type inodeOperations struct { // circular load dependency between it and inodeOperations). Even with // lazy loading, this approach defines the dependencies between objects // and the expected load behavior more concretely. +// +// +stateify savable type inodeFileState struct { // s is common file system state for Gofers. s *session `state:"wait"` diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index b6841526a..648a11435 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -27,6 +27,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/unet" ) +// +stateify savable type endpointMap struct { mu sync.RWMutex `state:"nosave"` // TODO: Make map with private unix sockets savable. @@ -63,6 +64,8 @@ func (e *endpointMap) get(key device.MultiDeviceKey) unix.BoundEndpoint { } // session holds state for each 9p session established during sys_mount. +// +// +stateify savable type session struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 23ec66f50..29c79284a 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,23 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "host_state", - srcs = [ - "control.go", - "descriptor.go", - "descriptor_state.go", - "file.go", - "fs.go", - "inode.go", - "inode_state.go", - "socket.go", - "socket_state.go", - ], - out = "host_state.go", - package = "host", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "host", @@ -28,7 +11,6 @@ go_library( "device.go", "file.go", "fs.go", - "host_state.go", "inode.go", "inode_state.go", "ioctl_unsafe.go", @@ -42,7 +24,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", "//pkg/fd", "//pkg/log", "//pkg/refs", @@ -52,20 +33,14 @@ go_library( "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", - "//pkg/sentry/fs/lock", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", - "//pkg/sentry/platform", "//pkg/sentry/safemem", - "//pkg/sentry/socket", "//pkg/sentry/socket/control", "//pkg/sentry/socket/unix", - "//pkg/sentry/uniqueid", - "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip", "//pkg/tcpip/link/rawfile", diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 613bd06e8..3aee4d11c 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -25,6 +25,8 @@ import ( ) // descriptor wraps a host fd. +// +// +stateify savable type descriptor struct { // donated is true if the host fd was donated by another process. donated bool diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index bdf844337..f9bef6d93 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -37,6 +37,8 @@ import ( ) // fileOperations implements fs.FileOperations for a host file descriptor. +// +// +stateify savable type fileOperations struct { fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index 974700636..e46ae433c 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -51,6 +51,8 @@ const maxTraversals = 10 // to lock down the configurations. This filesystem should only be mounted at root. // // Think twice before exposing this to applications. +// +// +stateify savable type Filesystem struct { // whitelist is a set of host paths to whitelist. paths []string @@ -266,8 +268,10 @@ func newMountSource(ctx context.Context, root string, mounter fs.FileOwner, file } // superOperations implements fs.MountSourceOperations. +// +// +stateify savable type superOperations struct { - fs.SimpleMountSourceOperations `state:"nosave"` + fs.SimpleMountSourceOperations // root is the path of the mount point. All inode mappings // are relative to this root. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 226bc5164..761ccde33 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -34,6 +34,8 @@ import ( // inodeOperations implements fs.InodeOperations for an fs.Inodes backed // by a host file descriptor. +// +// +stateify savable type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` @@ -65,6 +67,8 @@ type inodeOperations struct { // circular load dependency between it and inodeOperations). Even with // lazy loading, this approach defines the dependencies between objects // and the expected load behavior more concretely. +// +// +stateify savable type inodeFileState struct { // Common file system state. mops *superOperations `state:"wait"` diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index f4689f51f..1d93eb1e3 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -34,6 +34,8 @@ import ( ) // endpoint encapsulates the state needed to represent a host Unix socket. +// +// +stateify savable type endpoint struct { queue waiter.Queue `state:"nosave"` diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index 6c8e6f188..d0dbce5dd 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -28,6 +28,8 @@ import ( // Inode is a file system object that can be simultaneously referenced by different // components of the VFS (Dirent, fs.File, etc). +// +// +stateify savable type Inode struct { // AtomicRefCount is our reference count. refs.AtomicRefCount @@ -58,6 +60,8 @@ type Inode struct { // Note that in Linux fcntl(2) and flock(2) locks are _not_ cooperative, because race and // deadlock conditions make merging them prohibitive. We do the same and keep them oblivious // to each other but provide a "context" as a convenient container. +// +// +stateify savable type LockCtx struct { // Posix is a set of POSIX-style regional advisory locks, see fcntl(2). Posix lock.Locks diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index 358bbecdf..683140afe 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -20,6 +20,8 @@ import ( ) // Watches is the collection of inotify watches on an inode. +// +// +stateify savable type Watches struct { // mu protects the fields below. mu sync.RWMutex `state:"nosave"` diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 6f5e8ce5e..2aabdded8 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -34,6 +34,8 @@ import ( // // Lock ordering: // Inotify.mu -> Inode.Watches.mu -> Watch.mu -> Inotify.evMu +// +// +stateify savable type Inotify struct { // Unique identifier for this inotify instance. We don't just reuse the // inotify fd because fds can be duped. These should not be exposed to the diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index 217915ba4..e9b5e0f56 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -28,6 +28,8 @@ import ( const inotifyEventBaseSize = 16 // Event represents a struct inotify_event from linux. +// +// +stateify savable type Event struct { ilist.Entry diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index 8904ef544..3e1959e83 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -27,6 +27,8 @@ import ( // holding an extra ref on each dirent known (by inotify) to point to the // inode. These are known as pins. For a full discussion, see // fs/g3doc/inotify.md. +// +// +stateify savable type Watch struct { // Inotify instance which owns this watch. owner *Inotify diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index 2607d7ed3..3159ff1da 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,18 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "lock_state", - srcs = [ - "lock.go", - "lock_range.go", - "lock_set.go", - ], - out = "lock_state.go", - package = "lock", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "lock_range", @@ -49,13 +38,11 @@ go_library( "lock_range.go", "lock_set.go", "lock_set_functions.go", - "lock_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/lock", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/log", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 24d54c989..e9b376eb6 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -88,6 +88,8 @@ const LockEOF = math.MaxUint64 // // A Lock may be downgraded from a write lock to a read lock only if // the write lock's uid is the same as the read lock. +// +// +stateify savable type Lock struct { // Readers are the set of read lock holders identified by UniqueID. // If len(Readers) > 0 then HasWriter must be false. @@ -103,6 +105,8 @@ type Lock struct { } // Locks is a thread-safe wrapper around a LockSet. +// +// +stateify savable type Locks struct { // mu protects locks below. mu sync.Mutex `state:"nosave"` @@ -111,7 +115,7 @@ type Locks struct { locks LockSet // blockedQueue is the queue of waiters that are waiting on a lock. - blockedQueue waiter.Queue + blockedQueue waiter.Queue `state:"zerovalue"` } // Blocker is the interface used for blocking locks. Passing a nil Blocker diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index eb1897174..4ede767f9 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -101,6 +101,8 @@ func (i InodeMappings) String() string { // (e.g. cannot be mounted at different locations). // // TODO: Move mount-specific information out of MountSource. +// +// +stateify savable type MountSource struct { refs.AtomicRefCount @@ -260,6 +262,8 @@ func NewNonCachingMountSource(filesystem Filesystem, flags MountSourceFlags) *Mo } // SimpleMountSourceOperations implements MountSourceOperations. +// +// +stateify savable type SimpleMountSourceOperations struct { keep bool } diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index 1be81e3a1..d135e8a37 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -18,6 +18,8 @@ import "gvisor.googlesource.com/gvisor/pkg/sentry/context" // overlayMountSourceOperations implements MountSourceOperations for an overlay // mount point. +// +// +stateify savable type overlayMountSourceOperations struct { upper *MountSource lower *MountSource @@ -72,6 +74,8 @@ func (o *overlayMountSourceOperations) Destroy() { } // type overlayFilesystem is the filesystem for overlay mounts. +// +// +stateify savable type overlayFilesystem struct{} // Name implements Filesystem.Name. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index 87da4ee0e..144d3427d 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -32,6 +32,8 @@ import ( const DefaultTraversalLimit = 10 // MountNamespace defines a collection of mounts. +// +// +stateify savable type MountNamespace struct { refs.AtomicRefCount diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index 7357d6401..af13dc8c7 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -145,6 +145,8 @@ func newOverlayInode(ctx context.Context, o *overlayEntry, msrc *MountSource) *I } // overlayEntry is the overlay metadata of an Inode. It implements Mappable. +// +// +stateify savable type overlayEntry struct { // lowerExists is true if an Inode exists for this file in the lower // filesystem. If lowerExists is true, then the overlay must create diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 870df47b2..2d9f07f2f 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,32 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "proc_state", - srcs = [ - "cpuinfo.go", - "exec_args.go", - "fds.go", - "file.go", - "filesystems.go", - "fs.go", - "loadavg.go", - "meminfo.go", - "mounts.go", - "net.go", - "proc.go", - "stat.go", - "sys.go", - "sys_net.go", - "task.go", - "uid_gid_map.go", - "uptime.go", - "version.go", - ], - out = "proc_state.go", - package = "proc", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "proc", @@ -42,7 +16,6 @@ go_library( "mounts.go", "net.go", "proc.go", - "proc_state.go", "rpcinet_proc.go", "stat.go", "sys.go", @@ -56,9 +29,6 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/amutex", - "//pkg/log", - "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/device", @@ -73,8 +43,6 @@ go_library( "//pkg/sentry/socket/rpcinet", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", - "//pkg/syserr", "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index f80aaa5b1..4dfec03a4 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -27,6 +27,8 @@ import ( // cpuinfo is a file describing the CPU capabilities. // // Presently cpuinfo never changes, so it doesn't need to be a SeqFile. +// +// +stateify savable type cpuinfo struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index 0e1523bf1..a69cbaa0e 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -37,6 +37,8 @@ const ( // execArgFile is a file containing the exec args (either cmdline or environ) // for a given task. +// +// +stateify savable type execArgFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index 194a9c12a..cca8f874c 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -138,6 +138,8 @@ func (f *fd) Close() error { } // fdDir implements /proc/TID/fd. +// +// +stateify savable type fdDir struct { ramfs.Dir @@ -197,6 +199,8 @@ func (f *fdDir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset } // fdInfo is a single file in /proc/TID/fdinfo/. +// +// +stateify savable type fdInfo struct { ramfs.File @@ -229,6 +233,8 @@ func (*fdInfo) Truncate(ctx context.Context, inode *fs.Inode, size int64) error // fdInfoDir implements /proc/TID/fdinfo. It embeds an fdDir, but overrides // Lookup and Readdir. +// +// +stateify savable type fdInfoDir struct { ramfs.Dir diff --git a/pkg/sentry/fs/proc/file.go b/pkg/sentry/fs/proc/file.go index 9a433cdf8..4b2d08e75 100644 --- a/pkg/sentry/fs/proc/file.go +++ b/pkg/sentry/fs/proc/file.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// +stateify savable type file struct { fs.InodeOperations diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index 37db9cf9c..49b92fd8a 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -24,6 +24,8 @@ import ( ) // filesystemsData backs /proc/filesystems. +// +// +stateify savable type filesystemsData struct{} // NeedsUpdate returns true on the first generation. The set of registered file diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 3aadd6ac4..061824b8c 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -22,6 +22,8 @@ import ( ) // filesystem is a procfs. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 7583b6ccd..6fac251d2 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -23,6 +23,8 @@ import ( ) // loadavgData backs /proc/loadavg. +// +// +stateify savable type loadavgData struct{} // NeedsUpdate implements seqfile.SeqSource.NeedsUpdate. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 49cb0faed..53dfd59ef 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -26,6 +26,8 @@ import ( ) // meminfoData backs /proc/meminfo. +// +// +stateify savable type meminfoData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index 108432f4e..2b8167c28 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -71,6 +71,8 @@ func forEachMountSource(t *kernel.Task, fn func(string, *fs.MountSource)) { } // mountInfoFile is used to implement /proc/[pid]/mountinfo. +// +// +stateify savable type mountInfoFile struct { t *kernel.Task } @@ -152,6 +154,8 @@ func (mif *mountInfoFile) ReadSeqFileData(ctx context.Context, handle seqfile.Se } // mountsFile is used to implement /proc/[pid]/mountinfo. +// +// +stateify savable type mountsFile struct { t *kernel.Task } diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index b2a8d639c..07029a7bb 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -33,6 +33,8 @@ import ( ) // proc is a root proc node. +// +// +stateify savable type proc struct { ramfs.Dir @@ -47,6 +49,8 @@ type proc struct { // stubProcFSFile is a file type that can be used to return file contents // which are constant. This file is not writable and will always have mode // 0444. +// +// +stateify savable type stubProcFSFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index c84f7e20d..53c475652 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,22 +1,10 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "seqfile_state", - srcs = [ - "seqfile.go", - ], - out = "seqfile_state.go", - package = "seqfile", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "seqfile", - srcs = [ - "seqfile.go", - "seqfile_state.go", - ], + srcs = ["seqfile.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile", visibility = ["//pkg/sentry:internal"], deps = [ @@ -26,26 +14,16 @@ go_library( "//pkg/sentry/fs/ramfs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", ], ) -go_stateify( - name = "seqfile_test_state", - srcs = ["seqfile_test.go"], - out = "seqfile_test_state.go", - package = "seqfile", -) - go_test( name = "seqfile_test", size = "small", - srcs = [ - "seqfile_test.go", - "seqfile_test_state.go", - ], + srcs = ["seqfile_test.go"], embed = [":seqfile"], deps = [ + "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs/test", diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index c08565f8a..51cae5e37 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -30,6 +30,8 @@ import ( type SeqHandle interface{} // SeqData holds the data for one unit in the file. +// +// +stateify savable type SeqData struct { // The data to be returned to the user. Buf []byte @@ -82,6 +84,8 @@ func (s *SeqGenerationCounter) IsCurrent(generation int64) bool { } // SeqFile is used to provide dynamic files that can be ordered by record. +// +// +stateify savable type SeqFile struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index 284f3e52b..bf7650211 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -25,6 +25,8 @@ import ( ) // statData backs /proc/stat. +// +// +stateify savable type statData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index aab891c53..a2d36ca23 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -28,6 +28,8 @@ import ( ) // hostname is a file containing the system hostname. +// +// +stateify savable type hostname struct { ramfs.Entry } @@ -52,6 +54,8 @@ func (p *proc) newHostname(ctx context.Context, msrc *fs.MountSource) *fs.Inode } // mmapMinAddrData backs /proc/sys/vm/mmap_min_addr. +// +// +stateify savable type mmapMinAddrData struct { k *kernel.Kernel } @@ -74,6 +78,7 @@ func (d *mmapMinAddrData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHand }, 0 } +// +stateify savable type overcommitMemory struct{} func (*overcommitMemory) NeedsUpdate(generation int64) bool { diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index f3a5043f8..beb25be20 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -33,6 +33,7 @@ const ( tcpWMem ) +// +stateify savable type tcpMem struct { ramfs.Entry s inet.Stack @@ -100,6 +101,7 @@ func (m *tcpMem) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, return n, cperr } +// +stateify savable type tcpSack struct { ramfs.Entry s inet.Stack diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index efc635946..748ca4320 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -52,6 +52,8 @@ func getTaskMM(t *kernel.Task) (*mm.MemoryManager, error) { } // taskDir represents a task-level directory. +// +// +stateify savable type taskDir struct { ramfs.Dir @@ -92,6 +94,8 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace } // subtasks represents a /proc/TID/task directory. +// +// +stateify savable type subtasks struct { ramfs.Dir @@ -167,6 +171,8 @@ func (s *subtasks) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, off } // exe is an fs.InodeOperations symlink for the /proc/PID/exe file. +// +// +stateify savable type exe struct { ramfs.Symlink @@ -226,6 +232,8 @@ func (e *exe) Readlink(ctx context.Context, inode *fs.Inode) (string, error) { // namespaceFile represents a file in the namespacefs, such as the files in // /proc//ns. +// +// +stateify savable type namespaceFile struct { ramfs.Symlink @@ -274,6 +282,8 @@ func newNamespaceDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { } // mapsData implements seqfile.SeqSource for /proc/[pid]/maps. +// +// +stateify savable type mapsData struct { t *kernel.Task } @@ -311,6 +321,7 @@ func (md *mapsData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([ return []seqfile.SeqData{}, 0 } +// +stateify savable type taskStatData struct { t *kernel.Task @@ -391,6 +402,8 @@ func (s *taskStatData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) } // statmData implements seqfile.SeqSource for /proc/[pid]/statm. +// +// +stateify savable type statmData struct { t *kernel.Task } @@ -425,6 +438,8 @@ func (s *statmData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([ } // statusData implements seqfile.SeqSource for /proc/[pid]/status. +// +// +stateify savable type statusData struct { t *kernel.Task pidns *kernel.PIDNamespace @@ -490,6 +505,7 @@ type ioUsage interface { IOUsage() *usage.IO } +// +stateify savable type ioData struct { ioUsage } @@ -530,6 +546,8 @@ func (i *ioData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se // On Linux, /proc/[pid]/comm is writable, and writing to the comm file changes // the thread name. We don't implement this yet as there are no known users of // this feature. +// +// +stateify savable type comm struct { ramfs.Entry @@ -559,6 +577,8 @@ func (c *comm) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, off } // auxvec is a file containing the auxiliary vector for a task. +// +// +stateify savable type auxvec struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index 85acb5163..9811d9c9d 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -29,6 +29,8 @@ import ( // An idMapSeqSource is a seqfile.SeqSource that returns UID or GID mappings // from a task's user namespace. +// +// +stateify savable type idMapSeqSource struct { t *kernel.Task gids bool @@ -70,6 +72,7 @@ type idMapSeqHandle struct { value int } +// +stateify savable type idMapSeqFile struct { seqfile.SeqFile } diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index 4679d5821..f3a9b81df 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -27,6 +27,8 @@ import ( ) // uptime is a file containing the system uptime. +// +// +stateify savable type uptime struct { ramfs.Entry diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index c0f2e87e3..00f6a2afd 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -23,6 +23,8 @@ import ( ) // versionData backs /proc/version. +// +// +stateify savable type versionData struct { // k is the owning Kernel. k *kernel.Kernel diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index d84f2c624..5230157fe 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,19 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "ramfs_state", - srcs = [ - "dir.go", - "file.go", - "ramfs.go", - "socket.go", - "symlink.go", - ], - out = "ramfs_state.go", - package = "ramfs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "ramfs", @@ -21,7 +8,6 @@ go_library( "dir.go", "file.go", "ramfs.go", - "ramfs_state.go", "socket.go", "symlink.go", "tree.go", @@ -29,12 +15,8 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/amutex", - "//pkg/log", - "//pkg/refs", "//pkg/secio", "//pkg/sentry/context", - "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", @@ -42,7 +24,6 @@ go_library( "//pkg/sentry/memmap", "//pkg/sentry/safemem", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 19d5612ed..04432f28c 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -44,6 +44,8 @@ type CreateOps struct { } // Dir represents a single directory in the filesystem. +// +// +stateify savable type Dir struct { Entry diff --git a/pkg/sentry/fs/ramfs/ramfs.go b/pkg/sentry/fs/ramfs/ramfs.go index d6cfaf753..13e72e775 100644 --- a/pkg/sentry/fs/ramfs/ramfs.go +++ b/pkg/sentry/fs/ramfs/ramfs.go @@ -60,6 +60,8 @@ var ( // Entry represents common internal state for file and directory nodes. // This may be used by other packages to easily create ramfs files. +// +// +stateify savable type Entry struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoMappable `state:"nosave"` diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index b0c79325f..93427a1ff 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -21,6 +21,8 @@ import ( ) // Socket represents a socket. +// +// +stateify savable type Socket struct { Entry diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 9bbf78619..1c54d9991 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -22,6 +22,8 @@ import ( ) // Symlink represents a symlink. +// +// +stateify savable type Symlink struct { Entry diff --git a/pkg/sentry/fs/ramfs/test/BUILD b/pkg/sentry/fs/ramfs/test/BUILD index 57fee45e2..187eac49d 100644 --- a/pkg/sentry/fs/ramfs/test/BUILD +++ b/pkg/sentry/fs/ramfs/test/BUILD @@ -1,30 +1,16 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "test_state", - srcs = [ - "test.go", - ], - out = "test_state.go", - package = "test", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "test", testonly = 1, - srcs = [ - "test.go", - "test_state.go", - ], + srcs = ["test.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/sentry/context", - "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs", - "//pkg/state", ], ) diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 095ff1f25..bc24e980e 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,16 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "sys_state", - srcs = [ - "fs.go", - "sys.go", - ], - out = "sys_state.go", - package = "sys", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "sys", @@ -18,7 +8,6 @@ go_library( "device.go", "fs.go", "sys.go", - "sys_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/sys", visibility = ["//pkg/sentry:internal"], @@ -28,6 +17,5 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/fs/ramfs", "//pkg/sentry/usermem", - "//pkg/state", ], ) diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index c6d5f7fd8..625525540 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -20,6 +20,8 @@ import ( ) // filesystem is a sysfs. +// +// +stateify savable type filesystem struct{} func init() { diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index ccf56f644..b9b2fb4a1 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -22,12 +22,13 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -type Dir struct { +// +stateify savable +type dir struct { ramfs.Dir } func newDir(ctx context.Context, msrc *fs.MountSource, contents map[string]*fs.Inode) *fs.Inode { - d := &Dir{} + d := &dir{} d.InitDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(d, msrc, fs.StableAttr{ DeviceID: sysfsDevice.DeviceID(), diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index 8b1b7872e..ffdd7e0dc 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,33 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "timerfd_state", - srcs = [ - "timerfd.go", - ], - out = "timerfd_state.go", - package = "timerfd", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "timerfd", - srcs = [ - "timerfd.go", - "timerfd_state.go", - ], + srcs = ["timerfd.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/timerfd", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index ae58f6fd7..767db95a0 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -30,6 +30,8 @@ import ( ) // TimerOperations implements fs.FileOperations for timerfds. +// +// +stateify savable type TimerOperations struct { fsutil.ZeroSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` @@ -38,7 +40,7 @@ type TimerOperations struct { fsutil.NoMMap `state:"nosave"` fsutil.NoIoctl `state:"nosave"` - events waiter.Queue `state:"nosave"` + events waiter.Queue `state:"zerovalue"` timer *ktime.Timer // val is the number of timer expirations since the last successful call to diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index 473ab4296..cfe11ab02 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,18 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tmpfs_state", - srcs = [ - "file_regular.go", - "fs.go", - "inode_file.go", - "tmpfs.go", - ], - out = "tmpfs_state.go", - package = "tmpfs", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tmpfs", @@ -22,13 +10,11 @@ go_library( "fs.go", "inode_file.go", "tmpfs.go", - "tmpfs_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tmpfs", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", @@ -41,7 +27,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/tcpip/transport/unix", "//pkg/waiter", ], diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 9811d90bc..342688f81 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -25,6 +25,8 @@ import ( // regularFileOperations implements fs.FileOperations for a regular // tmpfs file. +// +// +stateify savable type regularFileOperations struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index 5bd9ade52..ca620e65e 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -47,6 +47,8 @@ const ( var modeRegexp = regexp.MustCompile("0[0-7][0-7][0-7]") // Filesystem is a tmpfs. +// +// +stateify savable type Filesystem struct{} func init() { diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 4e803c9ff..1e4fe47d2 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -43,6 +43,8 @@ import ( // include an InvalidatorRegion associated with that reference. When the // referenced portion of the file is removed (with Truncate), the associated // InvalidatorRegion is invalidated. +// +// +stateify savable type fileInodeOperations struct { fsutil.DeprecatedFileOperations `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 1cc7ae491..10cb5451d 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -49,6 +49,8 @@ func rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent } // Dir is a directory. +// +// +stateify savable type Dir struct { ramfs.Dir @@ -122,6 +124,8 @@ func (*Dir) StatFS(context.Context) (fs.Info, error) { } // Symlink is a symlink. +// +// +stateify savable type Symlink struct { ramfs.Symlink } @@ -149,6 +153,8 @@ func (s *Symlink) StatFS(context.Context) (fs.Info, error) { } // Socket is a socket. +// +// +stateify savable type Socket struct { ramfs.Socket } @@ -176,6 +182,8 @@ func (s *Socket) StatFS(context.Context) (fs.Info, error) { } // Fifo is a tmpfs named pipe. +// +// +stateify savable type Fifo struct { ramfs.Entry } diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index 363897b2c..3c446eef4 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,22 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tty_state", - srcs = [ - "dir.go", - "fs.go", - "inode.go", - "line_discipline.go", - "master.go", - "queue.go", - "slave.go", - "terminal.go", - ], - out = "tty_state.go", - package = "tty", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tty", @@ -29,7 +13,6 @@ go_library( "queue.go", "slave.go", "terminal.go", - "tty_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tty", visibility = ["//pkg/sentry:internal"], @@ -44,7 +27,6 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 2c5b2aed6..c91091db4 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -49,14 +49,16 @@ import ( // corresponding Dirents hold on their parent (this directory). // // dirInodeOperations implements fs.InodeOperations. +// +// +stateify savable type dirInodeOperations struct { - fsutil.DeprecatedFileOperations - fsutil.InodeNotSocket - fsutil.InodeNotRenameable - fsutil.InodeNotSymlink - fsutil.InodeNoExtendedAttributes - fsutil.NoMappable - fsutil.NoopWriteOut + fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.NoMappable `state:"nosave"` + fsutil.NoopWriteOut `state:"nosave"` // msrc is the super block this directory is on. // @@ -348,6 +350,8 @@ func (d *dirInodeOperations) masterClose(t *Terminal) { // // This is nearly identical to fsutil.DirFileOperations, except that it takes // df.di.mu in IterateDir. +// +// +stateify savable type dirFileOperations struct { waiter.AlwaysReady `state:"nosave"` fsutil.NoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index dbaffe95e..e28635607 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -28,6 +28,8 @@ var ptsDevice = device.NewAnonDevice() // // This devpts is always in the new "multi-instance" mode. i.e., it contains a // ptmx device tied to this mount. +// +// +stateify savable type filesystem struct{} func init() { @@ -69,6 +71,8 @@ func (f *filesystem) Mount(ctx context.Context, device string, flags fs.MountSou } // superOperations implements fs.MountSourceOperations, preventing caching. +// +// +stateify savable type superOperations struct{} // Revalidate implements fs.DirentOperations.Revalidate. diff --git a/pkg/sentry/fs/tty/inode.go b/pkg/sentry/fs/tty/inode.go index 04b9a7727..c0fa2b407 100644 --- a/pkg/sentry/fs/tty/inode.go +++ b/pkg/sentry/fs/tty/inode.go @@ -31,6 +31,8 @@ import ( // // * fs.InodeOperations.Release // * fs.InodeOperations.GetFile +// +// +stateify savable type inodeOperations struct { fsutil.DeprecatedFileOperations `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index f094635f5..d243ee40e 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -72,6 +72,8 @@ const ( // termiosMu // inQueue.mu // outQueue.mu +// +// +stateify savable type lineDiscipline struct { // inQueue is the input queue of the terminal. inQueue queue @@ -183,6 +185,8 @@ type transformer interface { // outputQueueTransformer implements transformer. It performs line discipline // transformations on the output queue. +// +// +stateify savable type outputQueueTransformer struct{} // transform does output processing for one end of the pty. See @@ -254,6 +258,8 @@ func (*outputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte // inputQueueTransformer implements transformer. It performs line discipline // transformations on the input queue. +// +// +stateify savable type inputQueueTransformer struct{} // transform does input processing for one end of the pty. Characters read are diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index 74cdbe874..c7198e218 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -27,6 +27,8 @@ import ( // masterInodeOperations are the fs.InodeOperations for the master end of the // Terminal (ptmx file). +// +// +stateify savable type masterInodeOperations struct { inodeOperations @@ -96,6 +98,8 @@ func (mi *masterInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flag } // masterFileOperations are the fs.FileOperations for the master end of a terminal. +// +// +stateify savable type masterFileOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 026d5e077..42c105abc 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -32,11 +32,13 @@ import ( // processed (i.e. undergo termios transformations) as they are added to the // read buffer. The read buffer is readable when its length is nonzero and // readable is true. +// +// +stateify savable type queue struct { // mu protects everything in queue. mu sync.Mutex `state:"nosave"` - waiter.Queue `state:"nosave"` + waiter.Queue `state:"zerovalue"` // readBuf is buffer of data ready to be read when readable is true. // This data has been processed. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index f5eec726e..1c562b172 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -27,6 +27,8 @@ import ( // slaveInodeOperations are the fs.InodeOperations for the slave end of the // Terminal (pts file). +// +// +stateify savable type slaveInodeOperations struct { inodeOperations @@ -86,6 +88,8 @@ func (si *slaveInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags } // slaveFileOperations are the fs.FileOperations for the slave end of a terminal. +// +// +stateify savable type slaveFileOperations struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index fa5b00409..3cb135124 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -21,6 +21,8 @@ import ( ) // Terminal is a pseudoterminal. +// +// +stateify savable type Terminal struct { refs.AtomicRefCount diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index eaf8f15b2..159c50efb 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -3,26 +3,15 @@ package( licenses = ["notice"], # Apache 2.0 ) -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "inet_state", - srcs = ["inet.go"], - out = "inet_state.go", - package = "inet", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "inet", srcs = [ "context.go", "inet.go", - "inet_state.go", "test_stack.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/inet", - deps = [ - "//pkg/sentry/context", - "//pkg/state", - ], + deps = ["//pkg/sentry/context"], ) diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index e4b326993..e54a61196 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -87,6 +87,8 @@ type InterfaceAddr struct { } // TCPBufferSize contains settings controlling TCP buffer sizing. +// +// +stateify savable type TCPBufferSize struct { // Min is the minimum size. Min int diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 1c1633068..69a3fbc45 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,59 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "kernel_state", - srcs = [ - "abstract_socket_namespace.go", - "fd_map.go", - "fs_context.go", - "ipc_namespace.go", - "kernel.go", - "kernel_state.go", - "pending_signals.go", - "pending_signals_state.go", - "process_group_list.go", - "ptrace.go", - "rseq.go", - "session_list.go", - "sessions.go", - "signal.go", - "signal_handlers.go", - "syscalls.go", - "syscalls_state.go", - "syslog.go", - "task.go", - "task_clone.go", - "task_context.go", - "task_exec.go", - "task_exit.go", - "task_list.go", - "task_resources.go", - "task_run.go", - "task_sched.go", - "task_signals.go", - "task_start.go", - "task_syscall.go", - "thread_group.go", - "threads.go", - "timekeeper.go", - "timekeeper_state.go", - "timer.go", - "uts_namespace.go", - "vdso.go", - "version.go", - ], - out = "kernel_autogen_state.go", - imports = [ - "gvisor.googlesource.com/gvisor/pkg/bpf", - "gvisor.googlesource.com/gvisor/pkg/sentry/arch", - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", - "gvisor.googlesource.com/gvisor/pkg/tcpip", - ], - package = "kernel", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "pending_signals_list", @@ -119,7 +67,6 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", - "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", @@ -165,6 +112,11 @@ go_library( "version.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel", + imports = [ + "gvisor.googlesource.com/gvisor/pkg/bpf", + "gvisor.googlesource.com/gvisor/pkg/sentry/arch", + "gvisor.googlesource.com/gvisor/pkg/tcpip", + ], visibility = ["//:sandbox"], deps = [ "//pkg/abi", diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 014c4a3bf..d6d1d341d 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" ) +// +stateify savable type abstractEndpoint struct { ep unix.BoundEndpoint wr *refs.WeakRef @@ -39,6 +40,8 @@ func (e *abstractEndpoint) WeakRefGone() { } // AbstractSocketNamespace is used to implement the Linux abstract socket functionality. +// +// +stateify savable type AbstractSocketNamespace struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 5b7b30557..a81085372 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,20 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "auth_state", - srcs = [ - "credentials.go", - "id.go", - "id_map_range.go", - "id_map_set.go", - "user_namespace.go", - ], - out = "auth_state.go", - package = "auth", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "id_map_range", @@ -48,7 +35,6 @@ go_library( name = "auth", srcs = [ "auth.go", - "auth_state.go", "capability_set.go", "context.go", "credentials.go", @@ -66,7 +52,6 @@ go_library( "//pkg/bits", "//pkg/log", "//pkg/sentry/context", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index f6fb05285..f18f7dac9 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -21,6 +21,8 @@ import ( // Credentials contains information required to authorize privileged operations // in a user namespace. +// +// +stateify savable type Credentials struct { // Real/effective/saved user/group IDs in the root user namespace. None of // these should ever be NoID. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index 6adb33530..bd0090e0f 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -77,6 +77,8 @@ func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool { // An IDMapEntry represents a mapping from a range of contiguous IDs in a user // namespace to an equally-sized range of contiguous IDs in the namespace's // parent. +// +// +stateify savable type IDMapEntry struct { // FirstID is the first ID in the range in the namespace. FirstID uint32 diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 0980aeadf..d359f3f31 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -23,6 +23,8 @@ import ( // A UserNamespace represents a user namespace. See user_namespaces(7) for // details. +// +// +stateify savable type UserNamespace struct { // parent is this namespace's parent. If this is the root namespace, parent // is nil. The parent pointer is immutable. diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 7d491efbc..5e8b36ed6 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,22 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "epoll_autogen_state", - srcs = [ - "epoll.go", - "epoll_state.go", - ], - out = "epoll_autogen_state.go", - package = "epoll", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "epoll", srcs = [ "epoll.go", - "epoll_autogen_state.go", "epoll_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/epoll", @@ -29,9 +18,7 @@ go_library( "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/kdefs", - "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index b572fcd7e..d87e64a1c 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -58,6 +58,8 @@ const ( // potentially be reassigned. We also cannot use just the file pointer because // it is possible to have multiple entries for the same file object as long as // they are created with different FDs (i.e., the FDs point to the same file). +// +// +stateify savable type FileIdentifier struct { File *fs.File Fd kdefs.FD @@ -65,6 +67,8 @@ type FileIdentifier struct { // pollEntry holds all the state associated with an event poll entry, that is, // a file being observed by an event poll object. +// +// +stateify savable type pollEntry struct { ilist.Entry file *refs.WeakRef `state:"manual"` @@ -92,6 +96,8 @@ func (p *pollEntry) WeakRefGone() { // EventPoll holds all the state associated with an event poll object, that is, // collection of files to observe and their current state. +// +// +stateify savable type EventPoll struct { fsutil.PipeSeek `state:"zerovalue"` fsutil.NotDirReaddir `state:"zerovalue"` @@ -102,7 +108,7 @@ type EventPoll struct { // Wait queue is used to notify interested parties when the event poll // object itself becomes readable or writable. - waiter.Queue + waiter.Queue `state:"zerovalue"` // files is the map of all the files currently being observed, it is // protected by mu. diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index 7ec179bd8..cc1120b4f 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,33 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "eventfd_state", - srcs = [ - "eventfd.go", - ], - out = "eventfd_state.go", - package = "eventfd", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "eventfd", - srcs = [ - "eventfd.go", - "eventfd_state.go", - ], + srcs = ["eventfd.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/eventfd", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", "//pkg/waiter/fdnotifier", diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index bd50bd9fe..a4ada0e78 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -35,6 +35,8 @@ import ( // EventOperations represents an event with the semantics of Linux's file-based event // notification (eventfd). Eventfds are usually internal to the Sentry but in certain // situations they may be converted into a host-backed eventfd. +// +// +stateify savable type EventOperations struct { fsutil.NoopRelease `state:"nosave"` fsutil.PipeSeek `state:"nosave"` @@ -49,7 +51,7 @@ type EventOperations struct { // Queue is used to notify interested parties when the event object // becomes readable or writable. - wq waiter.Queue `state:"nosave"` + wq waiter.Queue `state:"zerovalue"` // val is the current value of the event counter. val uint64 diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index 299506330..d5d4aaacb 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -46,6 +46,8 @@ func (f FDs) Less(i, j int) bool { } // FDFlags define flags for an individual descriptor. +// +// +stateify savable type FDFlags struct { // CloseOnExec indicates the descriptor should be closed on exec. CloseOnExec bool @@ -69,12 +71,16 @@ func (f FDFlags) ToLinuxFDFlags() (mask uint) { // descriptor holds the details about a file descriptor, namely a pointer the // file itself and the descriptor flags. +// +// +stateify savable type descriptor struct { file *fs.File flags FDFlags } // FDMap is used to manage File references and flags. +// +// +stateify savable type FDMap struct { refs.AtomicRefCount k *Kernel diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index dbc097696..f3f05e8f5 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -25,6 +25,8 @@ import ( // FSContext contains filesystem context. // // This includes umask and working directory. +// +// +stateify savable type FSContext struct { refs.AtomicRefCount diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index a97a43549..b44a26974 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "waiter_list", @@ -14,29 +14,15 @@ go_template_instance( }, ) -go_stateify( - name = "futex_state", - srcs = [ - "futex.go", - "waiter_list.go", - ], - out = "futex_state.go", - package = "futex", -) - go_library( name = "futex", srcs = [ "futex.go", - "futex_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex", visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/state", - "//pkg/syserror", - ], + deps = ["//pkg/syserror"], ) go_test( diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 15e3e5e2c..4a1f2a0ef 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -196,6 +196,8 @@ func bucketIndexForAddr(addr uintptr) uintptr { } // Manager holds futex state for a single virtual address space. +// +// +stateify savable type Manager struct { buckets [bucketCount]bucket `state:"zerovalue"` } diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index a86bda77b..5eef49f59 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -21,6 +21,8 @@ import ( ) // IPCNamespace represents an IPC namespace. +// +// +stateify savable type IPCNamespace struct { // User namespace which owns this IPC namespace. Immutable. userNS *auth.UserNamespace diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 64439cd9d..419a1d473 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -62,6 +62,8 @@ import ( // Kernel represents an emulated Linux kernel. It must be initialized by calling // Init() or LoadFrom(). +// +// +stateify savable type Kernel struct { // extMu serializes external changes to the Kernel with calls to // Kernel.SaveTo. (Kernel.SaveTo requires that the state of the Kernel @@ -158,7 +160,7 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. - exitErr error + exitErr error `state:"nosave"` // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index 5dc0f266c..06be5a7e1 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -38,6 +38,8 @@ const ( // pendingSignals holds a collection of pending signals. The zero value of // pendingSignals is a valid empty collection. pendingSignals is thread-unsafe; // users must provide synchronization. +// +// +stateify savable type pendingSignals struct { // signals contains all pending signals. // @@ -52,11 +54,14 @@ type pendingSignals struct { } // pendingSignalQueue holds a pendingSignalList for a single signal number. +// +// +stateify savable type pendingSignalQueue struct { pendingSignalList length int } +// +stateify savable type pendingSignal struct { // pendingSignalEntry links into a pendingSignalList. pendingSignalEntry diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 4600d19bd..19b23c6d2 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,20 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "pipe_state", - srcs = [ - "buffers.go", - "node.go", - "pipe.go", - "reader.go", - "reader_writer.go", - "writer.go", - ], - out = "pipe_state.go", - package = "pipe", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "pipe", @@ -23,7 +9,6 @@ go_library( "device.go", "node.go", "pipe.go", - "pipe_state.go", "reader.go", "reader_writer.go", "writer.go", @@ -34,15 +19,12 @@ go_library( "//pkg/abi/linux", "//pkg/amutex", "//pkg/ilist", - "//pkg/log", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index f300537c5..a82e45c3f 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -20,6 +20,8 @@ import ( // Buffer encapsulates a queueable byte buffer that can // easily be truncated. It is designed only for use with pipes. +// +// +stateify savable type Buffer struct { ilist.Entry data []byte diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index e418cf174..23d692da1 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -24,6 +24,8 @@ import ( ) // inodeOperations wraps fs.InodeOperations operations with common pipe opening semantics. +// +// +stateify savable type inodeOperations struct { fs.InodeOperations diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index 9a21df5b4..ced2559a7 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -41,6 +41,8 @@ const DefaultPipeSize = 65536 // Pipe is an encapsulation of a platform-independent pipe. // It manages a buffered byte queue shared between a reader/writer // pair. +// +// +stateify savable type Pipe struct { waiter.Queue `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 40d5e4943..1fa5e9a32 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -20,6 +20,8 @@ import ( // Reader satisfies the fs.FileOperations interface for read-only pipes. // Reader should be used with !fs.FileFlags.Write to reject writes. +// +// +stateify savable type Reader struct { ReaderWriter } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index dc642a3a6..82607367b 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -31,6 +31,8 @@ import ( // read and write requests. This should only be used directly for named pipes. // pipe(2) and pipe2(2) only support unidirectional pipes and should use // either pipe.Reader or pipe.Writer. +// +// +stateify savable type ReaderWriter struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index fd13008ac..d93324b53 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -20,6 +20,8 @@ import ( // Writer satisfies the fs.FileOperations interface for write-only pipes. // Writer should be used with !fs.FileFlags.Read to reject reads. +// +// +stateify savable type Writer struct { ReaderWriter } diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index f1c2c4bf0..e9e69004d 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -25,6 +25,8 @@ import ( // ptraceOptions are the subset of options controlling a task's ptrace behavior // that are set by ptrace(PTRACE_SETOPTIONS). +// +// +stateify savable type ptraceOptions struct { // ExitKill is true if the tracee should be sent SIGKILL when the tracer // exits. @@ -185,6 +187,8 @@ func (t *Task) hasTracer() bool { } // ptraceStop is a TaskStop placed on tasks in a ptrace-stop. +// +// +stateify savable type ptraceStop struct { // If frozen is true, the stopped task's tracer is currently operating on // it, so Task.Kill should not remove the stop. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 635372993..1f3de58e3 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -23,6 +23,8 @@ import ( // Restartable sequences, as described in https://lwn.net/Articles/650333/. // RSEQCriticalRegion describes a restartable sequence critical region. +// +// +stateify savable type RSEQCriticalRegion struct { // When a task in this thread group has its CPU preempted (as defined by // platform.ErrContextCPUPreempted) or has a signal delivered to an diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index 969145fe1..e7fa44e2c 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "waiter_list", @@ -14,21 +14,10 @@ go_template_instance( }, ) -go_stateify( - name = "semaphore_state", - srcs = [ - "semaphore.go", - "waiter_list.go", - ], - out = "semaphore_autogen_state.go", - package = "semaphore", -) - go_library( name = "semaphore", srcs = [ "semaphore.go", - "semaphore_autogen_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/semaphore", @@ -40,8 +29,6 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", - "//pkg/state", - "//pkg/state/statefile", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index a1ee83ce5..aa07946cf 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -42,6 +42,8 @@ const ( ) // Registry maintains a set of semaphores that can be found by key or ID. +// +// +stateify savable type Registry struct { // userNS owning the ipc name this registry belongs to. Immutable. userNS *auth.UserNamespace @@ -52,6 +54,8 @@ type Registry struct { } // Set represents a set of semaphores that can be operated atomically. +// +// +stateify savable type Set struct { // registry owning this sem set. Immutable. registry *Registry @@ -79,6 +83,8 @@ type Set struct { } // sem represents a single semanphore from a set. +// +// +stateify savable type sem struct { value int16 waiters waiterList `state:"zerovalue"` @@ -86,6 +92,8 @@ type sem struct { // waiter represents a caller that is waiting for the semaphore value to // become positive or zero. +// +// +stateify savable type waiter struct { waiterEntry diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index fa4c7b8f6..cf4e18805 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -27,6 +27,8 @@ type SessionID ThreadID type ProcessGroupID ThreadID // Session contains a leader threadgroup and a list of ProcessGroups. +// +// +stateify savable type Session struct { refs refs.AtomicRefCount @@ -76,6 +78,8 @@ func (s *Session) decRef() { } // ProcessGroup contains an originator threadgroup and a parent Session. +// +// +stateify savable type ProcessGroup struct { refs refs.AtomicRefCount // not exported. diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 0f88eb0ac..40e641355 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,22 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "shm_state", - srcs = [ - "shm.go", - ], - out = "shm_autogen_state.go", - package = "shm", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "shm", srcs = [ "device.go", "shm.go", - "shm_autogen_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm", visibility = ["//pkg/sentry:internal"], @@ -33,7 +23,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 7217e8103..1ac444094 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -72,6 +72,8 @@ const ( // Registry tracks all shared memory segments in an IPC namespace. The registry // provides the mechanisms for creating and finding segments, and reporting // global shm parameters. +// +// +stateify savable type Registry struct { // userNS owns the IPC namespace this registry belong to. Immutable. userNS *auth.UserNamespace @@ -288,6 +290,8 @@ func (r *Registry) remove(s *Shm) { // shmctl(SHM_RMID). // // Shm implements memmap.Mappable and memmap.MappingIdentity. +// +// +stateify savable type Shm struct { // AtomicRefCount tracks the number of references to this segment from // maps. A segment always holds a reference to itself, until it's marked for diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 21ba4ee70..3649f5e4d 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -22,6 +22,8 @@ import ( ) // SignalHandlers holds information about signal actions. +// +// +stateify savable type SignalHandlers struct { // mu protects actions, as well as the signal state of all tasks and thread // groups using this SignalHandlers object. (See comment on diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index e20fa3eb6..4c7811b6c 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -176,6 +176,8 @@ type Stracer interface { // SyscallTable is a lookup table of system calls. Critically, a SyscallTable // is *immutable*. In order to make supporting suspend and resume sane, they // must be uniquely registered and may not change during operation. +// +// +stateify savable type SyscallTable struct { // OS is the operating system that this syscall table implements. OS abi.OS `state:"wait"` diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 31541749e..125312b6a 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -23,6 +23,8 @@ import ( // syslog represents a sentry-global kernel log. // // Currently, it contains only fun messages for a dmesg easter egg. +// +// +stateify savable type syslog struct { // mu protects the below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index e705260da..19029adb1 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -52,6 +52,8 @@ import ( // All fields that are "exclusive to the task goroutine" can only be accessed // by the task goroutine while it is running. The task goroutine does not // require synchronization to read or write these fields. +// +// +stateify savable type Task struct { taskNode diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index 3b77a4965..526165af0 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -352,6 +352,7 @@ func (t *Task) unstopVforkParent() { } } +// +stateify savable type runSyscallAfterPtraceEventClone struct { vforkChild *Task @@ -369,6 +370,7 @@ func (r *runSyscallAfterPtraceEventClone) execute(t *Task) taskRunState { return (*runSyscallExit)(nil) } +// +stateify savable type runSyscallAfterVforkStop struct { // childTID has the same meaning as // runSyscallAfterPtraceEventClone.vforkChildTID. @@ -474,6 +476,8 @@ func (t *Task) Unshare(opts *SharingOptions) error { // current MM. (Normally, CLONE_VFORK is used in conjunction with CLONE_VM, so // that the child and parent share mappings until the child execve()s into a // new process image or exits.) +// +// +stateify savable type vforkStop struct{} // StopIgnoresKill implements TaskStop.Killable. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index 5c563ba08..9a59cbd33 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -35,6 +35,8 @@ var ErrNoSyscalls = errors.New("no syscall table found") type Auxmap map[string]interface{} // TaskContext is the subset of a task's data that is provided by the loader. +// +// +stateify savable type TaskContext struct { // Name is the thread name set by the prctl(PR_SET_NAME) system call. Name string diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 2285847a2..385299b24 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -73,6 +73,8 @@ import ( // execStop is a TaskStop that a task sets on itself when it wants to execve // and is waiting for the other tasks in its thread group to exit first. +// +// +stateify savable type execStop struct{} // Killable implements TaskStop.Killable. @@ -119,6 +121,8 @@ func (t *Task) Execve(newTC *TaskContext) (*SyscallControl, error) { // The runSyscallAfterExecStop state continues execve(2) after all siblings of // a thread in the execve syscall have exited. +// +// +stateify savable type runSyscallAfterExecStop struct { tc *TaskContext } diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index d6604f37b..b16844e91 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -38,6 +38,8 @@ import ( // An ExitStatus is a value communicated from an exiting task or thread group // to the party that reaps it. +// +// +stateify savable type ExitStatus struct { // Code is the numeric value passed to the call to exit or exit_group that // caused the exit. If the exit was not caused by such a call, Code is 0. @@ -222,6 +224,8 @@ func (t *Task) advanceExitStateLocked(oldExit, newExit TaskExitState) { } // runExit is the entry point into the task exit path. +// +// +stateify savable type runExit struct{} func (*runExit) execute(t *Task) taskRunState { @@ -229,6 +233,7 @@ func (*runExit) execute(t *Task) taskRunState { return (*runExitMain)(nil) } +// +stateify savable type runExitMain struct{} func (*runExitMain) execute(t *Task) taskRunState { @@ -531,6 +536,7 @@ func (t *Task) reparentLocked(parent *Task) { // tracer (if one exists) and reaps the leader immediately. In Linux, this is // in fs/exec.c:de_thread(); in the sentry, this is in Task.promoteLocked(). +// +stateify savable type runExitNotify struct{} func (*runExitNotify) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_resources.go b/pkg/sentry/kernel/task_resources.go index 4ca25664a..0832bf989 100644 --- a/pkg/sentry/kernel/task_resources.go +++ b/pkg/sentry/kernel/task_resources.go @@ -21,6 +21,8 @@ import ( // TaskResources is the subset of a task's data provided by its creator that is // not provided by the loader. +// +// +stateify savable type TaskResources struct { // SignalMask is the set of signals whose delivery is currently blocked. // diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index a03fa6ac0..8dd0ef6ea 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -131,6 +131,8 @@ func (t *Task) doStop() { // The runApp state checks for interrupts before executing untrusted // application code. +// +// +stateify savable type runApp struct{} func (*runApp) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index b50139077..49141ab74 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -65,6 +65,8 @@ const ( // TaskGoroutineSchedInfo contains task goroutine scheduling state which must // be read and updated atomically. +// +// +stateify savable type TaskGoroutineSchedInfo struct { // Timestamp was the value of Kernel.cpuClock when this // TaskGoroutineSchedInfo was last updated. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 91f6c0874..62ec530be 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -748,6 +748,8 @@ func (t *Task) CopyInSignalStack(addr usermem.Addr) (arch.SignalStack, error) { // groupStop is a TaskStop placed on tasks that have received a stop signal // (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU). (The term "group-stop" originates from // the ptrace man page.) +// +// +stateify savable type groupStop struct{} // Killable implements TaskStop.Killable. @@ -881,6 +883,8 @@ func (t *Task) signalStop(target *Task, code int32, status int32) { } // The runInterrupt state handles conditions indicated by interrupts. +// +// +stateify savable type runInterrupt struct{} func (*runInterrupt) execute(t *Task) taskRunState { @@ -1020,6 +1024,7 @@ func (*runInterrupt) execute(t *Task) taskRunState { return (*runApp)(nil) } +// +stateify savable type runInterruptAfterSignalDeliveryStop struct{} func (*runInterruptAfterSignalDeliveryStop) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 92ca0acd9..f0373c375 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -241,6 +241,7 @@ func (t *Task) doSyscallEnter(sysno uintptr, args arch.SyscallArguments) taskRun return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallAfterSyscallEnterStop struct{} func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { @@ -260,6 +261,7 @@ func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallAfterSysemuStop struct{} func (*runSyscallAfterSysemuStop) execute(t *Task) taskRunState { @@ -294,6 +296,7 @@ func (t *Task) doSyscallInvoke(sysno uintptr, args arch.SyscallArguments) taskRu return (*runSyscallExit)(nil).execute(t) } +// +stateify savable type runSyscallReinvoke struct{} func (*runSyscallReinvoke) execute(t *Task) taskRunState { @@ -310,6 +313,7 @@ func (*runSyscallReinvoke) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallExit struct{} func (*runSyscallExit) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 8fffd3446..441b8a822 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -28,6 +28,8 @@ import ( // groups" are usually called "processes" in userspace documentation.) // // ThreadGroup is a superset of Linux's struct signal_struct. +// +// +stateify savable type ThreadGroup struct { threadGroupNode diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 440da9dad..844213c35 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -50,6 +50,8 @@ func (tid ThreadID) String() string { const InitTID ThreadID = 1 // A TaskSet comprises all tasks in a system. +// +// +stateify savable type TaskSet struct { // mu protects all relationships betweens tasks and thread groups in the // TaskSet. (mu is approximately equivalent to Linux's tasklist_lock.) @@ -110,6 +112,8 @@ func (ts *TaskSet) forEachThreadGroupLocked(f func(tg *ThreadGroup)) { // // N.B. A task is said to be visible in a PID namespace if the PID namespace // contains a thread ID that maps to that task. +// +// +stateify savable type PIDNamespace struct { // owner is the TaskSet that this PID namespace belongs to. The owner // pointer is immutable. @@ -263,6 +267,8 @@ func (ns *PIDNamespace) UserNamespace() *auth.UserNamespace { // (threadGroupNode is an anonymous field in ThreadGroup; this is to expose // threadGroupEntry's methods on ThreadGroup to make it implement // threadGroupLinker.) +// +// +stateify savable type threadGroupNode struct { // pidns is the PID namespace containing the thread group and all of its // member tasks. The pidns pointer is immutable. @@ -382,6 +388,8 @@ func (tg *ThreadGroup) ID() ThreadID { // A taskNode defines the relationship between a task and the rest of the // system. The comments on threadGroupNode also apply to taskNode. +// +// +stateify savable type taskNode struct { // tg is the thread group that this task belongs to. The tg pointer is // immutable. diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index b3ed42aa4..5d8db2273 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,30 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "time_state", - srcs = [ - "time.go", - ], - out = "time_state.go", - package = "time", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "time", srcs = [ "context.go", "time.go", - "time_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/context", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index c223c2f19..6eadd2878 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -42,6 +42,8 @@ const ( // // Time may represent time with respect to any clock and may not have any // meaning in the real world. +// +// +stateify savable type Time struct { ns int64 } @@ -286,6 +288,8 @@ type TimerListener interface { } // Setting contains user-controlled mutable Timer properties. +// +// +stateify savable type Setting struct { // Enabled is true if the timer is running. Enabled bool @@ -371,6 +375,8 @@ func (s Setting) advancedTo(now Time) (Setting, uint64) { // // Timers should be created using NewTimer and must be cleaned up by calling // Timer.Destroy when no longer used. +// +// +stateify savable type Timer struct { // clock is the time source. clock is immutable. clock Clock diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index 4de8ac13b..df5dbe128 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -25,6 +25,8 @@ import ( ) // Timekeeper manages all of the kernel clocks. +// +// +stateify savable type Timekeeper struct { // clocks are the clock sources. // diff --git a/pkg/sentry/kernel/timer.go b/pkg/sentry/kernel/timer.go index 03a3310be..534d03d0f 100644 --- a/pkg/sentry/kernel/timer.go +++ b/pkg/sentry/kernel/timer.go @@ -26,6 +26,8 @@ import ( // timekeeperClock is a ktime.Clock that reads time from a // kernel.Timekeeper-managed clock. +// +// +stateify savable type timekeeperClock struct { tk *Timekeeper c sentrytime.ClockID @@ -49,6 +51,8 @@ func (tc *timekeeperClock) Now() ktime.Time { // tgClock is a ktime.Clock that measures the time a thread group has spent // executing. +// +// +stateify savable type tgClock struct { tg *ThreadGroup @@ -155,6 +159,8 @@ func (tc *taskClock) Now() ktime.Time { } // signalNotifier is a ktime.Listener that sends signals to a ThreadGroup. +// +// +stateify savable type signalNotifier struct { tg *ThreadGroup signal linux.Signal @@ -179,6 +185,8 @@ func (s *signalNotifier) Notify(exp uint64) { func (s *signalNotifier) Destroy() {} // TimerManager is a collection of supported process cpu timers. +// +// +stateify savable type TimerManager struct { // Clocks used to drive thread group execution time timers. virtClock *tgClock diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index 58e9b4d1b..7e0fe0d21 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -22,6 +22,8 @@ import ( // UTSNamespace represents a UTS namespace, a holder of two system identifiers: // the hostname and domain name. +// +// +stateify savable type UTSNamespace struct { // mu protects all fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 0bacbea49..971e8bc59 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -52,6 +52,8 @@ type vdsoParams struct { // Everything in the struct is 8 bytes for easy alignment. // // It must be kept in sync with params in vdso/vdso_time.cc. +// +// +stateify savable type VDSOParamPage struct { // The parameter page is fr, allocated from platform.Memory(). platform platform.Platform diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 3ce41cacc..90f4395d4 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,22 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "limits_state", - srcs = [ - "limits.go", - ], - out = "limits_state.go", - package = "limits", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "limits", srcs = [ "context.go", "limits.go", - "limits_state.go", "linux.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/limits", @@ -24,7 +14,6 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/sentry/context", - "//pkg/state", ], ) diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index 4230ba958..02c8b60e3 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -47,6 +47,8 @@ const ( const Infinity = ^uint64(0) // Limit specifies a system limit. +// +// +stateify savable type Limit struct { // Cur specifies the current limit. Cur uint64 @@ -55,6 +57,8 @@ type Limit struct { } // LimitSet represents the Limits that correspond to each LimitType. +// +// +stateify savable type LimitSet struct { mu sync.Mutex `state:"nosave"` data map[LimitType]Limit diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index e63052c6d..0beb4561b 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") +load("//tools/go_stateify:defs.bzl", "go_library") go_embed_data( name = "vdso_bin", @@ -10,23 +10,12 @@ go_embed_data( var = "vdsoBin", ) -go_stateify( - name = "loader_state", - srcs = [ - "vdso.go", - "vdso_state.go", - ], - out = "loader_state.go", - package = "loader", -) - go_library( name = "loader", srcs = [ "elf.go", "interpreter.go", "loader.go", - "loader_state.go", "vdso.go", "vdso_state.go", ":vdso_bin", @@ -40,7 +29,6 @@ go_library( "//pkg/cpuid", "//pkg/log", "//pkg/rand", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", @@ -55,7 +43,6 @@ go_library( "//pkg/sentry/uniqueid", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 2e8693f8e..a06e27ac9 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -193,6 +193,8 @@ func validateVDSO(ctx context.Context, f *fs.File, size uint64) (elfInfo, error) // // NOTE: to support multiple architectures or operating systems, this // would need to contain a VDSO for each. +// +// +stateify savable type VDSO struct { // ParamPage is the VDSO parameter page. This page should be updated to // inform the VDSO for timekeeping data. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index 92004ad9e..dc71e1c2d 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -18,6 +18,7 @@ import ( "debug/elf" ) +// +stateify savable type elfProgHeader struct { Type elf.ProgType Flags elf.ProgFlag diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index 2e367e189..c9e0b95a0 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,18 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "memmap_state", - srcs = [ - "mappable_range.go", - "mapping_set.go", - "mapping_set_impl.go", - ], - out = "memmap_state.go", - package = "memmap", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "mappable_range", @@ -46,7 +35,6 @@ go_library( "mapping_set.go", "mapping_set_impl.go", "memmap.go", - "memmap_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/memmap", visibility = ["//pkg/sentry:internal"], @@ -56,7 +44,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/platform", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index 0cd42ffbf..c9483905d 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -35,6 +35,8 @@ import ( type MappingsOfRange map[MappingOfRange]struct{} // MappingOfRange represents a mapping of a MappableRange. +// +// +stateify savable type MappingOfRange struct { MappingSpace MappingSpace AddrRange usermem.AddrRange diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 3f396986a..bbdfae247 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,24 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "mm_state", - srcs = [ - "aio_context.go", - "aio_context_state.go", - "file_refcount_set.go", - "io_list.go", - "mm.go", - "pma_set.go", - "save_restore.go", - "special_mappable.go", - "vma_set.go", - ], - out = "mm_state.go", - package = "mm", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "file_refcount_set", @@ -101,7 +84,6 @@ go_library( "lifecycle.go", "metadata.go", "mm.go", - "mm_state.go", "pma.go", "pma_set.go", "proc_pid_maps.go", @@ -131,7 +113,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/sync", "//pkg/syserror", "//pkg/tcpip/buffer", diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index 992bde5a5..b42156d45 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -28,6 +28,8 @@ import ( ) // aioManager creates and manages asynchronous I/O contexts. +// +// +stateify savable type aioManager struct { // mu protects below. mu sync.Mutex `state:"nosave"` @@ -89,12 +91,16 @@ func (a *aioManager) lookupAIOContext(id uint64) (*AIOContext, bool) { } // ioResult is a completed I/O operation. +// +// +stateify savable type ioResult struct { data interface{} ioEntry } // AIOContext is a single asynchronous I/O context. +// +// +stateify savable type AIOContext struct { // done is the notification channel used for all requests. done chan struct{} `state:"nosave"` @@ -190,6 +196,8 @@ func (ctx *AIOContext) WaitChannel() (chan struct{}, bool) { // aioMappable implements memmap.MappingIdentity and memmap.Mappable for AIO // ring buffers. +// +// +stateify savable type aioMappable struct { refs.AtomicRefCount diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index ce8097b7f..3299ae164 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -46,6 +46,8 @@ import ( ) // MemoryManager implements a virtual address space. +// +// +stateify savable type MemoryManager struct { // p is the platform. // @@ -207,6 +209,8 @@ type MemoryManager struct { } // vma represents a virtual memory area. +// +// +stateify savable type vma struct { // mappable is the virtual memory object mapped by this vma. If mappable is // nil, the vma represents a private anonymous mapping. @@ -346,6 +350,8 @@ func (v *vma) loadRealPerms(b int) { } // pma represents a platform mapping area. +// +// +stateify savable type pma struct { // file is the file mapped by this pma. Only pmas for which file == // platform.Platform.Memory() may be saved. pmas hold a reference to the @@ -380,6 +386,7 @@ type pma struct { internalMappings safemem.BlockSeq `state:"nosave"` } +// +stateify savable type privateRefs struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index 9d3614034..aa2f87107 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -28,6 +28,8 @@ import ( // semantics similar to Linux's mm/mmap.c:_install_special_mapping(), except // that SpecialMappable takes ownership of the memory that it represents // (_install_special_mapping() does not.) +// +// +stateify savable type SpecialMappable struct { refs.AtomicRefCount diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index 15a7fbbc3..af9ba5394 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,16 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "platform_state", - srcs = [ - "file_range.go", - ], - out = "platform_state.go", - package = "platform", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "file_range", @@ -30,7 +21,6 @@ go_library( "file_range.go", "mmap_min_addr.go", "platform.go", - "platform_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/platform", visibility = ["//pkg/sentry:internal"], @@ -44,7 +34,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index dadba1d38..2a5982763 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,18 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "filemem_autogen_state", - srcs = [ - "filemem.go", - "filemem_state.go", - "usage_set.go", - ], - out = "filemem_autogen_state.go", - package = "filemem", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "usage_set", @@ -38,7 +27,6 @@ go_library( name = "filemem", srcs = [ "filemem.go", - "filemem_autogen_state.go", "filemem_state.go", "filemem_unsafe.go", "usage_set.go", diff --git a/pkg/sentry/platform/filemem/filemem.go b/pkg/sentry/platform/filemem/filemem.go index 870274ae1..feb020ef8 100644 --- a/pkg/sentry/platform/filemem/filemem.go +++ b/pkg/sentry/platform/filemem/filemem.go @@ -155,6 +155,8 @@ type FileMem struct { } // usage tracks usage information. +// +// +stateify savable type usageInfo struct { // kind is the usage kind. kind usage.MemoryKind diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 929787aa0..a320fca0b 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,22 +1,10 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "socket_state", - srcs = [ - "socket.go", - ], - out = "socket_state_autogen.go", - package = "socket", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "socket", - srcs = [ - "socket.go", - "socket_state_autogen.go", - ], + srcs = ["socket.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket", visibility = ["//pkg/sentry:internal"], deps = [ @@ -29,7 +17,6 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/tcpip", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index faf2b4c27..c4874fdfb 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,26 +1,14 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "control_state", - srcs = [ - "control.go", - ], - out = "control_state.go", - imports = [ - "gvisor.googlesource.com/gvisor/pkg/sentry/fs", - ], - package = "control", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "control", - srcs = [ - "control.go", - "control_state.go", - ], + srcs = ["control.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/control", + imports = [ + "gvisor.googlesource.com/gvisor/pkg/sentry/fs", + ], visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", @@ -31,7 +19,6 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/kdefs", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/transport/unix", ], diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index 17ecdd11c..c31182e69 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -51,6 +51,8 @@ type SCMRights interface { // RightsFiles represents a SCM_RIGHTS socket control message. A reference is // maintained for each fs.File and is release either when an FD is created or // when the Release method is called. +// +// +stateify savable type RightsFiles []*fs.File // NewSCMRights creates a new SCM_RIGHTS socket control message representation @@ -128,6 +130,8 @@ func PackRights(t *kernel.Task, rights SCMRights, cloexec bool, buf []byte) []by } // scmCredentials represents an SCM_CREDENTIALS socket control message. +// +// +stateify savable type scmCredentials struct { t *kernel.Task kuid auth.KUID diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index 7ad5e88c5..49af8db85 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,24 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "epsocket_state", - srcs = [ - "epsocket.go", - "save_restore.go", - "stack.go", - ], - out = "epsocket_state.go", - package = "epsocket", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "epsocket", srcs = [ "device.go", "epsocket.go", - "epsocket_state.go", "provider.go", "save_restore.go", "stack.go", @@ -31,7 +19,6 @@ go_library( "//pkg/abi/linux", "//pkg/binary", "//pkg/log", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", @@ -44,7 +31,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index a2927e1b9..f969a1d7c 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -95,6 +95,8 @@ type commonEndpoint interface { // SocketOperations encapsulates all the state needed to represent a network stack // endpoint in the kernel context. +// +// +stateify savable type SocketOperations struct { socket.ReceiveTimeout fsutil.PipeSeek `state:"nosave"` diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index ec1d96ccb..12b4b4767 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -26,6 +26,8 @@ import ( ) // Stack implements inet.Stack for netstack/tcpip/stack.Stack. +// +// +stateify savable type Stack struct { Stack *stack.Stack `state:"manual"` } diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index 227ca3926..d623718b3 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,24 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "hostinet_state", - srcs = [ - "save_restore.go", - "socket.go", - "stack.go", - ], - out = "hostinet_autogen_state.go", - package = "hostinet", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "hostinet", srcs = [ "device.go", "hostinet.go", - "hostinet_autogen_state.go", "save_restore.go", "socket.go", "socket_unsafe.go", @@ -42,7 +30,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip/transport/unix", diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index b23a243f7..b852165f7 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,21 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "netlink_state", - srcs = [ - "socket.go", - ], - out = "netlink_state.go", - package = "netlink", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "netlink", srcs = [ "message.go", - "netlink_state.go", "provider.go", "socket.go", ], @@ -36,7 +26,6 @@ go_library( "//pkg/sentry/socket/netlink/port", "//pkg/sentry/socket/unix", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index ba6f686e4..3a7dbc5ed 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,23 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "port_state", - srcs = ["port.go"], - out = "port_state.go", - package = "port", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "port", - srcs = [ - "port.go", - "port_state.go", - ], + srcs = ["port.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/port", visibility = ["//pkg/sentry:internal"], - deps = ["//pkg/state"], ) go_test( diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 4ccf0b84c..1c5d4c3a5 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -32,6 +32,8 @@ import ( const maxPorts = 10000 // Manager allocates netlink port IDs. +// +// +stateify savable type Manager struct { // mu protects the fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index 726469fc9..e1bcfe252 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,32 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "route_state", - srcs = ["protocol.go"], - out = "route_state.go", - package = "route", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "route", - srcs = [ - "protocol.go", - "route_state.go", - ], + srcs = ["protocol.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/route", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", "//pkg/sentry/context", - "//pkg/sentry/fs", "//pkg/sentry/inet", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/socket/netlink", - "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", ], ) diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index e8030c518..55a76e916 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -43,6 +43,8 @@ func typeKind(typ uint16) commandKind { } // Protocol implements netlink.Protocol. +// +// +stateify savable type Protocol struct{} var _ netlink.Protocol = (*Protocol)(nil) diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 0b8f528d0..e15d1546c 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -51,6 +51,8 @@ var netlinkSocketDevice = device.NewAnonDevice() // to/from the kernel. // // Socket implements socket.Socket. +// +// +stateify savable type Socket struct { socket.ReceiveTimeout fsutil.PipeSeek `state:"nosave"` diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index bd4858a34..54fe64595 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -195,6 +195,8 @@ func NewDirent(ctx context.Context, d *device.Device) *fs.Dirent { // // Care must be taken when copying ReceiveTimeout as it contains atomic // variables. +// +// +stateify savable type ReceiveTimeout struct { // ns is length of the timeout in nanoseconds. // diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index 7d04d6b6b..9fe681e9a 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,15 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "unix_state", - srcs = [ - "unix.go", - ], - out = "unix_state.go", - package = "unix", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "unix", @@ -17,7 +8,6 @@ go_library( "device.go", "io.go", "unix.go", - "unix_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix", visibility = ["//pkg/sentry:internal"], @@ -37,7 +27,6 @@ go_library( "//pkg/sentry/socket/control", "//pkg/sentry/socket/epsocket", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip", diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 27bacbbc3..5b6411f97 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -42,6 +42,8 @@ import ( // SocketOperations is a Unix socket. It is similar to an epsocket, except it is backed // by a unix.Endpoint instead of a tcpip.Endpoint. +// +// +stateify savable type SocketOperations struct { refs.AtomicRefCount socket.ReceiveTimeout diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 32fca3811..bbdfad9da 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,18 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "linux_state", - srcs = [ - "sys_aio.go", - "sys_futex.go", - "sys_poll.go", - "sys_time.go", - ], - out = "linux_state.go", - package = "linux", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "linux", @@ -20,7 +8,6 @@ go_library( "error.go", "flags.go", "linux64.go", - "linux_state.go", "sigset.go", "sys_aio.go", "sys_capability.go", @@ -67,7 +54,6 @@ go_library( "//pkg/abi/linux", "//pkg/binary", "//pkg/bpf", - "//pkg/eventchannel", "//pkg/log", "//pkg/metric", "//pkg/rand", @@ -75,7 +61,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", - "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/lock", "//pkg/sentry/fs/timerfd", "//pkg/sentry/kernel", @@ -86,7 +71,6 @@ go_library( "//pkg/sentry/kernel/kdefs", "//pkg/sentry/kernel/pipe", "//pkg/sentry/kernel/sched", - "//pkg/sentry/kernel/semaphore", "//pkg/sentry/kernel/shm", "//pkg/sentry/kernel/time", "//pkg/sentry/limits", @@ -98,8 +82,6 @@ go_library( "//pkg/sentry/syscalls", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", - "//pkg/syserr", "//pkg/syserror", "//pkg/tcpip/transport/unix", "//pkg/waiter", diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index fc3397081..54e4afa9e 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -69,6 +69,8 @@ type ioCallback struct { } // ioEvent describes an I/O result. +// +// +stateify savable type ioEvent struct { Data uint64 Obj uint64 diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index 57762d058..1a0e1f5fb 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -132,6 +132,8 @@ func (f futexChecker) Op(addr uintptr, opIn uint32) (bool, error) { // futexWaitRestartBlock encapsulates the state required to restart futex(2) // via restart_syscall(2). +// +// +stateify savable type futexWaitRestartBlock struct { duration time.Duration diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index d4dbfd285..b9bdefadb 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -274,6 +274,8 @@ func copyOutTimevalRemaining(t *kernel.Task, startNs ktime.Time, timeout time.Du // pollRestartBlock encapsulates the state required to restart poll(2) via // restart_syscall(2). +// +// +stateify savable type pollRestartBlock struct { pfdAddr usermem.Addr nfds uint diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index dcee694b2..8e6683444 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -168,6 +168,8 @@ func Time(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC // clockNanosleepRestartBlock encapsulates the state required to restart // clock_nanosleep(2) via restart_syscall(2). +// +// +stateify savable type clockNanosleepRestartBlock struct { c ktime.Clock duration time.Duration diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index edee44d96..868dfd400 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,17 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "usage_state", - srcs = [ - "cpu.go", - "io.go", - "memory.go", - ], - out = "usage_state.go", - package = "usage", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "usage", @@ -21,7 +10,6 @@ go_library( "memory.go", "memory_unsafe.go", "usage.go", - "usage_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/usage", visibility = [ @@ -29,9 +17,6 @@ go_library( ], deps = [ "//pkg/bits", - "//pkg/log", "//pkg/sentry/memutil", - "//pkg/state", - "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index 1c2cc90e1..ed7b04b9e 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -20,6 +20,8 @@ import ( // CPUStats contains the subset of struct rusage fields that relate to CPU // scheduling. +// +// +stateify savable type CPUStats struct { // UserTime is the amount of time spent executing application code. UserTime time.Duration diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index a05053c32..49faa507d 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -19,6 +19,8 @@ import ( ) // IO contains I/O-related statistics. +// +// +stateify savable type IO struct { // CharsRead is the number of bytes read by read syscalls. CharsRead uint64 diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index 9dd1cd2b5..69ba919e0 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,19 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "usermem_state", - srcs = [ - "access_type.go", - "addr.go", - "addr_range.go", - "addr_range_seq_unsafe.go", - ], - out = "usermem_state.go", - package = "usermem", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "addr_range", @@ -36,7 +24,6 @@ go_library( "bytes_io.go", "bytes_io_unsafe.go", "usermem.go", - "usermem_state.go", "usermem_x86.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/usermem", @@ -47,7 +34,6 @@ go_library( "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/safemem", - "//pkg/state", "//pkg/syserror", "//pkg/tcpip/buffer", ], diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 7eabecf30..75346d854 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -20,6 +20,8 @@ import ( // AccessType specifies memory access types. This is used for // setting mapping permissions, as well as communicating faults. +// +// +stateify savable type AccessType struct { // Read is read access. Read bool diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index d175fdc74..fc94bee80 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -19,6 +19,8 @@ import ( ) // Addr represents a generic virtual address. +// +// +stateify savable type Addr uintptr // AddLength adds the given length to start and returns the result. ok is true diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 391d801d0..5153bd3b4 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,26 +1,13 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tcpip_state", - srcs = [ - "tcpip.go", - ], - out = "tcpip_state.go", - package = "tcpip", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "tcpip", - srcs = [ - "tcpip.go", - "tcpip_state.go", - ], + srcs = ["tcpip.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip", visibility = ["//visibility:public"], deps = [ - "//pkg/state", "//pkg/tcpip/buffer", "//pkg/waiter", ], diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index efeb6a448..11a725423 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,26 +1,15 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "buffer_state", - srcs = [ - "view.go", - ], - out = "buffer_state.go", - package = "buffer", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "buffer", srcs = [ - "buffer_state.go", "prependable.go", "view.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer", visibility = ["//visibility:public"], - deps = ["//pkg/state"], ) go_test( diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index a5774a327..bbb4e1d24 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -54,6 +54,8 @@ func (v *View) ToVectorisedView(views [1]View) VectorisedView { // VectorisedView is a vectorised version of View using non contigous memory. // It supports all the convenience methods supported by View. +// +// +stateify savable type VectorisedView struct { views []View size int diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 3aa2cfb24..8f22ba3a5 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,15 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tcp_header_state", - srcs = [ - "tcp.go", - ], - out = "tcp_header_state.go", - package = "header", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "header", @@ -25,13 +16,11 @@ go_library( "ipv6.go", "ipv6_fragment.go", "tcp.go", - "tcp_header_state.go", "udp.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/header", visibility = ["//visibility:public"], deps = [ - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/seqnum", ], diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index a95d282b0..6689a6dc5 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -120,6 +120,8 @@ type TCPSynOptions struct { } // SACKBlock represents a single contiguous SACK block. +// +// +stateify savable type SACKBlock struct { // Start indicates the lowest sequence number in the block. Start seqnum.Value @@ -131,6 +133,8 @@ type SACKBlock struct { // TCPOptions are used to parse and cache the TCP segment options for a non // syn/syn-ack segment. +// +// +stateify savable type TCPOptions struct { // TS is true if the TimeStamp option is enabled. TS bool diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index ac97ebe43..83b4d253f 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,14 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "fragmentation_state", - srcs = ["reassembler_list.go"], - out = "fragmentation_state.go", - package = "fragmentation", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "reassembler_list", @@ -26,7 +19,6 @@ go_library( srcs = [ "frag_heap.go", "fragmentation.go", - "fragmentation_state.go", "reassembler.go", "reassembler_list.go", ], @@ -34,7 +26,6 @@ go_library( visibility = ["//:sandbox"], deps = [ "//pkg/log", - "//pkg/state", "//pkg/tcpip/buffer", ], ) diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index a75869dac..c5c889239 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,25 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "seqnum_state", - srcs = [ - "seqnum.go", - ], - out = "seqnum_state.go", - package = "seqnum", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "seqnum", - srcs = [ - "seqnum.go", - "seqnum_state.go", - ], + srcs = ["seqnum.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/seqnum", visibility = [ "//visibility:public", ], - deps = ["//pkg/state"], ) diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index eb1e4645d..af0aec85c 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -213,6 +213,8 @@ const ( // FullAddress represents a full transport node address, as required by the // Connect() and Bind() methods. +// +// +stateify savable type FullAddress struct { // NIC is the ID of the NIC this address refers to. // @@ -256,6 +258,8 @@ func (s SlicePayload) Size() int { } // A ControlMessages contains socket control messages for IP sockets. +// +// +stateify savable type ControlMessages struct { // HasTimestamp indicates whether Timestamp is valid/set. HasTimestamp bool diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 28e3e1700..117532fea 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,19 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "ping_state", - srcs = [ - "endpoint.go", - "endpoint_state.go", - "ping_packet_list.go", - ], - out = "ping_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], - package = "ping", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "ping_packet_list", @@ -32,14 +20,13 @@ go_library( "endpoint.go", "endpoint_state.go", "ping_packet_list.go", - "ping_state.go", "protocol.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/ping", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index f15e44b61..a22684de9 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -26,6 +26,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) +// +stateify savable type pingPacket struct { pingPacketEntry senderAddress tcpip.FullAddress diff --git a/pkg/tcpip/transport/queue/BUILD b/pkg/tcpip/transport/queue/BUILD index fb878ad36..6dcec312e 100644 --- a/pkg/tcpip/transport/queue/BUILD +++ b/pkg/tcpip/transport/queue/BUILD @@ -1,27 +1,14 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "queue_state", - srcs = [ - "queue.go", - ], - out = "queue_state.go", - package = "queue", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "queue", - srcs = [ - "queue.go", - "queue_state.go", - ], + srcs = ["queue.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/queue", visibility = ["//:sandbox"], deps = [ "//pkg/ilist", - "//pkg/state", "//pkg/tcpip", "//pkg/waiter", ], diff --git a/pkg/tcpip/transport/queue/queue.go b/pkg/tcpip/transport/queue/queue.go index 6a17441ae..eb9ee8a3f 100644 --- a/pkg/tcpip/transport/queue/queue.go +++ b/pkg/tcpip/transport/queue/queue.go @@ -33,6 +33,8 @@ type Entry interface { } // Queue is a buffer queue. +// +// +stateify savable type Queue struct { ReaderQueue *waiter.Queue WriterQueue *waiter.Queue diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 6a7153e4d..9ebae6cc7 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,27 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "tcp_state", - srcs = [ - "endpoint.go", - "endpoint_state.go", - "rcv.go", - "reno.go", - "segment.go", - "segment_heap.go", - "segment_queue.go", - "segment_state.go", - "snd.go", - "snd_state.go", - "tcp_segment_list.go", - ], - out = "tcp_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], - package = "tcp", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "tcp_segment_list", @@ -53,15 +33,14 @@ go_library( "snd.go", "snd_state.go", "tcp_segment_list.go", - "tcp_state.go", "timer.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/tcp", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/rand", "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 5b8a1e20f..de1883d84 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -54,6 +54,8 @@ const ( ) // SACKInfo holds TCP SACK related information for a given endpoint. +// +// +stateify savable type SACKInfo struct { // Blocks is the maximum number of SACK blocks we track // per endpoint. @@ -69,6 +71,8 @@ type SACKInfo struct { // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. The protocol implementation, however, runs in a single // goroutine. +// +// +stateify savable type endpoint struct { // workMu is used to arbitrate which goroutine may perform protocol // work. Only the main protocol goroutine is expected to call Lock() on diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index b22a00ce1..92ef9c6f7 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -22,6 +22,8 @@ import ( // receiver holds the state necessary to receive TCP segments and turn them // into a stream of bytes. +// +// +stateify savable type receiver struct { ep *endpoint diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index 60f170a27..03ae8d747 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -16,6 +16,8 @@ package tcp // renoState stores the variables related to TCP New Reno congestion // control algorithm. +// +// +stateify savable type renoState struct { s *sender } diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 40928ba2c..8dccea2ba 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -36,6 +36,8 @@ const ( // segment represents a TCP segment. It holds the payload and parsed TCP segment // information, and can be added to intrusive lists. // segment is mostly immutable, the only field allowed to change is viewToDeliver. +// +// +stateify savable type segment struct { segmentEntry refCnt int32 diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 2ddcf5f10..6a2d7bc0b 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -21,6 +21,8 @@ import ( ) // segmentQueue is a bounded, thread-safe queue of TCP segments. +// +// +stateify savable type segmentQueue struct { mu sync.Mutex `state:"nosave"` list segmentList `state:"wait"` diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index e38686e1b..376e81846 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -54,6 +54,8 @@ type congestionControl interface { } // sender holds the state necessary to send TCP segments. +// +// +stateify savable type sender struct { ep *endpoint @@ -133,6 +135,8 @@ type sender struct { } // fastRecovery holds information related to fast recovery from a packet loss. +// +// +stateify savable type fastRecovery struct { // active whether the endpoint is in fast recovery. The following fields // are only meaningful when active is true. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index 33c8867f4..d536839af 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -18,6 +18,7 @@ import ( "time" ) +// +stateify savable type unixTime struct { second int64 nano int64 diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 790dd55a3..1a3a62d3d 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,19 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "udp_state", - srcs = [ - "endpoint.go", - "endpoint_state.go", - "udp_packet_list.go", - ], - out = "udp_state.go", - imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], - package = "udp", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "udp_packet_list", @@ -33,13 +21,12 @@ go_library( "endpoint_state.go", "protocol.go", "udp_packet_list.go", - "udp_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp", + imports = ["gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"], visibility = ["//visibility:public"], deps = [ "//pkg/sleep", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/header", diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 2a32c3a87..03fb76f92 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -25,6 +25,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) +// +stateify savable type udpPacket struct { udpPacketEntry senderAddress tcpip.FullAddress @@ -49,6 +50,8 @@ const ( // between users of the endpoint and the protocol implementation; it is legal to // have concurrent goroutines make calls into the endpoint, they are properly // synchronized. +// +// +stateify savable type endpoint struct { // The following fields are initialized at creation time and do not // change throughout the lifetime of the endpoint. diff --git a/pkg/tcpip/transport/unix/BUILD b/pkg/tcpip/transport/unix/BUILD index 676f2cf92..dae0bd079 100644 --- a/pkg/tcpip/transport/unix/BUILD +++ b/pkg/tcpip/transport/unix/BUILD @@ -1,17 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "unix_state", - srcs = [ - "connectioned.go", - "connectionless.go", - "unix.go", - ], - out = "unix_state.go", - package = "unix", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "unix", @@ -20,14 +9,11 @@ go_library( "connectioned_state.go", "connectionless.go", "unix.go", - "unix_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix", visibility = ["//:sandbox"], deps = [ "//pkg/ilist", - "//pkg/log", - "//pkg/state", "//pkg/tcpip", "//pkg/tcpip/buffer", "//pkg/tcpip/transport/queue", diff --git a/pkg/tcpip/transport/unix/connectioned.go b/pkg/tcpip/transport/unix/connectioned.go index 0e63186b2..dd7c03cf1 100644 --- a/pkg/tcpip/transport/unix/connectioned.go +++ b/pkg/tcpip/transport/unix/connectioned.go @@ -85,6 +85,8 @@ type ConnectingEndpoint interface { // path != "" && acceptedChan != nil => bound and listening. // // Only one of these will be true at any moment. +// +// +stateify savable type connectionedEndpoint struct { baseEndpoint diff --git a/pkg/tcpip/transport/unix/connectionless.go b/pkg/tcpip/transport/unix/connectionless.go index 3276ddcd0..2a6ec8b4b 100644 --- a/pkg/tcpip/transport/unix/connectionless.go +++ b/pkg/tcpip/transport/unix/connectionless.go @@ -25,6 +25,8 @@ import ( // // Specifically, this means datagram unix sockets not created with // socketpair(2). +// +// +stateify savable type connectionlessEndpoint struct { baseEndpoint } diff --git a/pkg/tcpip/transport/unix/unix.go b/pkg/tcpip/transport/unix/unix.go index 190a1ccdb..8e4af3139 100644 --- a/pkg/tcpip/transport/unix/unix.go +++ b/pkg/tcpip/transport/unix/unix.go @@ -60,6 +60,8 @@ type CredentialsControlMessage interface { } // A ControlMessages represents a collection of socket control messages. +// +// +stateify savable type ControlMessages struct { // Rights is a control message containing FDs. Rights RightsControlMessage @@ -235,6 +237,8 @@ type BoundEndpoint interface { } // message represents a message passed over a Unix domain socket. +// +// +stateify savable type message struct { ilist.Entry @@ -306,6 +310,8 @@ type Receiver interface { } // queueReceiver implements Receiver for datagram sockets. +// +// +stateify savable type queueReceiver struct { readQueue *queue.Queue } @@ -369,6 +375,8 @@ func (q *queueReceiver) RecvMaxQueueSize() int64 { func (*queueReceiver) Release() {} // streamQueueReceiver implements Receiver for stream sockets. +// +// +stateify savable type streamQueueReceiver struct { queueReceiver @@ -579,6 +587,7 @@ type ConnectedEndpoint interface { Release() } +// +stateify savable type connectedEndpoint struct { // endpoint represents the subset of the Endpoint functionality needed by // the connectedEndpoint. It is implemented by both connectionedEndpoint @@ -671,6 +680,8 @@ func (*connectedEndpoint) Release() {} // unix domain socket Endpoint implementations. // // Not to be used on its own. +// +// +stateify savable type baseEndpoint struct { *waiter.Queue diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 8256acdb4..5e611c54f 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,28 +1,13 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "waiter_state", - srcs = [ - "waiter.go", - ], - out = "waiter_state.go", - package = "waiter", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "waiter", - srcs = [ - "waiter.go", - "waiter_state.go", - ], + srcs = ["waiter.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/waiter", visibility = ["//visibility:public"], - deps = [ - "//pkg/ilist", - "//pkg/state", - ], + deps = ["//pkg/ilist"], ) go_test( diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 9b189bb9e..9825880ca 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -157,6 +157,8 @@ func NewChannelEntry(c chan struct{}) (Entry, chan struct{}) { // notifiers can notify them when events happen. // // The zero value for waiter.Queue is an empty queue ready for use. +// +// +stateify savable type Queue struct { list ilist.List `state:"zerovalue"` mu sync.RWMutex `state:"nosave"` -- cgit v1.2.3 From b6a37ab9d96b382e26e3836a42ea485c48a521a8 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 2 Aug 2018 15:55:19 -0700 Subject: Update comment reference PiperOrigin-RevId: 207180809 Change-Id: I08c264812919e81b2c56fdd4a9ef06924de8b52f --- pkg/abi/linux/tty.go | 24 ++++++++++++------------ pkg/sentry/fs/mount.go | 8 ++++---- pkg/sentry/syscalls/linux/sys_prctl.go | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index b640f7627..8c611d22a 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -286,18 +286,18 @@ var DefaultControlCharacters = [NumControlCharacters]uint8{ '\x7f', // VERASE = DEL ControlCharacter('U'), // VKILL = ^U ControlCharacter('D'), // VEOF = ^D - 0, // VTIME - 1, // VMIN - 0, // VSWTC - ControlCharacter('Q'), // VSTART = ^Q - ControlCharacter('S'), // VSTOP = ^S - ControlCharacter('Z'), // VSUSP = ^Z - 0, // VEOL - ControlCharacter('R'), // VREPRINT = ^R - ControlCharacter('O'), // VDISCARD = ^O - ControlCharacter('W'), // VWERASE = ^W - ControlCharacter('V'), // VLNEXT = ^V - 0, // VEOL2 + 0, // VTIME + 1, // VMIN + 0, // VSWTC + ControlCharacter('Q'), // VSTART = ^Q + ControlCharacter('S'), // VSTOP = ^S + ControlCharacter('Z'), // VSUSP = ^Z + 0, // VEOL + ControlCharacter('R'), // VREPRINT = ^R + ControlCharacter('O'), // VDISCARD = ^O + ControlCharacter('W'), // VWERASE = ^W + ControlCharacter('V'), // VLNEXT = ^V + 0, // VEOL2 } // MasterTermios is the terminal configuration of the master end of a Unix98 diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 4ede767f9..c72372929 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -159,10 +159,10 @@ const defaultDirentCacheSize uint64 = 1000 func NewMountSource(mops MountSourceOperations, filesystem Filesystem, flags MountSourceFlags) *MountSource { return &MountSource{ MountSourceOperations: mops, - Flags: flags, - Filesystem: filesystem, - fscache: NewDirentCache(defaultDirentCacheSize), - children: make(map[*MountSource]struct{}), + Flags: flags, + Filesystem: filesystem, + fscache: NewDirentCache(defaultDirentCacheSize), + children: make(map[*MountSource]struct{}), } } diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go index 911fef658..a1242acd3 100644 --- a/pkg/sentry/syscalls/linux/sys_prctl.go +++ b/pkg/sentry/syscalls/linux/sys_prctl.go @@ -113,7 +113,7 @@ func Prctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall return 0, nil, syscall.EINVAL } // no_new_privs is assumed to always be set. See - // auth.Credentials.UpdateForExec. + // kernel.Task.updateCredsForExec. return 0, nil, nil case linux.PR_GET_NO_NEW_PRIVS: -- cgit v1.2.3 From 4e171f7590284c1f4cedf90c92204873961b2e97 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Wed, 8 Aug 2018 22:38:41 -0700 Subject: Basic support for ip link/addr and ifconfig Closes #94 PiperOrigin-RevId: 207997580 Change-Id: I19b426f1586b5ec12f8b0cd5884d5b401d334924 --- pkg/abi/linux/netlink_route.go | 5 +++ pkg/sentry/inet/inet.go | 3 ++ pkg/sentry/socket/epsocket/epsocket.go | 52 ++++++++++------------- pkg/sentry/socket/epsocket/stack.go | 12 ++++-- pkg/sentry/socket/netlink/route/protocol.go | 15 ++++++- pkg/sentry/socket/netlink/socket.go | 64 ++++++++++++++++++++++++++--- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/stack/nic.go | 7 ++++ pkg/tcpip/stack/registration.go | 1 + pkg/tcpip/stack/stack.go | 36 ++++++++-------- runsc/boot/network.go | 5 ++- 11 files changed, 138 insertions(+), 64 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go index 0d88bc5c5..a5d778748 100644 --- a/pkg/abi/linux/netlink_route.go +++ b/pkg/abi/linux/netlink_route.go @@ -184,3 +184,8 @@ const ( IFA_MULTICAST = 7 IFA_FLAGS = 8 ) + +// Device types, from uapi/linux/if_arp.h. +const ( + ARPHRD_LOOPBACK = 772 +) diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index e54a61196..30ca4e0c0 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -67,6 +67,9 @@ type Interface struct { // Addr is the hardware device address. Addr []byte + + // MTU is the maximum transmission unit. + MTU uint32 } // InterfaceAddr contains information about a network interface address. diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index f969a1d7c..b32eda96f 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -48,7 +48,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/tcpip" "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" - nstack "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" + "gvisor.googlesource.com/gvisor/pkg/tcpip/stack" "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" "gvisor.googlesource.com/gvisor/pkg/waiter" ) @@ -452,7 +452,7 @@ func (s *SocketOperations) GetSockOpt(t *kernel.Task, level, name, outLen int) ( // sockets backed by a commonEndpoint. func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, skType unix.SockType, level, name, outLen int) (interface{}, *syserr.Error) { switch level { - case syscall.SOL_SOCKET: + case linux.SOL_SOCKET: switch name { case linux.SO_TYPE: if outLen < sizeOfInt32 { @@ -634,7 +634,7 @@ func (s *SocketOperations) SetSockOpt(t *kernel.Task, level int, name int, optVa // sockets backed by a commonEndpoint. func SetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, level int, name int, optVal []byte) *syserr.Error { switch level { - case syscall.SOL_SOCKET: + case linux.SOL_SOCKET: switch name { case linux.SO_SNDBUF: if len(optVal) < sizeOfInt32 { @@ -1191,7 +1191,9 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe if err != nil { return err } - usermem.ByteOrder.PutUint16(ifr.Data[:2], f) + // Drop the flags that don't fit in the size that we need to return. This + // matches Linux behavior. + usermem.ByteOrder.PutUint16(ifr.Data[:2], uint16(f)) case syscall.SIOCGIFADDR: // Copy the IPv4 address out. @@ -1304,7 +1306,7 @@ func ifconfIoctl(ctx context.Context, io usermem.IO, ifc *linux.IFConf) error { // interfaceStatusFlags returns status flags for an interface in the stack. // Flag values and meanings are described in greater detail in netdevice(7) in // the SIOCGIFFLAGS section. -func interfaceStatusFlags(stack inet.Stack, name string) (uint16, *syserr.Error) { +func interfaceStatusFlags(stack inet.Stack, name string) (uint32, *syserr.Error) { // epsocket should only ever be passed an epsocket.Stack. epstack, ok := stack.(*Stack) if !ok { @@ -1312,37 +1314,27 @@ func interfaceStatusFlags(stack inet.Stack, name string) (uint16, *syserr.Error) } // Find the NIC corresponding to this interface. - var ( - nicid tcpip.NICID - info nstack.NICInfo - found bool - ) - ns := epstack.Stack - for nicid, info = range ns.NICInfo() { + for _, info := range epstack.Stack.NICInfo() { if info.Name == name { - found = true - break + return nicStateFlagsToLinux(info.Flags), nil } } - if !found { - return 0, syserr.ErrNoDevice - } + return 0, syserr.ErrNoDevice +} - // Set flags based on NIC state. - nicFlags, err := ns.NICFlags(nicid) - if err != nil { - return 0, syserr.TranslateNetstackError(err) +func nicStateFlagsToLinux(f stack.NICStateFlags) uint32 { + var rv uint32 + if f.Up { + rv |= linux.IFF_UP | linux.IFF_LOWER_UP } - - var retFlags uint16 - if nicFlags.Up { - retFlags |= linux.IFF_UP + if f.Running { + rv |= linux.IFF_RUNNING } - if nicFlags.Running { - retFlags |= linux.IFF_RUNNING + if f.Promiscuous { + rv |= linux.IFF_PROMISC } - if nicFlags.Promiscuous { - retFlags |= linux.IFF_PROMISC + if f.Loopback { + rv |= linux.IFF_LOOPBACK } - return retFlags, nil + return rv } diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 12b4b4767..e4ed52fc8 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -41,10 +41,16 @@ func (s *Stack) SupportsIPv6() bool { func (s *Stack) Interfaces() map[int32]inet.Interface { is := make(map[int32]inet.Interface) for id, ni := range s.Stack.NICInfo() { + var devType uint16 + if ni.Flags.Loopback { + devType = linux.ARPHRD_LOOPBACK + } is[int32(id)] = inet.Interface{ - Name: ni.Name, - Addr: []byte(ni.LinkAddress), - // TODO: Other fields. + Name: ni.Name, + Addr: []byte(ni.LinkAddress), + Flags: uint32(nicStateFlagsToLinux(ni.Flags)), + DeviceType: devType, + MTU: ni.MTU, } } return is diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 55a76e916..70322b9ed 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -16,6 +16,8 @@ package route import ( + "bytes" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/inet" @@ -97,9 +99,18 @@ func (p *Protocol) dumpLinks(ctx context.Context, hdr linux.NetlinkMessageHeader }) m.PutAttrString(linux.IFLA_IFNAME, i.Name) + m.PutAttr(linux.IFLA_MTU, i.MTU) + + mac := make([]byte, 6) + brd := mac + if len(i.Addr) > 0 { + mac = i.Addr + brd = bytes.Repeat([]byte{0xff}, len(i.Addr)) + } + m.PutAttr(linux.IFLA_ADDRESS, mac) + m.PutAttr(linux.IFLA_BROADCAST, brd) - // TODO: There are many more attributes, such as - // MAC address. + // TODO: There are many more attributes. } return nil diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index e15d1546c..f3b2c7256 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -16,6 +16,7 @@ package netlink import ( + "math" "sync" "gvisor.googlesource.com/gvisor/pkg/abi/linux" @@ -39,8 +40,18 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// defaultSendBufferSize is the default size for the send buffer. -const defaultSendBufferSize = 16 * 1024 +const sizeOfInt32 int = 4 + +const ( + // minBufferSize is the smallest size of a send buffer. + minSendBufferSize = 4 << 10 // 4096 bytes. + + // defaultSendBufferSize is the default size for the send buffer. + defaultSendBufferSize = 16 * 1024 + + // maxBufferSize is the largest size a send buffer can grow to. + maxSendBufferSize = 4 << 20 // 4MB +) // netlinkSocketDevice is the netlink socket virtual device. var netlinkSocketDevice = device.NewAnonDevice() @@ -86,7 +97,7 @@ type Socket struct { // sendBufferSize is the send buffer "size". We don't actually have a // fixed buffer but only consume this many bytes. - sendBufferSize uint64 + sendBufferSize uint32 } var _ socket.Socket = (*Socket)(nil) @@ -273,13 +284,54 @@ func (s *Socket) Shutdown(t *kernel.Task, how int) *syserr.Error { // GetSockOpt implements socket.Socket.GetSockOpt. func (s *Socket) GetSockOpt(t *kernel.Task, level int, name int, outLen int) (interface{}, *syserr.Error) { - // TODO: no sockopts supported. + switch level { + case linux.SOL_SOCKET: + switch name { + case linux.SO_SNDBUF: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + return int32(s.sendBufferSize), nil + + case linux.SO_RCVBUF: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + // We don't have limit on receiving size. + return math.MaxInt32, nil + } + } + // TODO: other sockopts are not supported. return nil, syserr.ErrProtocolNotAvailable } // SetSockOpt implements socket.Socket.SetSockOpt. func (s *Socket) SetSockOpt(t *kernel.Task, level int, name int, opt []byte) *syserr.Error { - // TODO: no sockopts supported. + switch level { + case linux.SOL_SOCKET: + switch name { + case linux.SO_SNDBUF: + if len(opt) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + size := usermem.ByteOrder.Uint32(opt) + if size < minSendBufferSize { + size = minSendBufferSize + } else if size > maxSendBufferSize { + size = maxSendBufferSize + } + s.sendBufferSize = size + return nil + case linux.SO_RCVBUF: + if len(opt) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + // We don't have limit on receiving size. So just accept anything as + // valid for compatibility. + return nil + } + } + // TODO: other sockopts are not supported. return syserr.ErrProtocolNotAvailable } @@ -489,7 +541,7 @@ func (s *Socket) sendMsg(ctx context.Context, src usermem.IOSequence, to []byte, // For simplicity, and consistency with Linux, we copy in the entire // message up front. - if uint64(src.NumBytes()) > s.sendBufferSize { + if src.NumBytes() > int64(s.sendBufferSize) { return 0, syserr.ErrMessageTooLong } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index b4dc4833c..015275721 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -56,7 +56,7 @@ func (*endpoint) MTU() uint32 { // Capabilities implements stack.LinkEndpoint.Capabilities. Loopback advertises // itself as supporting checksum offload, but in reality it's just omitted. func (*endpoint) Capabilities() stack.LinkEndpointCapabilities { - return stack.CapabilityChecksumOffload | stack.CapabilitySaveRestore + return stack.CapabilityChecksumOffload | stack.CapabilitySaveRestore | stack.CapabilityLoopback } // MaxHeaderLength implements stack.LinkEndpoint.MaxHeaderLength. Given that the diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c1480f97b..592006a32 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -67,6 +67,13 @@ func (n *NIC) setPromiscuousMode(enable bool) { n.mu.Unlock() } +func (n *NIC) isPromiscuousMode() bool { + n.mu.RLock() + rv := n.promiscuous + n.mu.RUnlock() + return rv +} + // setSpoofing enables or disables address spoofing. func (n *NIC) setSpoofing(enable bool) { n.mu.Lock() diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 01a29689d..bbe887144 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -205,6 +205,7 @@ const ( CapabilityResolutionRequired CapabilitySaveRestore CapabilityDisconnectOk + CapabilityLoopback ) // LinkEndpoint is the interface implemented by data link layer protocols (e.g., diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 6c4aa7cc5..e2b9dc2c0 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -563,6 +563,12 @@ type NICInfo struct { Name string LinkAddress tcpip.LinkAddress ProtocolAddresses []tcpip.ProtocolAddress + + // Flags indicate the state of the NIC. + Flags NICStateFlags + + // MTU is the maximum transmission unit. + MTU uint32 } // NICInfo returns a map of NICIDs to their associated information. @@ -572,10 +578,18 @@ func (s *Stack) NICInfo() map[tcpip.NICID]NICInfo { nics := make(map[tcpip.NICID]NICInfo) for id, nic := range s.nics { + flags := NICStateFlags{ + Up: true, // Netstack interfaces are always up. + Running: nic.linkEP.IsAttached(), + Promiscuous: nic.isPromiscuousMode(), + Loopback: nic.linkEP.Capabilities()&CapabilityLoopback != 0, + } nics[id] = NICInfo{ Name: nic.name, LinkAddress: nic.linkEP.LinkAddress(), ProtocolAddresses: nic.Addresses(), + Flags: flags, + MTU: nic.linkEP.MTU(), } } return nics @@ -591,27 +605,9 @@ type NICStateFlags struct { // Promiscuous indicates whether the interface is in promiscuous mode. Promiscuous bool -} - -// NICFlags returns flags about the state of the NIC. It returns an error if -// the NIC corresponding to id cannot be found. -func (s *Stack) NICFlags(id tcpip.NICID) (NICStateFlags, *tcpip.Error) { - s.mu.RLock() - defer s.mu.RUnlock() - nic := s.nics[id] - if nic == nil { - return NICStateFlags{}, tcpip.ErrUnknownNICID - } - - ret := NICStateFlags{ - // Netstack interfaces are always up. - Up: true, - - Running: nic.linkEP.IsAttached(), - Promiscuous: nic.promiscuous, - } - return ret, nil + // Loopback indicates whether the interface is a loopback. + Loopback bool } // AddAddress adds a new network-layer address to the specified NIC. diff --git a/runsc/boot/network.go b/runsc/boot/network.go index d702ae74e..0e43c91be 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -133,15 +133,16 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct return fmt.Errorf("failed to dup FD %v: %v", oldFD, err) } + mac := tcpip.LinkAddress(generateRndMac()) linkEP := fdbased.New(&fdbased.Options{ FD: newFD, MTU: uint32(link.MTU), EthernetHeader: true, HandleLocal: true, - Address: tcpip.LinkAddress(generateRndMac()), + Address: mac, }) - log.Infof("Enabling interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses) + log.Infof("Enabling interface %q with id %d on addresses %+v (%v)", link.Name, nicID, link.Addresses, mac) if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses); err != nil { return err } -- cgit v1.2.3 From 2e06b23aa61216fcdbefcd6b11a24bca7a456b16 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 9 Aug 2018 16:49:23 -0700 Subject: Fix missing O_LARGEFILE from O_CREAT files Cleanup some more syscall.O_* references while we're here. PiperOrigin-RevId: 208133460 Change-Id: I48db71a38f817e4f4673977eafcc0e3874eb9a25 --- pkg/abi/linux/file.go | 4 ++++ pkg/sentry/kernel/fd_map.go | 6 ++++-- pkg/sentry/syscalls/linux/flags.go | 14 ++------------ pkg/sentry/syscalls/linux/sys_file.go | 32 ++++++++++++++++++-------------- pkg/sentry/syscalls/linux/sys_pipe.go | 7 ++++--- 5 files changed, 32 insertions(+), 31 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index f2b7e26ca..509f6b5b3 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -27,6 +27,10 @@ const ( O_RDONLY = 00000000 O_WRONLY = 00000001 O_RDWR = 00000002 + O_CREAT = 00000100 + O_EXCL = 00000200 + O_NOCTTY = 00000400 + O_TRUNC = 00001000 O_APPEND = 00002000 O_NONBLOCK = 00004000 O_ASYNC = 00020000 diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index d5d4aaacb..cad0b0a20 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -53,7 +53,8 @@ type FDFlags struct { CloseOnExec bool } -// ToLinuxFileFlags converts a kernel.FDFlags object to a Linux file flags representation. +// ToLinuxFileFlags converts a kernel.FDFlags object to a Linux file flags +// representation. func (f FDFlags) ToLinuxFileFlags() (mask uint) { if f.CloseOnExec { mask |= linux.O_CLOEXEC @@ -61,7 +62,8 @@ func (f FDFlags) ToLinuxFileFlags() (mask uint) { return } -// ToLinuxFDFlags converts a kernel.FDFlags object to a Linux descriptor flags representation. +// ToLinuxFDFlags converts a kernel.FDFlags object to a Linux descriptor flags +// representation. func (f FDFlags) ToLinuxFDFlags() (mask uint) { if f.CloseOnExec { mask |= linux.FD_CLOEXEC diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index e8db3e0de..f01483cd3 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -34,8 +34,8 @@ func flagsToPermissions(mask uint) (p fs.PermMask) { return } -// linuxToFlags converts linux file flags to a FileFlags object. -func linuxToFlags(mask uint) (flags fs.FileFlags) { +// linuxToFlags converts Linux file flags to a FileFlags object. +func linuxToFlags(mask uint) fs.FileFlags { return fs.FileFlags{ Direct: mask&linux.O_DIRECT != 0, Sync: mask&linux.O_SYNC != 0, @@ -48,13 +48,3 @@ func linuxToFlags(mask uint) (flags fs.FileFlags) { LargeFile: mask&linux.O_LARGEFILE != 0, } } - -// linuxToSettableFlags converts linux file flags to a SettableFileFlags object. -func linuxToSettableFlags(mask uint) fs.SettableFileFlags { - return fs.SettableFileFlags{ - Direct: mask&linux.O_DIRECT != 0, - NonBlocking: mask&linux.O_NONBLOCK != 0, - Append: mask&linux.O_APPEND != 0, - Async: mask&linux.O_ASYNC != 0, - } -} diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 94b7ac7a5..2cf429f5c 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -164,7 +164,7 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u if dirPath { return syserror.ENOTDIR } - if fileFlags.Write && flags&syscall.O_TRUNC != 0 { + if fileFlags.Write && flags&linux.O_TRUNC != 0 { if err := d.Inode.Truncate(t, d, 0); err != nil { return err } @@ -178,7 +178,7 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u defer file.DecRef() // Success. - fdFlags := kernel.FDFlags{CloseOnExec: flags&syscall.O_CLOEXEC != 0} + fdFlags := kernel.FDFlags{CloseOnExec: flags&linux.O_CLOEXEC != 0} newFD, err := t.FDMap().NewFDFrom(0, file, fdFlags, t.ThreadGroup().Limits()) if err != nil { return err @@ -302,6 +302,10 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod return syserror.ENOTDIR } + fileFlags := linuxToFlags(flags) + // Linux always adds the O_LARGEFILE flag when running in 64-bit mode. + fileFlags.LargeFile = true + // Does this file exist already? targetDirent, err := t.MountNamespace().FindInode(t, root, d, name, linux.MaxSymlinkTraversals) var newFile *fs.File @@ -311,7 +315,7 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod defer targetDirent.DecRef() // Check if we wanted to create. - if flags&syscall.O_EXCL != 0 { + if flags&linux.O_EXCL != 0 { return syserror.EEXIST } @@ -323,14 +327,14 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod } // Should we truncate the file? - if flags&syscall.O_TRUNC != 0 { + if flags&linux.O_TRUNC != 0 { if err := targetDirent.Inode.Truncate(t, targetDirent, 0); err != nil { return err } } // Create a new fs.File. - newFile, err = targetDirent.Inode.GetFile(t, targetDirent, linuxToFlags(flags)) + newFile, err = targetDirent.Inode.GetFile(t, targetDirent, fileFlags) if err != nil { return syserror.ConvertIntr(err, kernel.ERESTARTSYS) } @@ -346,7 +350,7 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod // Attempt a creation. perms := fs.FilePermsFromMode(mode &^ linux.FileMode(t.FSContext().Umask())) - newFile, err = d.Create(t, root, name, linuxToFlags(flags), perms) + newFile, err = d.Create(t, root, name, fileFlags, perms) if err != nil { // No luck, bail. return err @@ -356,7 +360,7 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod } // Success. - fdFlags := kernel.FDFlags{CloseOnExec: flags&syscall.O_CLOEXEC != 0} + fdFlags := kernel.FDFlags{CloseOnExec: flags&linux.O_CLOEXEC != 0} newFD, err := t.FDMap().NewFDFrom(0, newFile, fdFlags, t.ThreadGroup().Limits()) if err != nil { return err @@ -380,7 +384,7 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod func Open(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { addr := args[0].Pointer() flags := uint(args[1].Uint()) - if flags&syscall.O_CREAT != 0 { + if flags&linux.O_CREAT != 0 { mode := linux.FileMode(args[2].ModeT()) n, err := createAt(t, linux.AT_FDCWD, addr, flags, mode) return n, nil, err @@ -394,7 +398,7 @@ func Openat(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal dirFD := kdefs.FD(args[0].Int()) addr := args[1].Pointer() flags := uint(args[2].Uint()) - if flags&syscall.O_CREAT != 0 { + if flags&linux.O_CREAT != 0 { mode := linux.FileMode(args[3].ModeT()) n, err := createAt(t, dirFD, addr, flags, mode) return n, nil, err @@ -407,7 +411,7 @@ func Openat(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal func Creat(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { addr := args[0].Pointer() mode := linux.FileMode(args[1].ModeT()) - n, err := createAt(t, linux.AT_FDCWD, addr, syscall.O_WRONLY|syscall.O_TRUNC, mode) + n, err := createAt(t, linux.AT_FDCWD, addr, linux.O_WRONLY|linux.O_TRUNC, mode) return n, nil, err } @@ -747,7 +751,7 @@ func Dup3(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC } defer oldFile.DecRef() - err := t.FDMap().NewFDAt(newfd, oldFile, kernel.FDFlags{CloseOnExec: flags&syscall.O_CLOEXEC != 0}, t.ThreadGroup().Limits()) + err := t.FDMap().NewFDAt(newfd, oldFile, kernel.FDFlags{CloseOnExec: flags&linux.O_CLOEXEC != 0}, t.ThreadGroup().Limits()) if err != nil { return 0, nil, err } @@ -802,7 +806,7 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall switch cmd { case linux.F_DUPFD, linux.F_DUPFD_CLOEXEC: from := kdefs.FD(args[2].Int()) - fdFlags := kernel.FDFlags{CloseOnExec: cmd == syscall.F_DUPFD_CLOEXEC} + fdFlags := kernel.FDFlags{CloseOnExec: cmd == linux.F_DUPFD_CLOEXEC} fd, err := t.FDMap().NewFDFrom(from, file, fdFlags, t.ThreadGroup().Limits()) if err != nil { return 0, nil, err @@ -813,13 +817,13 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall case linux.F_SETFD: flags := args[2].Uint() t.FDMap().SetFlags(fd, kernel.FDFlags{ - CloseOnExec: flags&syscall.FD_CLOEXEC != 0, + CloseOnExec: flags&linux.FD_CLOEXEC != 0, }) case linux.F_GETFL: return uintptr(file.Flags().ToLinux()), nil, nil case linux.F_SETFL: flags := uint(args[2].Uint()) - file.SetFlags(linuxToSettableFlags(flags)) + file.SetFlags(linuxToFlags(flags).Settable()) case linux.F_SETLK, linux.F_SETLKW: // In Linux the file system can choose to provide lock operations for an inode. // Normally pipe and socket types lack lock operations. We diverge and use a heavy diff --git a/pkg/sentry/syscalls/linux/sys_pipe.go b/pkg/sentry/syscalls/linux/sys_pipe.go index 3efc06a27..2b544f145 100644 --- a/pkg/sentry/syscalls/linux/sys_pipe.go +++ b/pkg/sentry/syscalls/linux/sys_pipe.go @@ -17,6 +17,7 @@ package linux import ( "syscall" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" @@ -26,7 +27,7 @@ import ( // pipe2 implements the actual system call with flags. func pipe2(t *kernel.Task, addr usermem.Addr, flags uint) (uintptr, error) { - if flags&^(syscall.O_NONBLOCK|syscall.O_CLOEXEC) != 0 { + if flags&^(linux.O_NONBLOCK|linux.O_CLOEXEC) != 0 { return 0, syscall.EINVAL } r, w := pipe.NewConnectedPipe(t, pipe.DefaultPipeSize, usermem.PageSize) @@ -38,14 +39,14 @@ func pipe2(t *kernel.Task, addr usermem.Addr, flags uint) (uintptr, error) { defer w.DecRef() rfd, err := t.FDMap().NewFDFrom(0, r, kernel.FDFlags{ - CloseOnExec: flags&syscall.O_CLOEXEC != 0}, + CloseOnExec: flags&linux.O_CLOEXEC != 0}, t.ThreadGroup().Limits()) if err != nil { return 0, err } wfd, err := t.FDMap().NewFDFrom(0, w, kernel.FDFlags{ - CloseOnExec: flags&syscall.O_CLOEXEC != 0}, + CloseOnExec: flags&linux.O_CLOEXEC != 0}, t.ThreadGroup().Limits()) if err != nil { t.FDMap().Remove(rfd) -- cgit v1.2.3 From ae6f092fe117a738df34e072ef5ba01a41c89222 Mon Sep 17 00:00:00 2001 From: Justine Olshan Date: Fri, 10 Aug 2018 16:09:52 -0700 Subject: Implemented the splice(2) syscall. Currently the implementation matches the behavior of moving data between two file descriptors. However, it does not implement this through zero-copy movement. Thus, this code is a starting point to build the more complex implementation. PiperOrigin-RevId: 208284483 Change-Id: Ibde79520a3d50bc26aead7ad4f128d2be31db14e --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/splice.go | 20 +++ pkg/sentry/syscalls/linux/BUILD | 1 + pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_splice.go | 260 ++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 pkg/abi/linux/splice.go create mode 100644 pkg/sentry/syscalls/linux/sys_splice.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index ac4ceefbc..9a44c2042 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -43,6 +43,7 @@ go_library( "shm.go", "signal.go", "socket.go", + "splice.go", "time.go", "tty.go", "uio.go", diff --git a/pkg/abi/linux/splice.go b/pkg/abi/linux/splice.go new file mode 100644 index 000000000..9331ec84b --- /dev/null +++ b/pkg/abi/linux/splice.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// Flags for splice(2). +const ( + SPLICE_F_NONBLOCK = 2 +) diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index bbdfad9da..62423c0fa 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -34,6 +34,7 @@ go_library( "sys_shm.go", "sys_signal.go", "sys_socket.go", + "sys_splice.go", "sys_stat.go", "sys_sync.go", "sys_sysinfo.go", diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index c102af101..485c96202 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -319,7 +319,7 @@ var AMD64 = &kernel.SyscallTable{ 272: Unshare, 273: syscalls.Error(syscall.ENOSYS), // SetRobustList, obsolete 274: syscalls.Error(syscall.ENOSYS), // GetRobustList, obsolete - // 275: Splice, TODO + 275: Splice, // 276: Tee, TODO // 277: SyncFileRange, TODO // 278: Vmsplice, TODO diff --git a/pkg/sentry/syscalls/linux/sys_splice.go b/pkg/sentry/syscalls/linux/sys_splice.go new file mode 100644 index 000000000..8151e3599 --- /dev/null +++ b/pkg/sentry/syscalls/linux/sys_splice.go @@ -0,0 +1,260 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +import ( + "io" + + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/pipe" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +// Splice implements linux syscall splice(2). +func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + fdIn := kdefs.FD(args[0].Int()) + offIn := args[1].Pointer() + fdOut := kdefs.FD(args[2].Int()) + offOut := args[3].Pointer() + size := int64(args[4].SizeT()) + flags := uint(args[5].Uint()) + + fileIn := t.FDMap().GetFile(fdIn) + if fileIn == nil { + return 0, nil, syserror.EBADF + } + defer fileIn.DecRef() + fileOut := t.FDMap().GetFile(fdOut) + if fileOut == nil { + return 0, nil, syserror.EBADF + } + defer fileOut.DecRef() + + // Check for whether we have pipes. + ipipe := fs.IsPipe(fileIn.Dirent.Inode.StableAttr) + opipe := fs.IsPipe(fileOut.Dirent.Inode.StableAttr) + if (ipipe && offIn != 0) || (opipe && offOut != 0) { + return 0, nil, syserror.ESPIPE + } + + // Check if both file descriptors are pipes. + if ipipe && opipe { + var readPipe *pipe.Pipe + switch p := fileIn.FileOperations.(type) { + case *pipe.Reader: + readPipe = p.ReaderWriter.Pipe + case *pipe.ReaderWriter: + readPipe = p.Pipe + default: + return 0, nil, syserror.EBADF + } + var writePipe *pipe.Pipe + switch p := fileOut.FileOperations.(type) { + case *pipe.Writer: + writePipe = p.ReaderWriter.Pipe + case *pipe.ReaderWriter: + writePipe = p.Pipe + default: + return 0, nil, syserror.EBADF + } + + // Splicing with two ends of the same pipe is not allowed. + if readPipe == writePipe { + return 0, nil, syserror.EINVAL + } + spliced, err := splicePipeToPipe(t, fileIn, fileOut, size, flags) + if err != nil { + return 0, nil, err + } + return uintptr(spliced), nil, nil + } + + // Check if the file descriptor that contains the data to move is a pipe. + if ipipe { + flagsOut := fileOut.Flags() + offset := uint64(fileOut.Offset()) + + // If there is an offset for the file, ensure the file has the Pwrite flag. + if offOut != 0 { + if !flagsOut.Pwrite { + return 0, nil, syserror.EINVAL + } + if _, err := t.CopyIn(offOut, &offset); err != nil { + return 0, nil, err + } + } + + if !flagsOut.Write { + return 0, nil, syserror.EBADF + } + + if flagsOut.Append { + return 0, nil, syserror.EINVAL + } + + switch fileIn.FileOperations.(type) { + case *pipe.Reader, *pipe.ReaderWriter: + // If the pipe in is a Reader or ReaderWriter, we can continue. + default: + return 0, nil, syserror.EBADF + } + spliced, err := spliceWrite(t, fileIn, fileOut, size, offset, flags) + if err != nil { + return 0, nil, err + } + + // Make sure value that offset points to is updated. + if offOut == 0 { + fileOut.Seek(t, fs.SeekSet, spliced+int64(offset)) + } else if _, err := t.CopyOut(offOut, spliced+int64(offset)); err != nil { + return 0, nil, err + } + return uintptr(spliced), nil, nil + } + + // Check if the file descriptor that the data will be moved to is a pipe. + if opipe { + flagsIn := fileIn.Flags() + offset := uint64(fileIn.Offset()) + + // If there is an offset for the file, ensure the file has the Pread flag. + if offIn != 0 { + if !flagsIn.Pread { + return 0, nil, syserror.EINVAL + } + if _, err := t.CopyIn(offIn, &offset); err != nil { + return 0, nil, err + } + } + + if !flagsIn.Read { + return 0, nil, syserror.EBADF + } + + switch fileOut.FileOperations.(type) { + case *pipe.Writer, *pipe.ReaderWriter: + // If the pipe out is a Writer or ReaderWriter, we can continue. + default: + return 0, nil, syserror.EBADF + } + spliced, err := spliceRead(t, fileIn, fileOut, size, offset, flags) + if err != nil { + return 0, nil, err + } + + // Make sure value that offset points to is updated. + if offIn == 0 { + fileOut.Seek(t, fs.SeekSet, spliced+int64(offset)) + } else if _, err := t.CopyOut(offIn, spliced+int64(offset)); err != nil { + return 0, nil, err + } + return uintptr(spliced), nil, nil + } + + // Splice requires one of the file descriptors to be a pipe. + return 0, nil, syserror.EINVAL +} + +// splicePipeToPipe moves data from one pipe to another pipe. +// TODO: Implement with zero copy movement/without copying between +// user and kernel address spaces. +func splicePipeToPipe(t *kernel.Task, inPipe *fs.File, outPipe *fs.File, size int64, flags uint) (int64, error) { + w := &fs.FileWriter{t, outPipe} + if flags == linux.SPLICE_F_NONBLOCK { + r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} + return io.Copy(w, r) + } + var n int64 + for read := int64(0); read < size; { + var err error + r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} + n, err = io.Copy(w, r) + if err != nil && err != syserror.ErrWouldBlock { + return 0, err + } + read += n + } + return n, nil +} + +// spliceRead moves data from a file to a pipe. +// TODO: Implement with zero copy movement/without copying between +// user and kernel address spaces. +func spliceRead(t *kernel.Task, inFile *fs.File, outPipe *fs.File, size int64, offset uint64, flags uint) (int64, error) { + w := &fs.FileWriter{t, outPipe} + if flags == linux.SPLICE_F_NONBLOCK { + r := io.NewSectionReader(&fs.FileReader{t, inFile}, int64(offset), size) + return io.Copy(w, r) + } + var n int64 + for read := int64(0); read < size; { + r := io.NewSectionReader(&fs.FileReader{t, inFile}, int64(offset), size) + var err error + n, err = io.Copy(w, r) + if err != nil && err != syserror.ErrWouldBlock { + return 0, err + } + read += n + } + return n, nil +} + +// offsetWriter implements io.Writer on a section of an underlying +// WriterAt starting from the offset and ending at the limit. +type offsetWriter struct { + w io.WriterAt + off int64 + limit int64 +} + +// Write implements io.Writer.Write and writes the content of the offsetWriter +// starting at the offset and ending at the limit into the given buffer. +func (o *offsetWriter) Write(p []byte) (n int, err error) { + if o.off >= o.limit { + return 0, io.EOF + } + if max := o.limit - o.off; int64(len(p)) > max { + p = p[0:max] + } + n, err = o.w.WriteAt(p, o.off) + o.off += int64(n) + return n, err +} + +// spliceWrite moves data from a pipe to a file. +// TODO: Implement with zero copy movement/without copying between +// user and kernel address spaces. +func spliceWrite(t *kernel.Task, inPipe *fs.File, outFile *fs.File, size int64, offset uint64, flags uint) (int64, error) { + w := &offsetWriter{&fs.FileWriter{t, outFile}, int64(offset), int64(offset) + size} + if flags == linux.SPLICE_F_NONBLOCK { + r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} + return io.Copy(w, r) + } + var n int64 + for read := int64(0); read < size; { + var err error + r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} + n, err = io.Copy(w, r) + if err != nil && err != syserror.ErrWouldBlock { + return 0, err + } + read += n + } + return n, nil +} -- cgit v1.2.3 From 6cf22781673d75cca459fd668cf291b387d52e0d Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Tue, 14 Aug 2018 11:49:42 -0700 Subject: Automated rollback of changelist 208284483 PiperOrigin-RevId: 208685417 Change-Id: Ie2849c4811e3a2d14a002f521cef018ded0c6c4a --- pkg/abi/linux/BUILD | 1 - pkg/abi/linux/splice.go | 20 --- pkg/sentry/syscalls/linux/BUILD | 1 - pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_splice.go | 260 -------------------------------- 5 files changed, 1 insertion(+), 283 deletions(-) delete mode 100644 pkg/abi/linux/splice.go delete mode 100644 pkg/sentry/syscalls/linux/sys_splice.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 9a44c2042..ac4ceefbc 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -43,7 +43,6 @@ go_library( "shm.go", "signal.go", "socket.go", - "splice.go", "time.go", "tty.go", "uio.go", diff --git a/pkg/abi/linux/splice.go b/pkg/abi/linux/splice.go deleted file mode 100644 index 9331ec84b..000000000 --- a/pkg/abi/linux/splice.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2018 Google Inc. -// -// 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 linux - -// Flags for splice(2). -const ( - SPLICE_F_NONBLOCK = 2 -) diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 62423c0fa..bbdfad9da 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -34,7 +34,6 @@ go_library( "sys_shm.go", "sys_signal.go", "sys_socket.go", - "sys_splice.go", "sys_stat.go", "sys_sync.go", "sys_sysinfo.go", diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 485c96202..c102af101 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -319,7 +319,7 @@ var AMD64 = &kernel.SyscallTable{ 272: Unshare, 273: syscalls.Error(syscall.ENOSYS), // SetRobustList, obsolete 274: syscalls.Error(syscall.ENOSYS), // GetRobustList, obsolete - 275: Splice, + // 275: Splice, TODO // 276: Tee, TODO // 277: SyncFileRange, TODO // 278: Vmsplice, TODO diff --git a/pkg/sentry/syscalls/linux/sys_splice.go b/pkg/sentry/syscalls/linux/sys_splice.go deleted file mode 100644 index 8151e3599..000000000 --- a/pkg/sentry/syscalls/linux/sys_splice.go +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright 2018 Google Inc. -// -// 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 linux - -import ( - "io" - - "gvisor.googlesource.com/gvisor/pkg/abi/linux" - "gvisor.googlesource.com/gvisor/pkg/sentry/arch" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/pipe" - "gvisor.googlesource.com/gvisor/pkg/syserror" -) - -// Splice implements linux syscall splice(2). -func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - fdIn := kdefs.FD(args[0].Int()) - offIn := args[1].Pointer() - fdOut := kdefs.FD(args[2].Int()) - offOut := args[3].Pointer() - size := int64(args[4].SizeT()) - flags := uint(args[5].Uint()) - - fileIn := t.FDMap().GetFile(fdIn) - if fileIn == nil { - return 0, nil, syserror.EBADF - } - defer fileIn.DecRef() - fileOut := t.FDMap().GetFile(fdOut) - if fileOut == nil { - return 0, nil, syserror.EBADF - } - defer fileOut.DecRef() - - // Check for whether we have pipes. - ipipe := fs.IsPipe(fileIn.Dirent.Inode.StableAttr) - opipe := fs.IsPipe(fileOut.Dirent.Inode.StableAttr) - if (ipipe && offIn != 0) || (opipe && offOut != 0) { - return 0, nil, syserror.ESPIPE - } - - // Check if both file descriptors are pipes. - if ipipe && opipe { - var readPipe *pipe.Pipe - switch p := fileIn.FileOperations.(type) { - case *pipe.Reader: - readPipe = p.ReaderWriter.Pipe - case *pipe.ReaderWriter: - readPipe = p.Pipe - default: - return 0, nil, syserror.EBADF - } - var writePipe *pipe.Pipe - switch p := fileOut.FileOperations.(type) { - case *pipe.Writer: - writePipe = p.ReaderWriter.Pipe - case *pipe.ReaderWriter: - writePipe = p.Pipe - default: - return 0, nil, syserror.EBADF - } - - // Splicing with two ends of the same pipe is not allowed. - if readPipe == writePipe { - return 0, nil, syserror.EINVAL - } - spliced, err := splicePipeToPipe(t, fileIn, fileOut, size, flags) - if err != nil { - return 0, nil, err - } - return uintptr(spliced), nil, nil - } - - // Check if the file descriptor that contains the data to move is a pipe. - if ipipe { - flagsOut := fileOut.Flags() - offset := uint64(fileOut.Offset()) - - // If there is an offset for the file, ensure the file has the Pwrite flag. - if offOut != 0 { - if !flagsOut.Pwrite { - return 0, nil, syserror.EINVAL - } - if _, err := t.CopyIn(offOut, &offset); err != nil { - return 0, nil, err - } - } - - if !flagsOut.Write { - return 0, nil, syserror.EBADF - } - - if flagsOut.Append { - return 0, nil, syserror.EINVAL - } - - switch fileIn.FileOperations.(type) { - case *pipe.Reader, *pipe.ReaderWriter: - // If the pipe in is a Reader or ReaderWriter, we can continue. - default: - return 0, nil, syserror.EBADF - } - spliced, err := spliceWrite(t, fileIn, fileOut, size, offset, flags) - if err != nil { - return 0, nil, err - } - - // Make sure value that offset points to is updated. - if offOut == 0 { - fileOut.Seek(t, fs.SeekSet, spliced+int64(offset)) - } else if _, err := t.CopyOut(offOut, spliced+int64(offset)); err != nil { - return 0, nil, err - } - return uintptr(spliced), nil, nil - } - - // Check if the file descriptor that the data will be moved to is a pipe. - if opipe { - flagsIn := fileIn.Flags() - offset := uint64(fileIn.Offset()) - - // If there is an offset for the file, ensure the file has the Pread flag. - if offIn != 0 { - if !flagsIn.Pread { - return 0, nil, syserror.EINVAL - } - if _, err := t.CopyIn(offIn, &offset); err != nil { - return 0, nil, err - } - } - - if !flagsIn.Read { - return 0, nil, syserror.EBADF - } - - switch fileOut.FileOperations.(type) { - case *pipe.Writer, *pipe.ReaderWriter: - // If the pipe out is a Writer or ReaderWriter, we can continue. - default: - return 0, nil, syserror.EBADF - } - spliced, err := spliceRead(t, fileIn, fileOut, size, offset, flags) - if err != nil { - return 0, nil, err - } - - // Make sure value that offset points to is updated. - if offIn == 0 { - fileOut.Seek(t, fs.SeekSet, spliced+int64(offset)) - } else if _, err := t.CopyOut(offIn, spliced+int64(offset)); err != nil { - return 0, nil, err - } - return uintptr(spliced), nil, nil - } - - // Splice requires one of the file descriptors to be a pipe. - return 0, nil, syserror.EINVAL -} - -// splicePipeToPipe moves data from one pipe to another pipe. -// TODO: Implement with zero copy movement/without copying between -// user and kernel address spaces. -func splicePipeToPipe(t *kernel.Task, inPipe *fs.File, outPipe *fs.File, size int64, flags uint) (int64, error) { - w := &fs.FileWriter{t, outPipe} - if flags == linux.SPLICE_F_NONBLOCK { - r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} - return io.Copy(w, r) - } - var n int64 - for read := int64(0); read < size; { - var err error - r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} - n, err = io.Copy(w, r) - if err != nil && err != syserror.ErrWouldBlock { - return 0, err - } - read += n - } - return n, nil -} - -// spliceRead moves data from a file to a pipe. -// TODO: Implement with zero copy movement/without copying between -// user and kernel address spaces. -func spliceRead(t *kernel.Task, inFile *fs.File, outPipe *fs.File, size int64, offset uint64, flags uint) (int64, error) { - w := &fs.FileWriter{t, outPipe} - if flags == linux.SPLICE_F_NONBLOCK { - r := io.NewSectionReader(&fs.FileReader{t, inFile}, int64(offset), size) - return io.Copy(w, r) - } - var n int64 - for read := int64(0); read < size; { - r := io.NewSectionReader(&fs.FileReader{t, inFile}, int64(offset), size) - var err error - n, err = io.Copy(w, r) - if err != nil && err != syserror.ErrWouldBlock { - return 0, err - } - read += n - } - return n, nil -} - -// offsetWriter implements io.Writer on a section of an underlying -// WriterAt starting from the offset and ending at the limit. -type offsetWriter struct { - w io.WriterAt - off int64 - limit int64 -} - -// Write implements io.Writer.Write and writes the content of the offsetWriter -// starting at the offset and ending at the limit into the given buffer. -func (o *offsetWriter) Write(p []byte) (n int, err error) { - if o.off >= o.limit { - return 0, io.EOF - } - if max := o.limit - o.off; int64(len(p)) > max { - p = p[0:max] - } - n, err = o.w.WriteAt(p, o.off) - o.off += int64(n) - return n, err -} - -// spliceWrite moves data from a pipe to a file. -// TODO: Implement with zero copy movement/without copying between -// user and kernel address spaces. -func spliceWrite(t *kernel.Task, inPipe *fs.File, outFile *fs.File, size int64, offset uint64, flags uint) (int64, error) { - w := &offsetWriter{&fs.FileWriter{t, outFile}, int64(offset), int64(offset) + size} - if flags == linux.SPLICE_F_NONBLOCK { - r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} - return io.Copy(w, r) - } - var n int64 - for read := int64(0); read < size; { - var err error - r := &io.LimitedReader{R: &fs.FileReader{t, inPipe}, N: size} - n, err = io.Copy(w, r) - if err != nil && err != syserror.ErrWouldBlock { - return 0, err - } - read += n - } - return n, nil -} -- cgit v1.2.3 From 64403265a04aa0c8be3ebb652a09f6e2d7a84ca7 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Thu, 23 Aug 2018 16:31:25 -0700 Subject: Implement POSIX per-process interval timers. PiperOrigin-RevId: 210021612 Change-Id: If7c161e6fd08cf17942bfb6bc5a8d2c4e271c61e --- pkg/abi/linux/signal.go | 20 ++ pkg/abi/linux/time.go | 4 + pkg/sentry/arch/signal_amd64.go | 30 +++ pkg/sentry/kernel/BUILD | 2 +- pkg/sentry/kernel/kernel.go | 19 +- pkg/sentry/kernel/pending_signals.go | 17 +- pkg/sentry/kernel/pending_signals_state.go | 21 +- pkg/sentry/kernel/posixtimer.go | 306 +++++++++++++++++++++++++++++ pkg/sentry/kernel/ptrace.go | 2 +- pkg/sentry/kernel/task_exec.go | 16 ++ pkg/sentry/kernel/task_exit.go | 2 +- pkg/sentry/kernel/task_signals.go | 12 +- pkg/sentry/kernel/thread_group.go | 27 ++- pkg/sentry/kernel/time/time.go | 23 ++- pkg/sentry/syscalls/linux/linux64.go | 10 +- pkg/sentry/syscalls/linux/sys_timer.go | 85 ++++++++ pkg/sentry/syscalls/linux/sys_timerfd.go | 33 +--- 17 files changed, 579 insertions(+), 50 deletions(-) create mode 100644 pkg/sentry/kernel/posixtimer.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index fed2a159f..b2c7230c4 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -209,3 +209,23 @@ const ( // POLL_HUP indicates that a device disconnected. POLL_HUP = SI_POLL | 6 ) + +// Sigevent represents struct sigevent. +type Sigevent struct { + Value uint64 // union sigval {int, void*} + Signo int32 + Notify int32 + + // struct sigevent here contains 48-byte union _sigev_un. However, only + // member _tid is significant to the kernel. + Tid int32 + UnRemainder [44]byte +} + +// Possible values for Sigevent.Notify, aka struct sigevent::sigev_notify. +const ( + SIGEV_SIGNAL = 0 + SIGEV_NONE = 1 + SIGEV_THREAD = 2 + SIGEV_THREAD_ID = 4 +) diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go index 9109a2848..4569f4208 100644 --- a/pkg/abi/linux/time.go +++ b/pkg/abi/linux/time.go @@ -222,3 +222,7 @@ type Tms struct { CUTime ClockT CSTime ClockT } + +// TimerID represents type timer_t, which identifies a POSIX per-process +// interval timer. +type TimerID int32 diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index e81717e8b..9ca4c8ed1 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -176,6 +176,36 @@ func (s *SignalInfo) SetUid(val int32) { usermem.ByteOrder.PutUint32(s.Fields[4:8], uint32(val)) } +// Sigval returns the sigval field, which is aliased to both si_int and si_ptr. +func (s *SignalInfo) Sigval() uint64 { + return usermem.ByteOrder.Uint64(s.Fields[8:16]) +} + +// SetSigval mutates the sigval field. +func (s *SignalInfo) SetSigval(val uint64) { + usermem.ByteOrder.PutUint64(s.Fields[8:16], val) +} + +// TimerID returns the si_timerid field. +func (s *SignalInfo) TimerID() linux.TimerID { + return linux.TimerID(usermem.ByteOrder.Uint32(s.Fields[0:4])) +} + +// SetTimerID sets the si_timerid field. +func (s *SignalInfo) SetTimerID(val linux.TimerID) { + usermem.ByteOrder.PutUint32(s.Fields[0:4], uint32(val)) +} + +// Overrun returns the si_overrun field. +func (s *SignalInfo) Overrun() int32 { + return int32(usermem.ByteOrder.Uint32(s.Fields[4:8])) +} + +// SetOverrun sets the si_overrun field. +func (s *SignalInfo) SetOverrun(val int32) { + usermem.ByteOrder.PutUint32(s.Fields[4:8], uint32(val)) +} + // Addr returns the si_addr field. func (s *SignalInfo) Addr() uint64 { return usermem.ByteOrder.Uint64(s.Fields[0:8]) diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 69a3fbc45..a7b847e94 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -71,6 +71,7 @@ go_library( "pending_signals.go", "pending_signals_list.go", "pending_signals_state.go", + "posixtimer.go", "process_group_list.go", "ptrace.go", "rseq.go", @@ -114,7 +115,6 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel", imports = [ "gvisor.googlesource.com/gvisor/pkg/bpf", - "gvisor.googlesource.com/gvisor/pkg/sentry/arch", "gvisor.googlesource.com/gvisor/pkg/tcpip", ], visibility = ["//:sandbox"], diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index cb43fdcdc..33cd727c6 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -19,9 +19,11 @@ // Lock order (outermost locks must be taken first): // // Kernel.extMu -// TaskSet.mu -// SignalHandlers.mu -// Task.mu +// ThreadGroup.timerMu +// ktime.Timer.mu (for IntervalTimer) +// TaskSet.mu +// SignalHandlers.mu +// Task.mu // // Locking SignalHandlers.mu in multiple SignalHandlers requires locking // TaskSet.mu exclusively first. Locking Task.mu in multiple Tasks at the same @@ -706,8 +708,12 @@ func (k *Kernel) pauseTimeLocked() { if t == t.tg.leader { t.tg.tm.pause() } - // This means we'll iterate FDMaps shared by multiple tasks repeatedly, - // but ktime.Timer.Pause is idempotent so this is harmless. + // This means we'll iterate ThreadGroups and FDMaps shared by multiple + // tasks repeatedly, but ktime.Timer.Pause is idempotent so this is + // harmless. + for _, it := range t.tg.timers { + it.PauseTimer() + } if fdm := t.tr.FDMap; fdm != nil { for _, desc := range fdm.files { if tfd, ok := desc.file.FileOperations.(*timerfd.TimerOperations); ok { @@ -735,6 +741,9 @@ func (k *Kernel) resumeTimeLocked() { if t == t.tg.leader { t.tg.tm.resume() } + for _, it := range t.tg.timers { + it.ResumeTimer() + } if fdm := t.tr.FDMap; fdm != nil { for _, desc := range fdm.files { if tfd, ok := desc.file.FileOperations.(*timerfd.TimerOperations); ok { diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index 06be5a7e1..bb5db0309 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -46,7 +46,7 @@ type pendingSignals struct { // Note that signals is zero-indexed, but signal 1 is the first valid // signal, so signals[0] contains signals with signo 1 etc. This offset is // usually handled by using Signal.index(). - signals [linux.SignalMaximum]pendingSignalQueue `state:".([]*arch.SignalInfo)"` + signals [linux.SignalMaximum]pendingSignalQueue `state:".([]savedPendingSignal)"` // Bit i of pendingSet is set iff there is at least one signal with signo // i+1 pending. @@ -66,13 +66,16 @@ type pendingSignal struct { // pendingSignalEntry links into a pendingSignalList. pendingSignalEntry *arch.SignalInfo + + // If timer is not nil, it is the IntervalTimer which sent this signal. + timer *IntervalTimer } // enqueue enqueues the given signal. enqueue returns true on success and false // on failure (if the given signal's queue is full). // // Preconditions: info represents a valid signal. -func (p *pendingSignals) enqueue(info *arch.SignalInfo) bool { +func (p *pendingSignals) enqueue(info *arch.SignalInfo, timer *IntervalTimer) bool { sig := linux.Signal(info.Signo) q := &p.signals[sig.Index()] if sig.IsStandard() { @@ -82,7 +85,7 @@ func (p *pendingSignals) enqueue(info *arch.SignalInfo) bool { } else if q.length >= rtSignalCap { return false } - q.pendingSignalList.PushBack(&pendingSignal{SignalInfo: info}) + q.pendingSignalList.PushBack(&pendingSignal{SignalInfo: info, timer: timer}) q.length++ p.pendingSet |= linux.SignalSetOf(sig) return true @@ -119,12 +122,20 @@ func (p *pendingSignals) dequeueSpecific(sig linux.Signal) *arch.SignalInfo { if q.length == 0 { p.pendingSet &^= linux.SignalSetOf(sig) } + if ps.timer != nil { + ps.timer.updateDequeuedSignalLocked(ps.SignalInfo) + } return ps.SignalInfo } // discardSpecific causes all pending signals with number sig to be discarded. func (p *pendingSignals) discardSpecific(sig linux.Signal) { q := &p.signals[sig.Index()] + for ps := q.pendingSignalList.Front(); ps != nil; ps = ps.Next() { + if ps.timer != nil { + ps.timer.signalRejectedLocked() + } + } q.pendingSignalList.Reset() q.length = 0 p.pendingSet &^= linux.SignalSetOf(sig) diff --git a/pkg/sentry/kernel/pending_signals_state.go b/pkg/sentry/kernel/pending_signals_state.go index af61f6e8e..6d90ed033 100644 --- a/pkg/sentry/kernel/pending_signals_state.go +++ b/pkg/sentry/kernel/pending_signals_state.go @@ -18,20 +18,29 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/arch" ) +// +stateify savable +type savedPendingSignal struct { + si *arch.SignalInfo + timer *IntervalTimer +} + // saveSignals is invoked by stateify. -func (p *pendingSignals) saveSignals() []*arch.SignalInfo { - var pending []*arch.SignalInfo +func (p *pendingSignals) saveSignals() []savedPendingSignal { + var pending []savedPendingSignal for _, q := range p.signals { for ps := q.pendingSignalList.Front(); ps != nil; ps = ps.Next() { - pending = append(pending, ps.SignalInfo) + pending = append(pending, savedPendingSignal{ + si: ps.SignalInfo, + timer: ps.timer, + }) } } return pending } // loadSignals is invoked by stateify. -func (p *pendingSignals) loadSignals(pending []*arch.SignalInfo) { - for _, si := range pending { - p.enqueue(si) +func (p *pendingSignals) loadSignals(pending []savedPendingSignal) { + for _, sps := range pending { + p.enqueue(sps.si, sps.timer) } } diff --git a/pkg/sentry/kernel/posixtimer.go b/pkg/sentry/kernel/posixtimer.go new file mode 100644 index 000000000..0ab958529 --- /dev/null +++ b/pkg/sentry/kernel/posixtimer.go @@ -0,0 +1,306 @@ +// Copyright 2018 Google Inc. +// +// 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 kernel + +import ( + "math" + + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +// IntervalTimer represents a POSIX interval timer as described by +// timer_create(2). +// +// +stateify savable +type IntervalTimer struct { + timer *ktime.Timer + + // If target is not nil, it receives signo from timer expirations. If group + // is true, these signals are thread-group-directed. These fields are + // immutable. + target *Task + signo linux.Signal + id linux.TimerID + sigval uint64 + group bool + + // If sigpending is true, a signal to target is already queued, and timer + // expirations should increment overrunCur instead of sending another + // signal. sigpending is protected by target's signal mutex. (If target is + // nil, the timer will never send signals, so sigpending will be unused.) + sigpending bool + + // If sigorphan is true, timer's setting has been changed since sigpending + // last became true, such that overruns should no longer be counted in the + // pending signals si_overrun. sigorphan is protected by target's signal + // mutex. + sigorphan bool + + // overrunCur is the number of overruns that have occurred since the last + // time a signal was sent. overrunCur is protected by target's signal + // mutex. + overrunCur uint64 + + // Consider the last signal sent by this timer that has been dequeued. + // overrunLast is the number of overruns that occurred between when this + // signal was sent and when it was dequeued. Equivalently, overrunLast was + // the value of overrunCur when this signal was dequeued. overrunLast is + // protected by target's signal mutex. + overrunLast uint64 +} + +// DestroyTimer releases it's resources. +func (it *IntervalTimer) DestroyTimer() { + it.timer.Destroy() + it.timerSettingChanged() + // A destroyed IntervalTimer is still potentially reachable via a + // pendingSignal; nil out timer so that it won't be saved. + it.timer = nil +} + +func (it *IntervalTimer) timerSettingChanged() { + if it.target == nil { + return + } + it.target.tg.pidns.owner.mu.RLock() + defer it.target.tg.pidns.owner.mu.RUnlock() + it.target.tg.signalHandlers.mu.Lock() + defer it.target.tg.signalHandlers.mu.Unlock() + it.sigorphan = true + it.overrunCur = 0 + it.overrunLast = 0 +} + +// PauseTimer pauses the associated Timer. +func (it *IntervalTimer) PauseTimer() { + it.timer.Pause() +} + +// ResumeTimer resumes the associated Timer. +func (it *IntervalTimer) ResumeTimer() { + it.timer.Resume() +} + +// Preconditions: it.target's signal mutex must be locked. +func (it *IntervalTimer) updateDequeuedSignalLocked(si *arch.SignalInfo) { + it.sigpending = false + if it.sigorphan { + return + } + it.overrunLast = it.overrunCur + it.overrunCur = 0 + si.SetOverrun(saturateI32FromU64(it.overrunLast)) +} + +// Preconditions: it.target's signal mutex must be locked. +func (it *IntervalTimer) signalRejectedLocked() { + it.sigpending = false + if it.sigorphan { + return + } + it.overrunCur++ +} + +// Notify implements ktime.TimerListener.Notify. +func (it *IntervalTimer) Notify(exp uint64) { + if it.target == nil { + return + } + + it.target.tg.pidns.owner.mu.RLock() + defer it.target.tg.pidns.owner.mu.RUnlock() + it.target.tg.signalHandlers.mu.Lock() + defer it.target.tg.signalHandlers.mu.Unlock() + + if it.sigpending { + it.overrunCur += exp + return + } + + // sigpending must be set before sendSignalTimerLocked() so that it can be + // unset if the signal is discarded (in which case sendSignalTimerLocked() + // will return nil). + it.sigpending = true + it.sigorphan = false + it.overrunCur += exp - 1 + si := &arch.SignalInfo{ + Signo: int32(it.signo), + Code: arch.SignalInfoTimer, + } + si.SetTimerID(it.id) + si.SetSigval(it.sigval) + // si_overrun is set when the signal is dequeued. + if err := it.target.sendSignalTimerLocked(si, it.group, it); err != nil { + it.signalRejectedLocked() + } +} + +// Destroy implements ktime.TimerListener.Destroy. Users of Timer should call +// DestroyTimer instead. +func (it *IntervalTimer) Destroy() { +} + +// IntervalTimerCreate implements timer_create(2). +func (t *Task) IntervalTimerCreate(c ktime.Clock, sigev *linux.Sigevent) (linux.TimerID, error) { + t.tg.timerMu.Lock() + defer t.tg.timerMu.Unlock() + + // Allocate a timer ID. + var id linux.TimerID + end := t.tg.nextTimerID + for { + id = t.tg.nextTimerID + _, ok := t.tg.timers[id] + t.tg.nextTimerID++ + if t.tg.nextTimerID < 0 { + t.tg.nextTimerID = 0 + } + if !ok { + break + } + if t.tg.nextTimerID == end { + return 0, syserror.EAGAIN + } + } + + // "The implementation of the default case where evp [sic] is NULL is + // handled inside glibc, which invokes the underlying system call with a + // suitably populated sigevent structure." - timer_create(2). This is + // misleading; the timer_create syscall also handles a NULL sevp as + // described by the man page + // (kernel/time/posix-timers.c:sys_timer_create(), do_timer_create()). This + // must be handled here instead of the syscall wrapper since sigval is the + // timer ID, which isn't available until we allocate it in this function. + if sigev == nil { + sigev = &linux.Sigevent{ + Signo: int32(linux.SIGALRM), + Notify: linux.SIGEV_SIGNAL, + Value: uint64(id), + } + } + + // Construct the timer. + it := &IntervalTimer{ + id: id, + sigval: sigev.Value, + } + switch sigev.Notify { + case linux.SIGEV_NONE: + // leave it.target = nil + case linux.SIGEV_SIGNAL, linux.SIGEV_THREAD: + // POSIX SIGEV_THREAD semantics are implemented in userspace by libc; + // to the kernel, SIGEV_THREAD and SIGEV_SIGNAL are equivalent. (See + // Linux's kernel/time/posix-timers.c:good_sigevent().) + it.target = t.tg.leader + it.group = true + case linux.SIGEV_THREAD_ID: + t.tg.pidns.owner.mu.RLock() + target, ok := t.tg.pidns.tasks[ThreadID(sigev.Tid)] + t.tg.pidns.owner.mu.RUnlock() + if !ok || target.tg != t.tg { + return 0, syserror.EINVAL + } + it.target = target + default: + return 0, syserror.EINVAL + } + if sigev.Notify != linux.SIGEV_NONE { + it.signo = linux.Signal(sigev.Signo) + if !it.signo.IsValid() { + return 0, syserror.EINVAL + } + } + it.timer = ktime.NewTimer(c, it) + + t.tg.timers[id] = it + return id, nil +} + +// IntervalTimerDelete implements timer_delete(2). +func (t *Task) IntervalTimerDelete(id linux.TimerID) error { + t.tg.timerMu.Lock() + defer t.tg.timerMu.Unlock() + it := t.tg.timers[id] + if it == nil { + return syserror.EINVAL + } + delete(t.tg.timers, id) + it.DestroyTimer() + return nil +} + +// IntervalTimerSettime implements timer_settime(2). +func (t *Task) IntervalTimerSettime(id linux.TimerID, its linux.Itimerspec, abs bool) (linux.Itimerspec, error) { + t.tg.timerMu.Lock() + defer t.tg.timerMu.Unlock() + it := t.tg.timers[id] + if it == nil { + return linux.Itimerspec{}, syserror.EINVAL + } + + newS, err := ktime.SettingFromItimerspec(its, abs, it.timer.Clock()) + if err != nil { + return linux.Itimerspec{}, err + } + tm, oldS := it.timer.SwapAnd(newS, it.timerSettingChanged) + its = ktime.ItimerspecFromSetting(tm, oldS) + return its, nil +} + +// IntervalTimerGettime implements timer_gettime(2). +func (t *Task) IntervalTimerGettime(id linux.TimerID) (linux.Itimerspec, error) { + t.tg.timerMu.Lock() + defer t.tg.timerMu.Unlock() + it := t.tg.timers[id] + if it == nil { + return linux.Itimerspec{}, syserror.EINVAL + } + + tm, s := it.timer.Get() + its := ktime.ItimerspecFromSetting(tm, s) + return its, nil +} + +// IntervalTimerGetoverrun implements timer_getoverrun(2). +// +// Preconditions: The caller must be running on the task goroutine. +func (t *Task) IntervalTimerGetoverrun(id linux.TimerID) (int32, error) { + t.tg.timerMu.Lock() + defer t.tg.timerMu.Unlock() + it := t.tg.timers[id] + if it == nil { + return 0, syserror.EINVAL + } + // By timer_create(2) invariant, either it.target == nil (in which case + // it.overrunLast is immutably 0) or t.tg == it.target.tg; and the fact + // that t is executing timer_getoverrun(2) means that t.tg can't be + // completing execve, so t.tg.signalHandlers can't be changing, allowing us + // to lock t.tg.signalHandlers.mu without holding the TaskSet mutex. + t.tg.signalHandlers.mu.Lock() + defer t.tg.signalHandlers.mu.Unlock() + // This is consistent with Linux after 78c9c4dfbf8c ("posix-timers: + // Sanitize overrun handling"). + return saturateI32FromU64(it.overrunLast), nil +} + +func saturateI32FromU64(x uint64) int32 { + if x > math.MaxInt32 { + return math.MaxInt32 + } + return int32(x) +} diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index e9e69004d..1a0d1876d 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -627,7 +627,7 @@ func (t *Task) ptraceClone(kind ptraceCloneKind, child *Task, opts *CloneOptions // running, so we don't have to. child.pendingSignals.enqueue(&arch.SignalInfo{ Signo: int32(linux.SIGSTOP), - }) + }, nil) child.tg.signalHandlers.mu.Unlock() } } diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 385299b24..bb3d0bd02 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -143,6 +143,22 @@ func (r *runSyscallAfterExecStop) execute(t *Task) taskRunState { oldTID = tracer.tg.pidns.tids[t] } t.promoteLocked() + // "POSIX timers are not preserved (timer_create(2))." - execve(2). Handle + // this first since POSIX timers are protected by the signal mutex, which + // we're about to change. Note that we have to stop and destroy timers + // without holding any mutexes to avoid circular lock ordering. + var its []*IntervalTimer + t.tg.signalHandlers.mu.Lock() + for _, it := range t.tg.timers { + its = append(its, it) + } + t.tg.timers = make(map[linux.TimerID]*IntervalTimer) + t.tg.signalHandlers.mu.Unlock() + t.tg.pidns.owner.mu.Unlock() + for _, it := range its { + it.DestroyTimer() + } + t.tg.pidns.owner.mu.Lock() // "During an execve(2), the dispositions of handled signals are reset to // the default; the dispositions of ignored signals are left unchanged. ... // [The] signal mask is preserved across execve(2). ... [The] pending diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index b16844e91..b37fcf4c1 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -129,7 +129,7 @@ func (t *Task) killLocked() { // enqueueing an actual siginfo, such that // kernel/signal.c:collect_signal() initializes si_code to SI_USER. Code: arch.SignalInfoUser, - }) + }, nil) t.interrupt() } diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 62ec530be..4a66bce6b 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -396,6 +396,10 @@ func (tg *ThreadGroup) SendTimerSignal(info *arch.SignalInfo, includeSys bool) e } func (t *Task) sendSignalLocked(info *arch.SignalInfo, group bool) error { + return t.sendSignalTimerLocked(info, group, nil) +} + +func (t *Task) sendSignalTimerLocked(info *arch.SignalInfo, group bool, timer *IntervalTimer) error { if t.exitState == TaskExitDead { return syserror.ESRCH } @@ -429,6 +433,9 @@ func (t *Task) sendSignalLocked(info *arch.SignalInfo, group bool) error { ignored := computeAction(sig, t.tg.signalHandlers.actions[sig]) == SignalActionIgnore if linux.SignalSetOf(sig)&t.tr.SignalMask == 0 && ignored && !t.hasTracer() { t.Debugf("Discarding ignored signal %d", sig) + if timer != nil { + timer.signalRejectedLocked() + } return nil } @@ -436,11 +443,14 @@ func (t *Task) sendSignalLocked(info *arch.SignalInfo, group bool) error { if group { q = &t.tg.pendingSignals } - if !q.enqueue(info) { + if !q.enqueue(info, timer) { if sig.IsRealtime() { return syserror.EAGAIN } t.Debugf("Discarding duplicate signal %d", sig) + if timer != nil { + timer.signalRejectedLocked() + } return nil } diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 441b8a822..13dce08ce 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -155,6 +155,14 @@ type ThreadGroup struct { // tm contains process timers. TimerManager fields are immutable. tm TimerManager + // timers is the thread group's POSIX interval timers. nextTimerID is the + // TimerID at which allocation should begin searching for an unused ID. + // + // timers and nextTimerID are protected by timerMu. + timerMu sync.Mutex `state:"nosave"` + timers map[linux.TimerID]*IntervalTimer + nextTimerID linux.TimerID + // exitedCPUStats is the CPU usage for all exited tasks in the thread // group. exitedCPUStats is protected by the TaskSet mutex. exitedCPUStats usage.CPUStats @@ -218,6 +226,7 @@ func NewThreadGroup(ns *PIDNamespace, sh *SignalHandlers, terminationSignal linu limits: limits, } tg.tm = newTimerManager(tg, monotonicClock) + tg.timers = make(map[linux.TimerID]*IntervalTimer) tg.rscr.Store(&RSEQCriticalRegion{}) return tg } @@ -252,9 +261,23 @@ func (tg *ThreadGroup) Limits() *limits.LimitSet { // release releases the thread group's resources. func (tg *ThreadGroup) release() { - // This must be done without holding the TaskSet mutex since thread group - // timers call SendSignal with Timer.mu locked. + // These must be done without holding the TaskSet or signal mutexes since + // timers send signals with Timer.mu locked. + tg.tm.destroy() + + var its []*IntervalTimer + tg.pidns.owner.mu.Lock() + tg.signalHandlers.mu.Lock() + for _, it := range tg.timers { + its = append(its, it) + } + tg.timers = make(map[linux.TimerID]*IntervalTimer) // nil maps can't be saved + tg.signalHandlers.mu.Unlock() + tg.pidns.owner.mu.Unlock() + for _, it := range its { + it.DestroyTimer() + } } // forEachChildThreadGroupLocked indicates over all child ThreadGroups. diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index 6eadd2878..1f6fed007 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -320,8 +320,8 @@ func SettingFromSpec(value time.Duration, interval time.Duration, c Clock) (Sett }, nil } -// SettingFromAbsSpec converts a (value, interval) pair to a Setting based on a -// reading from c. value is interpreted as an absolute time. +// SettingFromAbsSpec converts a (value, interval) pair to a Setting. value is +// interpreted as an absolute time. func SettingFromAbsSpec(value Time, interval time.Duration) (Setting, error) { if value.Before(ZeroTime) { return Setting{}, syserror.EINVAL @@ -336,6 +336,16 @@ func SettingFromAbsSpec(value Time, interval time.Duration) (Setting, error) { }, nil } +// SettingFromItimerspec converts a linux.Itimerspec to a Setting. If abs is +// true, its.Value is interpreted as an absolute time. Otherwise, it is +// interpreted as a time relative to c.Now(). +func SettingFromItimerspec(its linux.Itimerspec, abs bool, c Clock) (Setting, error) { + if abs { + return SettingFromAbsSpec(FromTimespec(its.Value), its.Interval.ToDuration()) + } + return SettingFromSpec(its.Value.ToDuration(), its.Interval.ToDuration(), c) +} + // SpecFromSetting converts a timestamp and a Setting to a (relative value, // interval) pair, as used by most Linux syscalls that return a struct // itimerval or struct itimerspec. @@ -346,6 +356,15 @@ func SpecFromSetting(now Time, s Setting) (value, period time.Duration) { return s.Next.Sub(now), s.Period } +// ItimerspecFromSetting converts a Setting to a linux.Itimerspec. +func ItimerspecFromSetting(now Time, s Setting) linux.Itimerspec { + val, iv := SpecFromSetting(now, s) + return linux.Itimerspec{ + Interval: linux.DurationToTimespec(iv), + Value: linux.DurationToTimespec(val), + } +} + // advancedTo returns an updated Setting and a number of expirations after // the associated Clock indicates a time of now. // diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index c102af101..4465549ad 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -266,11 +266,11 @@ var AMD64 = &kernel.SyscallTable{ 219: RestartSyscall, // 220: Semtimedop, TODO 221: Fadvise64, - // 222: TimerCreate, TODO - // 223: TimerSettime, TODO - // 224: TimerGettime, TODO - // 225: TimerGetoverrun, TODO - // 226: TimerDelete, TODO + 222: TimerCreate, + 223: TimerSettime, + 224: TimerGettime, + 225: TimerGetoverrun, + 226: TimerDelete, 227: ClockSettime, 228: ClockGettime, 229: ClockGetres, diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go index 4ed077626..aaed75c81 100644 --- a/pkg/sentry/syscalls/linux/sys_timer.go +++ b/pkg/sentry/syscalls/linux/sys_timer.go @@ -166,3 +166,88 @@ func Alarm(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall return uintptr(sec), nil, nil } + +// TimerCreate implements linux syscall timer_create(2). +func TimerCreate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + clockID := args[0].Int() + sevp := args[1].Pointer() + timerIDp := args[2].Pointer() + + c, err := getClock(t, clockID) + if err != nil { + return 0, nil, err + } + + var sev *linux.Sigevent + if sevp != 0 { + sev = &linux.Sigevent{} + if _, err = t.CopyIn(sevp, sev); err != nil { + return 0, nil, err + } + } + + id, err := t.IntervalTimerCreate(c, sev) + if err != nil { + return 0, nil, err + } + + if _, err := t.CopyOut(timerIDp, &id); err != nil { + t.IntervalTimerDelete(id) + return 0, nil, err + } + + return uintptr(id), nil, nil +} + +// TimerSettime implements linux syscall timer_settime(2). +func TimerSettime(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + timerID := linux.TimerID(args[0].Value) + flags := args[1].Int() + newValAddr := args[2].Pointer() + oldValAddr := args[3].Pointer() + + var newVal linux.Itimerspec + if _, err := t.CopyIn(newValAddr, &newVal); err != nil { + return 0, nil, err + } + oldVal, err := t.IntervalTimerSettime(timerID, newVal, flags&linux.TIMER_ABSTIME != 0) + if err != nil { + return 0, nil, err + } + if oldValAddr != 0 { + if _, err := t.CopyOut(oldValAddr, &oldVal); err != nil { + return 0, nil, err + } + } + return 0, nil, nil +} + +// TimerGettime implements linux syscall timer_gettime(2). +func TimerGettime(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + timerID := linux.TimerID(args[0].Value) + curValAddr := args[1].Pointer() + + curVal, err := t.IntervalTimerGettime(timerID) + if err != nil { + return 0, nil, err + } + _, err = t.CopyOut(curValAddr, &curVal) + return 0, nil, err +} + +// TimerGetoverrun implements linux syscall timer_getoverrun(2). +func TimerGetoverrun(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + timerID := linux.TimerID(args[0].Value) + + o, err := t.IntervalTimerGetoverrun(timerID) + if err != nil { + return 0, nil, err + } + return uintptr(o), nil, nil +} + +// TimerDelete implements linux syscall timer_delete(2). +func TimerDelete(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + timerID := linux.TimerID(args[0].Value) + return 0, nil, t.IntervalTimerDelete(timerID) +} diff --git a/pkg/sentry/syscalls/linux/sys_timerfd.go b/pkg/sentry/syscalls/linux/sys_timerfd.go index cb81d42b9..92c6a3d60 100644 --- a/pkg/sentry/syscalls/linux/sys_timerfd.go +++ b/pkg/sentry/syscalls/linux/sys_timerfd.go @@ -85,28 +85,18 @@ func TimerfdSettime(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kerne if _, err := t.CopyIn(newValAddr, &newVal); err != nil { return 0, nil, err } - var s ktime.Setting - var err error - if flags&linux.TFD_TIMER_ABSTIME != 0 { - s, err = ktime.SettingFromAbsSpec(ktime.FromTimespec(newVal.Value), - newVal.Interval.ToDuration()) - } else { - s, err = ktime.SettingFromSpec(newVal.Value.ToDuration(), - newVal.Interval.ToDuration(), tf.Clock()) - } + newS, err := ktime.SettingFromItimerspec(newVal, flags&linux.TFD_TIMER_ABSTIME != 0, tf.Clock()) if err != nil { return 0, nil, err } - valueNS, intervalNS := ktime.SpecFromSetting(tf.SetTime(s)) - if oldValAddr == 0 { - return 0, nil, nil - } - oldVal := linux.Itimerspec{ - Interval: linux.DurationToTimespec(intervalNS), - Value: linux.DurationToTimespec(valueNS), + tm, oldS := tf.SetTime(newS) + if oldValAddr != 0 { + oldVal := ktime.ItimerspecFromSetting(tm, oldS) + if _, err := t.CopyOut(oldValAddr, &oldVal); err != nil { + return 0, nil, err + } } - _, err = t.CopyOut(oldValAddr, &oldVal) - return 0, nil, err + return 0, nil, nil } // TimerfdGettime implements Linux syscall timerfd_gettime(2). @@ -125,11 +115,8 @@ func TimerfdGettime(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kerne return 0, nil, syserror.EINVAL } - valueNS, intervalNS := ktime.SpecFromSetting(tf.GetTime()) - curVal := linux.Itimerspec{ - Interval: linux.DurationToTimespec(intervalNS), - Value: linux.DurationToTimespec(valueNS), - } + tm, s := tf.GetTime() + curVal := ktime.ItimerspecFromSetting(tm, s) _, err := t.CopyOut(curValAddr, &curVal) return 0, nil, err } -- cgit v1.2.3 From 106de2182d34197d76fb68863cd4a102ebac2dbb Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Fri, 24 Aug 2018 17:42:30 -0700 Subject: runsc: Terminal support for "docker exec -ti". This CL adds terminal support for "docker exec". We previously only supported consoles for the container process, but not exec processes. The SYS_IOCTL syscall was added to the default seccomp filter list, but only for ioctls that get/set winsize and termios structs. We need to allow these ioctl for all containers because it's possible to run "exec -ti" on a container that was started without an attached console, after the filters have been installed. Note that control-character signals are still not properly supported. Tested with: $ docker run --runtime=runsc -it alpine In another terminial: $ docker exec -it /bin/sh PiperOrigin-RevId: 210185456 Change-Id: I6d2401e53a7697bb988c120a8961505c335f96d9 --- pkg/abi/linux/ioctl.go | 6 +++- pkg/abi/linux/tty.go | 8 +++++ pkg/sentry/control/proc.go | 17 +++++------ pkg/sentry/fs/host/BUILD | 1 - pkg/sentry/fs/host/file.go | 19 ++++++------ pkg/sentry/fs/host/ioctl_unsafe.go | 19 +++++++++++- runsc/boot/controller.go | 2 +- runsc/boot/filter/BUILD | 1 + runsc/boot/filter/config.go | 38 +++++++++++++++++++----- runsc/boot/filter/filter.go | 6 +--- runsc/boot/loader.go | 2 +- runsc/cmd/BUILD | 1 + runsc/cmd/exec.go | 39 ++++++++++++++++++++++-- runsc/console/BUILD | 16 ++++++++++ runsc/console/console.go | 61 ++++++++++++++++++++++++++++++++++++++ runsc/sandbox/BUILD | 3 +- runsc/sandbox/console.go | 60 ------------------------------------- runsc/sandbox/sandbox.go | 20 +++++++------ 18 files changed, 207 insertions(+), 112 deletions(-) create mode 100644 runsc/console/BUILD create mode 100644 runsc/console/console.go delete mode 100644 runsc/sandbox/console.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 3ef046562..4d7a2dfd7 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -21,8 +21,12 @@ const ( TCGETS = 0x00005401 TCSETS = 0x00005402 TCSETSW = 0x00005403 - TIOCINQ = 0x0000541b + TIOCGPGRP = 0x0000540f + TIOCSPGRP = 0x00005410 TIOCOUTQ = 0x00005411 + TIOCGWINSZ = 0x00005413 + TIOCSWINSZ = 0x00005414 + TIOCINQ = 0x0000541b FIONREAD = TIOCINQ FIONBIO = 0x00005421 TIOCGPTN = 0x80045430 diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index 8c611d22a..81156867c 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -26,6 +26,14 @@ const ( disabledChar = 0 ) +// Winsize is struct winsize, defined in uapi/asm-generic/termios.h. +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + // Termios is struct termios, defined in uapi/asm-generic/termbits.h. type Termios struct { InputFlags uint32 diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index d94ae560f..2493c5175 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -19,7 +19,6 @@ import ( "encoding/json" "fmt" "sort" - "syscall" "text/tabwriter" "time" @@ -73,6 +72,10 @@ type ExecArgs struct { // Capabilities is the list of capabilities to give to the process. Capabilities *auth.TaskCapabilities + // StdioIsPty indicates that FDs 0, 1, and 2 are connected to a host + // pty fd. + StdioIsPty bool + // FilePayload determines the files to give to the new process. urpc.FilePayload } @@ -108,17 +111,11 @@ func (proc *Proc) Exec(args *ExecArgs, waitStatus *uint32) error { mounter := fs.FileOwnerFromContext(ctx) for appFD, f := range args.FilePayload.Files { - // Copy the underlying FD. - newFD, err := syscall.Dup(int(f.Fd())) - if err != nil { - return err - } - f.Close() + enableIoctl := args.StdioIsPty && appFD <= 2 - // Install the given file as an FD. - file, err := host.NewFile(ctx, newFD, mounter) + // Import the given file FD. This dups the FD as well. + file, err := host.ImportFile(ctx, int(f.Fd()), mounter, enableIoctl) if err != nil { - syscall.Close(newFD) return err } defer file.DecRef() diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 29c79284a..f1252b0f2 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -48,7 +48,6 @@ go_library( "//pkg/unet", "//pkg/waiter", "//pkg/waiter/fdnotifier", - "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index f9bef6d93..8d2463c78 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -18,7 +18,6 @@ import ( "fmt" "syscall" - "golang.org/x/sys/unix" "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/fd" "gvisor.googlesource.com/gvisor/pkg/log" @@ -296,7 +295,7 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys fd := f.iops.fileState.FD() ioctl := args[1].Uint64() switch ioctl { - case unix.TCGETS: + case linux.TCGETS: termios, err := ioctlGetTermios(fd) if err != nil { return 0, err @@ -306,7 +305,7 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys }) return 0, err - case unix.TCSETS, unix.TCSETSW: + case linux.TCSETS, linux.TCSETSW: var termios linux.Termios if _, err := usermem.CopyObjectIn(ctx, io, args[2].Pointer(), &termios, usermem.IOOpts{ AddressSpaceActive: true, @@ -316,7 +315,7 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys err := ioctlSetTermios(fd, ioctl, &termios) return 0, err - case unix.TIOCGPGRP: + case linux.TIOCGPGRP: // Args: pid_t *argp // When successful, equivalent to *argp = tcgetpgrp(fd). // Get the process group ID of the foreground process group on @@ -332,7 +331,7 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys }) return 0, err - case unix.TIOCSPGRP: + case linux.TIOCSPGRP: // Args: const pid_t *argp // Equivalent to tcsetpgrp(fd, *argp). // Set the foreground process group ID of this terminal. @@ -343,10 +342,10 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys log.Warningf("Ignoring application ioctl(TIOCSPGRP) call") return 0, nil - case unix.TIOCGWINSZ: + case linux.TIOCGWINSZ: // Args: struct winsize *argp // Get window size. - winsize, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + winsize, err := ioctlGetWinsize(fd) if err != nil { return 0, err } @@ -355,16 +354,16 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys }) return 0, err - case unix.TIOCSWINSZ: + case linux.TIOCSWINSZ: // Args: const struct winsize *argp // Set window size. - var winsize unix.Winsize + var winsize linux.Winsize if _, err := usermem.CopyObjectIn(ctx, io, args[2].Pointer(), &winsize, usermem.IOOpts{ AddressSpaceActive: true, }); err != nil { return 0, err } - err := unix.IoctlSetWinsize(fd, unix.TIOCSWINSZ, &winsize) + err := ioctlSetWinsize(fd, &winsize) return 0, err default: diff --git a/pkg/sentry/fs/host/ioctl_unsafe.go b/pkg/sentry/fs/host/ioctl_unsafe.go index 3c07c3850..bc965a1c2 100644 --- a/pkg/sentry/fs/host/ioctl_unsafe.go +++ b/pkg/sentry/fs/host/ioctl_unsafe.go @@ -23,7 +23,7 @@ import ( func ioctlGetTermios(fd int) (*linux.Termios, error) { var t linux.Termios - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&t))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.TCGETS, uintptr(unsafe.Pointer(&t))) if errno != 0 { return nil, errno } @@ -37,3 +37,20 @@ func ioctlSetTermios(fd int, req uint64, t *linux.Termios) error { } return nil } + +func ioctlGetWinsize(fd int) (*linux.Winsize, error) { + var w linux.Winsize + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.TIOCGWINSZ, uintptr(unsafe.Pointer(&w))) + if errno != 0 { + return nil, errno + } + return &w, nil +} + +func ioctlSetWinsize(fd int, w *linux.Winsize) error { + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.TIOCSWINSZ, uintptr(unsafe.Pointer(w))) + if errno != 0 { + return errno + } + return nil +} diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index 69e88d8e0..2d6b507b3 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -227,7 +227,7 @@ func (cm *containerManager) Start(args *StartArgs, _ *struct{}) error { // Execute runs a command on a created or running sandbox. func (cm *containerManager) Execute(e *control.ExecArgs, waitStatus *uint32) error { - log.Debugf("containerManager.Execute") + log.Debugf("containerManager.Execute: %+v", *e) proc := control.Proc{Kernel: cm.l.k} if err := proc.Exec(e, waitStatus); err != nil { return fmt.Errorf("error executing: %+v: %v", e, err) diff --git a/runsc/boot/filter/BUILD b/runsc/boot/filter/BUILD index c9837c236..96be051fe 100644 --- a/runsc/boot/filter/BUILD +++ b/runsc/boot/filter/BUILD @@ -18,6 +18,7 @@ go_library( "//runsc/boot:__subpackages__", ], deps = [ + "//pkg/abi/linux", "//pkg/log", "//pkg/seccomp", "//pkg/sentry/platform", diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index e45e599c3..db2e3f9d8 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -18,6 +18,7 @@ import ( "syscall" "golang.org/x/sys/unix" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/seccomp" ) @@ -78,15 +79,36 @@ var allowedSyscalls = seccomp.SyscallRules{ syscall.SYS_TGKILL: {}, syscall.SYS_WRITE: {}, syscall.SYS_WRITEV: {}, -} -// TODO: Ioctl is needed in order to support tty consoles. -// Once filters support argument-checking, we should only allow ioctl -// with tty-related arguments. -func consoleFilters() seccomp.SyscallRules { - return seccomp.SyscallRules{ - syscall.SYS_IOCTL: {}, - } + // SYS_IOCTL is needed for terminal support, but we only allow + // setting/getting termios and winsize. + syscall.SYS_IOCTL: []seccomp.Rule{ + { + seccomp.AllowAny{}, /* fd */ + seccomp.AllowValue(linux.TCGETS), + seccomp.AllowAny{}, /* termios struct */ + }, + { + seccomp.AllowAny{}, /* fd */ + seccomp.AllowValue(linux.TCSETS), + seccomp.AllowAny{}, /* termios struct */ + }, + { + seccomp.AllowAny{}, /* fd */ + seccomp.AllowValue(linux.TCSETSW), + seccomp.AllowAny{}, /* termios struct */ + }, + { + seccomp.AllowAny{}, /* fd */ + seccomp.AllowValue(linux.TIOCSWINSZ), + seccomp.AllowAny{}, /* winsize struct */ + }, + { + seccomp.AllowAny{}, /* fd */ + seccomp.AllowValue(linux.TIOCGWINSZ), + seccomp.AllowAny{}, /* winsize struct */ + }, + }, } // whitelistFSFilters returns syscalls made by whitelistFS. Using WhitelistFS diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index 6ea9c464e..c57bbd2e5 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -28,7 +28,7 @@ import ( ) // Install installs seccomp filters for based on the given platform. -func Install(p platform.Platform, whitelistFS, console, hostNetwork bool) error { +func Install(p platform.Platform, whitelistFS, hostNetwork bool) error { s := allowedSyscalls // Set of additional filters used by -race and -msan. Returns empty @@ -39,10 +39,6 @@ func Install(p platform.Platform, whitelistFS, console, hostNetwork bool) error Report("direct file access allows unrestricted file access!") s.Merge(whitelistFSFilters()) } - if console { - Report("console is enabled: syscall filters less restrictive!") - s.Merge(consoleFilters()) - } if hostNetwork { Report("host networking enabled: syscall filters less restrictive!") s.Merge(hostInetFilters()) diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 2f212c704..0e94cf215 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -340,7 +340,7 @@ func (l *Loader) run() error { } else { whitelistFS := l.conf.FileAccess == FileAccessDirect hostNet := l.conf.Network == NetworkHost - if err := filter.Install(l.k.Platform, whitelistFS, l.console, hostNet); err != nil { + if err := filter.Install(l.k.Platform, whitelistFS, hostNet); err != nil { return fmt.Errorf("Failed to install seccomp filters: %v", err) } } diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD index c45784749..b9ef4022f 100644 --- a/runsc/cmd/BUILD +++ b/runsc/cmd/BUILD @@ -38,6 +38,7 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/urpc", "//runsc/boot", + "//runsc/console", "//runsc/container", "//runsc/fsgofer", "//runsc/specutils", diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 4ee370656..b84a80119 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -35,6 +35,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/urpc" "gvisor.googlesource.com/gvisor/runsc/boot" + "gvisor.googlesource.com/gvisor/runsc/console" "gvisor.googlesource.com/gvisor/runsc/container" "gvisor.googlesource.com/gvisor/runsc/specutils" ) @@ -50,6 +51,11 @@ type Exec struct { detach bool processPath string pidFile string + + // consoleSocket is the path to an AF_UNIX socket which will receive a + // file descriptor referencing the master end of the console's + // pseudoterminal. + consoleSocket string } // Name implements subcommands.Command.Name. @@ -91,6 +97,7 @@ func (ex *Exec) SetFlags(f *flag.FlagSet) { f.BoolVar(&ex.detach, "detach", false, "detach from the container's process") f.StringVar(&ex.processPath, "process", "", "path to the process.json") f.StringVar(&ex.pidFile, "pid-file", "", "filename that the container pid will be written to") + f.StringVar(&ex.consoleSocket, "console-socket", "", "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal") } // Execute implements subcommands.Command.Execute. It starts a process in an @@ -178,11 +185,35 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat args = append(args, a) } } - cmd := exec.Command(binPath, args...) + + // Exec stdio defaults to current process stdio. cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr + + // If the console control socket file is provided, then create a new + // pty master/slave pair and set the tty on the sandbox process. + if ex.consoleSocket != "" { + // Create a new tty pair and send the master on the provided + // socket. + tty, err := console.NewWithSocket(ex.consoleSocket) + if err != nil { + Fatalf("error setting up console with socket %q: %v", ex.consoleSocket, err) + } + defer tty.Close() + + // Set stdio to the new tty slave. + cmd.Stdin = tty + cmd.Stdout = tty + cmd.Stderr = tty + cmd.SysProcAttr = &syscall.SysProcAttr{ + Setsid: true, + Setctty: true, + Ctty: int(tty.Fd()), + } + } + if err := cmd.Start(); err != nil { Fatalf("failure to start child exec process, err: %v", err) } @@ -252,11 +283,12 @@ func (ex *Exec) argsFromCLI(argv []string) (*control.ExecArgs, error) { return &control.ExecArgs{ Argv: argv, WorkingDirectory: ex.cwd, - FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}}, KUID: ex.user.kuid, KGID: ex.user.kgid, ExtraKGIDs: extraKGIDs, Capabilities: caps, + StdioIsPty: ex.consoleSocket != "", + FilePayload: urpc.FilePayload{[]*os.File{os.Stdin, os.Stdout, os.Stderr}}, }, nil } @@ -292,11 +324,12 @@ func argsFromProcess(p *specs.Process) (*control.ExecArgs, error) { Argv: p.Args, Envv: p.Env, WorkingDirectory: p.Cwd, - FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}}, KUID: auth.KUID(p.User.UID), KGID: auth.KGID(p.User.GID), ExtraKGIDs: extraKGIDs, Capabilities: caps, + StdioIsPty: p.Terminal, + FilePayload: urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}}, }, nil } diff --git a/runsc/console/BUILD b/runsc/console/BUILD new file mode 100644 index 000000000..fa1a7d430 --- /dev/null +++ b/runsc/console/BUILD @@ -0,0 +1,16 @@ +package(licenses = ["notice"]) # Apache 2.0 + +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "console", + srcs = ["console.go"], + importpath = "gvisor.googlesource.com/gvisor/runsc/console", + visibility = [ + "//runsc:__subpackages__", + ], + deps = [ + "@com_github_kr_pty//:go_default_library", + "@org_golang_x_sys//unix:go_default_library", + ], +) diff --git a/runsc/console/console.go b/runsc/console/console.go new file mode 100644 index 000000000..2f2745b2b --- /dev/null +++ b/runsc/console/console.go @@ -0,0 +1,61 @@ +// Copyright 2018 Google Inc. +// +// 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 console contains utilities for working with pty consols in runsc. +package console + +import ( + "fmt" + "net" + "os" + + "github.com/kr/pty" + "golang.org/x/sys/unix" +) + +// NewWithSocket creates pty master/slave pair, sends the master FD over the given +// socket, and returns the slave. +func NewWithSocket(socketPath string) (*os.File, error) { + // Create a new pty master and slave. + ptyMaster, ptySlave, err := pty.Open() + if err != nil { + return nil, fmt.Errorf("error opening pty: %v", err) + } + defer ptyMaster.Close() + + // Get a connection to the socket path. + conn, err := net.Dial("unix", socketPath) + if err != nil { + ptySlave.Close() + return nil, fmt.Errorf("error dial socket %q: %v", socketPath, err) + } + uc, ok := conn.(*net.UnixConn) + if !ok { + ptySlave.Close() + return nil, fmt.Errorf("connection is not a UnixConn: %T", conn) + } + socket, err := uc.File() + if err != nil { + ptySlave.Close() + return nil, fmt.Errorf("error getting file for unix socket %v: %v", uc, err) + } + + // Send the master FD over the connection. + msg := unix.UnixRights(int(ptyMaster.Fd())) + if err := unix.Sendmsg(int(socket.Fd()), []byte("pty-master"), msg, nil, 0); err != nil { + ptySlave.Close() + return nil, fmt.Errorf("error sending console over unix socket %q: %v", socketPath, err) + } + return ptySlave, nil +} diff --git a/runsc/sandbox/BUILD b/runsc/sandbox/BUILD index d26a4dac6..e9a39f797 100644 --- a/runsc/sandbox/BUILD +++ b/runsc/sandbox/BUILD @@ -5,7 +5,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "sandbox", srcs = [ - "console.go", "namespace.go", "network.go", "sandbox.go", @@ -21,9 +20,9 @@ go_library( "//pkg/sentry/control", "//pkg/urpc", "//runsc/boot", + "//runsc/console", "//runsc/fsgofer", "//runsc/specutils", - "@com_github_kr_pty//:go_default_library", "@com_github_opencontainers_runtime-spec//specs-go:go_default_library", "@com_github_vishvananda_netlink//:go_default_library", "@org_golang_x_sys//unix:go_default_library", diff --git a/runsc/sandbox/console.go b/runsc/sandbox/console.go deleted file mode 100644 index 3f133e12a..000000000 --- a/runsc/sandbox/console.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2018 Google Inc. -// -// 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 sandbox - -import ( - "fmt" - "net" - "os" - - "github.com/kr/pty" - "golang.org/x/sys/unix" -) - -// setupConsole creates pty master/slave pair, sends the master FD over the -// given socket, and returns the slave. -func setupConsole(socketPath string) (*os.File, error) { - // Create a new pty master and slave. - ptyMaster, ptySlave, err := pty.Open() - if err != nil { - return nil, fmt.Errorf("error opening pty: %v", err) - } - defer ptyMaster.Close() - - // Get a connection to the socket path. - conn, err := net.Dial("unix", socketPath) - if err != nil { - ptySlave.Close() - return nil, fmt.Errorf("error dial socket %q: %v", socketPath, err) - } - uc, ok := conn.(*net.UnixConn) - if !ok { - ptySlave.Close() - return nil, fmt.Errorf("connection is not a UnixConn: %T", conn) - } - socket, err := uc.File() - if err != nil { - ptySlave.Close() - return nil, fmt.Errorf("error getting file for unix socket %v: %v", uc, err) - } - - // Send the master FD over the connection. - msg := unix.UnixRights(int(ptyMaster.Fd())) - if err := unix.Sendmsg(int(socket.Fd()), []byte("pty-master"), msg, nil, 0); err != nil { - ptySlave.Close() - return nil, fmt.Errorf("error sending console over unix socket %q: %v", socketPath, err) - } - return ptySlave, nil -} diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 7789608f8..e54ba4ba3 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -31,6 +31,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/control" "gvisor.googlesource.com/gvisor/pkg/urpc" "gvisor.googlesource.com/gvisor/runsc/boot" + "gvisor.googlesource.com/gvisor/runsc/console" "gvisor.googlesource.com/gvisor/runsc/fsgofer" "gvisor.googlesource.com/gvisor/runsc/specutils" ) @@ -392,7 +393,7 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund "boot", "--bundle", bundleDir, "--controller-fd="+strconv.Itoa(nextFD), - fmt.Sprintf("--console=%t", consoleEnabled)) + "--console="+strconv.FormatBool(consoleEnabled)) nextFD++ controllerFile := os.NewFile(uintptr(fd), "control_server_socket") @@ -407,14 +408,19 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund nextFD++ } + // Sandbox stdio defaults to current process stdio. + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + // If the console control socket file is provided, then create a new // pty master/slave pair and set the tty on the sandbox process. if consoleEnabled { - // setupConsole will send the master on the socket, and return - // the slave. - tty, err := setupConsole(consoleSocket) + // console.NewWithSocket will send the master on the socket, + // and return the slave. + tty, err := console.NewWithSocket(consoleSocket) if err != nil { - return fmt.Errorf("error setting up control socket %q: %v", consoleSocket, err) + return fmt.Errorf("error setting up console with socket %q: %v", consoleSocket, err) } defer tty.Close() @@ -423,10 +429,6 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund cmd.Stderr = tty cmd.SysProcAttr.Setctty = true cmd.SysProcAttr.Ctty = int(tty.Fd()) - } else { - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr } // Detach from this session, otherwise cmd will get SIGHUP and SIGCONT -- cgit v1.2.3 From 2524111fc63343fd7372f5ea0266130adea778a5 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Mon, 27 Aug 2018 10:48:02 -0700 Subject: runsc: Terminal resizing support. Implements the TIOCGWINSZ and TIOCSWINSZ ioctls, which allow processes to resize the terminal. This allows, for example, sshd to properly set the window size for ssh sessions. PiperOrigin-RevId: 210392504 Change-Id: I0d4789154d6d22f02509b31d71392e13ee4a50ba --- pkg/abi/linux/tty.go | 10 ++++++++++ pkg/sentry/fs/tty/line_discipline.go | 24 ++++++++++++++++++++++++ pkg/sentry/fs/tty/master.go | 4 ++++ pkg/sentry/fs/tty/slave.go | 4 ++++ 4 files changed, 42 insertions(+) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index 81156867c..f63dc52aa 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -328,3 +328,13 @@ var DefaultSlaveTermios = KernelTermios{ InputSpeed: 38400, OutputSpeed: 38400, } + +// WindowSize corresponds to struct winsize defined in +// include/uapi/asm-generic/termios.h. +// +// +stateify savable +type WindowSize struct { + Rows uint16 + Cols uint16 + _ [4]byte // Padding for 2 unused shorts. +} diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index c7f6c5645..31804571e 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -76,6 +76,12 @@ const ( // // +stateify savable type lineDiscipline struct { + // sizeMu protects size. + sizeMu sync.Mutex `state:"nosave"` + + // size is the terminal size (width and height). + size linux.WindowSize + // inQueue is the input queue of the terminal. inQueue queue @@ -142,6 +148,24 @@ func (l *lineDiscipline) setTermios(ctx context.Context, io usermem.IO, args arc return 0, err } +func (l *lineDiscipline) windowSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error { + l.sizeMu.Lock() + defer l.sizeMu.Unlock() + _, err := usermem.CopyObjectOut(ctx, io, args[2].Pointer(), l.size, usermem.IOOpts{ + AddressSpaceActive: true, + }) + return err +} + +func (l *lineDiscipline) setWindowSize(ctx context.Context, io usermem.IO, args arch.SyscallArguments) error { + l.sizeMu.Lock() + defer l.sizeMu.Unlock() + _, err := usermem.CopyObjectIn(ctx, io, args[2].Pointer(), &l.size, usermem.IOOpts{ + AddressSpaceActive: true, + }) + return err +} + func (l *lineDiscipline) masterReadiness() waiter.EventMask { // We don't have to lock a termios because the default master termios // is immutable. diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index c8dc08c1a..ae7540eff 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -172,6 +172,10 @@ func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args a case linux.TIOCSPTLCK: // TODO: Implement pty locking. For now just pretend we do. return 0, nil + case linux.TIOCGWINSZ: + return 0, mf.t.ld.windowSize(ctx, io, args) + case linux.TIOCSWINSZ: + return 0, mf.t.ld.setWindowSize(ctx, io, args) default: return 0, syserror.ENOTTY } diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index ab92ced7e..963331b9b 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -150,6 +150,10 @@ func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args ar AddressSpaceActive: true, }) return 0, err + case linux.TIOCGWINSZ: + return 0, sf.si.t.ld.windowSize(ctx, io, args) + case linux.TIOCSWINSZ: + return 0, sf.si.t.ld.setWindowSize(ctx, io, args) default: return 0, syserror.ENOTTY } -- cgit v1.2.3 From f0492d45aa31e32f8a04b13b7bf53e0161e1afb6 Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Mon, 27 Aug 2018 17:20:36 -0700 Subject: Add /proc/sys/kernel/shm[all,max,mni]. PiperOrigin-RevId: 210459956 Change-Id: I51859b90fa967631e0a54a390abc3b5541fbee66 --- pkg/abi/linux/shm.go | 11 +++++++++++ pkg/sentry/fs/proc/sys.go | 6 ++++++ pkg/sentry/kernel/shm/shm.go | 34 ++++++++-------------------------- 3 files changed, 25 insertions(+), 26 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/shm.go b/pkg/abi/linux/shm.go index 9149ed094..f50b3c2e2 100644 --- a/pkg/abi/linux/shm.go +++ b/pkg/abi/linux/shm.go @@ -14,6 +14,8 @@ package linux +import "math" + // shmat(2) flags. Source: include/uapi/linux/shm.h const ( SHM_RDONLY = 010000 // Read-only access. @@ -38,6 +40,15 @@ const ( SHM_INFO = 14 ) +// SHM defaults as specified by linux. Source: include/uapi/linux/shm.h +const ( + SHMMIN = 1 + SHMMNI = 4096 + SHMMAX = math.MaxUint64 - 1<<24 + SHMALL = math.MaxUint64 - 1<<24 + SHMSEG = 4096 +) + // ShmidDS is equivalent to struct shmid64_ds. Source: // include/uapi/asm-generic/shmbuf.h type ShmidDS struct { diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index a2d36ca23..384b4ffe1 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -17,7 +17,9 @@ package proc import ( "fmt" "io" + "strconv" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile" @@ -102,6 +104,10 @@ func (p *proc) newKernelDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode d := &ramfs.Dir{} d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) d.AddChild(ctx, "hostname", p.newHostname(ctx, msrc)) + + d.AddChild(ctx, "shmmax", p.newStubProcFSFile(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMAX, 10)))) + d.AddChild(ctx, "shmall", p.newStubProcFSFile(ctx, msrc, []byte(strconv.FormatUint(linux.SHMALL, 10)))) + d.AddChild(ctx, "shmmni", p.newStubProcFSFile(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMNI, 10)))) return newFile(d, msrc, fs.SpecialDirectory, nil) } diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 1ac444094..77973951e 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -35,7 +35,6 @@ package shm import ( "fmt" - "math" "sync" "gvisor.googlesource.com/gvisor/pkg/abi/linux" @@ -52,23 +51,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/syserror" ) -// Various limits for shared memory segments. -const ( - // shmsTotalMaxPages is the system-wide limit on all shared memory segments, measured - // in number of pages. - shmsTotalMaxPages = math.MaxInt64 // SHMALL - - // shmMaxSize is the maximum size of a single segment, in bytes. - shmMaxSize = math.MaxInt64 // SHMMAX - - // shmMinSize is the minimum specifiable size of a segment, effectively - // yielding a size rounded up to the next page size. Measured in bytes. - shmMinSize = 1 // SHMMIN - - // shmsTotalMax is the maximum number of segments on the system. - shmsTotalMax = 4096 // SHMMNI -) - // Registry tracks all shared memory segments in an IPC namespace. The registry // provides the mechanisms for creating and finding segments, and reporting // global shm parameters. @@ -119,7 +101,7 @@ func (r *Registry) findByKey(key int32) *Shm { // FindOrCreate looks up or creates a segment in the registry. It's functionally // analogous to open(2). func (r *Registry) FindOrCreate(ctx context.Context, pid, key int32, size uint64, mode linux.FileMode, private, create, exclusive bool) (*Shm, error) { - if create && (size < shmMinSize || size > shmMaxSize) { + if create && (size < linux.SHMMIN || size > linux.SHMMAX) { // "A new segment was to be created and size is less than SHMMIN or // greater than SHMMAX." - man shmget(2) return nil, syserror.EINVAL @@ -128,7 +110,7 @@ func (r *Registry) FindOrCreate(ctx context.Context, pid, key int32, size uint64 r.mu.Lock() defer r.mu.Unlock() - if len(r.shms) >= shmsTotalMax { + if len(r.shms) >= linux.SHMMNI { // "All possible shared memory IDs have been taken (SHMMNI) ..." // - man shmget(2) return nil, syserror.ENOSPC @@ -179,7 +161,7 @@ func (r *Registry) FindOrCreate(ctx context.Context, pid, key int32, size uint64 return nil, syserror.EINVAL } - if numPages := sizeAligned / usermem.PageSize; r.totalPages+numPages > shmsTotalMaxPages { + if numPages := sizeAligned / usermem.PageSize; r.totalPages+numPages > linux.SHMALL { // "... allocating a segment of the requested size would cause the // system to exceed the system-wide limit on shared memory (SHMALL)." // - man shmget(2) @@ -245,11 +227,11 @@ func (r *Registry) newShm(ctx context.Context, pid, key int32, creator fs.FileOw // system. See shmctl(IPC_INFO). func (r *Registry) IPCInfo() *linux.ShmParams { return &linux.ShmParams{ - ShmMax: shmMaxSize, - ShmMin: shmMinSize, - ShmMni: shmsTotalMax, - ShmSeg: shmsTotalMax, // Linux also sets this to SHMMNI. - ShmAll: shmsTotalMaxPages, + ShmMax: linux.SHMMAX, + ShmMin: linux.SHMMIN, + ShmMni: linux.SHMMNI, + ShmSeg: linux.SHMSEG, + ShmAll: linux.SHMALL, } } -- cgit v1.2.3 From 2b8dae0bc5594f7088dd028268efaedbb5a72507 Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Wed, 5 Sep 2018 09:20:18 -0700 Subject: Open(2) isn't honoring O_NOFOLLOW PiperOrigin-RevId: 211644897 Change-Id: I882ed827a477d6c03576463ca5bf2d6351892b90 --- pkg/abi/linux/file.go | 1 + pkg/sentry/syscalls/linux/sys_file.go | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 509f6b5b3..9bf229a57 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -37,6 +37,7 @@ const ( O_DIRECT = 00040000 O_LARGEFILE = 00100000 O_DIRECTORY = 00200000 + O_NOFOLLOW = 00400000 O_CLOEXEC = 02000000 O_SYNC = 04010000 O_PATH = 010000000 diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 2cf429f5c..3e28d4b8a 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -136,7 +136,8 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u return 0, err } - err = fileOpOn(t, dirFD, path, true /* resolve */, func(root *fs.Dirent, d *fs.Dirent) error { + resolve := flags&linux.O_NOFOLLOW == 0 + err = fileOpOn(t, dirFD, path, resolve, func(root *fs.Dirent, d *fs.Dirent) error { // First check a few things about the filesystem before trying to get the file // reference. // @@ -147,6 +148,10 @@ func openAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint) (fd u return err } + if fs.IsSymlink(d.Inode.StableAttr) && !resolve { + return syserror.ELOOP + } + fileFlags := linuxToFlags(flags) // Linux always adds the O_LARGEFILE flag when running in 64-bit mode. fileFlags.LargeFile = true -- cgit v1.2.3 From 3aa50f18a4102429aa40f5d0e518357ceaed2373 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 14 Sep 2018 15:58:56 -0700 Subject: Reuse readlink parameter, add sockaddr max. PiperOrigin-RevId: 213058623 Change-Id: I522598c655d633b9330990951ff1c54d1023ec29 --- pkg/abi/linux/socket.go | 4 ++++ pkg/sentry/fs/host/util_unsafe.go | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 9a78cc131..19b5fa212 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -140,6 +140,10 @@ const ( SO_TYPE = 3 ) +// SockAddrMax is the maximum size of a struct sockaddr, from +// uapi/linux/socket.h. +const SockAddrMax = 128 + // SockAddrInt is struct sockaddr_in, from uapi/linux/in.h. type SockAddrInet struct { Family uint16 diff --git a/pkg/sentry/fs/host/util_unsafe.go b/pkg/sentry/fs/host/util_unsafe.go index c38d2392d..2ecb54319 100644 --- a/pkg/sentry/fs/host/util_unsafe.go +++ b/pkg/sentry/fs/host/util_unsafe.go @@ -23,6 +23,9 @@ import ( ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" ) +// NulByte is a single NUL byte. It is passed to readlinkat as an empty string. +var NulByte byte = '\x00' + func createLink(fd int, name string, linkName string) error { namePtr, err := syscall.BytePtrFromString(name) if err != nil { @@ -50,7 +53,7 @@ func readLink(fd int) (string, error) { n, _, errno := syscall.Syscall6( syscall.SYS_READLINKAT, uintptr(fd), - uintptr(unsafe.Pointer(syscall.StringBytePtr(""))), + uintptr(unsafe.Pointer(&NulByte)), // "" uintptr(unsafe.Pointer(&b[0])), uintptr(l), 0, 0) -- cgit v1.2.3 From b709d239870143102cf4e44b65cc26cea78a6ccb Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Thu, 27 Sep 2018 18:15:07 -0700 Subject: Forward ioctl(TCSETSF) calls on host ttys to the host kernel. We already forward TCSETS and TCSETSW. TCSETSF is roughly equivalent but discards pending input. The filters were relaxed to allow host ioctls with TCSETSF argument. This fixes programs like "passwd" that prevent user input from being displayed on the terminal. Before: root@b8a0240fc836:/# passwd Enter new UNIX password: 123 Retype new UNIX password: 123 passwd: password updated successfully After: root@ae6f5dabe402:/# passwd Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully PiperOrigin-RevId: 214869788 Change-Id: I31b4d1373c1388f7b51d0f2f45ce40aa8e8b0b58 --- pkg/abi/linux/ioctl.go | 1 + pkg/sentry/fs/host/file.go | 2 +- runsc/boot/filter/config.go | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 4d7a2dfd7..1c9dc7b03 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -21,6 +21,7 @@ const ( TCGETS = 0x00005401 TCSETS = 0x00005402 TCSETSW = 0x00005403 + TCSETSF = 0x00005404 TIOCGPGRP = 0x0000540f TIOCSPGRP = 0x00005410 TIOCOUTQ = 0x00005411 diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index 8d2463c78..6f469b5cc 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -305,7 +305,7 @@ func (f *fileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.Sys }) return 0, err - case linux.TCSETS, linux.TCSETSW: + case linux.TCSETS, linux.TCSETSW, linux.TCSETSF: var termios linux.Termios if _, err := usermem.CopyObjectIn(ctx, io, args[2].Pointer(), &termios, usermem.IOOpts{ AddressSpaceActive: true, diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index 0bcc640d5..352c64253 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -147,6 +147,11 @@ var allowedSyscalls = seccomp.SyscallRules{ seccomp.AllowValue(linux.TCSETS), seccomp.AllowAny{}, /* termios struct */ }, + { + seccomp.AllowAny{}, /* fd */ + seccomp.AllowValue(linux.TCSETSF), + seccomp.AllowAny{}, /* termios struct */ + }, { seccomp.AllowAny{}, /* fd */ seccomp.AllowValue(linux.TCSETSW), -- cgit v1.2.3 From 0400e5459288592768af12ab71609c6df6afe3d7 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 1 Oct 2018 14:15:52 -0700 Subject: Add itimer types to linux package, strace PiperOrigin-RevId: 215278262 Change-Id: Icd10384c99802be6097be938196044386441e282 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/timer.go | 23 +++++++++++++++++++++++ pkg/sentry/strace/linux64.go | 4 ++-- pkg/sentry/strace/strace.go | 19 +++++++++++++++++++ pkg/sentry/strace/syscalls.go | 7 +++++-- pkg/sentry/syscalls/linux/sys_timer.go | 27 +++++++-------------------- 6 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 pkg/abi/linux/timer.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index ac4ceefbc..f8f82c0da 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -44,6 +44,7 @@ go_library( "signal.go", "socket.go", "time.go", + "timer.go", "tty.go", "uio.go", "utsname.go", diff --git a/pkg/abi/linux/timer.go b/pkg/abi/linux/timer.go new file mode 100644 index 000000000..6c4675c35 --- /dev/null +++ b/pkg/abi/linux/timer.go @@ -0,0 +1,23 @@ +// Copyright 2018 Google Inc. +// +// 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 linux + +// itimer types for getitimer(2) and setitimer(2), from +// include/uapi/linux/time.h. +const ( + ITIMER_REAL = 0 + ITIMER_VIRTUAL = 1 + ITIMER_PROF = 2 +) diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index 63851246c..1df148e7d 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -53,9 +53,9 @@ var linuxAMD64 = SyscallMap{ 33: makeSyscallInfo("dup2", Hex, Hex), 34: makeSyscallInfo("pause"), 35: makeSyscallInfo("nanosleep", Timespec, PostTimespec), - 36: makeSyscallInfo("getitimer", Hex, PostItimerVal), + 36: makeSyscallInfo("getitimer", ItimerType, PostItimerVal), 37: makeSyscallInfo("alarm", Hex), - 38: makeSyscallInfo("setitimer", Hex, ItimerVal, PostItimerVal), + 38: makeSyscallInfo("setitimer", ItimerType, ItimerVal, PostItimerVal), 39: makeSyscallInfo("getpid"), 40: makeSyscallInfo("sendfile", Hex, Hex, Hex, Hex), 41: makeSyscallInfo("socket", SockFamily, SockType, SockProtocol), diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index 539e665d2..c99c33c33 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -24,6 +24,7 @@ import ( "syscall" "time" + "gvisor.googlesource.com/gvisor/pkg/abi" "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/bits" "gvisor.googlesource.com/gvisor/pkg/eventchannel" @@ -46,6 +47,22 @@ var LogMaximumSize uint = DefaultLogMaximumSize // do anything useful with binary text dump of byte array arguments. var EventMaximumSize uint +// ItimerTypes are the possible itimer types. +var ItimerTypes = abi.ValueSet{ + { + Value: linux.ITIMER_REAL, + Name: "ITIMER_REAL", + }, + { + Value: linux.ITIMER_VIRTUAL, + Name: "ITIMER_VIRTUAL", + }, + { + Value: linux.ITIMER_PROF, + Name: "ITIMER_PROF", + }, +} + func iovecs(t *kernel.Task, addr usermem.Addr, iovcnt int, printContent bool, maxBytes uint64) string { if iovcnt < 0 || iovcnt > linux.UIO_MAXIOV { return fmt.Sprintf("%#x (error decoding iovecs: invalid iovcnt)", addr) @@ -322,6 +339,8 @@ func (i *SyscallInfo) pre(t *kernel.Task, args arch.SyscallArguments, maximumBlo output = append(output, futex(uint64(args[arg].Uint()))) case PtraceRequest: output = append(output, PtraceRequestSet.Parse(args[arg].Uint64())) + case ItimerType: + output = append(output, ItimerTypes.Parse(uint64(args[arg].Int()))) 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 770a0d2b9..8be4fa318 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -150,6 +150,9 @@ const ( // Utimbuf is a pointer to a struct utimbuf. Utimbuf + // Rusage is a struct rusage, formatted after syscall execution. + Rusage + // CloneFlags are clone(2) flags. CloneFlags @@ -165,8 +168,8 @@ const ( // PtraceRequest is the ptrace(2) request. PtraceRequest - // Rusage is a struct rusage, formatted after syscall execution. - Rusage + // ItimerType is an itimer type (ITIMER_REAL, etc). + ItimerType ) // defaultFormat is the syscall argument format to use if the actual format is diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go index aaed75c81..a12d12d9d 100644 --- a/pkg/sentry/syscalls/linux/sys_timer.go +++ b/pkg/sentry/syscalls/linux/sys_timer.go @@ -25,19 +25,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// ItimerType denotes the type of interval timer. -type ItimerType int - -// Interval timer types from . -const ( - // ItimerReal equals to ITIMER_REAL. - ItimerReal ItimerType = iota - // ItimerVirtual equals to ITIMER_VIRTUAL. - ItimerVirtual - // ItimerProf equals to ITIMER_PROF. - ItimerProf -) - const nsecPerSec = int64(time.Second) // copyItimerValIn copies an ItimerVal from the untrusted app range to the @@ -83,13 +70,13 @@ func copyItimerValOut(t *kernel.Task, addr usermem.Addr, itv *linux.ItimerVal) e } } -func findTimer(t *kernel.Task, w ItimerType) (*ktime.Timer, error) { - switch w { - case ItimerReal: +func findTimer(t *kernel.Task, which int32) (*ktime.Timer, error) { + switch which { + case linux.ITIMER_REAL: return t.ThreadGroup().Timer().RealTimer, nil - case ItimerVirtual: + case linux.ITIMER_VIRTUAL: return t.ThreadGroup().Timer().VirtualTimer, nil - case ItimerProf: + case linux.ITIMER_PROF: return t.ThreadGroup().Timer().ProfTimer, nil default: return nil, syscall.EINVAL @@ -98,7 +85,7 @@ func findTimer(t *kernel.Task, w ItimerType) (*ktime.Timer, error) { // Getitimer implements linux syscall getitimer(2). func Getitimer(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - timerID := ItimerType(args[0].Int()) + timerID := args[0].Int() val := args[1].Pointer() timer, err := findTimer(t, timerID) @@ -116,7 +103,7 @@ func Getitimer(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys // Setitimer implements linux syscall setitimer(2). func Setitimer(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - timerID := ItimerType(args[0].Int()) + timerID := args[0].Int() newVal := args[1].Pointer() oldVal := args[2].Pointer() -- cgit v1.2.3 From 213f6688a56e7bcd1205c77dc79c3e5cfee817fe Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Wed, 3 Oct 2018 17:28:52 -0700 Subject: Implement TIOCSCTTY ioctl as a noop. PiperOrigin-RevId: 215658757 Change-Id: If63b33293f3e53a7f607ae72daa79e2b7ef6fcfd --- pkg/abi/linux/ioctl.go | 1 + pkg/sentry/fs/tty/slave.go | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 1c9dc7b03..afd9ee82b 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -22,6 +22,7 @@ const ( TCSETS = 0x00005402 TCSETSW = 0x00005403 TCSETSF = 0x00005404 + TIOCSCTTY = 0x0000540e TIOCGPGRP = 0x0000540f TIOCSPGRP = 0x00005410 TIOCOUTQ = 0x00005411 diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 963331b9b..4a0d4fdb9 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -154,6 +154,12 @@ func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args ar return 0, sf.si.t.ld.windowSize(ctx, io, args) case linux.TIOCSWINSZ: return 0, sf.si.t.ld.setWindowSize(ctx, io, args) + case linux.TIOCSCTTY: + // Make the given terminal the controlling terminal of the + // calling process. + // TODO: Implement once we have support for job + // control. + return 0, nil default: return 0, syserror.ENOTTY } -- cgit v1.2.3 From 569c2b06c47d269d961405fa652d45e51860d005 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 8 Oct 2018 11:38:02 -0700 Subject: Statfs Namelen should be NAME_MAX not PATH_MAX We accidentally set the wrong maximum. I've also added PATH_MAX and NAME_MAX to the linux abi package. PiperOrigin-RevId: 216221311 Change-Id: I44805fcf21508831809692184a0eba4cee469633 --- pkg/abi/linux/fs.go | 6 ++++++ pkg/sentry/loader/elf.go | 3 +-- pkg/sentry/strace/strace.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 4 ++-- pkg/sentry/syscalls/linux/sys_stat.go | 4 +--- pkg/sentry/syscalls/linux/sys_thread.go | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index 00b239351..32a0812b4 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -28,6 +28,12 @@ const ( V9FS_MAGIC = 0x01021997 ) +// Filesystem path limits, from uapi/linux/limits.h. +const ( + NAME_MAX = 255 + PATH_MAX = 4096 +) + // Statfs is struct statfs, from uapi/asm-generic/statfs.h. type Statfs struct { // Type is one of the filesystem magic values, defined above. diff --git a/pkg/sentry/loader/elf.go b/pkg/sentry/loader/elf.go index f4deaa905..849be5a3d 100644 --- a/pkg/sentry/loader/elf.go +++ b/pkg/sentry/loader/elf.go @@ -19,7 +19,6 @@ import ( "debug/elf" "fmt" "io" - "syscall" "gvisor.googlesource.com/gvisor/pkg/abi" "gvisor.googlesource.com/gvisor/pkg/abi/linux" @@ -409,7 +408,7 @@ func loadParsedELF(ctx context.Context, m *mm.MemoryManager, f *fs.File, info el ctx.Infof("PT_INTERP path too small: %v", phdr.Filesz) return loadedELF{}, syserror.ENOEXEC } - if phdr.Filesz > syscall.PathMax { + if phdr.Filesz > linux.PATH_MAX { ctx.Infof("PT_INTERP path too big: %v", phdr.Filesz) return loadedELF{}, syserror.ENOEXEC } diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index c99c33c33..f2a22aaa5 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -133,7 +133,7 @@ func dump(t *kernel.Task, addr usermem.Addr, size uint, maximumBlobSize uint) st } func path(t *kernel.Task, addr usermem.Addr) string { - path, err := t.CopyInString(addr, syscall.PathMax) + path, err := t.CopyInString(addr, linux.PATH_MAX) if err != nil { return fmt.Sprintf("%#x (error decoding path: %s)", addr, err) } diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 97881a1f5..015afda9b 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -115,7 +115,7 @@ func fileOpOn(t *kernel.Task, dirFD kdefs.FD, path string, resolve bool, fn func // copyInPath copies a path in. func copyInPath(t *kernel.Task, addr usermem.Addr, allowEmpty bool) (path string, dirPath bool, err error) { - path, err = t.CopyInString(addr, syscall.PathMax) + path, err = t.CopyInString(addr, linux.PATH_MAX) if err != nil { return "", false, err } @@ -1080,7 +1080,7 @@ func symlinkAt(t *kernel.Task, dirFD kdefs.FD, newAddr usermem.Addr, oldAddr use // The oldPath is copied in verbatim. This is because the symlink // will include all details, including trailing slashes. - oldPath, err := t.CopyInString(oldAddr, syscall.PathMax) + oldPath, err := t.CopyInString(oldAddr, linux.PATH_MAX) if err != nil { return err } diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go index 6e21b34fd..619a14d7c 100644 --- a/pkg/sentry/syscalls/linux/sys_stat.go +++ b/pkg/sentry/syscalls/linux/sys_stat.go @@ -15,8 +15,6 @@ package linux import ( - "syscall" - "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" @@ -198,7 +196,7 @@ func statfsImpl(t *kernel.Task, d *fs.Dirent, addr usermem.Addr) error { Files: info.TotalFiles, FilesFree: info.FreeFiles, // Same as Linux for simple_statfs, see fs/libfs.c. - NameLength: syscall.PathMax, + NameLength: linux.NAME_MAX, FragmentSize: d.Inode.StableAttr.BlockSize, // Leave other fields 0 like simple_statfs does. } diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index 0adbf160f..550f63a43 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -76,7 +76,7 @@ func Execve(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal envvAddr := args[2].Pointer() // Extract our arguments. - filename, err := t.CopyInString(filenameAddr, syscall.PathMax) + filename, err := t.CopyInString(filenameAddr, linux.PATH_MAX) if err != nil { return 0, nil, err } -- cgit v1.2.3 From acf7a951894a1b445ff61e945e32c989892f476f Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Tue, 9 Oct 2018 09:51:01 -0700 Subject: Add memunit to sysinfo(2). Also properly add padding after Procs in the linux.Sysinfo structure. This will be implicitly padded to 64bits so we need to do the same. PiperOrigin-RevId: 216372907 Change-Id: I6eb6a27800da61d8f7b7b6e87bf0391a48fdb475 --- pkg/abi/linux/linux.go | 1 + pkg/sentry/syscalls/linux/sys_sysinfo.go | 1 + 2 files changed, 2 insertions(+) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go index a946849c5..de2af80dc 100644 --- a/pkg/abi/linux/linux.go +++ b/pkg/abi/linux/linux.go @@ -31,6 +31,7 @@ type Sysinfo struct { TotalSwap uint64 FreeSwap uint64 Procs uint16 + _ [6]byte // Pad Procs to 64bits. TotalHigh uint64 FreeHigh uint64 Unit uint32 diff --git a/pkg/sentry/syscalls/linux/sys_sysinfo.go b/pkg/sentry/syscalls/linux/sys_sysinfo.go index bd0ffcd5c..6560bac57 100644 --- a/pkg/sentry/syscalls/linux/sys_sysinfo.go +++ b/pkg/sentry/syscalls/linux/sys_sysinfo.go @@ -36,6 +36,7 @@ func Sysinfo(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca Uptime: t.Kernel().MonotonicClock().Now().Seconds(), TotalRAM: totalSize, FreeRAM: totalSize - totalUsage, + Unit: 1, } _, err := t.CopyOut(addr, si) return 0, nil, err -- cgit v1.2.3 From 463e73d46d76042c39050d02cf3b0f875e55eb01 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Wed, 10 Oct 2018 22:39:32 -0700 Subject: Add seccomp filter configuration to ptrace stubs. This is a defense-in-depth measure. If the sentry is compromised, this prevents system call injection to the stubs. There is some complexity with respect to ptrace and seccomp interactions, so this protection is not really available for kernel versions < 4.8; this is detected dynamically. Note that this also solves the vsyscall emulation issue by adding in appropriate trapping for those system calls. It does mean that a compromised sentry could theoretically inject these into the stub (ignoring the trap and resume, thereby allowing execution), but they are harmless. PiperOrigin-RevId: 216647581 Change-Id: Id06c232cbac1f9489b1803ec97f83097fcba8eb8 --- pkg/abi/BUILD | 1 + pkg/abi/abi_linux.go | 20 +++ pkg/seccomp/BUILD | 3 - pkg/seccomp/seccomp.go | 224 +++++++++++++++++-------- pkg/seccomp/seccomp_rules.go | 8 +- pkg/seccomp/seccomp_test.go | 172 ++++++++++++++----- pkg/seccomp/seccomp_unsafe.go | 24 ++- pkg/sentry/arch/arch_amd64.go | 5 + pkg/sentry/platform/ptrace/BUILD | 2 + pkg/sentry/platform/ptrace/ptrace_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess.go | 150 +++++++++++------ pkg/sentry/platform/ptrace/subprocess_amd64.go | 16 +- pkg/sentry/platform/ptrace/subprocess_linux.go | 175 +++++++++++++++++-- pkg/sentry/strace/BUILD | 1 + pkg/sentry/strace/strace.go | 11 ++ 15 files changed, 620 insertions(+), 194 deletions(-) create mode 100644 pkg/abi/abi_linux.go (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index c014d2c4b..1ba4f3a46 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -6,6 +6,7 @@ go_library( name = "abi", srcs = [ "abi.go", + "abi_linux.go", "flag.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/abi", diff --git a/pkg/abi/abi_linux.go b/pkg/abi/abi_linux.go new file mode 100644 index 000000000..dd5d67b51 --- /dev/null +++ b/pkg/abi/abi_linux.go @@ -0,0 +1,20 @@ +// Copyright 2018 Google Inc. +// +// 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. + +// +build linux + +package abi + +// Host specifies the host ABI. +const Host = Linux diff --git a/pkg/seccomp/BUILD b/pkg/seccomp/BUILD index b3e2f0b38..1975d17a6 100644 --- a/pkg/seccomp/BUILD +++ b/pkg/seccomp/BUILD @@ -28,12 +28,9 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/seccomp", visibility = ["//visibility:public"], deps = [ - "//pkg/abi", "//pkg/abi/linux", "//pkg/bpf", "//pkg/log", - "//pkg/sentry/arch", - "//pkg/sentry/strace", ], ) diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index 49da3c775..a746dc9b3 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -20,31 +20,36 @@ import ( "reflect" "sort" - "gvisor.googlesource.com/gvisor/pkg/abi" "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/bpf" "gvisor.googlesource.com/gvisor/pkg/log" - "gvisor.googlesource.com/gvisor/pkg/sentry/arch" - "gvisor.googlesource.com/gvisor/pkg/sentry/strace" ) const ( - // violationLabel is added to the program to take action on a violation. - violationLabel = "violation" - // skipOneInst is the offset to take for skipping one instruction. skipOneInst = 1 + + // defaultLabel is the label for the default action. + defaultLabel = "default_action" ) // Install generates BPF code based on the set of syscalls provided. It only -// allows syscalls that conform to the specification (*) and generates SIGSYS +// allows syscalls that conform to the specification and generates SIGSYS // trap unless kill is set. // -// (*) The current implementation only checks the syscall number. It does NOT -// validate any of the arguments. +// This is a convenience wrapper around BuildProgram and SetFilter. func Install(rules SyscallRules, kill bool) error { log.Infof("Installing seccomp filters for %d syscalls (kill=%t)", len(rules), kill) - instrs, err := buildProgram(rules, kill) + defaultAction := uint32(linux.SECCOMP_RET_TRAP) + if kill { + defaultAction = uint32(linux.SECCOMP_RET_KILL) + } + instrs, err := BuildProgram([]RuleSet{ + RuleSet{ + Rules: rules, + Action: uint32(linux.SECCOMP_RET_ALLOW), + }, + }, defaultAction) if log.IsLogging(log.Debug) { programStr, errDecode := bpf.DecodeProgram(instrs) if errDecode != nil { @@ -56,60 +61,84 @@ func Install(rules SyscallRules, kill bool) error { return err } - if err := seccomp(instrs); err != nil { - return err + // Perform the actual installation. + if errno := SetFilter(instrs); errno != 0 { + return fmt.Errorf("Failed to set filter: %v", errno) } log.Infof("Seccomp filters installed.") return nil } -// buildProgram builds a BPF program that whitelists all given syscall rules. -func buildProgram(rules SyscallRules, kill bool) ([]linux.BPFInstruction, error) { +// RuleSet is a set of rules and associated action. +type RuleSet struct { + Rules SyscallRules + Action uint32 + + // Vsyscall indicates that a check is made for a function being called + // from kernel mappings. This is where the vsyscall page is located + // (and typically) emulated, so this RuleSet will not match any + // functions not dispatched from the vsyscall page. + Vsyscall bool +} + +// SyscallName gives names to system calls. It is used purely for debugging purposes. +// +// An alternate namer can be provided to the package at initialization time. +var SyscallName = func(sysno uintptr) string { + return fmt.Sprintf("syscall_%d", sysno) +} + +// BuildProgram builds a BPF program from the given map of actions to matching +// SyscallRules. The single generated program covers all provided RuleSets. +func BuildProgram(rules []RuleSet, defaultAction uint32) ([]linux.BPFInstruction, error) { program := bpf.NewProgramBuilder() - violationAction := uint32(linux.SECCOMP_RET_KILL) - if !kill { - violationAction = linux.SECCOMP_RET_TRAP - } // Be paranoid and check that syscall is done in the expected architecture. // // A = seccomp_data.arch - // if (A != AUDIT_ARCH_X86_64) goto violation + // if (A != AUDIT_ARCH_X86_64) goto defaultAction. program.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArch) - // violationLabel is at the bottom of the program. The size of program + // defaultLabel is at the bottom of the program. The size of program // may exceeds 255 lines, which is the limit of a condition jump. program.AddJump(bpf.Jmp|bpf.Jeq|bpf.K, linux.AUDIT_ARCH_X86_64, skipOneInst, 0) - program.AddDirectJumpLabel(violationLabel) - + program.AddDirectJumpLabel(defaultLabel) if err := buildIndex(rules, program); err != nil { return nil, err } - // violation: return violationAction - if err := program.AddLabel(violationLabel); err != nil { + // Exhausted: return defaultAction. + if err := program.AddLabel(defaultLabel); err != nil { return nil, err } - program.AddStmt(bpf.Ret|bpf.K, violationAction) + program.AddStmt(bpf.Ret|bpf.K, defaultAction) return program.Instructions() } -// buildIndex builds a BST to quickly search through all syscalls that are whitelisted. -func buildIndex(rules SyscallRules, program *bpf.ProgramBuilder) error { - syscalls := []uintptr{} - for sysno := range rules { - syscalls = append(syscalls, sysno) +// buildIndex builds a BST to quickly search through all syscalls. +func buildIndex(rules []RuleSet, program *bpf.ProgramBuilder) error { + // Build a list of all application system calls, across all given rule + // sets. We have a simple BST, but may dispatch individual matchers + // with different actions. The matchers are evaluated linearly. + requiredSyscalls := make(map[uintptr]struct{}) + for _, rs := range rules { + for sysno := range rs.Rules { + requiredSyscalls[sysno] = struct{}{} + } } - - t, ok := strace.Lookup(abi.Linux, arch.AMD64) - if !ok { - panic("Can't find amd64 Linux syscall table") + syscalls := make([]uintptr, 0, len(requiredSyscalls)) + for sysno, _ := range requiredSyscalls { + syscalls = append(syscalls, sysno) } - sort.Slice(syscalls, func(i, j int) bool { return syscalls[i] < syscalls[j] }) - for _, s := range syscalls { - log.Infof("syscall filter: %v (%v): %s", s, t.Name(s), rules[s]) + for _, sysno := range syscalls { + for _, rs := range rules { + // Print only if there is a corresponding set of rules. + if _, ok := rs.Rules[sysno]; ok { + log.Debugf("syscall filter %v: %s => 0x%x", SyscallName(sysno), rs.Rules[sysno], rs.Action) + } + } } root := createBST(syscalls) @@ -119,7 +148,7 @@ func buildIndex(rules SyscallRules, program *bpf.ProgramBuilder) error { // // A = seccomp_data.nr program.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetNR) - return root.traverse(buildBSTProgram, program, rules) + return root.traverse(buildBSTProgram, rules, program) } // createBST converts sorted syscall slice into a balanced BST. @@ -136,15 +165,23 @@ func createBST(syscalls []uintptr) *node { return &parent } -func ruleViolationLabel(sysno uintptr, idx int) string { - return fmt.Sprintf("ruleViolation_%v_%v", sysno, idx) +func vsyscallViolationLabel(ruleSetIdx int, sysno uintptr) string { + return fmt.Sprintf("vsyscallViolation_%v_%v", ruleSetIdx, sysno) +} + +func ruleViolationLabel(ruleSetIdx int, sysno uintptr, idx int) string { + return fmt.Sprintf("ruleViolation_%v_%v_%v", ruleSetIdx, sysno, idx) } func checkArgsLabel(sysno uintptr) string { return fmt.Sprintf("checkArgs_%v", sysno) } -func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, sysno uintptr) error { +// addSyscallArgsCheck adds argument checks for a single system call. It does +// not insert a jump to the default action at the end and it is the +// responsibility of the caller to insert an appropriate jump after calling +// this function. +func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, action uint32, ruleSetIdx int, sysno uintptr) error { for ruleidx, rule := range rules { labelled := false for i, arg := range rule { @@ -155,28 +192,29 @@ func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, sysno uintptr) err high, low := uint32(a>>32), uint32(a) // assert arg_low == low p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArgLow(i)) - p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, low, 0, ruleViolationLabel(sysno, ruleidx)) + p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, low, 0, ruleViolationLabel(ruleSetIdx, sysno, ruleidx)) // assert arg_high == high p.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetArgHigh(i)) - p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, high, 0, ruleViolationLabel(sysno, ruleidx)) + p.AddJumpFalseLabel(bpf.Jmp|bpf.Jeq|bpf.K, high, 0, ruleViolationLabel(ruleSetIdx, sysno, ruleidx)) labelled = true - default: return fmt.Errorf("unknown syscall rule type: %v", reflect.TypeOf(a)) } } } - // Matched, allow the syscall. - p.AddStmt(bpf.Ret|bpf.K, linux.SECCOMP_RET_ALLOW) - // Label the end of the rule if necessary. + + // Matched, emit the given action. + p.AddStmt(bpf.Ret|bpf.K, action) + + // Label the end of the rule if necessary. This is added for + // the jumps above when the argument check fails. if labelled { - if err := p.AddLabel(ruleViolationLabel(sysno, ruleidx)); err != nil { + if err := p.AddLabel(ruleViolationLabel(ruleSetIdx, sysno, ruleidx)); err != nil { return err } } } - // Not matched? - p.AddDirectJumpLabel(violationLabel) + return nil } @@ -188,16 +226,16 @@ func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, sysno uintptr) err // (A > 22) ? goto index_35 : goto index_9 // // index_9: // SYS_MMAP(9), leaf -// A == 9) ? goto argument check : violation +// A == 9) ? goto argument check : defaultLabel // // index_35: // SYS_NANOSLEEP(35), single child // (A == 35) ? goto argument check : continue -// (A > 35) ? goto index_50 : goto violation +// (A > 35) ? goto index_50 : goto defaultLabel // // index_50: // SYS_LISTEN(50), leaf -// (A == 50) ? goto argument check : goto violation +// (A == 50) ? goto argument check : goto defaultLabel // -func buildBSTProgram(program *bpf.ProgramBuilder, rules SyscallRules, n *node) error { +func buildBSTProgram(n *node, rules []RuleSet, program *bpf.ProgramBuilder) error { // Root node is never referenced by label, skip it. if !n.root { if err := program.AddLabel(n.label()); err != nil { @@ -209,11 +247,10 @@ func buildBSTProgram(program *bpf.ProgramBuilder, rules SyscallRules, n *node) e program.AddJumpTrueLabel(bpf.Jmp|bpf.Jeq|bpf.K, uint32(sysno), checkArgsLabel(sysno), 0) if n.left == nil && n.right == nil { // Leaf nodes don't require extra check. - program.AddDirectJumpLabel(violationLabel) + program.AddDirectJumpLabel(defaultLabel) } else { // Non-leaf node. Check which turn to take otherwise. Using direct jumps // in case that the offset may exceed the limit of a conditional jump (255) - // Note that 'violationLabel' is returned for nil children. program.AddJump(bpf.Jmp|bpf.Jgt|bpf.K, uint32(sysno), 0, skipOneInst) program.AddDirectJumpLabel(n.right.label()) program.AddDirectJumpLabel(n.left.label()) @@ -222,12 +259,60 @@ func buildBSTProgram(program *bpf.ProgramBuilder, rules SyscallRules, n *node) e if err := program.AddLabel(checkArgsLabel(sysno)); err != nil { return err } - // No rules, just allow it and save one jmp. - if len(rules[sysno]) == 0 { - program.AddStmt(bpf.Ret|bpf.K, linux.SECCOMP_RET_ALLOW) - return nil + + emitted := false + for ruleSetIdx, rs := range rules { + if _, ok := rs.Rules[sysno]; ok { + // If there are no rules, then this will always match. + // Remember we've done this so that we can emit a + // sensible error. We can't catch all overlaps, but we + // can catch this one at least. + if emitted { + return fmt.Errorf("unreachable action for %v: 0x%x (rule set %d)", SyscallName(sysno), rs.Action, ruleSetIdx) + } + + // Emit a vsyscall check if this rule requires a + // Vsyscall match. This rule ensures that the top bit + // is set in the instruction pointer, which is where + // the vsyscall page will be mapped. + if rs.Vsyscall { + program.AddStmt(bpf.Ld|bpf.Abs|bpf.W, seccompDataOffsetIPHigh) + program.AddJumpFalseLabel(bpf.Jmp|bpf.Jset|bpf.K, 0x80000000, 0, vsyscallViolationLabel(ruleSetIdx, sysno)) + } + + // Emit matchers. + if len(rs.Rules[sysno]) == 0 { + // This is a blanket action. + program.AddStmt(bpf.Ret|bpf.K, rs.Action) + emitted = true + } else { + // Add an argument check for these particular + // arguments. This will continue execution and + // check the next rule set. We need to ensure + // that at the very end, we insert a direct + // jump label for the unmatched case. + if err := addSyscallArgsCheck(program, rs.Rules[sysno], rs.Action, ruleSetIdx, sysno); err != nil { + return err + } + } + + // If there was a Vsyscall check for this rule, then we + // need to add an appropriate label for the jump above. + if rs.Vsyscall { + if err := program.AddLabel(vsyscallViolationLabel(ruleSetIdx, sysno)); err != nil { + return err + } + } + } } - return addSyscallArgsCheck(program, rules[sysno], sysno) + + // Not matched? We only need to insert a jump to the default label if + // not default action has been emitted for this call. + if !emitted { + program.AddDirectJumpLabel(defaultLabel) + } + + return nil } // node represents a tree node. @@ -238,26 +323,27 @@ type node struct { root bool } -// label returns the label corresponding to this node. If node is nil (syscall not present), -// violationLabel is returned for convenience. +// label returns the label corresponding to this node. +// +// If n is nil, then the defaultLabel is returned. func (n *node) label() string { if n == nil { - return violationLabel + return defaultLabel } return fmt.Sprintf("index_%v", n.value) } -type traverseFunc func(*bpf.ProgramBuilder, SyscallRules, *node) error +type traverseFunc func(*node, []RuleSet, *bpf.ProgramBuilder) error -func (n *node) traverse(fn traverseFunc, p *bpf.ProgramBuilder, rules SyscallRules) error { +func (n *node) traverse(fn traverseFunc, rules []RuleSet, p *bpf.ProgramBuilder) error { if n == nil { return nil } - if err := fn(p, rules, n); err != nil { + if err := fn(n, rules, p); err != nil { return err } - if err := n.left.traverse(fn, p, rules); err != nil { + if err := n.left.traverse(fn, rules, p); err != nil { return err } - return n.right.traverse(fn, p, rules) + return n.right.traverse(fn, rules, p) } diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index 9215e5c90..6b707f195 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -24,9 +24,11 @@ import "fmt" // __u64 args[6]; // }; const ( - seccompDataOffsetNR = 0 - seccompDataOffsetArch = 4 - seccompDataOffsetArgs = 16 + seccompDataOffsetNR = 0 + seccompDataOffsetArch = 4 + seccompDataOffsetIPLow = 8 + seccompDataOffsetIPHigh = 12 + seccompDataOffsetArgs = 16 ) func seccompDataOffsetArgLow(i int) uint32 { diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 42cf85c03..0188ad4f3 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -76,14 +76,18 @@ func TestBasic(t *testing.T) { } for _, test := range []struct { - // filters are the set of syscall that are allowed. - filters SyscallRules - kill bool - specs []spec + ruleSets []RuleSet + defaultAction uint32 + specs []spec }{ { - filters: SyscallRules{1: {}}, - kill: false, + ruleSets: []RuleSet{ + { + Rules: SyscallRules{1: {}}, + Action: linux.SECCOMP_RET_ALLOW, + }, + }, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { desc: "Single syscall allowed", @@ -98,12 +102,61 @@ func TestBasic(t *testing.T) { }, }, { - filters: SyscallRules{ - 1: {}, - 3: {}, - 5: {}, + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: []Rule{ + { + AllowValue(0x1), + }, + }, + }, + Action: linux.SECCOMP_RET_ALLOW, + }, + { + Rules: SyscallRules{ + 1: {}, + 2: {}, + }, + Action: linux.SECCOMP_RET_TRAP, + }, }, - kill: false, + defaultAction: linux.SECCOMP_RET_KILL, + specs: []spec{ + { + desc: "Multiple rulesets allowed (1a)", + data: seccompData{nr: 1, arch: linux.AUDIT_ARCH_X86_64, args: [6]uint64{0x1}}, + want: linux.SECCOMP_RET_ALLOW, + }, + { + desc: "Multiple rulesets allowed (1b)", + data: seccompData{nr: 1, arch: linux.AUDIT_ARCH_X86_64}, + want: linux.SECCOMP_RET_TRAP, + }, + { + desc: "Multiple rulesets allowed (2)", + data: seccompData{nr: 1, arch: linux.AUDIT_ARCH_X86_64}, + want: linux.SECCOMP_RET_TRAP, + }, + { + desc: "Multiple rulesets allowed (2)", + data: seccompData{nr: 0, arch: linux.AUDIT_ARCH_X86_64}, + want: linux.SECCOMP_RET_KILL, + }, + }, + }, + { + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: {}, + 3: {}, + 5: {}, + }, + Action: linux.SECCOMP_RET_ALLOW, + }, + }, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { desc: "Multiple syscalls allowed (1)", @@ -148,8 +201,15 @@ func TestBasic(t *testing.T) { }, }, { - filters: SyscallRules{1: {}}, - kill: false, + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: {}, + }, + Action: linux.SECCOMP_RET_ALLOW, + }, + }, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { desc: "Wrong architecture", @@ -159,26 +219,38 @@ func TestBasic(t *testing.T) { }, }, { - filters: SyscallRules{1: {}}, - kill: true, + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: {}, + }, + Action: linux.SECCOMP_RET_ALLOW, + }, + }, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { - desc: "Syscall disallowed, action kill", + desc: "Syscall disallowed, action trap", data: seccompData{nr: 2, arch: linux.AUDIT_ARCH_X86_64}, - want: linux.SECCOMP_RET_KILL, + want: linux.SECCOMP_RET_TRAP, }, }, }, { - filters: SyscallRules{ - 1: []Rule{ - { - AllowAny{}, - AllowValue(0xf), + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: []Rule{ + { + AllowAny{}, + AllowValue(0xf), + }, + }, }, + Action: linux.SECCOMP_RET_ALLOW, }, }, - kill: false, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { desc: "Syscall argument allowed", @@ -193,17 +265,22 @@ func TestBasic(t *testing.T) { }, }, { - filters: SyscallRules{ - 1: []Rule{ - { - AllowValue(0xf), - }, - { - AllowValue(0xe), + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: []Rule{ + { + AllowValue(0xf), + }, + { + AllowValue(0xe), + }, + }, }, + Action: linux.SECCOMP_RET_ALLOW, }, }, - kill: false, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { desc: "Syscall argument allowed, two rules", @@ -218,16 +295,21 @@ func TestBasic(t *testing.T) { }, }, { - filters: SyscallRules{ - 1: []Rule{ - { - AllowValue(0), - AllowValue(math.MaxUint64 - 1), - AllowValue(math.MaxUint32), + ruleSets: []RuleSet{ + { + Rules: SyscallRules{ + 1: []Rule{ + { + AllowValue(0), + AllowValue(math.MaxUint64 - 1), + AllowValue(math.MaxUint32), + }, + }, }, + Action: linux.SECCOMP_RET_ALLOW, }, }, - kill: false, + defaultAction: linux.SECCOMP_RET_TRAP, specs: []spec{ { desc: "64bit syscall argument allowed", @@ -259,7 +341,7 @@ func TestBasic(t *testing.T) { }, }, } { - instrs, err := buildProgram(test.filters, test.kill) + instrs, err := BuildProgram(test.ruleSets, test.defaultAction) if err != nil { t.Errorf("%s: buildProgram() got error: %v", test.specs[0].desc, err) continue @@ -282,6 +364,7 @@ func TestBasic(t *testing.T) { } } +// TestRandom tests that randomly generated rules are encoded correctly. func TestRandom(t *testing.T) { rand.Seed(time.Now().UnixNano()) size := rand.Intn(50) + 1 @@ -294,7 +377,12 @@ func TestRandom(t *testing.T) { } fmt.Printf("Testing filters: %v", syscallRules) - instrs, err := buildProgram(syscallRules, false) + instrs, err := BuildProgram([]RuleSet{ + RuleSet{ + Rules: syscallRules, + Action: uint32(linux.SECCOMP_RET_ALLOW), + }, + }, uint32(linux.SECCOMP_RET_TRAP)) if err != nil { t.Fatalf("buildProgram() got error: %v", err) } @@ -319,8 +407,8 @@ func TestRandom(t *testing.T) { } } -// TestReadDeal checks that a process dies when it trips over the filter and that it -// doesn't die when the filter is not triggered. +// TestReadDeal checks that a process dies when it trips over the filter and +// that it doesn't die when the filter is not triggered. func TestRealDeal(t *testing.T) { for _, test := range []struct { die bool diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go index 6682f8d9b..ae18534bf 100644 --- a/pkg/seccomp/seccomp_unsafe.go +++ b/pkg/seccomp/seccomp_unsafe.go @@ -17,7 +17,6 @@ package seccomp import ( - "fmt" "syscall" "unsafe" @@ -31,19 +30,28 @@ type sockFprog struct { Filter *linux.BPFInstruction } -func seccomp(instrs []linux.BPFInstruction) error { +// SetFilter installs the given BPF program. +// +// This is safe to call from an afterFork context. +// +//go:nosplit +func SetFilter(instrs []linux.BPFInstruction) syscall.Errno { // SYS_SECCOMP is not available in syscall package. const SYS_SECCOMP = 317 // PR_SET_NO_NEW_PRIVS is required in order to enable seccomp. See seccomp(2) for details. - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, linux.PR_SET_NO_NEW_PRIVS, 1, 0); err != 0 { - return fmt.Errorf("failed to set PR_SET_NO_NEW_PRIVS: %v", err) + if _, _, errno := syscall.RawSyscall(syscall.SYS_PRCTL, linux.PR_SET_NO_NEW_PRIVS, 1, 0); errno != 0 { + return errno } - sockProg := sockFprog{Len: uint16(len(instrs)), Filter: (*linux.BPFInstruction)(unsafe.Pointer(&instrs[0]))} // TODO: Use SECCOMP_FILTER_FLAG_KILL_PROCESS when available. - if _, _, err := syscall.RawSyscall(SYS_SECCOMP, linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, uintptr(unsafe.Pointer(&sockProg))); err != 0 { - return fmt.Errorf("failed to set seccomp filter: %v", err) + sockProg := sockFprog{ + Len: uint16(len(instrs)), + Filter: (*linux.BPFInstruction)(unsafe.Pointer(&instrs[0])), } - return nil + if _, _, errno := syscall.RawSyscall(SYS_SECCOMP, linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, uintptr(unsafe.Pointer(&sockProg))); errno != 0 { + return errno + } + + return 0 } diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index f1e408af9..5ba6c19ea 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build amd64 + package arch import ( @@ -26,6 +28,9 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// Host specifies the host architecture. +const Host = AMD64 + // These constants come directly from Linux. const ( // maxAddr64 is the maximum userspace address. It is TASK_SIZE in Linux diff --git a/pkg/sentry/platform/ptrace/BUILD b/pkg/sentry/platform/ptrace/BUILD index ceee895dc..debae058b 100644 --- a/pkg/sentry/platform/ptrace/BUILD +++ b/pkg/sentry/platform/ptrace/BUILD @@ -19,6 +19,8 @@ go_library( visibility = ["//:sandbox"], deps = [ "//pkg/abi/linux", + "//pkg/log", + "//pkg/seccomp", "//pkg/sentry/arch", "//pkg/sentry/platform", "//pkg/sentry/platform/filemem", diff --git a/pkg/sentry/platform/ptrace/ptrace_unsafe.go b/pkg/sentry/platform/ptrace/ptrace_unsafe.go index b55b2795a..46a8bda8e 100644 --- a/pkg/sentry/platform/ptrace/ptrace_unsafe.go +++ b/pkg/sentry/platform/ptrace/ptrace_unsafe.go @@ -136,7 +136,7 @@ func (t *thread) clone(initRegs *syscall.PtraceRegs) (*thread, error) { return nil, syscall.EINVAL } rval, err := t.syscallIgnoreInterrupt( - initRegs, + &t.initRegs, syscall.SYS_CLONE, arch.SyscallArgument{Value: uintptr( syscall.CLONE_FILES | diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go index 035ebc332..6d5ad6b71 100644 --- a/pkg/sentry/platform/ptrace/subprocess.go +++ b/pkg/sentry/platform/ptrace/subprocess.go @@ -47,6 +47,11 @@ type thread struct { tgid int32 tid int32 cpu uint32 + + // initRegs are the initial registers for the first thread. + // + // These are used for the register set for system calls. + initRegs syscall.PtraceRegs } // threadPool is a collection of threads. @@ -99,11 +104,6 @@ func (tp *threadPool) lookupOrCreate(currentTID int32, newThread func() *thread) type subprocess struct { platform.NoAddressSpaceIO - // initRegs are the initial registers for the first thread. - // - // These are used for the register set for system calls. - initRegs syscall.PtraceRegs - // requests is used to signal creation of new threads. requests chan chan *thread @@ -142,7 +142,6 @@ func newSubprocess(create func() (*thread, error)) (*subprocess, error) { // thread, and responding to requests to make additional threads in the // traced process. The process will be killed and reaped when the // request channel is closed, which happens in Release below. - var initRegs syscall.PtraceRegs errChan := make(chan error) requests := make(chan chan *thread) go func() { // S/R-SAFE: Platform-related. @@ -156,22 +155,12 @@ func newSubprocess(create func() (*thread, error)) (*subprocess, error) { return } - // Grab registers. - // - // Note that we adjust the current register RIP value to be - // just before the current system call executed. This depends - // on the definition of the stub itself. - if err := firstThread.getRegs(&initRegs); err != nil { - panic(fmt.Sprintf("ptrace get regs failed: %v", err)) - } - initRegs.Rip -= initRegsRipAdjustment - // Ready to handle requests. errChan <- nil // Wait for requests to create threads. for r := range requests { - t, err := firstThread.clone(&initRegs) + t, err := firstThread.clone(&firstThread.initRegs) if err != nil { // Should not happen: not recoverable. panic(fmt.Sprintf("error initializing first thread: %v", err)) @@ -183,15 +172,12 @@ func newSubprocess(create func() (*thread, error)) (*subprocess, error) { // (Hopefully nobody tgkilled it with a signal < // SIGSTOP before the SIGSTOP was delivered, in which // case that signal would be delivered before SIGSTOP.) - if sig := t.wait(); sig != syscall.SIGSTOP { + if sig := t.wait(stopped); sig != syscall.SIGSTOP { panic(fmt.Sprintf("error waiting for new clone: expected SIGSTOP, got %v", sig)) } - // Detach the thread without suppressing the SIGSTOP, - // causing it to enter group-stop. - if _, _, errno := syscall.RawSyscall6(syscall.SYS_PTRACE, syscall.PTRACE_DETACH, uintptr(t.tid), 0, uintptr(syscall.SIGSTOP), 0, 0); errno != 0 { - panic(fmt.Sprintf("can't detach new clone: %v", errno)) - } + // Detach the thread. + t.detach() // Return the thread. r <- t @@ -208,7 +194,6 @@ func newSubprocess(create func() (*thread, error)) (*subprocess, error) { // Ready. sp := &subprocess{ - initRegs: initRegs, requests: requests, sysemuThreads: threadPool{ threads: make(map[int32]*thread), @@ -277,16 +262,48 @@ func (t *thread) attach() { // stopped from the SIGSTOP queued by CLONE_PTRACE (see inner loop of // newSubprocess), so we always expect to see signal-delivery-stop with // SIGSTOP. - if sig := t.wait(); sig != syscall.SIGSTOP { + if sig := t.wait(stopped); sig != syscall.SIGSTOP { panic(fmt.Sprintf("wait failed: expected SIGSTOP, got %v", sig)) } // Initialize options. t.init() + + // Grab registers. + // + // Note that we adjust the current register RIP value to be just before + // the current system call executed. This depends on the definition of + // the stub itself. + if err := t.getRegs(&t.initRegs); err != nil { + panic(fmt.Sprintf("ptrace get regs failed: %v", err)) + } + t.initRegs.Rip -= initRegsRipAdjustment } +// detach detachs from the thread. +// +// Because the SIGSTOP is not supressed, the thread will enter group-stop. +func (t *thread) detach() { + if _, _, errno := syscall.RawSyscall6(syscall.SYS_PTRACE, syscall.PTRACE_DETACH, uintptr(t.tid), 0, uintptr(syscall.SIGSTOP), 0, 0); errno != 0 { + panic(fmt.Sprintf("can't detach new clone: %v", errno)) + } +} + +// waitOutcome is used for wait below. +type waitOutcome int + +const ( + // stopped indicates that the process was stopped. + stopped waitOutcome = iota + + // killed indicates that the process was killed. + killed +) + // wait waits for a stop event. -func (t *thread) wait() syscall.Signal { +// +// Precondition: outcome is a valid waitOutcome. +func (t *thread) wait(outcome waitOutcome) syscall.Signal { var status syscall.WaitStatus for { @@ -300,25 +317,55 @@ func (t *thread) wait() syscall.Signal { if int(r) != int(t.tid) { panic(fmt.Sprintf("ptrace wait returned %v, expected %v", r, t.tid)) } - if !status.Stopped() { - panic(fmt.Sprintf("ptrace status unexpected: got %v, wanted stopped", status)) - } - if status.StopSignal() == 0 { - continue // Spurious stop. + switch outcome { + case stopped: + if !status.Stopped() { + panic(fmt.Sprintf("ptrace status unexpected: got %v, wanted stopped", status)) + } + stopSig := status.StopSignal() + if stopSig == 0 { + continue // Spurious stop. + } + if stopSig == syscall.SIGTRAP { + // Re-encode the trap cause the way it's expected. + return stopSig | syscall.Signal(status.TrapCause()<<8) + } + // Not a trap signal. + return stopSig + case killed: + if !status.Exited() && !status.Signaled() { + panic(fmt.Sprintf("ptrace status unexpected: got %v, wanted exited", status)) + } + return syscall.Signal(status.ExitStatus()) + default: + // Should not happen. + panic(fmt.Sprintf("unknown outcome: %v", outcome)) } - return status.StopSignal() } } +// destroy kills the thread. +// +// Note that this should not be used in the general case; the death of threads +// will typically cause the death of the parent. This is a utility method for +// manually created threads. +func (t *thread) destroy() { + t.detach() + syscall.Tgkill(int(t.tgid), int(t.tid), syscall.Signal(syscall.SIGKILL)) + t.wait(killed) +} + // init initializes trace options. func (t *thread) init() { - // Set our TRACESYSGOOD option to differeniate real SIGTRAP. + // Set our TRACESYSGOOD option to differeniate real SIGTRAP. Also, we + // require the SECCOMP option to ensure that seccomp violations + // generate a ptrace event. _, _, errno := syscall.RawSyscall6( syscall.SYS_PTRACE, syscall.PTRACE_SETOPTIONS, uintptr(t.tid), 0, - syscall.PTRACE_O_TRACESYSGOOD, + syscall.PTRACE_O_TRACESYSGOOD|_PTRACE_O_TRACESECCOMP, 0, 0) if errno != 0 { panic(fmt.Sprintf("ptrace set options failed: %v", errno)) @@ -342,8 +389,8 @@ func (t *thread) syscall(regs *syscall.PtraceRegs) (uintptr, error) { panic(fmt.Sprintf("ptrace syscall-enter failed: %v", errno)) } - sig := t.wait() - if sig == (0x80 | syscall.SIGTRAP) { + sig := t.wait(stopped) + if sig == (syscallEvent | syscall.SIGTRAP) { // Reached syscall-enter-stop. break } else { @@ -360,7 +407,7 @@ func (t *thread) syscall(regs *syscall.PtraceRegs) (uintptr, error) { // Wait for syscall-exit-stop. "[Signal-delivery-stop] never happens // between syscall-enter-stop and syscall-exit-stop; it happens *after* // syscall-exit-stop.)" - ptrace(2), "Syscall-stops" - if sig := t.wait(); sig != (0x80 | syscall.SIGTRAP) { + if sig := t.wait(stopped); sig != (syscallEvent | syscall.SIGTRAP) { panic(fmt.Sprintf("wait failed: expected SIGTRAP, got %v [%d]", sig, sig)) } @@ -403,22 +450,23 @@ func (t *thread) NotifyInterrupt() { // // This function returns true on a system call, false on a signal. func (s *subprocess) switchToApp(c *context, ac arch.Context) bool { - regs := &ac.StateData().Regs - s.resetSysemuRegs(regs) + // Lock the thread for ptrace operations. + runtime.LockOSThread() + defer runtime.UnlockOSThread() // Extract floating point state. fpState := ac.FloatingPointData() fpLen, _ := ac.FeatureSet().ExtendedStateSize() useXsave := ac.FeatureSet().UseXsave() - // Lock the thread for ptrace operations. - runtime.LockOSThread() - defer runtime.UnlockOSThread() - // Grab our thread from the pool. currentTID := int32(procid.Current()) t := s.sysemuThreads.lookupOrCreate(currentTID, s.newThread) + // Reset necessary registers. + regs := &ac.StateData().Regs + t.resetSysemuRegs(regs) + // Check for interrupts, and ensure that future interrupts will signal t. if !c.interrupt.Enable(t) { // Pending interrupt; simulate. @@ -459,7 +507,7 @@ func (s *subprocess) switchToApp(c *context, ac arch.Context) bool { } // Wait for the syscall-enter stop. - sig := t.wait() + sig := t.wait(stopped) // Refresh all registers. if err := t.getRegs(regs); err != nil { @@ -470,13 +518,17 @@ func (s *subprocess) switchToApp(c *context, ac arch.Context) bool { } // Is it a system call? - if sig == (0x80 | syscall.SIGTRAP) { + if sig == (syscallEvent | syscall.SIGTRAP) { // Ensure registers are sane. updateSyscallRegs(regs) return true - } - - if sig == syscall.SIGSTOP { + } else if sig == (seccompEvent | syscall.SIGTRAP) { + // Seccomp is enabled, and caught the system call. This + // is an emulated vsyscall call, since those are caught + // only by seccomp and explicitly set to trace. + updateSyscallRegs(regs) + return true + } else if sig == syscall.SIGSTOP { // SIGSTOP was delivered to another thread in the same thread // group, which initiated another group stop. Just ignore it. continue @@ -507,7 +559,7 @@ func (s *subprocess) syscall(sysno uintptr, args ...arch.SyscallArgument) (uintp currentTID := int32(procid.Current()) t := s.syscallThreads.lookupOrCreate(currentTID, s.newThread) - return t.syscallIgnoreInterrupt(&s.initRegs, sysno, args...) + return t.syscallIgnoreInterrupt(&t.initRegs, sysno, args...) } // MapFile implements platform.AddressSpace.MapFile. diff --git a/pkg/sentry/platform/ptrace/subprocess_amd64.go b/pkg/sentry/platform/ptrace/subprocess_amd64.go index 8211215df..c38dc1ff8 100644 --- a/pkg/sentry/platform/ptrace/subprocess_amd64.go +++ b/pkg/sentry/platform/ptrace/subprocess_amd64.go @@ -43,20 +43,20 @@ const ( // resetSysemuRegs sets up emulation registers. // // This should be called prior to calling sysemu. -func (s *subprocess) resetSysemuRegs(regs *syscall.PtraceRegs) { - regs.Cs = s.initRegs.Cs - regs.Ss = s.initRegs.Ss - regs.Ds = s.initRegs.Ds - regs.Es = s.initRegs.Es - regs.Fs = s.initRegs.Fs - regs.Gs = s.initRegs.Gs +func (t *thread) resetSysemuRegs(regs *syscall.PtraceRegs) { + regs.Cs = t.initRegs.Cs + regs.Ss = t.initRegs.Ss + regs.Ds = t.initRegs.Ds + regs.Es = t.initRegs.Es + regs.Fs = t.initRegs.Fs + regs.Gs = t.initRegs.Gs } // createSyscallRegs sets up syscall registers. // // This should be called to generate registers for a system call. func createSyscallRegs(initRegs *syscall.PtraceRegs, sysno uintptr, args ...arch.SyscallArgument) syscall.PtraceRegs { - // Copy initial registers (RIP, segments, etc.). + // Copy initial registers. regs := *initRegs // Set our syscall number. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index b212bbdfe..53adadadd 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -21,14 +21,167 @@ import ( "syscall" "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/log" + "gvisor.googlesource.com/gvisor/pkg/seccomp" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/platform/procid" ) +const ( + syscallEvent syscall.Signal = 0x80 + seccompEvent syscall.Signal = 0x700 // 0x7 (PTRACE_SECCOMP_EVENT) << 8 + _PTRACE_O_TRACESECCOMP = 0x80 // 1 << 0x7 (PTRACE_SECCOMP_EVENT) +) + +// probeSeccomp returns true iff seccomp is run after ptrace notifications, +// which is generally the case for kernel version >= 4.8. This check is dynamic +// because kernels have be backported behavior. +// +// See createStub for more information. +// +// Precondition: the runtime OS thread must be locked. +func probeSeccomp() bool { + // Create a completely new, destroyable process. + t, err := attachedThread(0, uint32(linux.SECCOMP_RET_ERRNO)) + if err != nil { + panic(fmt.Sprintf("seccomp probe failed: %v", err)) + } + defer t.destroy() + + // Set registers to the yield system call. This call is not allowed + // by the filters specified in the attachThread function. + regs := createSyscallRegs(&t.initRegs, syscall.SYS_SCHED_YIELD) + if err := t.setRegs(®s); err != nil { + panic(fmt.Sprintf("ptrace set regs failed: %v", err)) + } + + for { + // Attempt an emulation. + if _, _, errno := syscall.RawSyscall(syscall.SYS_PTRACE, syscall.PTRACE_SYSEMU, uintptr(t.tid), 0); errno != 0 { + panic(fmt.Sprintf("ptrace syscall-enter failed: %v", errno)) + } + + sig := t.wait(stopped) + if sig == (syscallEvent | syscall.SIGTRAP) { + // Did the seccomp errno hook already run? This would + // indicate that seccomp is first in line and we're + // less than 4.8. + if err := t.getRegs(®s); err != nil { + panic(fmt.Sprintf("ptrace get-regs failed: %v", err)) + } + if _, err := syscallReturnValue(®s); err == nil { + // The seccomp errno mode ran first, and reset + // the error in the registers. + return false + } + // The seccomp hook did not run yet, and therefore it + // is safe to use RET_KILL mode for dispatched calls. + return true + } + } +} + // createStub creates a fresh stub processes. // // Precondition: the runtime OS thread must be locked. func createStub() (*thread, error) { + // The exact interactions of ptrace and seccomp are complex, and + // changed in recent kernel versions. Before commit 93e35efb8de45, the + // seccomp check is done before the ptrace emulation check. This means + // that any calls not matching this list will trigger the seccomp + // default action instead of notifying ptrace. + // + // After commit 93e35efb8de45, the seccomp check is done after the + // ptrace emulation check. This simplifies using SYSEMU, since seccomp + // will never run for emulation. Seccomp will only run for injected + // system calls, and thus we can use RET_KILL as our violation action. + var defaultAction uint32 + if probeSeccomp() { + log.Infof("Latest seccomp behavior found (kernel >= 4.8 likely)") + defaultAction = uint32(linux.SECCOMP_RET_KILL) + } else { + // We must rely on SYSEMU behavior; tracing with SYSEMU is broken. + log.Infof("Legacy seccomp behavior found (kernel < 4.8 likely)") + defaultAction = uint32(linux.SECCOMP_RET_ALLOW) + } + + // When creating the new child process, we specify SIGKILL as the + // signal to deliver when the child exits. We never expect a subprocess + // to exit; they are pooled and reused. This is done to ensure that if + // a subprocess is OOM-killed, this process (and all other stubs, + // transitively) will be killed as well. It's simply not possible to + // safely handle a single stub getting killed: the exact state of + // execution is unknown and not recoverable. + return attachedThread(uintptr(syscall.SIGKILL)|syscall.CLONE_FILES, defaultAction) +} + +// attachedThread returns a new attached thread. +// +// Precondition: the runtime OS thread must be locked. +func attachedThread(flags uintptr, defaultAction uint32) (*thread, error) { + // Create a BPF program that allows only the system calls needed by the + // stub and all its children. This is used to create child stubs + // (below), so we must include the ability to fork, but otherwise lock + // down available calls only to what is needed. + rules := []seccomp.RuleSet{ + // Rules for trapping vsyscall access. + seccomp.RuleSet{ + Rules: seccomp.SyscallRules{ + syscall.SYS_GETTIMEOFDAY: {}, + syscall.SYS_TIME: {}, + 309: {}, // SYS_GETCPU. + }, + Action: uint32(linux.SECCOMP_RET_TRACE), + Vsyscall: true, + }, + } + if defaultAction != uint32(linux.SECCOMP_RET_ALLOW) { + rules = append(rules, seccomp.RuleSet{ + Rules: seccomp.SyscallRules{ + syscall.SYS_CLONE: []seccomp.Rule{ + // Allow creation of new subprocesses (used by the master). + {seccomp.AllowValue(syscall.CLONE_FILES | syscall.SIGKILL)}, + // Allow creation of new threads within a single address space (used by addresss spaces). + {seccomp.AllowValue( + syscall.CLONE_FILES | + syscall.CLONE_FS | + syscall.CLONE_SIGHAND | + syscall.CLONE_THREAD | + syscall.CLONE_PTRACE | + syscall.CLONE_VM)}, + }, + + // For the initial process creation. + syscall.SYS_WAIT4: {}, + syscall.SYS_ARCH_PRCTL: []seccomp.Rule{ + {seccomp.AllowValue(linux.ARCH_SET_CPUID), seccomp.AllowValue(0)}, + }, + syscall.SYS_EXIT: {}, + + // For the stub prctl dance (all). + syscall.SYS_PRCTL: []seccomp.Rule{ + {seccomp.AllowValue(syscall.PR_SET_PDEATHSIG), seccomp.AllowValue(syscall.SIGKILL)}, + }, + syscall.SYS_GETPPID: {}, + + // For the stub to stop itself (all). + syscall.SYS_GETPID: {}, + syscall.SYS_KILL: []seccomp.Rule{ + {seccomp.AllowAny{}, seccomp.AllowValue(syscall.SIGSTOP)}, + }, + + // Injected to support the address space operations. + syscall.SYS_MMAP: {}, + syscall.SYS_MUNMAP: {}, + }, + Action: uint32(linux.SECCOMP_RET_ALLOW), + }) + } + instrs, err := seccomp.BuildProgram(rules, defaultAction) + if err != nil { + return nil, err + } + // Declare all variables up front in order to ensure that there's no // need for allocations between beforeFork & afterFork. var ( @@ -43,14 +196,8 @@ func createStub() (*thread, error) { // Among other things, beforeFork masks all signals. beforeFork() - // When creating the new child process, we specify SIGKILL as the - // signal to deliver when the child exits. We never expect a subprocess - // to exit; they are pooled and reused. This is done to ensure that if - // a subprocess is OOM-killed, this process (and all other stubs, - // transitively) will be killed as well. It's simply not possible to - // safely handle a single stub getting killed: the exact state of - // execution is unknown and not recoverable. - pid, _, errno = syscall.RawSyscall6(syscall.SYS_CLONE, uintptr(syscall.SIGKILL)|syscall.CLONE_FILES, 0, 0, 0, 0, 0) + // Do the clone. + pid, _, errno = syscall.RawSyscall6(syscall.SYS_CLONE, flags, 0, 0, 0, 0, 0) if errno != 0 { afterFork() return nil, errno @@ -67,7 +214,7 @@ func createStub() (*thread, error) { tid: int32(pid), cpu: ^uint32(0), } - if sig := t.wait(); sig != syscall.SIGSTOP { + if sig := t.wait(stopped); sig != syscall.SIGSTOP { return nil, fmt.Errorf("wait failed: expected SIGSTOP, got %v", sig) } t.attach() @@ -86,6 +233,12 @@ func createStub() (*thread, error) { syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0) } + // Set an aggressive BPF filter for the stub and all it's children. See + // the description of the BPF program built above. + if errno := seccomp.SetFilter(instrs); errno != 0 { + syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0) + } + // Enable cpuid-faulting; this may fail on older kernels or hardware, // so we just disregard the result. Host CPUID will be enabled. syscall.RawSyscall(syscall.SYS_ARCH_PRCTL, linux.ARCH_SET_CPUID, 0, 0) @@ -105,7 +258,7 @@ func (s *subprocess) createStub() (*thread, error) { t := s.syscallThreads.lookupOrCreate(currentTID, s.newThread) // Pass the expected PPID to the child via R15. - regs := s.initRegs + regs := t.initRegs regs.R15 = uint64(t.tgid) // Call fork in a subprocess. @@ -138,7 +291,7 @@ func (s *subprocess) createStub() (*thread, error) { // status. If the wait succeeds, we'll assume that it was the SIGSTOP. // If the child actually exited, the attach below will fail. _, err = t.syscallIgnoreInterrupt( - &s.initRegs, + &t.initRegs, syscall.SYS_WAIT4, arch.SyscallArgument{Value: uintptr(pid)}, arch.SyscallArgument{Value: 0}, diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index e1c8db67a..674554081 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -24,6 +24,7 @@ go_library( "//pkg/binary", "//pkg/bits", "//pkg/eventchannel", + "//pkg/seccomp", "//pkg/sentry/arch", "//pkg/sentry/kernel", "//pkg/sentry/socket/control", diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index f2a22aaa5..a16f5490e 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -28,6 +28,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/bits" "gvisor.googlesource.com/gvisor/pkg/eventchannel" + "gvisor.googlesource.com/gvisor/pkg/seccomp" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" pb "gvisor.googlesource.com/gvisor/pkg/sentry/strace/strace_go_proto" @@ -699,3 +700,13 @@ func EnableAll(sinks SinkType) { table.FeatureEnable.EnableAll(flags) } } + +func init() { + t, ok := Lookup(abi.Host, arch.Host) + if ok { + // Provide the native table as the lookup for seccomp + // debugging. This is best-effort. This is provided this way to + // avoid dependencies from seccomp to this package. + seccomp.SyscallName = t.Name + } +} -- cgit v1.2.3 From 8fce67af24945f82378b4c2731cca1788936d074 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Fri, 19 Oct 2018 16:34:09 -0700 Subject: Use correct company name in copyright header PiperOrigin-RevId: 217951017 Change-Id: Ie08bf6987f98467d07457bcf35b5f1ff6e43c035 --- kokoro/run_build.sh | 2 +- kokoro/run_tests.sh | 2 +- pkg/abi/abi.go | 2 +- pkg/abi/abi_linux.go | 2 +- pkg/abi/flag.go | 2 +- pkg/abi/linux/aio.go | 2 +- pkg/abi/linux/ashmem.go | 2 +- pkg/abi/linux/binder.go | 2 +- pkg/abi/linux/bpf.go | 2 +- pkg/abi/linux/capability.go | 2 +- pkg/abi/linux/dev.go | 2 +- pkg/abi/linux/elf.go | 2 +- pkg/abi/linux/errors.go | 2 +- pkg/abi/linux/eventfd.go | 2 +- pkg/abi/linux/exec.go | 2 +- pkg/abi/linux/fcntl.go | 2 +- pkg/abi/linux/file.go | 2 +- pkg/abi/linux/fs.go | 2 +- pkg/abi/linux/futex.go | 2 +- pkg/abi/linux/inotify.go | 2 +- pkg/abi/linux/ioctl.go | 2 +- pkg/abi/linux/ip.go | 2 +- pkg/abi/linux/ipc.go | 2 +- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/linux.go | 2 +- pkg/abi/linux/mm.go | 2 +- pkg/abi/linux/netdevice.go | 2 +- pkg/abi/linux/netlink.go | 2 +- pkg/abi/linux/netlink_route.go | 2 +- pkg/abi/linux/poll.go | 2 +- pkg/abi/linux/prctl.go | 2 +- pkg/abi/linux/ptrace.go | 2 +- pkg/abi/linux/rusage.go | 2 +- pkg/abi/linux/sched.go | 2 +- pkg/abi/linux/seccomp.go | 2 +- pkg/abi/linux/sem.go | 2 +- pkg/abi/linux/shm.go | 2 +- pkg/abi/linux/signal.go | 2 +- pkg/abi/linux/socket.go | 2 +- pkg/abi/linux/time.go | 2 +- pkg/abi/linux/timer.go | 2 +- pkg/abi/linux/tty.go | 2 +- pkg/abi/linux/uio.go | 2 +- pkg/abi/linux/utsname.go | 2 +- pkg/amutex/amutex.go | 2 +- pkg/amutex/amutex_test.go | 2 +- pkg/atomicbitops/atomic_bitops.go | 2 +- pkg/atomicbitops/atomic_bitops_amd64.s | 2 +- pkg/atomicbitops/atomic_bitops_common.go | 2 +- pkg/atomicbitops/atomic_bitops_test.go | 2 +- pkg/binary/binary.go | 2 +- pkg/binary/binary_test.go | 2 +- pkg/bits/bits.go | 2 +- pkg/bits/bits_template.go | 2 +- pkg/bits/uint64_arch_amd64.go | 2 +- pkg/bits/uint64_arch_amd64_asm.s | 2 +- pkg/bits/uint64_arch_generic.go | 2 +- pkg/bits/uint64_test.go | 2 +- pkg/bpf/bpf.go | 2 +- pkg/bpf/decoder.go | 2 +- pkg/bpf/decoder_test.go | 2 +- pkg/bpf/input_bytes.go | 2 +- pkg/bpf/interpreter.go | 2 +- pkg/bpf/interpreter_test.go | 2 +- pkg/bpf/program_builder.go | 2 +- pkg/bpf/program_builder_test.go | 2 +- pkg/compressio/compressio.go | 2 +- pkg/compressio/compressio_test.go | 2 +- pkg/control/client/client.go | 2 +- pkg/control/server/server.go | 2 +- pkg/cpuid/cpu_amd64.s | 2 +- pkg/cpuid/cpuid.go | 2 +- pkg/cpuid/cpuid_parse_test.go | 2 +- pkg/cpuid/cpuid_test.go | 2 +- pkg/dhcp/client.go | 2 +- pkg/dhcp/dhcp.go | 2 +- pkg/dhcp/dhcp_string.go | 2 +- pkg/dhcp/dhcp_test.go | 2 +- pkg/dhcp/server.go | 2 +- pkg/eventchannel/event.go | 2 +- pkg/eventchannel/event.proto | 2 +- pkg/fd/fd.go | 2 +- pkg/fd/fd_test.go | 2 +- pkg/gate/gate.go | 2 +- pkg/gate/gate_test.go | 2 +- pkg/ilist/list.go | 2 +- pkg/ilist/list_test.go | 2 +- pkg/linewriter/linewriter.go | 2 +- pkg/linewriter/linewriter_test.go | 2 +- pkg/log/glog.go | 2 +- pkg/log/glog_unsafe.go | 2 +- pkg/log/json.go | 2 +- pkg/log/json_test.go | 2 +- pkg/log/log.go | 2 +- pkg/log/log_test.go | 2 +- pkg/metric/metric.go | 2 +- pkg/metric/metric.proto | 2 +- pkg/metric/metric_test.go | 2 +- pkg/p9/buffer.go | 2 +- pkg/p9/client.go | 2 +- pkg/p9/client_file.go | 2 +- pkg/p9/client_test.go | 2 +- pkg/p9/file.go | 2 +- pkg/p9/handlers.go | 2 +- pkg/p9/local_server/local_server.go | 2 +- pkg/p9/messages.go | 2 +- pkg/p9/messages_test.go | 2 +- pkg/p9/p9.go | 2 +- pkg/p9/p9_test.go | 2 +- pkg/p9/p9test/client_test.go | 2 +- pkg/p9/p9test/mocks.go | 2 +- pkg/p9/pool.go | 2 +- pkg/p9/pool_test.go | 2 +- pkg/p9/server.go | 2 +- pkg/p9/transport.go | 2 +- pkg/p9/transport_test.go | 2 +- pkg/p9/version.go | 2 +- pkg/p9/version_test.go | 2 +- pkg/rand/rand.go | 2 +- pkg/rand/rand_linux.go | 2 +- pkg/refs/refcounter.go | 2 +- pkg/refs/refcounter_state.go | 2 +- pkg/refs/refcounter_test.go | 2 +- pkg/seccomp/seccomp.go | 2 +- pkg/seccomp/seccomp_rules.go | 2 +- pkg/seccomp/seccomp_test.go | 2 +- pkg/seccomp/seccomp_test_victim.go | 2 +- pkg/seccomp/seccomp_unsafe.go | 2 +- pkg/secio/full_reader.go | 2 +- pkg/secio/secio.go | 2 +- pkg/secio/secio_test.go | 2 +- pkg/segment/range.go | 2 +- pkg/segment/set.go | 2 +- pkg/segment/set_state.go | 2 +- pkg/segment/test/segment_test.go | 2 +- pkg/segment/test/set_functions.go | 2 +- pkg/sentry/arch/aligned.go | 2 +- pkg/sentry/arch/arch.go | 2 +- pkg/sentry/arch/arch_amd64.go | 2 +- pkg/sentry/arch/arch_amd64.s | 2 +- pkg/sentry/arch/arch_state_x86.go | 2 +- pkg/sentry/arch/arch_x86.go | 2 +- pkg/sentry/arch/auxv.go | 2 +- pkg/sentry/arch/registers.proto | 2 +- pkg/sentry/arch/signal_act.go | 2 +- pkg/sentry/arch/signal_amd64.go | 2 +- pkg/sentry/arch/signal_info.go | 2 +- pkg/sentry/arch/signal_stack.go | 2 +- pkg/sentry/arch/stack.go | 2 +- pkg/sentry/arch/syscalls_amd64.go | 2 +- pkg/sentry/context/context.go | 2 +- pkg/sentry/context/contexttest/contexttest.go | 2 +- pkg/sentry/control/control.go | 2 +- pkg/sentry/control/proc.go | 2 +- pkg/sentry/control/proc_test.go | 2 +- pkg/sentry/control/state.go | 2 +- pkg/sentry/device/device.go | 2 +- pkg/sentry/device/device_test.go | 2 +- pkg/sentry/fs/anon/anon.go | 2 +- pkg/sentry/fs/anon/device.go | 2 +- pkg/sentry/fs/ashmem/area.go | 2 +- pkg/sentry/fs/ashmem/device.go | 2 +- pkg/sentry/fs/ashmem/pin_board.go | 2 +- pkg/sentry/fs/ashmem/pin_board_test.go | 2 +- pkg/sentry/fs/attr.go | 2 +- pkg/sentry/fs/binder/binder.go | 2 +- pkg/sentry/fs/context.go | 2 +- pkg/sentry/fs/copy_up.go | 2 +- pkg/sentry/fs/copy_up_test.go | 2 +- pkg/sentry/fs/dentry.go | 2 +- pkg/sentry/fs/dev/dev.go | 2 +- pkg/sentry/fs/dev/device.go | 2 +- pkg/sentry/fs/dev/fs.go | 2 +- pkg/sentry/fs/dev/full.go | 2 +- pkg/sentry/fs/dev/null.go | 2 +- pkg/sentry/fs/dev/random.go | 2 +- pkg/sentry/fs/dirent.go | 2 +- pkg/sentry/fs/dirent_cache.go | 2 +- pkg/sentry/fs/dirent_cache_test.go | 2 +- pkg/sentry/fs/dirent_refs_test.go | 2 +- pkg/sentry/fs/dirent_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener_test.go | 2 +- pkg/sentry/fs/fdpipe/pipe_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe_test.go | 2 +- pkg/sentry/fs/file.go | 2 +- pkg/sentry/fs/file_operations.go | 2 +- pkg/sentry/fs/file_overlay.go | 2 +- pkg/sentry/fs/file_overlay_test.go | 2 +- pkg/sentry/fs/file_state.go | 2 +- pkg/sentry/fs/file_test.go | 2 +- pkg/sentry/fs/filesystems.go | 2 +- pkg/sentry/fs/filetest/filetest.go | 2 +- pkg/sentry/fs/flags.go | 2 +- pkg/sentry/fs/fs.go | 2 +- pkg/sentry/fs/fsutil/dirty_set.go | 2 +- pkg/sentry/fs/fsutil/dirty_set_test.go | 2 +- pkg/sentry/fs/fsutil/file.go | 2 +- pkg/sentry/fs/fsutil/file_range_set.go | 2 +- pkg/sentry/fs/fsutil/frame_ref_set.go | 2 +- pkg/sentry/fs/fsutil/fsutil.go | 2 +- pkg/sentry/fs/fsutil/handle.go | 2 +- pkg/sentry/fs/fsutil/handle_test.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_state.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go | 2 +- pkg/sentry/fs/fsutil/inode.go | 2 +- pkg/sentry/fs/fsutil/inode_cached.go | 2 +- pkg/sentry/fs/fsutil/inode_cached_test.go | 2 +- pkg/sentry/fs/gofer/attr.go | 2 +- pkg/sentry/fs/gofer/cache_policy.go | 2 +- pkg/sentry/fs/gofer/context_file.go | 2 +- pkg/sentry/fs/gofer/device.go | 2 +- pkg/sentry/fs/gofer/file.go | 2 +- pkg/sentry/fs/gofer/file_state.go | 2 +- pkg/sentry/fs/gofer/fs.go | 2 +- pkg/sentry/fs/gofer/gofer_test.go | 2 +- pkg/sentry/fs/gofer/handles.go | 2 +- pkg/sentry/fs/gofer/inode.go | 2 +- pkg/sentry/fs/gofer/inode_state.go | 2 +- pkg/sentry/fs/gofer/path.go | 2 +- pkg/sentry/fs/gofer/session.go | 2 +- pkg/sentry/fs/gofer/session_state.go | 2 +- pkg/sentry/fs/gofer/socket.go | 2 +- pkg/sentry/fs/gofer/util.go | 2 +- pkg/sentry/fs/host/control.go | 2 +- pkg/sentry/fs/host/descriptor.go | 2 +- pkg/sentry/fs/host/descriptor_state.go | 2 +- pkg/sentry/fs/host/descriptor_test.go | 2 +- pkg/sentry/fs/host/device.go | 2 +- pkg/sentry/fs/host/file.go | 2 +- pkg/sentry/fs/host/fs.go | 2 +- pkg/sentry/fs/host/fs_test.go | 2 +- pkg/sentry/fs/host/inode.go | 2 +- pkg/sentry/fs/host/inode_state.go | 2 +- pkg/sentry/fs/host/inode_test.go | 2 +- pkg/sentry/fs/host/ioctl_unsafe.go | 2 +- pkg/sentry/fs/host/socket.go | 2 +- pkg/sentry/fs/host/socket_iovec.go | 2 +- pkg/sentry/fs/host/socket_state.go | 2 +- pkg/sentry/fs/host/socket_test.go | 2 +- pkg/sentry/fs/host/socket_unsafe.go | 2 +- pkg/sentry/fs/host/tty.go | 2 +- pkg/sentry/fs/host/util.go | 2 +- pkg/sentry/fs/host/util_unsafe.go | 2 +- pkg/sentry/fs/host/wait_test.go | 2 +- pkg/sentry/fs/inode.go | 2 +- pkg/sentry/fs/inode_inotify.go | 2 +- pkg/sentry/fs/inode_operations.go | 2 +- pkg/sentry/fs/inode_overlay.go | 2 +- pkg/sentry/fs/inode_overlay_test.go | 2 +- pkg/sentry/fs/inotify.go | 2 +- pkg/sentry/fs/inotify_event.go | 2 +- pkg/sentry/fs/inotify_watch.go | 2 +- pkg/sentry/fs/lock/lock.go | 2 +- pkg/sentry/fs/lock/lock_range_test.go | 2 +- pkg/sentry/fs/lock/lock_set_functions.go | 2 +- pkg/sentry/fs/lock/lock_test.go | 2 +- pkg/sentry/fs/mock.go | 2 +- pkg/sentry/fs/mount.go | 2 +- pkg/sentry/fs/mount_overlay.go | 2 +- pkg/sentry/fs/mount_state.go | 2 +- pkg/sentry/fs/mount_test.go | 2 +- pkg/sentry/fs/mounts.go | 2 +- pkg/sentry/fs/mounts_test.go | 2 +- pkg/sentry/fs/offset.go | 2 +- pkg/sentry/fs/overlay.go | 2 +- pkg/sentry/fs/path.go | 2 +- pkg/sentry/fs/path_test.go | 2 +- pkg/sentry/fs/proc/cpuinfo.go | 2 +- pkg/sentry/fs/proc/device/device.go | 2 +- pkg/sentry/fs/proc/exec_args.go | 2 +- pkg/sentry/fs/proc/fds.go | 2 +- pkg/sentry/fs/proc/file.go | 2 +- pkg/sentry/fs/proc/filesystems.go | 2 +- pkg/sentry/fs/proc/fs.go | 2 +- pkg/sentry/fs/proc/loadavg.go | 2 +- pkg/sentry/fs/proc/meminfo.go | 2 +- pkg/sentry/fs/proc/mounts.go | 2 +- pkg/sentry/fs/proc/net.go | 2 +- pkg/sentry/fs/proc/net_test.go | 2 +- pkg/sentry/fs/proc/proc.go | 2 +- pkg/sentry/fs/proc/rpcinet_proc.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile_test.go | 2 +- pkg/sentry/fs/proc/stat.go | 2 +- pkg/sentry/fs/proc/sys.go | 2 +- pkg/sentry/fs/proc/sys_net.go | 2 +- pkg/sentry/fs/proc/sys_net_test.go | 2 +- pkg/sentry/fs/proc/task.go | 2 +- pkg/sentry/fs/proc/uid_gid_map.go | 2 +- pkg/sentry/fs/proc/uptime.go | 2 +- pkg/sentry/fs/proc/version.go | 2 +- pkg/sentry/fs/ramfs/dir.go | 2 +- pkg/sentry/fs/ramfs/file.go | 2 +- pkg/sentry/fs/ramfs/ramfs.go | 2 +- pkg/sentry/fs/ramfs/socket.go | 2 +- pkg/sentry/fs/ramfs/symlink.go | 2 +- pkg/sentry/fs/ramfs/test/test.go | 2 +- pkg/sentry/fs/ramfs/tree.go | 2 +- pkg/sentry/fs/ramfs/tree_test.go | 2 +- pkg/sentry/fs/restore.go | 2 +- pkg/sentry/fs/save.go | 2 +- pkg/sentry/fs/seek.go | 2 +- pkg/sentry/fs/sync.go | 2 +- pkg/sentry/fs/sys/device.go | 2 +- pkg/sentry/fs/sys/devices.go | 2 +- pkg/sentry/fs/sys/fs.go | 2 +- pkg/sentry/fs/sys/sys.go | 2 +- pkg/sentry/fs/timerfd/timerfd.go | 2 +- pkg/sentry/fs/tmpfs/device.go | 2 +- pkg/sentry/fs/tmpfs/file_regular.go | 2 +- pkg/sentry/fs/tmpfs/file_test.go | 2 +- pkg/sentry/fs/tmpfs/fs.go | 2 +- pkg/sentry/fs/tmpfs/inode_file.go | 2 +- pkg/sentry/fs/tmpfs/tmpfs.go | 2 +- pkg/sentry/fs/tty/dir.go | 2 +- pkg/sentry/fs/tty/fs.go | 2 +- pkg/sentry/fs/tty/inode.go | 2 +- pkg/sentry/fs/tty/line_discipline.go | 2 +- pkg/sentry/fs/tty/master.go | 2 +- pkg/sentry/fs/tty/queue.go | 2 +- pkg/sentry/fs/tty/slave.go | 2 +- pkg/sentry/fs/tty/terminal.go | 2 +- pkg/sentry/fs/tty/tty_test.go | 2 +- pkg/sentry/hostcpu/getcpu_amd64.s | 2 +- pkg/sentry/hostcpu/hostcpu.go | 2 +- pkg/sentry/hostcpu/hostcpu_test.go | 2 +- pkg/sentry/inet/context.go | 2 +- pkg/sentry/inet/inet.go | 2 +- pkg/sentry/inet/test_stack.go | 2 +- pkg/sentry/kernel/abstract_socket_namespace.go | 2 +- pkg/sentry/kernel/auth/auth.go | 2 +- pkg/sentry/kernel/auth/capability_set.go | 2 +- pkg/sentry/kernel/auth/context.go | 2 +- pkg/sentry/kernel/auth/credentials.go | 2 +- pkg/sentry/kernel/auth/id.go | 2 +- pkg/sentry/kernel/auth/id_map.go | 2 +- pkg/sentry/kernel/auth/id_map_functions.go | 2 +- pkg/sentry/kernel/auth/user_namespace.go | 2 +- pkg/sentry/kernel/context.go | 2 +- pkg/sentry/kernel/epoll/epoll.go | 2 +- pkg/sentry/kernel/epoll/epoll_state.go | 2 +- pkg/sentry/kernel/epoll/epoll_test.go | 2 +- pkg/sentry/kernel/eventfd/eventfd.go | 2 +- pkg/sentry/kernel/eventfd/eventfd_test.go | 2 +- pkg/sentry/kernel/fasync/fasync.go | 2 +- pkg/sentry/kernel/fd_map.go | 2 +- pkg/sentry/kernel/fd_map_test.go | 2 +- pkg/sentry/kernel/fs_context.go | 2 +- pkg/sentry/kernel/futex/futex.go | 2 +- pkg/sentry/kernel/futex/futex_test.go | 2 +- pkg/sentry/kernel/ipc_namespace.go | 2 +- pkg/sentry/kernel/kdefs/kdefs.go | 2 +- pkg/sentry/kernel/kernel.go | 2 +- pkg/sentry/kernel/kernel_state.go | 2 +- pkg/sentry/kernel/memevent/memory_events.go | 2 +- pkg/sentry/kernel/memevent/memory_events.proto | 2 +- pkg/sentry/kernel/pending_signals.go | 2 +- pkg/sentry/kernel/pending_signals_state.go | 2 +- pkg/sentry/kernel/pipe/buffers.go | 2 +- pkg/sentry/kernel/pipe/device.go | 2 +- pkg/sentry/kernel/pipe/node.go | 2 +- pkg/sentry/kernel/pipe/node_test.go | 2 +- pkg/sentry/kernel/pipe/pipe.go | 2 +- pkg/sentry/kernel/pipe/pipe_test.go | 2 +- pkg/sentry/kernel/pipe/reader.go | 2 +- pkg/sentry/kernel/pipe/reader_writer.go | 2 +- pkg/sentry/kernel/pipe/writer.go | 2 +- pkg/sentry/kernel/posixtimer.go | 2 +- pkg/sentry/kernel/ptrace.go | 2 +- pkg/sentry/kernel/rseq.go | 2 +- pkg/sentry/kernel/sched/cpuset.go | 2 +- pkg/sentry/kernel/sched/cpuset_test.go | 2 +- pkg/sentry/kernel/sched/sched.go | 2 +- pkg/sentry/kernel/seccomp.go | 2 +- pkg/sentry/kernel/semaphore/semaphore.go | 2 +- pkg/sentry/kernel/semaphore/semaphore_test.go | 2 +- pkg/sentry/kernel/sessions.go | 2 +- pkg/sentry/kernel/shm/device.go | 2 +- pkg/sentry/kernel/shm/shm.go | 2 +- pkg/sentry/kernel/signal.go | 2 +- pkg/sentry/kernel/signal_handlers.go | 2 +- pkg/sentry/kernel/syscalls.go | 2 +- pkg/sentry/kernel/syscalls_state.go | 2 +- pkg/sentry/kernel/syslog.go | 2 +- pkg/sentry/kernel/table_test.go | 2 +- pkg/sentry/kernel/task.go | 2 +- pkg/sentry/kernel/task_acct.go | 2 +- pkg/sentry/kernel/task_block.go | 2 +- pkg/sentry/kernel/task_clone.go | 2 +- pkg/sentry/kernel/task_context.go | 2 +- pkg/sentry/kernel/task_exec.go | 2 +- pkg/sentry/kernel/task_exit.go | 2 +- pkg/sentry/kernel/task_futex.go | 2 +- pkg/sentry/kernel/task_identity.go | 2 +- pkg/sentry/kernel/task_log.go | 2 +- pkg/sentry/kernel/task_net.go | 2 +- pkg/sentry/kernel/task_run.go | 2 +- pkg/sentry/kernel/task_sched.go | 2 +- pkg/sentry/kernel/task_signals.go | 2 +- pkg/sentry/kernel/task_start.go | 2 +- pkg/sentry/kernel/task_stop.go | 2 +- pkg/sentry/kernel/task_syscall.go | 2 +- pkg/sentry/kernel/task_test.go | 2 +- pkg/sentry/kernel/task_usermem.go | 2 +- pkg/sentry/kernel/thread_group.go | 2 +- pkg/sentry/kernel/threads.go | 2 +- pkg/sentry/kernel/time/context.go | 2 +- pkg/sentry/kernel/time/time.go | 2 +- pkg/sentry/kernel/timekeeper.go | 2 +- pkg/sentry/kernel/timekeeper_state.go | 2 +- pkg/sentry/kernel/timekeeper_test.go | 2 +- pkg/sentry/kernel/uts_namespace.go | 2 +- pkg/sentry/kernel/vdso.go | 2 +- pkg/sentry/kernel/version.go | 2 +- pkg/sentry/limits/context.go | 2 +- pkg/sentry/limits/limits.go | 2 +- pkg/sentry/limits/limits_test.go | 2 +- pkg/sentry/limits/linux.go | 2 +- pkg/sentry/loader/elf.go | 2 +- pkg/sentry/loader/interpreter.go | 2 +- pkg/sentry/loader/loader.go | 2 +- pkg/sentry/loader/vdso.go | 2 +- pkg/sentry/loader/vdso_state.go | 2 +- pkg/sentry/memmap/mapping_set.go | 2 +- pkg/sentry/memmap/mapping_set_test.go | 2 +- pkg/sentry/memmap/memmap.go | 2 +- pkg/sentry/memutil/memutil.go | 2 +- pkg/sentry/memutil/memutil_unsafe.go | 2 +- pkg/sentry/mm/address_space.go | 2 +- pkg/sentry/mm/aio_context.go | 2 +- pkg/sentry/mm/aio_context_state.go | 2 +- pkg/sentry/mm/debug.go | 2 +- pkg/sentry/mm/io.go | 2 +- pkg/sentry/mm/lifecycle.go | 2 +- pkg/sentry/mm/metadata.go | 2 +- pkg/sentry/mm/mm.go | 2 +- pkg/sentry/mm/mm_test.go | 2 +- pkg/sentry/mm/pma.go | 2 +- pkg/sentry/mm/proc_pid_maps.go | 2 +- pkg/sentry/mm/save_restore.go | 2 +- pkg/sentry/mm/shm.go | 2 +- pkg/sentry/mm/special_mappable.go | 2 +- pkg/sentry/mm/syscalls.go | 2 +- pkg/sentry/mm/vma.go | 2 +- pkg/sentry/platform/context.go | 2 +- pkg/sentry/platform/filemem/filemem.go | 2 +- pkg/sentry/platform/filemem/filemem_state.go | 2 +- pkg/sentry/platform/filemem/filemem_test.go | 2 +- pkg/sentry/platform/filemem/filemem_unsafe.go | 2 +- pkg/sentry/platform/interrupt/interrupt.go | 2 +- pkg/sentry/platform/interrupt/interrupt_test.go | 2 +- pkg/sentry/platform/kvm/address_space.go | 2 +- pkg/sentry/platform/kvm/allocator.go | 2 +- pkg/sentry/platform/kvm/bluepill.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.s | 2 +- pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/bluepill_fault.go | 2 +- pkg/sentry/platform/kvm/bluepill_unsafe.go | 2 +- pkg/sentry/platform/kvm/context.go | 2 +- pkg/sentry/platform/kvm/host_map.go | 2 +- pkg/sentry/platform/kvm/kvm.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/kvm_const.go | 2 +- pkg/sentry/platform/kvm/kvm_test.go | 2 +- pkg/sentry/platform/kvm/machine.go | 2 +- pkg/sentry/platform/kvm/machine_amd64.go | 2 +- pkg/sentry/platform/kvm/machine_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/machine_unsafe.go | 2 +- pkg/sentry/platform/kvm/physical_map.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.s | 2 +- pkg/sentry/platform/kvm/virtual_map.go | 2 +- pkg/sentry/platform/kvm/virtual_map_test.go | 2 +- pkg/sentry/platform/mmap_min_addr.go | 2 +- pkg/sentry/platform/platform.go | 2 +- pkg/sentry/platform/procid/procid.go | 2 +- pkg/sentry/platform/procid/procid_amd64.s | 2 +- pkg/sentry/platform/procid/procid_net_test.go | 2 +- pkg/sentry/platform/procid/procid_test.go | 2 +- pkg/sentry/platform/ptrace/ptrace.go | 2 +- pkg/sentry/platform/ptrace/ptrace_unsafe.go | 2 +- pkg/sentry/platform/ptrace/stub_amd64.s | 2 +- pkg/sentry/platform/ptrace/stub_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess.go | 2 +- pkg/sentry/platform/ptrace/subprocess_amd64.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess_unsafe.go | 2 +- pkg/sentry/platform/ring0/defs.go | 2 +- pkg/sentry/platform/ring0/defs_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.s | 2 +- pkg/sentry/platform/ring0/gen_offsets/main.go | 2 +- pkg/sentry/platform/ring0/kernel.go | 2 +- pkg/sentry/platform/ring0/kernel_amd64.go | 2 +- pkg/sentry/platform/ring0/kernel_unsafe.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.s | 2 +- pkg/sentry/platform/ring0/offsets_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/pcids_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/walker_amd64.go | 2 +- pkg/sentry/platform/ring0/ring0.go | 2 +- pkg/sentry/platform/ring0/x86.go | 2 +- pkg/sentry/platform/safecopy/atomic_amd64.s | 2 +- pkg/sentry/platform/safecopy/memclr_amd64.s | 2 +- pkg/sentry/platform/safecopy/memcpy_amd64.s | 2 +- pkg/sentry/platform/safecopy/safecopy.go | 2 +- pkg/sentry/platform/safecopy/safecopy_test.go | 2 +- pkg/sentry/platform/safecopy/safecopy_unsafe.go | 2 +- pkg/sentry/platform/safecopy/sighandler_amd64.s | 2 +- pkg/sentry/safemem/block_unsafe.go | 2 +- pkg/sentry/safemem/io.go | 2 +- pkg/sentry/safemem/io_test.go | 2 +- pkg/sentry/safemem/safemem.go | 2 +- pkg/sentry/safemem/seq_test.go | 2 +- pkg/sentry/safemem/seq_unsafe.go | 2 +- pkg/sentry/sighandling/sighandling.go | 2 +- pkg/sentry/sighandling/sighandling_unsafe.go | 2 +- pkg/sentry/socket/control/control.go | 2 +- pkg/sentry/socket/epsocket/device.go | 2 +- pkg/sentry/socket/epsocket/epsocket.go | 2 +- pkg/sentry/socket/epsocket/provider.go | 2 +- pkg/sentry/socket/epsocket/save_restore.go | 2 +- pkg/sentry/socket/epsocket/stack.go | 2 +- pkg/sentry/socket/hostinet/device.go | 2 +- pkg/sentry/socket/hostinet/hostinet.go | 2 +- pkg/sentry/socket/hostinet/save_restore.go | 2 +- pkg/sentry/socket/hostinet/socket.go | 2 +- pkg/sentry/socket/hostinet/socket_unsafe.go | 2 +- pkg/sentry/socket/hostinet/stack.go | 2 +- pkg/sentry/socket/netlink/message.go | 2 +- pkg/sentry/socket/netlink/port/port.go | 2 +- pkg/sentry/socket/netlink/port/port_test.go | 2 +- pkg/sentry/socket/netlink/provider.go | 2 +- pkg/sentry/socket/netlink/route/protocol.go | 2 +- pkg/sentry/socket/netlink/socket.go | 2 +- pkg/sentry/socket/rpcinet/conn/conn.go | 2 +- pkg/sentry/socket/rpcinet/device.go | 2 +- pkg/sentry/socket/rpcinet/notifier/notifier.go | 2 +- pkg/sentry/socket/rpcinet/rpcinet.go | 2 +- pkg/sentry/socket/rpcinet/socket.go | 2 +- pkg/sentry/socket/rpcinet/stack.go | 2 +- pkg/sentry/socket/rpcinet/stack_unsafe.go | 2 +- pkg/sentry/socket/socket.go | 2 +- pkg/sentry/socket/unix/device.go | 2 +- pkg/sentry/socket/unix/io.go | 2 +- pkg/sentry/socket/unix/transport/connectioned.go | 2 +- pkg/sentry/socket/unix/transport/connectioned_state.go | 2 +- pkg/sentry/socket/unix/transport/connectionless.go | 2 +- pkg/sentry/socket/unix/transport/queue.go | 2 +- pkg/sentry/socket/unix/transport/unix.go | 2 +- pkg/sentry/socket/unix/unix.go | 2 +- pkg/sentry/state/state.go | 2 +- pkg/sentry/state/state_metadata.go | 2 +- pkg/sentry/state/state_unsafe.go | 2 +- pkg/sentry/strace/clone.go | 2 +- pkg/sentry/strace/futex.go | 2 +- pkg/sentry/strace/linux64.go | 2 +- pkg/sentry/strace/open.go | 2 +- pkg/sentry/strace/ptrace.go | 2 +- pkg/sentry/strace/socket.go | 2 +- pkg/sentry/strace/strace.go | 2 +- pkg/sentry/strace/strace.proto | 2 +- pkg/sentry/strace/syscalls.go | 2 +- pkg/sentry/syscalls/epoll.go | 2 +- pkg/sentry/syscalls/linux/error.go | 2 +- pkg/sentry/syscalls/linux/flags.go | 2 +- pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sigset.go | 2 +- pkg/sentry/syscalls/linux/sys_aio.go | 2 +- pkg/sentry/syscalls/linux/sys_capability.go | 2 +- pkg/sentry/syscalls/linux/sys_epoll.go | 2 +- pkg/sentry/syscalls/linux/sys_eventfd.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 2 +- pkg/sentry/syscalls/linux/sys_futex.go | 2 +- pkg/sentry/syscalls/linux/sys_getdents.go | 2 +- pkg/sentry/syscalls/linux/sys_identity.go | 2 +- pkg/sentry/syscalls/linux/sys_inotify.go | 2 +- pkg/sentry/syscalls/linux/sys_lseek.go | 2 +- pkg/sentry/syscalls/linux/sys_mmap.go | 2 +- pkg/sentry/syscalls/linux/sys_mount.go | 2 +- pkg/sentry/syscalls/linux/sys_pipe.go | 2 +- pkg/sentry/syscalls/linux/sys_poll.go | 2 +- pkg/sentry/syscalls/linux/sys_prctl.go | 2 +- pkg/sentry/syscalls/linux/sys_random.go | 2 +- pkg/sentry/syscalls/linux/sys_read.go | 2 +- pkg/sentry/syscalls/linux/sys_rlimit.go | 2 +- pkg/sentry/syscalls/linux/sys_rusage.go | 2 +- pkg/sentry/syscalls/linux/sys_sched.go | 2 +- pkg/sentry/syscalls/linux/sys_seccomp.go | 2 +- pkg/sentry/syscalls/linux/sys_sem.go | 2 +- pkg/sentry/syscalls/linux/sys_shm.go | 2 +- pkg/sentry/syscalls/linux/sys_signal.go | 2 +- pkg/sentry/syscalls/linux/sys_socket.go | 2 +- pkg/sentry/syscalls/linux/sys_stat.go | 2 +- pkg/sentry/syscalls/linux/sys_sync.go | 2 +- pkg/sentry/syscalls/linux/sys_sysinfo.go | 2 +- pkg/sentry/syscalls/linux/sys_syslog.go | 2 +- pkg/sentry/syscalls/linux/sys_thread.go | 2 +- pkg/sentry/syscalls/linux/sys_time.go | 2 +- pkg/sentry/syscalls/linux/sys_timer.go | 2 +- pkg/sentry/syscalls/linux/sys_timerfd.go | 2 +- pkg/sentry/syscalls/linux/sys_tls.go | 2 +- pkg/sentry/syscalls/linux/sys_utsname.go | 2 +- pkg/sentry/syscalls/linux/sys_write.go | 2 +- pkg/sentry/syscalls/linux/timespec.go | 2 +- pkg/sentry/syscalls/polling.go | 2 +- pkg/sentry/syscalls/syscalls.go | 2 +- pkg/sentry/syscalls/unimplemented_syscall.proto | 2 +- pkg/sentry/time/calibrated_clock.go | 2 +- pkg/sentry/time/calibrated_clock_test.go | 2 +- pkg/sentry/time/clock_id.go | 2 +- pkg/sentry/time/clocks.go | 2 +- pkg/sentry/time/muldiv_amd64.s | 2 +- pkg/sentry/time/parameters.go | 2 +- pkg/sentry/time/parameters_test.go | 2 +- pkg/sentry/time/sampler.go | 2 +- pkg/sentry/time/sampler_test.go | 2 +- pkg/sentry/time/sampler_unsafe.go | 2 +- pkg/sentry/time/tsc_amd64.s | 2 +- pkg/sentry/uniqueid/context.go | 2 +- pkg/sentry/usage/cpu.go | 2 +- pkg/sentry/usage/io.go | 2 +- pkg/sentry/usage/memory.go | 2 +- pkg/sentry/usage/memory_unsafe.go | 2 +- pkg/sentry/usage/usage.go | 2 +- pkg/sentry/usermem/access_type.go | 2 +- pkg/sentry/usermem/addr.go | 2 +- pkg/sentry/usermem/addr_range_seq_test.go | 2 +- pkg/sentry/usermem/addr_range_seq_unsafe.go | 2 +- pkg/sentry/usermem/bytes_io.go | 2 +- pkg/sentry/usermem/bytes_io_unsafe.go | 2 +- pkg/sentry/usermem/usermem.go | 2 +- pkg/sentry/usermem/usermem_test.go | 2 +- pkg/sentry/usermem/usermem_x86.go | 2 +- pkg/sentry/watchdog/watchdog.go | 2 +- pkg/sleep/commit_amd64.s | 2 +- pkg/sleep/commit_asm.go | 2 +- pkg/sleep/commit_noasm.go | 2 +- pkg/sleep/empty.s | 2 +- pkg/sleep/sleep_test.go | 2 +- pkg/sleep/sleep_unsafe.go | 2 +- pkg/state/decode.go | 2 +- pkg/state/encode.go | 2 +- pkg/state/encode_unsafe.go | 2 +- pkg/state/map.go | 2 +- pkg/state/object.proto | 2 +- pkg/state/printer.go | 2 +- pkg/state/state.go | 2 +- pkg/state/state_test.go | 2 +- pkg/state/statefile/statefile.go | 2 +- pkg/state/statefile/statefile_test.go | 2 +- pkg/state/stats.go | 2 +- pkg/sync/atomicptr_unsafe.go | 2 +- pkg/sync/atomicptrtest/atomicptr_test.go | 2 +- pkg/sync/memmove_unsafe.go | 2 +- pkg/sync/norace_unsafe.go | 2 +- pkg/sync/race_unsafe.go | 2 +- pkg/sync/seqatomic_unsafe.go | 2 +- pkg/sync/seqatomictest/seqatomic_test.go | 2 +- pkg/sync/seqcount.go | 2 +- pkg/sync/seqcount_test.go | 2 +- pkg/sync/sync.go | 2 +- pkg/syserr/host_linux.go | 2 +- pkg/syserr/netstack.go | 2 +- pkg/syserr/syserr.go | 2 +- pkg/syserror/syserror.go | 2 +- pkg/syserror/syserror_test.go | 2 +- pkg/tcpip/adapters/gonet/gonet.go | 2 +- pkg/tcpip/adapters/gonet/gonet_test.go | 2 +- pkg/tcpip/buffer/prependable.go | 2 +- pkg/tcpip/buffer/view.go | 2 +- pkg/tcpip/buffer/view_test.go | 2 +- pkg/tcpip/checker/checker.go | 2 +- pkg/tcpip/header/arp.go | 2 +- pkg/tcpip/header/checksum.go | 2 +- pkg/tcpip/header/eth.go | 2 +- pkg/tcpip/header/gue.go | 2 +- pkg/tcpip/header/icmpv4.go | 2 +- pkg/tcpip/header/icmpv6.go | 2 +- pkg/tcpip/header/interfaces.go | 2 +- pkg/tcpip/header/ipv4.go | 2 +- pkg/tcpip/header/ipv6.go | 2 +- pkg/tcpip/header/ipv6_fragment.go | 2 +- pkg/tcpip/header/ipversion_test.go | 2 +- pkg/tcpip/header/tcp.go | 2 +- pkg/tcpip/header/tcp_test.go | 2 +- pkg/tcpip/header/udp.go | 2 +- pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 2 +- pkg/tcpip/link/fdbased/endpoint_test.go | 2 +- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64.s | 2 +- pkg/tcpip/link/rawfile/blockingpoll_unsafe.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go | 2 +- pkg/tcpip/link/rawfile/errors.go | 2 +- pkg/tcpip/link/rawfile/rawfile_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_test.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/rx.go | 2 +- pkg/tcpip/link/sharedmem/pipe/tx.go | 2 +- pkg/tcpip/link/sharedmem/queue/queue_test.go | 2 +- pkg/tcpip/link/sharedmem/queue/rx.go | 2 +- pkg/tcpip/link/sharedmem/queue/tx.go | 2 +- pkg/tcpip/link/sharedmem/rx.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/tx.go | 2 +- pkg/tcpip/link/sniffer/pcap.go | 2 +- pkg/tcpip/link/sniffer/sniffer.go | 2 +- pkg/tcpip/link/tun/tun_unsafe.go | 2 +- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 2 +- pkg/tcpip/network/arp/arp.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap_test.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation_test.go | 2 +- pkg/tcpip/network/fragmentation/reassembler.go | 2 +- pkg/tcpip/network/fragmentation/reassembler_test.go | 2 +- pkg/tcpip/network/hash/hash.go | 2 +- pkg/tcpip/network/ip_test.go | 2 +- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv4/ipv4_test.go | 2 +- pkg/tcpip/network/ipv6/icmp.go | 2 +- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 2 +- pkg/tcpip/ports/ports.go | 2 +- pkg/tcpip/ports/ports_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/seqnum/seqnum.go | 2 +- pkg/tcpip/stack/linkaddrcache.go | 2 +- pkg/tcpip/stack/linkaddrcache_test.go | 2 +- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/stack/registration.go | 2 +- pkg/tcpip/stack/route.go | 2 +- pkg/tcpip/stack/stack.go | 2 +- pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/stack/stack_test.go | 2 +- pkg/tcpip/stack/transport_demuxer.go | 2 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 2 +- pkg/tcpip/tcpip_test.go | 2 +- pkg/tcpip/time.s | 2 +- pkg/tcpip/time_unsafe.go | 2 +- pkg/tcpip/transport/ping/endpoint.go | 2 +- pkg/tcpip/transport/ping/endpoint_state.go | 2 +- pkg/tcpip/transport/ping/protocol.go | 2 +- pkg/tcpip/transport/tcp/accept.go | 2 +- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/cubic.go | 2 +- pkg/tcpip/transport/tcp/dual_stack_test.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/tcp/endpoint_state.go | 2 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/rcv.go | 2 +- pkg/tcpip/transport/tcp/reno.go | 2 +- pkg/tcpip/transport/tcp/sack.go | 2 +- pkg/tcpip/transport/tcp/segment.go | 2 +- pkg/tcpip/transport/tcp/segment_heap.go | 2 +- pkg/tcpip/transport/tcp/segment_queue.go | 2 +- pkg/tcpip/transport/tcp/segment_state.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 2 +- pkg/tcpip/transport/tcp/snd_state.go | 2 +- pkg/tcpip/transport/tcp/tcp_sack_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 2 +- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/tcp/timer.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- pkg/tcpip/transport/udp/endpoint_state.go | 2 +- pkg/tcpip/transport/udp/protocol.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 2 +- pkg/tmutex/tmutex.go | 2 +- pkg/tmutex/tmutex_test.go | 2 +- pkg/unet/unet.go | 2 +- pkg/unet/unet_test.go | 2 +- pkg/unet/unet_unsafe.go | 2 +- pkg/urpc/urpc.go | 2 +- pkg/urpc/urpc_test.go | 2 +- pkg/waiter/fdnotifier/fdnotifier.go | 2 +- pkg/waiter/fdnotifier/poll_unsafe.go | 2 +- pkg/waiter/waiter.go | 2 +- pkg/waiter/waiter_test.go | 2 +- runsc/boot/compat.go | 2 +- runsc/boot/config.go | 2 +- runsc/boot/controller.go | 2 +- runsc/boot/debug.go | 2 +- runsc/boot/events.go | 2 +- runsc/boot/fds.go | 2 +- runsc/boot/filter/config.go | 2 +- runsc/boot/filter/extra_filters.go | 2 +- runsc/boot/filter/extra_filters_msan.go | 2 +- runsc/boot/filter/extra_filters_race.go | 2 +- runsc/boot/filter/filter.go | 2 +- runsc/boot/fs.go | 2 +- runsc/boot/limits.go | 2 +- runsc/boot/loader.go | 2 +- runsc/boot/loader_test.go | 2 +- runsc/boot/network.go | 2 +- runsc/boot/strace.go | 2 +- runsc/cgroup/cgroup.go | 2 +- runsc/cgroup/cgroup_test.go | 2 +- runsc/cmd/boot.go | 2 +- runsc/cmd/capability.go | 2 +- runsc/cmd/capability_test.go | 2 +- runsc/cmd/checkpoint.go | 2 +- runsc/cmd/cmd.go | 2 +- runsc/cmd/create.go | 2 +- runsc/cmd/debug.go | 2 +- runsc/cmd/delete.go | 2 +- runsc/cmd/delete_test.go | 2 +- runsc/cmd/events.go | 2 +- runsc/cmd/exec.go | 2 +- runsc/cmd/exec_test.go | 2 +- runsc/cmd/gofer.go | 2 +- runsc/cmd/kill.go | 2 +- runsc/cmd/list.go | 2 +- runsc/cmd/path.go | 2 +- runsc/cmd/pause.go | 2 +- runsc/cmd/ps.go | 2 +- runsc/cmd/restore.go | 2 +- runsc/cmd/resume.go | 2 +- runsc/cmd/run.go | 2 +- runsc/cmd/spec.go | 2 +- runsc/cmd/start.go | 2 +- runsc/cmd/state.go | 2 +- runsc/cmd/wait.go | 2 +- runsc/console/console.go | 2 +- runsc/container/console_test.go | 2 +- runsc/container/container.go | 2 +- runsc/container/container_test.go | 2 +- runsc/container/fs.go | 2 +- runsc/container/fs_test.go | 2 +- runsc/container/hook.go | 2 +- runsc/container/multi_container_test.go | 2 +- runsc/container/status.go | 2 +- runsc/container/test_app.go | 2 +- runsc/fsgofer/filter/config.go | 2 +- runsc/fsgofer/filter/extra_filters.go | 2 +- runsc/fsgofer/filter/extra_filters_msan.go | 2 +- runsc/fsgofer/filter/extra_filters_race.go | 2 +- runsc/fsgofer/filter/filter.go | 2 +- runsc/fsgofer/fsgofer.go | 2 +- runsc/fsgofer/fsgofer_test.go | 2 +- runsc/fsgofer/fsgofer_unsafe.go | 2 +- runsc/main.go | 2 +- runsc/sandbox/chroot.go | 2 +- runsc/sandbox/network.go | 2 +- runsc/sandbox/sandbox.go | 2 +- runsc/specutils/namespace.go | 2 +- runsc/specutils/specutils.go | 2 +- runsc/specutils/specutils_test.go | 2 +- runsc/test/image/image.go | 2 +- runsc/test/image/image_test.go | 2 +- runsc/test/image/mysql.sql | 2 +- runsc/test/image/ruby.rb | 2 +- runsc/test/image/ruby.sh | 2 +- runsc/test/install.sh | 2 +- runsc/test/integration/exec_test.go | 2 +- runsc/test/integration/integration.go | 2 +- runsc/test/integration/integration_test.go | 2 +- runsc/test/root/cgroup_test.go | 2 +- runsc/test/root/chroot_test.go | 2 +- runsc/test/root/root.go | 2 +- runsc/test/testutil/docker.go | 2 +- runsc/test/testutil/testutil.go | 2 +- runsc/test/testutil/testutil_race.go | 2 +- runsc/tools/dockercfg/dockercfg.go | 2 +- tools/go_generics/generics.go | 2 +- tools/go_generics/generics_tests/all_stmts/input.go | 2 +- tools/go_generics/generics_tests/all_stmts/output/output.go | 2 +- tools/go_generics/generics_tests/all_types/input.go | 2 +- tools/go_generics/generics_tests/all_types/lib/lib.go | 2 +- tools/go_generics/generics_tests/all_types/output/output.go | 2 +- tools/go_generics/generics_tests/consts/input.go | 2 +- tools/go_generics/generics_tests/consts/output/output.go | 2 +- tools/go_generics/generics_tests/imports/input.go | 2 +- tools/go_generics/generics_tests/imports/output/output.go | 2 +- tools/go_generics/generics_tests/remove_typedef/input.go | 2 +- tools/go_generics/generics_tests/remove_typedef/output/output.go | 2 +- tools/go_generics/generics_tests/simple/input.go | 2 +- tools/go_generics/generics_tests/simple/output/output.go | 2 +- tools/go_generics/globals/globals_visitor.go | 2 +- tools/go_generics/globals/scope.go | 2 +- tools/go_generics/go_generics_unittest.sh | 2 +- tools/go_generics/imports.go | 2 +- tools/go_generics/merge.go | 2 +- tools/go_generics/remove.go | 2 +- tools/go_generics/rules_tests/template.go | 2 +- tools/go_generics/rules_tests/template_test.go | 2 +- tools/go_stateify/main.go | 2 +- tools/workspace_status.sh | 2 +- vdso/barrier.h | 2 +- vdso/check_vdso.py | 2 +- vdso/compiler.h | 2 +- vdso/cycle_clock.h | 2 +- vdso/seqlock.h | 2 +- vdso/syscalls.h | 2 +- vdso/vdso.cc | 2 +- vdso/vdso_time.cc | 2 +- vdso/vdso_time.h | 2 +- 923 files changed, 923 insertions(+), 923 deletions(-) (limited to 'pkg/abi') diff --git a/kokoro/run_build.sh b/kokoro/run_build.sh index f2b719f52..89e24b037 100755 --- a/kokoro/run_build.sh +++ b/kokoro/run_build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/kokoro/run_tests.sh b/kokoro/run_tests.sh index 3f8841cee..0a0d73d29 100755 --- a/kokoro/run_tests.sh +++ b/kokoro/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/pkg/abi/abi.go b/pkg/abi/abi.go index a53c2747b..7770f0405 100644 --- a/pkg/abi/abi.go +++ b/pkg/abi/abi.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/abi_linux.go b/pkg/abi/abi_linux.go index dd5d67b51..9d9f361a4 100644 --- a/pkg/abi/abi_linux.go +++ b/pkg/abi/abi_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index 0391ccf37..0698e410f 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/aio.go b/pkg/abi/linux/aio.go index 9c39ca2ef..1b7ca714a 100644 --- a/pkg/abi/linux/aio.go +++ b/pkg/abi/linux/aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ashmem.go b/pkg/abi/linux/ashmem.go index 7fbfd2e68..ced1e44d4 100644 --- a/pkg/abi/linux/ashmem.go +++ b/pkg/abi/linux/ashmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/binder.go b/pkg/abi/linux/binder.go index b228898f9..522dc6f53 100644 --- a/pkg/abi/linux/binder.go +++ b/pkg/abi/linux/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index 80e5b1af1..d9cd09948 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go index b470ce0a5..7d96f013e 100644 --- a/pkg/abi/linux/capability.go +++ b/pkg/abi/linux/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go index ea5b16b7b..5b1199aac 100644 --- a/pkg/abi/linux/dev.go +++ b/pkg/abi/linux/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go index 76c13b677..928067c04 100644 --- a/pkg/abi/linux/elf.go +++ b/pkg/abi/linux/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go index b5ddb2b2f..01e4095b8 100644 --- a/pkg/abi/linux/errors.go +++ b/pkg/abi/linux/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/eventfd.go b/pkg/abi/linux/eventfd.go index bc0fb44d2..5614f5cf1 100644 --- a/pkg/abi/linux/eventfd.go +++ b/pkg/abi/linux/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/exec.go b/pkg/abi/linux/exec.go index 4d81eca54..a07c29243 100644 --- a/pkg/abi/linux/exec.go +++ b/pkg/abi/linux/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index 2a5ad6ed7..c8558933a 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 9bf229a57..72e5c6f83 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index 32a0812b4..7817bfb52 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go index f63f5200c..5dff01fba 100644 --- a/pkg/abi/linux/futex.go +++ b/pkg/abi/linux/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/inotify.go b/pkg/abi/linux/inotify.go index 072a2d146..79c5d3593 100644 --- a/pkg/abi/linux/inotify.go +++ b/pkg/abi/linux/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index afd9ee82b..9afc3d1ef 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go index 6b68999ab..fcec16965 100644 --- a/pkg/abi/linux/ip.go +++ b/pkg/abi/linux/ip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go index 81e9904dd..10681768b 100644 --- a/pkg/abi/linux/ipc.go +++ b/pkg/abi/linux/ipc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index e1f0932ec..b2e51b9bd 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go index de2af80dc..d365f693d 100644 --- a/pkg/abi/linux/linux.go +++ b/pkg/abi/linux/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index b48e1d18a..3fcdf8235 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go index 88654a1b3..e3b6b1e40 100644 --- a/pkg/abi/linux/netdevice.go +++ b/pkg/abi/linux/netdevice.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go index e823ffa7e..10ceb5bf2 100644 --- a/pkg/abi/linux/netlink.go +++ b/pkg/abi/linux/netlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go index a5d778748..4200b6506 100644 --- a/pkg/abi/linux/netlink_route.go +++ b/pkg/abi/linux/netlink_route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/poll.go b/pkg/abi/linux/poll.go index f373cfca1..9f0b15d1c 100644 --- a/pkg/abi/linux/poll.go +++ b/pkg/abi/linux/poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index 074ec03f0..e152c4c27 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/ptrace.go b/pkg/abi/linux/ptrace.go index ba48d4d6d..7db4f5464 100644 --- a/pkg/abi/linux/ptrace.go +++ b/pkg/abi/linux/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/rusage.go b/pkg/abi/linux/rusage.go index a4a89abda..7fea4b589 100644 --- a/pkg/abi/linux/rusage.go +++ b/pkg/abi/linux/rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/sched.go b/pkg/abi/linux/sched.go index 05fda1604..ef96a3801 100644 --- a/pkg/abi/linux/sched.go +++ b/pkg/abi/linux/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index a8de9d3d0..9963ceeba 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go index 3495f5cd0..d1a0bdb32 100644 --- a/pkg/abi/linux/sem.go +++ b/pkg/abi/linux/sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/shm.go b/pkg/abi/linux/shm.go index f50b3c2e2..82a80e609 100644 --- a/pkg/abi/linux/shm.go +++ b/pkg/abi/linux/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index b2c7230c4..bf9bce6ed 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 19b5fa212..af0761a3b 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go index 4569f4208..bbd21e726 100644 --- a/pkg/abi/linux/time.go +++ b/pkg/abi/linux/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/timer.go b/pkg/abi/linux/timer.go index 6c4675c35..a6f420bdb 100644 --- a/pkg/abi/linux/timer.go +++ b/pkg/abi/linux/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index f63dc52aa..e6f7c5b2a 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/uio.go b/pkg/abi/linux/uio.go index 93c972774..7e00d9959 100644 --- a/pkg/abi/linux/uio.go +++ b/pkg/abi/linux/uio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/abi/linux/utsname.go b/pkg/abi/linux/utsname.go index 7d33d20de..f80ed7d4a 100644 --- a/pkg/abi/linux/utsname.go +++ b/pkg/abi/linux/utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/amutex/amutex.go b/pkg/amutex/amutex.go index 1cb73359a..26b674435 100644 --- a/pkg/amutex/amutex.go +++ b/pkg/amutex/amutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/amutex/amutex_test.go b/pkg/amutex/amutex_test.go index 876e47b19..104e0dab1 100644 --- a/pkg/amutex/amutex_test.go +++ b/pkg/amutex/amutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops.go b/pkg/atomicbitops/atomic_bitops.go index 6635ea0d2..9a57f9599 100644 --- a/pkg/atomicbitops/atomic_bitops.go +++ b/pkg/atomicbitops/atomic_bitops.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops_amd64.s b/pkg/atomicbitops/atomic_bitops_amd64.s index 542452bec..b37e3aad3 100644 --- a/pkg/atomicbitops/atomic_bitops_amd64.s +++ b/pkg/atomicbitops/atomic_bitops_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops_common.go b/pkg/atomicbitops/atomic_bitops_common.go index 542ff4e83..b03242baa 100644 --- a/pkg/atomicbitops/atomic_bitops_common.go +++ b/pkg/atomicbitops/atomic_bitops_common.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/atomicbitops/atomic_bitops_test.go b/pkg/atomicbitops/atomic_bitops_test.go index ec0c07ee2..ee6207cb3 100644 --- a/pkg/atomicbitops/atomic_bitops_test.go +++ b/pkg/atomicbitops/atomic_bitops_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/binary/binary.go b/pkg/binary/binary.go index 3b18a86ee..02f7e9fb8 100644 --- a/pkg/binary/binary.go +++ b/pkg/binary/binary.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/binary/binary_test.go b/pkg/binary/binary_test.go index 921a0369a..d8d481f32 100644 --- a/pkg/binary/binary_test.go +++ b/pkg/binary/binary_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/bits.go b/pkg/bits/bits.go index 50ca4bff7..eb3c80f49 100644 --- a/pkg/bits/bits.go +++ b/pkg/bits/bits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/bits_template.go b/pkg/bits/bits_template.go index 0a01f29c2..8c578cca2 100644 --- a/pkg/bits/bits_template.go +++ b/pkg/bits/bits_template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_arch_amd64.go b/pkg/bits/uint64_arch_amd64.go index 068597f68..1fef89394 100644 --- a/pkg/bits/uint64_arch_amd64.go +++ b/pkg/bits/uint64_arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_arch_amd64_asm.s b/pkg/bits/uint64_arch_amd64_asm.s index 33885641a..8c7322f0f 100644 --- a/pkg/bits/uint64_arch_amd64_asm.s +++ b/pkg/bits/uint64_arch_amd64_asm.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_arch_generic.go b/pkg/bits/uint64_arch_generic.go index 862033a4b..cfb47400b 100644 --- a/pkg/bits/uint64_arch_generic.go +++ b/pkg/bits/uint64_arch_generic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bits/uint64_test.go b/pkg/bits/uint64_test.go index 906017e1a..d6dbaf602 100644 --- a/pkg/bits/uint64_test.go +++ b/pkg/bits/uint64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/bpf.go b/pkg/bpf/bpf.go index 757744090..98d44d911 100644 --- a/pkg/bpf/bpf.go +++ b/pkg/bpf/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/decoder.go b/pkg/bpf/decoder.go index ef41e9edc..ae6b8839a 100644 --- a/pkg/bpf/decoder.go +++ b/pkg/bpf/decoder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/decoder_test.go b/pkg/bpf/decoder_test.go index 18709b944..f093e1e41 100644 --- a/pkg/bpf/decoder_test.go +++ b/pkg/bpf/decoder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/input_bytes.go b/pkg/bpf/input_bytes.go index 74af038eb..745c0749b 100644 --- a/pkg/bpf/input_bytes.go +++ b/pkg/bpf/input_bytes.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index 111ada9d1..86c7add4d 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/interpreter_test.go b/pkg/bpf/interpreter_test.go index 9e5e33228..c46a43991 100644 --- a/pkg/bpf/interpreter_test.go +++ b/pkg/bpf/interpreter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/program_builder.go b/pkg/bpf/program_builder.go index bad56d7ac..b4ce228e1 100644 --- a/pkg/bpf/program_builder.go +++ b/pkg/bpf/program_builder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/bpf/program_builder_test.go b/pkg/bpf/program_builder_test.go index 7e4f06584..0e0b79d88 100644 --- a/pkg/bpf/program_builder_test.go +++ b/pkg/bpf/program_builder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/compressio/compressio.go b/pkg/compressio/compressio.go index 667f17c5c..205536812 100644 --- a/pkg/compressio/compressio.go +++ b/pkg/compressio/compressio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/compressio/compressio_test.go b/pkg/compressio/compressio_test.go index 7cb5f8dc4..1bbabee79 100644 --- a/pkg/compressio/compressio_test.go +++ b/pkg/compressio/compressio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/control/client/client.go b/pkg/control/client/client.go index f7c2e8776..0d0c9f148 100644 --- a/pkg/control/client/client.go +++ b/pkg/control/client/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/control/server/server.go b/pkg/control/server/server.go index d00061ce3..c46b5d70b 100644 --- a/pkg/control/server/server.go +++ b/pkg/control/server/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpu_amd64.s b/pkg/cpuid/cpu_amd64.s index 48a13c6fd..905c1d12e 100644 --- a/pkg/cpuid/cpu_amd64.s +++ b/pkg/cpuid/cpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index e91e34dc7..5b083a5fb 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpuid_parse_test.go b/pkg/cpuid/cpuid_parse_test.go index c4f52818c..81b06f48c 100644 --- a/pkg/cpuid/cpuid_parse_test.go +++ b/pkg/cpuid/cpuid_parse_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/cpuid/cpuid_test.go b/pkg/cpuid/cpuid_test.go index 02f732f85..0decd8f08 100644 --- a/pkg/cpuid/cpuid_test.go +++ b/pkg/cpuid/cpuid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 92c634a14..3330c4998 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go index ceaba34c3..ad11e178a 100644 --- a/pkg/dhcp/dhcp.go +++ b/pkg/dhcp/dhcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/dhcp_string.go b/pkg/dhcp/dhcp_string.go index 7cabed29e..8533895bd 100644 --- a/pkg/dhcp/dhcp_string.go +++ b/pkg/dhcp/dhcp_string.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index d60e3752b..a21dce6bc 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 26700bdbc..3e06ab4c7 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/eventchannel/event.go b/pkg/eventchannel/event.go index bfd28256e..41a7b5ed3 100644 --- a/pkg/eventchannel/event.go +++ b/pkg/eventchannel/event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/eventchannel/event.proto b/pkg/eventchannel/event.proto index 455f03658..c1679c7e7 100644 --- a/pkg/eventchannel/event.proto +++ b/pkg/eventchannel/event.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/fd/fd.go b/pkg/fd/fd.go index 32d24c41b..f6656ffa1 100644 --- a/pkg/fd/fd.go +++ b/pkg/fd/fd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/fd/fd_test.go b/pkg/fd/fd_test.go index 94b3eb7cc..42bb3ef6c 100644 --- a/pkg/fd/fd_test.go +++ b/pkg/fd/fd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 93808c9dd..48122bf5a 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/gate/gate_test.go b/pkg/gate/gate_test.go index 06587339b..95620fa8e 100644 --- a/pkg/gate/gate_test.go +++ b/pkg/gate/gate_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 4ae02eee9..51c9b6df3 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/ilist/list_test.go b/pkg/ilist/list_test.go index 2c56280f6..4bda570b6 100644 --- a/pkg/ilist/list_test.go +++ b/pkg/ilist/list_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/linewriter/linewriter.go b/pkg/linewriter/linewriter.go index 98f974410..5fbd4e779 100644 --- a/pkg/linewriter/linewriter.go +++ b/pkg/linewriter/linewriter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/linewriter/linewriter_test.go b/pkg/linewriter/linewriter_test.go index ce97cca05..9140ee6af 100644 --- a/pkg/linewriter/linewriter_test.go +++ b/pkg/linewriter/linewriter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/glog.go b/pkg/log/glog.go index 58b4052e6..fbb58501b 100644 --- a/pkg/log/glog.go +++ b/pkg/log/glog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/glog_unsafe.go b/pkg/log/glog_unsafe.go index c320190b8..bb06aa7d3 100644 --- a/pkg/log/glog_unsafe.go +++ b/pkg/log/glog_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/json.go b/pkg/log/json.go index 3887f1cd5..96bd13d87 100644 --- a/pkg/log/json.go +++ b/pkg/log/json.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/json_test.go b/pkg/log/json_test.go index 3b167dab0..b8c7a795e 100644 --- a/pkg/log/json_test.go +++ b/pkg/log/json_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/log.go b/pkg/log/log.go index c496e86e4..b8d456aae 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go index d93e989dc..a59d457dd 100644 --- a/pkg/log/log_test.go +++ b/pkg/log/log_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index 763cd6bc2..02af75974 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/metric/metric.proto b/pkg/metric/metric.proto index 6108cb7c0..917fda1ac 100644 --- a/pkg/metric/metric.proto +++ b/pkg/metric/metric.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/metric/metric_test.go b/pkg/metric/metric_test.go index 7d156e4a5..40034a589 100644 --- a/pkg/metric/metric_test.go +++ b/pkg/metric/metric_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/buffer.go b/pkg/p9/buffer.go index fc65d2c5f..9575ddf12 100644 --- a/pkg/p9/buffer.go +++ b/pkg/p9/buffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/client.go b/pkg/p9/client.go index 5fa231bc5..3ebfab82a 100644 --- a/pkg/p9/client.go +++ b/pkg/p9/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/client_file.go b/pkg/p9/client_file.go index a46efd27f..066639fda 100644 --- a/pkg/p9/client_file.go +++ b/pkg/p9/client_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/client_test.go b/pkg/p9/client_test.go index 06302a76a..f7145452d 100644 --- a/pkg/p9/client_test.go +++ b/pkg/p9/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/file.go b/pkg/p9/file.go index 9723fa24d..d2e89e373 100644 --- a/pkg/p9/file.go +++ b/pkg/p9/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index ea41f97c7..959dff31d 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/local_server/local_server.go b/pkg/p9/local_server/local_server.go index cef3701a7..1e6aaa762 100644 --- a/pkg/p9/local_server/local_server.go +++ b/pkg/p9/local_server/local_server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/messages.go b/pkg/p9/messages.go index b3d76801b..972c37344 100644 --- a/pkg/p9/messages.go +++ b/pkg/p9/messages.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/messages_test.go b/pkg/p9/messages_test.go index f353755f1..dfb41bb76 100644 --- a/pkg/p9/messages_test.go +++ b/pkg/p9/messages_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9.go b/pkg/p9/p9.go index c6899c3ce..3b0993ecd 100644 --- a/pkg/p9/p9.go +++ b/pkg/p9/p9.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9_test.go b/pkg/p9/p9_test.go index a50ac80a4..02498346c 100644 --- a/pkg/p9/p9_test.go +++ b/pkg/p9/p9_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9test/client_test.go b/pkg/p9/p9test/client_test.go index 34ddccd8b..db562b9ba 100644 --- a/pkg/p9/p9test/client_test.go +++ b/pkg/p9/p9test/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/p9test/mocks.go b/pkg/p9/p9test/mocks.go index 9d039ac63..9a8c14975 100644 --- a/pkg/p9/p9test/mocks.go +++ b/pkg/p9/p9test/mocks.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/pool.go b/pkg/p9/pool.go index 9a508b898..34ed898e8 100644 --- a/pkg/p9/pool.go +++ b/pkg/p9/pool.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/pool_test.go b/pkg/p9/pool_test.go index 96be2c8bd..71052d8c4 100644 --- a/pkg/p9/pool_test.go +++ b/pkg/p9/pool_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/server.go b/pkg/p9/server.go index 28a273ac6..5c7cb18c8 100644 --- a/pkg/p9/server.go +++ b/pkg/p9/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/transport.go b/pkg/p9/transport.go index b5df29961..97396806c 100644 --- a/pkg/p9/transport.go +++ b/pkg/p9/transport.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/transport_test.go b/pkg/p9/transport_test.go index d6d4b6365..3352a5205 100644 --- a/pkg/p9/transport_test.go +++ b/pkg/p9/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/version.go b/pkg/p9/version.go index 8783eaa7e..ceb6fabbf 100644 --- a/pkg/p9/version.go +++ b/pkg/p9/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/p9/version_test.go b/pkg/p9/version_test.go index 634ac3ca5..c053614c9 100644 --- a/pkg/p9/version_test.go +++ b/pkg/p9/version_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/rand/rand.go b/pkg/rand/rand.go index e81f0f5db..593a14380 100644 --- a/pkg/rand/rand.go +++ b/pkg/rand/rand.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/rand/rand_linux.go b/pkg/rand/rand_linux.go index a2be66b3b..7ebe8f3b0 100644 --- a/pkg/rand/rand_linux.go +++ b/pkg/rand/rand_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 638a93bab..8f08c74c7 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/refs/refcounter_state.go b/pkg/refs/refcounter_state.go index 093eae785..136f06fbf 100644 --- a/pkg/refs/refcounter_state.go +++ b/pkg/refs/refcounter_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/refs/refcounter_test.go b/pkg/refs/refcounter_test.go index cc11bcd71..abaa87453 100644 --- a/pkg/refs/refcounter_test.go +++ b/pkg/refs/refcounter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index a746dc9b3..1dfbf749e 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index 6b707f195..a9278c64b 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 0188ad4f3..226f30b7b 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_test_victim.go b/pkg/seccomp/seccomp_test_victim.go index 4f2ae4dac..007038273 100644 --- a/pkg/seccomp/seccomp_test_victim.go +++ b/pkg/seccomp/seccomp_test_victim.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go index ae18534bf..dd009221a 100644 --- a/pkg/seccomp/seccomp_unsafe.go +++ b/pkg/seccomp/seccomp_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/secio/full_reader.go b/pkg/secio/full_reader.go index b2dbb8615..90b1772a7 100644 --- a/pkg/secio/full_reader.go +++ b/pkg/secio/full_reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/secio/secio.go b/pkg/secio/secio.go index fc625efb8..e5f74a497 100644 --- a/pkg/secio/secio.go +++ b/pkg/secio/secio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/secio/secio_test.go b/pkg/secio/secio_test.go index 64b4cc17d..8304c4f74 100644 --- a/pkg/secio/secio_test.go +++ b/pkg/secio/secio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 34c067265..057bcd7ff 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/set.go b/pkg/segment/set.go index cffec2a2c..a9a3b8875 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/set_state.go b/pkg/segment/set_state.go index a763d1915..b86e1b75f 100644 --- a/pkg/segment/set_state.go +++ b/pkg/segment/set_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/test/segment_test.go b/pkg/segment/test/segment_test.go index 7ea24b177..0825105db 100644 --- a/pkg/segment/test/segment_test.go +++ b/pkg/segment/test/segment_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/segment/test/set_functions.go b/pkg/segment/test/set_functions.go index 37c196ea1..05ba5fbb9 100644 --- a/pkg/segment/test/set_functions.go +++ b/pkg/segment/test/set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/aligned.go b/pkg/sentry/arch/aligned.go index 193232e27..c88c034f6 100644 --- a/pkg/sentry/arch/aligned.go +++ b/pkg/sentry/arch/aligned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 21cb84502..575b7ba66 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 5ba6c19ea..bb80a7bed 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_amd64.s b/pkg/sentry/arch/arch_amd64.s index 10d621b6d..fa9857df7 100644 --- a/pkg/sentry/arch/arch_amd64.s +++ b/pkg/sentry/arch/arch_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index e9c23a06b..604bd08a6 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index b35eec53c..59bf89d99 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 81cfb4a01..5df65a691 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/registers.proto b/pkg/sentry/arch/registers.proto index 437ff44ca..f4c2f7043 100644 --- a/pkg/sentry/arch/registers.proto +++ b/pkg/sentry/arch/registers.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_act.go b/pkg/sentry/arch/signal_act.go index 36437b965..ad098c746 100644 --- a/pkg/sentry/arch/signal_act.go +++ b/pkg/sentry/arch/signal_act.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index 9ca4c8ed1..f7f054b0b 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_info.go b/pkg/sentry/arch/signal_info.go index ec004ae75..fa0ecbec5 100644 --- a/pkg/sentry/arch/signal_info.go +++ b/pkg/sentry/arch/signal_info.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/signal_stack.go b/pkg/sentry/arch/signal_stack.go index ba43dd1d4..c02ae3b7c 100644 --- a/pkg/sentry/arch/signal_stack.go +++ b/pkg/sentry/arch/signal_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/stack.go b/pkg/sentry/arch/stack.go index 6c1b9be82..716a3574d 100644 --- a/pkg/sentry/arch/stack.go +++ b/pkg/sentry/arch/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/arch/syscalls_amd64.go b/pkg/sentry/arch/syscalls_amd64.go index 41d8ba0d1..47c31d4b9 100644 --- a/pkg/sentry/arch/syscalls_amd64.go +++ b/pkg/sentry/arch/syscalls_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go index 598c5b4ff..12bdcef85 100644 --- a/pkg/sentry/context/context.go +++ b/pkg/sentry/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/context/contexttest/contexttest.go b/pkg/sentry/context/contexttest/contexttest.go index b3c6a566b..d2f084ed7 100644 --- a/pkg/sentry/context/contexttest/contexttest.go +++ b/pkg/sentry/context/contexttest/contexttest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/control.go b/pkg/sentry/control/control.go index a6ee6e649..32d30b6ea 100644 --- a/pkg/sentry/control/control.go +++ b/pkg/sentry/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index 0ba730c1e..b6ac2f312 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/proc_test.go b/pkg/sentry/control/proc_test.go index 22c826236..5d52cd829 100644 --- a/pkg/sentry/control/proc_test.go +++ b/pkg/sentry/control/proc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/control/state.go b/pkg/sentry/control/state.go index cee4db636..0a480c84a 100644 --- a/pkg/sentry/control/state.go +++ b/pkg/sentry/control/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/device/device.go b/pkg/sentry/device/device.go index 21fee8f8a..27e4eb258 100644 --- a/pkg/sentry/device/device.go +++ b/pkg/sentry/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/device/device_test.go b/pkg/sentry/device/device_test.go index dfec45046..5d8805c2f 100644 --- a/pkg/sentry/device/device_test.go +++ b/pkg/sentry/device/device_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/anon/anon.go b/pkg/sentry/fs/anon/anon.go index ddc2c0985..743cf511f 100644 --- a/pkg/sentry/fs/anon/anon.go +++ b/pkg/sentry/fs/anon/anon.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/anon/device.go b/pkg/sentry/fs/anon/device.go index 1c666729c..2d1249299 100644 --- a/pkg/sentry/fs/anon/device.go +++ b/pkg/sentry/fs/anon/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index bfd7f2762..5372875ac 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index d0986fa11..962da141b 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index ecba395a0..7c997f533 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ashmem/pin_board_test.go b/pkg/sentry/fs/ashmem/pin_board_test.go index f4ea5de6d..736e628dc 100644 --- a/pkg/sentry/fs/ashmem/pin_board_test.go +++ b/pkg/sentry/fs/ashmem/pin_board_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 091f4ac63..59e060e3c 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index 502a262dd..42b9e8b26 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/context.go b/pkg/sentry/fs/context.go index da46ad77f..1775d3486 100644 --- a/pkg/sentry/fs/context.go +++ b/pkg/sentry/fs/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/copy_up.go b/pkg/sentry/fs/copy_up.go index 8c949b176..d65dc74bf 100644 --- a/pkg/sentry/fs/copy_up.go +++ b/pkg/sentry/fs/copy_up.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/copy_up_test.go b/pkg/sentry/fs/copy_up_test.go index c3c9d963d..64f030f72 100644 --- a/pkg/sentry/fs/copy_up_test.go +++ b/pkg/sentry/fs/copy_up_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index b347468ff..ef6d1a870 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index 3f4f2a40a..05a5005ad 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/device.go b/pkg/sentry/fs/dev/device.go index 9d935e008..3cecdf6e2 100644 --- a/pkg/sentry/fs/dev/device.go +++ b/pkg/sentry/fs/dev/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index 2ae49be4e..d96f4f423 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 492b8eb3a..eeda646ab 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 2977c8670..68090f353 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index 47b76218f..33e4913e4 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 27fea0019..2c01485a8 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index c680e4828..502b0a09b 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_cache_test.go b/pkg/sentry/fs/dirent_cache_test.go index 82b7f6bd5..5d0e9d91c 100644 --- a/pkg/sentry/fs/dirent_cache_test.go +++ b/pkg/sentry/fs/dirent_cache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go index f9dcba316..325404e27 100644 --- a/pkg/sentry/fs/dirent_refs_test.go +++ b/pkg/sentry/fs/dirent_refs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/dirent_state.go b/pkg/sentry/fs/dirent_state.go index 04ab197b9..5cf151dab 100644 --- a/pkg/sentry/fs/dirent_state.go +++ b/pkg/sentry/fs/dirent_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 2e34604e6..bfafff5ec 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go index 945cfaf08..92ab6ff0e 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go index 83f6c1986..69516e048 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_state.go b/pkg/sentry/fs/fdpipe/pipe_state.go index 99c40d8ed..4395666ad 100644 --- a/pkg/sentry/fs/fdpipe/pipe_state.go +++ b/pkg/sentry/fs/fdpipe/pipe_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go index 6cd314f5b..d3f15be6b 100644 --- a/pkg/sentry/fs/fdpipe/pipe_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 36794d378..d6752ed1b 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go index d223bb5c7..28e8e233d 100644 --- a/pkg/sentry/fs/file_operations.go +++ b/pkg/sentry/fs/file_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 41e646ee8..9b958b64b 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_overlay_test.go b/pkg/sentry/fs/file_overlay_test.go index 830458ff9..11e4f7203 100644 --- a/pkg/sentry/fs/file_overlay_test.go +++ b/pkg/sentry/fs/file_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_state.go b/pkg/sentry/fs/file_state.go index f848d1b79..1c3bae3e8 100644 --- a/pkg/sentry/fs/file_state.go +++ b/pkg/sentry/fs/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/file_test.go b/pkg/sentry/fs/file_test.go index 18aee7101..f3ed9a70b 100644 --- a/pkg/sentry/fs/file_test.go +++ b/pkg/sentry/fs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index 5a1e7a270..ba8be85e4 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go index 1831aa82f..65ca196d9 100644 --- a/pkg/sentry/fs/filetest/filetest.go +++ b/pkg/sentry/fs/filetest/filetest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index 1aa271560..bf2a20b33 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go index 6ec9ff446..b5c72990e 100644 --- a/pkg/sentry/fs/fs.go +++ b/pkg/sentry/fs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 8e31e48fd..5add16ac4 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/dirty_set_test.go b/pkg/sentry/fs/fsutil/dirty_set_test.go index f7693cb19..f5c9d9215 100644 --- a/pkg/sentry/fs/fsutil/dirty_set_test.go +++ b/pkg/sentry/fs/fsutil/dirty_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index d5881613b..46db2e51c 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/file_range_set.go b/pkg/sentry/fs/fsutil/file_range_set.go index da6949ccb..dd7ab4b4a 100644 --- a/pkg/sentry/fs/fsutil/file_range_set.go +++ b/pkg/sentry/fs/fsutil/file_range_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/frame_ref_set.go b/pkg/sentry/fs/fsutil/frame_ref_set.go index 14dece315..b6e783614 100644 --- a/pkg/sentry/fs/fsutil/frame_ref_set.go +++ b/pkg/sentry/fs/fsutil/frame_ref_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/fsutil.go b/pkg/sentry/fs/fsutil/fsutil.go index 6fe4ef13d..3d7f3732d 100644 --- a/pkg/sentry/fs/fsutil/fsutil.go +++ b/pkg/sentry/fs/fsutil/fsutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/handle.go b/pkg/sentry/fs/fsutil/handle.go index e7efd3c0f..8920b72ee 100644 --- a/pkg/sentry/fs/fsutil/handle.go +++ b/pkg/sentry/fs/fsutil/handle.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/handle_test.go b/pkg/sentry/fs/fsutil/handle_test.go index d94c3eb0d..43e1a3bdf 100644 --- a/pkg/sentry/fs/fsutil/handle_test.go +++ b/pkg/sentry/fs/fsutil/handle_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index 9c1e2f76f..9599665f0 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_state.go b/pkg/sentry/fs/fsutil/host_file_mapper_state.go index 57705decd..bbd15b30b 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_state.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go index 790f3a5a6..86df76822 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index 3acc32752..d4db1c2de 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index 6777c8bf7..b0af44ddd 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go index 996c91849..e388ec3d7 100644 --- a/pkg/sentry/fs/fsutil/inode_cached_test.go +++ b/pkg/sentry/fs/fsutil/inode_cached_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/attr.go b/pkg/sentry/fs/gofer/attr.go index 5e24767f9..98700d014 100644 --- a/pkg/sentry/fs/gofer/attr.go +++ b/pkg/sentry/fs/gofer/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/cache_policy.go b/pkg/sentry/fs/gofer/cache_policy.go index 98f43c578..3d380f0e8 100644 --- a/pkg/sentry/fs/gofer/cache_policy.go +++ b/pkg/sentry/fs/gofer/cache_policy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/context_file.go b/pkg/sentry/fs/gofer/context_file.go index d4b6f6eb7..a0265c2aa 100644 --- a/pkg/sentry/fs/gofer/context_file.go +++ b/pkg/sentry/fs/gofer/context_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/device.go b/pkg/sentry/fs/gofer/device.go index fac7306d4..52c5acf48 100644 --- a/pkg/sentry/fs/gofer/device.go +++ b/pkg/sentry/fs/gofer/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index c4a210656..6d961813d 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go index 715af8f16..dd4f817bf 100644 --- a/pkg/sentry/fs/gofer/file_state.go +++ b/pkg/sentry/fs/gofer/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index 3ae93f059..ed30cb1f1 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/gofer_test.go b/pkg/sentry/fs/gofer/gofer_test.go index c8d7bd773..3190d1e18 100644 --- a/pkg/sentry/fs/gofer/gofer_test.go +++ b/pkg/sentry/fs/gofer/gofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/handles.go b/pkg/sentry/fs/gofer/handles.go index a3e52aad6..f32e99ce0 100644 --- a/pkg/sentry/fs/gofer/handles.go +++ b/pkg/sentry/fs/gofer/handles.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 7fc8f77b0..5811b8b12 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go index ad11034f9..ad4d3df58 100644 --- a/pkg/sentry/fs/gofer/inode_state.go +++ b/pkg/sentry/fs/gofer/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/path.go b/pkg/sentry/fs/gofer/path.go index 0bf7881da..a324dc990 100644 --- a/pkg/sentry/fs/gofer/path.go +++ b/pkg/sentry/fs/gofer/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index 4e2293398..7552216f3 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/session_state.go b/pkg/sentry/fs/gofer/session_state.go index 8e6424492..f657135fc 100644 --- a/pkg/sentry/fs/gofer/session_state.go +++ b/pkg/sentry/fs/gofer/session_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/socket.go b/pkg/sentry/fs/gofer/socket.go index d072da624..76ce58810 100644 --- a/pkg/sentry/fs/gofer/socket.go +++ b/pkg/sentry/fs/gofer/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/gofer/util.go b/pkg/sentry/fs/gofer/util.go index d9ed8c81e..1a759370d 100644 --- a/pkg/sentry/fs/gofer/util.go +++ b/pkg/sentry/fs/gofer/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/control.go b/pkg/sentry/fs/host/control.go index d2e34a69d..0753640a2 100644 --- a/pkg/sentry/fs/host/control.go +++ b/pkg/sentry/fs/host/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 148291ba6..7c9d2b299 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/descriptor_state.go b/pkg/sentry/fs/host/descriptor_state.go index 7fb274451..530c0109f 100644 --- a/pkg/sentry/fs/host/descriptor_state.go +++ b/pkg/sentry/fs/host/descriptor_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/descriptor_test.go b/pkg/sentry/fs/host/descriptor_test.go index f393a8b54..6bc1bd2ae 100644 --- a/pkg/sentry/fs/host/descriptor_test.go +++ b/pkg/sentry/fs/host/descriptor_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/device.go b/pkg/sentry/fs/host/device.go index f2a0b6b15..b5adedf44 100644 --- a/pkg/sentry/fs/host/device.go +++ b/pkg/sentry/fs/host/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index 22a5d9f12..975084c86 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index e46ae433c..fec890964 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/fs_test.go b/pkg/sentry/fs/host/fs_test.go index b08125ca8..e69559aac 100644 --- a/pkg/sentry/fs/host/fs_test.go +++ b/pkg/sentry/fs/host/fs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index e32497203..08754bd6b 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/inode_state.go b/pkg/sentry/fs/host/inode_state.go index 8bc99d94b..b7c1a9581 100644 --- a/pkg/sentry/fs/host/inode_state.go +++ b/pkg/sentry/fs/host/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go index 0ff87c418..9f1561bd5 100644 --- a/pkg/sentry/fs/host/inode_test.go +++ b/pkg/sentry/fs/host/inode_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/ioctl_unsafe.go b/pkg/sentry/fs/host/ioctl_unsafe.go index bc965a1c2..175dca613 100644 --- a/pkg/sentry/fs/host/ioctl_unsafe.go +++ b/pkg/sentry/fs/host/ioctl_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index 0eb267c00..af53bf533 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_iovec.go b/pkg/sentry/fs/host/socket_iovec.go index 1a9587b90..d4ce4a8c1 100644 --- a/pkg/sentry/fs/host/socket_iovec.go +++ b/pkg/sentry/fs/host/socket_iovec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_state.go b/pkg/sentry/fs/host/socket_state.go index 7fa500bfb..2932c1f16 100644 --- a/pkg/sentry/fs/host/socket_state.go +++ b/pkg/sentry/fs/host/socket_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go index 483e99dd6..e9a88b124 100644 --- a/pkg/sentry/fs/host/socket_test.go +++ b/pkg/sentry/fs/host/socket_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/socket_unsafe.go b/pkg/sentry/fs/host/socket_unsafe.go index 5e4c5feed..f35e2492d 100644 --- a/pkg/sentry/fs/host/socket_unsafe.go +++ b/pkg/sentry/fs/host/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go index ad1323610..cf3639c46 100644 --- a/pkg/sentry/fs/host/tty.go +++ b/pkg/sentry/fs/host/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/util.go b/pkg/sentry/fs/host/util.go index 74c703eb7..40c450660 100644 --- a/pkg/sentry/fs/host/util.go +++ b/pkg/sentry/fs/host/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/util_unsafe.go b/pkg/sentry/fs/host/util_unsafe.go index 2ecb54319..d00da89d6 100644 --- a/pkg/sentry/fs/host/util_unsafe.go +++ b/pkg/sentry/fs/host/util_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go index c5f5c9c0d..9ca8c399f 100644 --- a/pkg/sentry/fs/host/wait_test.go +++ b/pkg/sentry/fs/host/wait_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index 409c81a97..95769ccf8 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index 683140afe..e213df924 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index 3ee3de10e..77973ce79 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index cf698a4da..78923fb5b 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go index 23e5635a4..bba20da14 100644 --- a/pkg/sentry/fs/inode_overlay_test.go +++ b/pkg/sentry/fs/inode_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 2aabdded8..f251df0d1 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index e9b5e0f56..9e3e9d816 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index 3e1959e83..b83544c9f 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 439e645db..5ff800d2d 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock_range_test.go b/pkg/sentry/fs/lock/lock_range_test.go index 06a37c701..b0ab882b9 100644 --- a/pkg/sentry/fs/lock/lock_range_test.go +++ b/pkg/sentry/fs/lock/lock_range_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock_set_functions.go b/pkg/sentry/fs/lock/lock_set_functions.go index e16f485be..395592a4b 100644 --- a/pkg/sentry/fs/lock/lock_set_functions.go +++ b/pkg/sentry/fs/lock/lock_set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/lock/lock_test.go b/pkg/sentry/fs/lock/lock_test.go index c60f5f7a2..67fa4b1dd 100644 --- a/pkg/sentry/fs/lock/lock_test.go +++ b/pkg/sentry/fs/lock/lock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go index 846b6e8bb..6bfcda6bb 100644 --- a/pkg/sentry/fs/mock.go +++ b/pkg/sentry/fs/mock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 8345876fc..24e28ddb2 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index dbc608c7e..fb91635bc 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount_state.go b/pkg/sentry/fs/mount_state.go index f5ed1dd8d..6344d5160 100644 --- a/pkg/sentry/fs/mount_state.go +++ b/pkg/sentry/fs/mount_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mount_test.go b/pkg/sentry/fs/mount_test.go index 968b435ab..a1c9f4f79 100644 --- a/pkg/sentry/fs/mount_test.go +++ b/pkg/sentry/fs/mount_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index c0a803b2d..7c5348cce 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/mounts_test.go b/pkg/sentry/fs/mounts_test.go index 8669f3a38..cc7c32c9b 100644 --- a/pkg/sentry/fs/mounts_test.go +++ b/pkg/sentry/fs/mounts_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/offset.go b/pkg/sentry/fs/offset.go index 7cc8398e6..38aee765a 100644 --- a/pkg/sentry/fs/offset.go +++ b/pkg/sentry/fs/offset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index 5a30af419..036c0f733 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/path.go b/pkg/sentry/fs/path.go index b74f6ed8c..91a9a8ffd 100644 --- a/pkg/sentry/fs/path.go +++ b/pkg/sentry/fs/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/path_test.go b/pkg/sentry/fs/path_test.go index 7ab070855..391b010a7 100644 --- a/pkg/sentry/fs/path_test.go +++ b/pkg/sentry/fs/path_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index 4dfec03a4..f8be06dc3 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/device/device.go b/pkg/sentry/fs/proc/device/device.go index 6194afe88..04b687bcf 100644 --- a/pkg/sentry/fs/proc/device/device.go +++ b/pkg/sentry/fs/proc/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index a69cbaa0e..b4896053f 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index dada8f982..5ebb33703 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/file.go b/pkg/sentry/fs/proc/file.go index 4b3448245..f659e590a 100644 --- a/pkg/sentry/fs/proc/file.go +++ b/pkg/sentry/fs/proc/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index 49b92fd8a..c050a00be 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 061824b8c..63f737ff4 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 6fac251d2..78f3a1dc0 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 53dfd59ef..b31258eed 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index 81dcc153a..0b0e87528 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index 8cd6fe9d3..45f2a1211 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/net_test.go b/pkg/sentry/fs/proc/net_test.go index a31a20494..94677cc1d 100644 --- a/pkg/sentry/fs/proc/net_test.go +++ b/pkg/sentry/fs/proc/net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index 07029a7bb..33030bebf 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/rpcinet_proc.go b/pkg/sentry/fs/proc/rpcinet_proc.go index 50d0271f9..d025069df 100644 --- a/pkg/sentry/fs/proc/rpcinet_proc.go +++ b/pkg/sentry/fs/proc/rpcinet_proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 51cae5e37..0499ba65b 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go index d90e3e736..f9a2ca38e 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index bf7650211..f2bbef375 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index 384b4ffe1..54562508d 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index beb25be20..801eb6a1e 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go index 7ba392346..0ce9d30f1 100644 --- a/pkg/sentry/fs/proc/sys_net_test.go +++ b/pkg/sentry/fs/proc/sys_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 748ca4320..404faea0a 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index a7e4cf0a6..f70399686 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index f3a9b81df..80c7ce0b4 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index 00f6a2afd..b6d49d5e9 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 075e13b01..0a911b155 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/file.go b/pkg/sentry/fs/ramfs/file.go index 0b94d92a1..b7fc98ffc 100644 --- a/pkg/sentry/fs/ramfs/file.go +++ b/pkg/sentry/fs/ramfs/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/ramfs.go b/pkg/sentry/fs/ramfs/ramfs.go index 83cbcab23..d77688a34 100644 --- a/pkg/sentry/fs/ramfs/ramfs.go +++ b/pkg/sentry/fs/ramfs/ramfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 9ac00eb18..8c81478c8 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 1c54d9991..a21fac2c7 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/test/test.go b/pkg/sentry/fs/ramfs/test/test.go index fb669558f..11bff7729 100644 --- a/pkg/sentry/fs/ramfs/test/test.go +++ b/pkg/sentry/fs/ramfs/test/test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/tree.go b/pkg/sentry/fs/ramfs/tree.go index 1fb335f74..29a70f698 100644 --- a/pkg/sentry/fs/ramfs/tree.go +++ b/pkg/sentry/fs/ramfs/tree.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/ramfs/tree_test.go b/pkg/sentry/fs/ramfs/tree_test.go index 68e2929d5..d5567d9e1 100644 --- a/pkg/sentry/fs/ramfs/tree_test.go +++ b/pkg/sentry/fs/ramfs/tree_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/restore.go b/pkg/sentry/fs/restore.go index b4ac85a27..da2df7e1d 100644 --- a/pkg/sentry/fs/restore.go +++ b/pkg/sentry/fs/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/save.go b/pkg/sentry/fs/save.go index bf2a85143..90988d385 100644 --- a/pkg/sentry/fs/save.go +++ b/pkg/sentry/fs/save.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/seek.go b/pkg/sentry/fs/seek.go index 1268726c2..72f3fb632 100644 --- a/pkg/sentry/fs/seek.go +++ b/pkg/sentry/fs/seek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sync.go b/pkg/sentry/fs/sync.go index 9738a8f22..6dcc2fe8d 100644 --- a/pkg/sentry/fs/sync.go +++ b/pkg/sentry/fs/sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/device.go b/pkg/sentry/fs/sys/device.go index 54e414d1b..38ecd0c18 100644 --- a/pkg/sentry/fs/sys/device.go +++ b/pkg/sentry/fs/sys/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go index 2cf3a6f98..e64aa0edc 100644 --- a/pkg/sentry/fs/sys/devices.go +++ b/pkg/sentry/fs/sys/devices.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index 625525540..5ce33f87f 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index 7b9697668..7cc1942c7 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index 767db95a0..7423e816c 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/device.go b/pkg/sentry/fs/tmpfs/device.go index e588b3440..aade93c26 100644 --- a/pkg/sentry/fs/tmpfs/device.go +++ b/pkg/sentry/fs/tmpfs/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 342688f81..1f9d69909 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/file_test.go b/pkg/sentry/fs/tmpfs/file_test.go index f064eb1ac..b5830d3df 100644 --- a/pkg/sentry/fs/tmpfs/file_test.go +++ b/pkg/sentry/fs/tmpfs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index ca620e65e..7c91e248b 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 1e4fe47d2..42a7d7b9c 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 38be6db46..91b782540 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 7c0c0b0c1..e32b05c1d 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index d9f8f02f3..0c412eb21 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/inode.go b/pkg/sentry/fs/tty/inode.go index c0fa2b407..d5d1caafc 100644 --- a/pkg/sentry/fs/tty/inode.go +++ b/pkg/sentry/fs/tty/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index 31804571e..484366f85 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index ae7540eff..dad0cad79 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 01dc8d1ac..a09ca0119 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 4a0d4fdb9..9de3168bf 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index 3cb135124..79f9d76d7 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/fs/tty/tty_test.go b/pkg/sentry/fs/tty/tty_test.go index 32e1b1556..ad535838f 100644 --- a/pkg/sentry/fs/tty/tty_test.go +++ b/pkg/sentry/fs/tty/tty_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/hostcpu/getcpu_amd64.s b/pkg/sentry/hostcpu/getcpu_amd64.s index 7f6247d81..409db1450 100644 --- a/pkg/sentry/hostcpu/getcpu_amd64.s +++ b/pkg/sentry/hostcpu/getcpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/hostcpu/hostcpu.go b/pkg/sentry/hostcpu/hostcpu.go index fa46499ad..3adc847bb 100644 --- a/pkg/sentry/hostcpu/hostcpu.go +++ b/pkg/sentry/hostcpu/hostcpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/hostcpu/hostcpu_test.go b/pkg/sentry/hostcpu/hostcpu_test.go index a82e1a271..38de0e1f6 100644 --- a/pkg/sentry/hostcpu/hostcpu_test.go +++ b/pkg/sentry/hostcpu/hostcpu_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/inet/context.go b/pkg/sentry/inet/context.go index 370381f41..d05e96f15 100644 --- a/pkg/sentry/inet/context.go +++ b/pkg/sentry/inet/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index 30ca4e0c0..8206377cc 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/inet/test_stack.go b/pkg/sentry/inet/test_stack.go index bc10926ee..05c1a1792 100644 --- a/pkg/sentry/inet/test_stack.go +++ b/pkg/sentry/inet/test_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 45088c988..1ea2cee36 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/auth.go b/pkg/sentry/kernel/auth/auth.go index c49a6b852..19f15fd36 100644 --- a/pkg/sentry/kernel/auth/auth.go +++ b/pkg/sentry/kernel/auth/auth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/capability_set.go b/pkg/sentry/kernel/auth/capability_set.go index 5b8164c49..88d6243aa 100644 --- a/pkg/sentry/kernel/auth/capability_set.go +++ b/pkg/sentry/kernel/auth/capability_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/context.go b/pkg/sentry/kernel/auth/context.go index 914589b28..f7e945599 100644 --- a/pkg/sentry/kernel/auth/context.go +++ b/pkg/sentry/kernel/auth/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index f18f7dac9..de33f1953 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/id.go b/pkg/sentry/kernel/auth/id.go index 37522b018..e5bed44d7 100644 --- a/pkg/sentry/kernel/auth/id.go +++ b/pkg/sentry/kernel/auth/id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index bd0090e0f..43f439825 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/id_map_functions.go b/pkg/sentry/kernel/auth/id_map_functions.go index 889291d96..8f1a189ec 100644 --- a/pkg/sentry/kernel/auth/id_map_functions.go +++ b/pkg/sentry/kernel/auth/id_map_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index d359f3f31..5bb9c44c0 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/context.go b/pkg/sentry/kernel/context.go index 261ca6f7a..b629521eb 100644 --- a/pkg/sentry/kernel/context.go +++ b/pkg/sentry/kernel/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index a8eb114c0..9c13ecfcc 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/epoll/epoll_state.go b/pkg/sentry/kernel/epoll/epoll_state.go index dabb32f49..7f3e2004a 100644 --- a/pkg/sentry/kernel/epoll/epoll_state.go +++ b/pkg/sentry/kernel/epoll/epoll_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/epoll/epoll_test.go b/pkg/sentry/kernel/epoll/epoll_test.go index bc869fc13..d89c1b745 100644 --- a/pkg/sentry/kernel/epoll/epoll_test.go +++ b/pkg/sentry/kernel/epoll/epoll_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index a4ada0e78..26dc59a85 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/eventfd/eventfd_test.go b/pkg/sentry/kernel/eventfd/eventfd_test.go index 71326b62f..14e8996d9 100644 --- a/pkg/sentry/kernel/eventfd/eventfd_test.go +++ b/pkg/sentry/kernel/eventfd/eventfd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go index f77339cae..aa4aac109 100644 --- a/pkg/sentry/kernel/fasync/fasync.go +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index cad0b0a20..715f4714d 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fd_map_test.go b/pkg/sentry/kernel/fd_map_test.go index 95123aef3..b49996137 100644 --- a/pkg/sentry/kernel/fd_map_test.go +++ b/pkg/sentry/kernel/fd_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index f3f05e8f5..3cf0db280 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 54b1982a0..ea69d433b 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/futex/futex_test.go b/pkg/sentry/kernel/futex/futex_test.go index 726c26990..ea506a29b 100644 --- a/pkg/sentry/kernel/futex/futex_test.go +++ b/pkg/sentry/kernel/futex/futex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 5eef49f59..9ceb9bd92 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/kdefs/kdefs.go b/pkg/sentry/kernel/kdefs/kdefs.go index bbb476544..8eafe810b 100644 --- a/pkg/sentry/kernel/kdefs/kdefs.go +++ b/pkg/sentry/kernel/kdefs/kdefs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 5d6856f3c..bad558d48 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go index bb2d5102d..a0a69b498 100644 --- a/pkg/sentry/kernel/kernel_state.go +++ b/pkg/sentry/kernel/kernel_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/memevent/memory_events.go b/pkg/sentry/kernel/memevent/memory_events.go index f7a183a1d..f05ef1b64 100644 --- a/pkg/sentry/kernel/memevent/memory_events.go +++ b/pkg/sentry/kernel/memevent/memory_events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/memevent/memory_events.proto b/pkg/sentry/kernel/memevent/memory_events.proto index abc565054..43b8deb76 100644 --- a/pkg/sentry/kernel/memevent/memory_events.proto +++ b/pkg/sentry/kernel/memevent/memory_events.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index bb5db0309..373e11772 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pending_signals_state.go b/pkg/sentry/kernel/pending_signals_state.go index 6d90ed033..72be6702f 100644 --- a/pkg/sentry/kernel/pending_signals_state.go +++ b/pkg/sentry/kernel/pending_signals_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index a82e45c3f..fa8045910 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/device.go b/pkg/sentry/kernel/pipe/device.go index 8d383577a..eec5c5de8 100644 --- a/pkg/sentry/kernel/pipe/device.go +++ b/pkg/sentry/kernel/pipe/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 23d692da1..4b0e00b85 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/node_test.go b/pkg/sentry/kernel/pipe/node_test.go index cc1ebf4f6..eda551594 100644 --- a/pkg/sentry/kernel/pipe/node_test.go +++ b/pkg/sentry/kernel/pipe/node_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index ced2559a7..126054826 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/pipe_test.go b/pkg/sentry/kernel/pipe/pipe_test.go index 49ef8c8ac..3b9895927 100644 --- a/pkg/sentry/kernel/pipe/pipe_test.go +++ b/pkg/sentry/kernel/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 1fa5e9a32..f27379969 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 82607367b..63efc5bbe 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index d93324b53..6fea9769c 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/posixtimer.go b/pkg/sentry/kernel/posixtimer.go index 0ab958529..40b5acca3 100644 --- a/pkg/sentry/kernel/posixtimer.go +++ b/pkg/sentry/kernel/posixtimer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 9fe28f435..20bac2b70 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 1f3de58e3..46b03c700 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sched/cpuset.go b/pkg/sentry/kernel/sched/cpuset.go index 0a97603f0..69aee9127 100644 --- a/pkg/sentry/kernel/sched/cpuset.go +++ b/pkg/sentry/kernel/sched/cpuset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sched/cpuset_test.go b/pkg/sentry/kernel/sched/cpuset_test.go index 8a6e12958..a036ed513 100644 --- a/pkg/sentry/kernel/sched/cpuset_test.go +++ b/pkg/sentry/kernel/sched/cpuset_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sched/sched.go b/pkg/sentry/kernel/sched/sched.go index f1de1da60..e59909baf 100644 --- a/pkg/sentry/kernel/sched/sched.go +++ b/pkg/sentry/kernel/sched/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index d77c05e2f..37dd3e4c9 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index aa07946cf..232a276dc 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go index f9eb382e9..5f886bf31 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_test.go +++ b/pkg/sentry/kernel/semaphore/semaphore_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index a9b4e7647..78a5b4063 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/shm/device.go b/pkg/sentry/kernel/shm/device.go index b0dacdbe0..bbc653ed8 100644 --- a/pkg/sentry/kernel/shm/device.go +++ b/pkg/sentry/kernel/shm/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 77973951e..8d0d14e45 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/signal.go b/pkg/sentry/kernel/signal.go index e3a2a777a..b066df132 100644 --- a/pkg/sentry/kernel/signal.go +++ b/pkg/sentry/kernel/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 3649f5e4d..3f1ac9898 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 4c7811b6c..19b711e9c 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/syscalls_state.go b/pkg/sentry/kernel/syscalls_state.go index 826809a70..981455d46 100644 --- a/pkg/sentry/kernel/syscalls_state.go +++ b/pkg/sentry/kernel/syscalls_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 6531bd5d2..2aecf3eea 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/table_test.go b/pkg/sentry/kernel/table_test.go index 71ca75555..3b29d3c6a 100644 --- a/pkg/sentry/kernel/table_test.go +++ b/pkg/sentry/kernel/table_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index 4f0b7fe3f..e22ec768d 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_acct.go b/pkg/sentry/kernel/task_acct.go index d2052921e..24230af89 100644 --- a/pkg/sentry/kernel/task_acct.go +++ b/pkg/sentry/kernel/task_acct.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_block.go b/pkg/sentry/kernel/task_block.go index 6dc7b938e..e5027e551 100644 --- a/pkg/sentry/kernel/task_block.go +++ b/pkg/sentry/kernel/task_block.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index de3aef40d..755fe0370 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index d2df7e9d1..45b8d2b04 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 1b760aba4..a9b74da8e 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index 65969ca9b..44fbb487c 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_futex.go b/pkg/sentry/kernel/task_futex.go index 62ebbcb0d..5a11ca3df 100644 --- a/pkg/sentry/kernel/task_futex.go +++ b/pkg/sentry/kernel/task_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_identity.go b/pkg/sentry/kernel/task_identity.go index b0921b2eb..8f90ed786 100644 --- a/pkg/sentry/kernel/task_identity.go +++ b/pkg/sentry/kernel/task_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_log.go b/pkg/sentry/kernel/task_log.go index 1769da210..f4c881c2d 100644 --- a/pkg/sentry/kernel/task_log.go +++ b/pkg/sentry/kernel/task_log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_net.go b/pkg/sentry/kernel/task_net.go index 4df2e53d3..fc7cefc1f 100644 --- a/pkg/sentry/kernel/task_net.go +++ b/pkg/sentry/kernel/task_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 49ac933b7..596b9aa16 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index 19dcc963a..3b3cdc24a 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index e2925a708..fe24f7542 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go index 6c8d7d316..c82a32c78 100644 --- a/pkg/sentry/kernel/task_start.go +++ b/pkg/sentry/kernel/task_start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_stop.go b/pkg/sentry/kernel/task_stop.go index feaf6cae4..36846484c 100644 --- a/pkg/sentry/kernel/task_stop.go +++ b/pkg/sentry/kernel/task_stop.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index f0373c375..0318adb35 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_test.go b/pkg/sentry/kernel/task_test.go index 82ef858a1..3f37f505d 100644 --- a/pkg/sentry/kernel/task_test.go +++ b/pkg/sentry/kernel/task_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/task_usermem.go b/pkg/sentry/kernel/task_usermem.go index 2b4954869..c8e973bd5 100644 --- a/pkg/sentry/kernel/task_usermem.go +++ b/pkg/sentry/kernel/task_usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index dfff7b52d..d7652f57c 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 4e3d19e97..bdb907905 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/time/context.go b/pkg/sentry/kernel/time/context.go index ac4dc01d8..3675ea20d 100644 --- a/pkg/sentry/kernel/time/context.go +++ b/pkg/sentry/kernel/time/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index 52e0dfba1..ca0f4ba2e 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index 2167f3efe..6bff80f13 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/timekeeper_state.go b/pkg/sentry/kernel/timekeeper_state.go index 2e7fed4d8..f3a3ed543 100644 --- a/pkg/sentry/kernel/timekeeper_state.go +++ b/pkg/sentry/kernel/timekeeper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go index 34a5cec27..71674c21c 100644 --- a/pkg/sentry/kernel/timekeeper_test.go +++ b/pkg/sentry/kernel/timekeeper_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index 7e0fe0d21..ed5f0c031 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 971e8bc59..0ec858a4a 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/kernel/version.go b/pkg/sentry/kernel/version.go index a9e84673f..72bb0f93c 100644 --- a/pkg/sentry/kernel/version.go +++ b/pkg/sentry/kernel/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/context.go b/pkg/sentry/limits/context.go index 75e97bf92..bf413eb7d 100644 --- a/pkg/sentry/limits/context.go +++ b/pkg/sentry/limits/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index 02c8b60e3..ba0b7d4fd 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/limits_test.go b/pkg/sentry/limits/limits_test.go index dd6f80750..d41f62554 100644 --- a/pkg/sentry/limits/limits_test.go +++ b/pkg/sentry/limits/limits_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/limits/linux.go b/pkg/sentry/limits/linux.go index 8e6a24341..511db6733 100644 --- a/pkg/sentry/limits/linux.go +++ b/pkg/sentry/limits/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/elf.go b/pkg/sentry/loader/elf.go index 849be5a3d..9b1e81dc9 100644 --- a/pkg/sentry/loader/elf.go +++ b/pkg/sentry/loader/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/interpreter.go b/pkg/sentry/loader/interpreter.go index 54534952b..06a3c7156 100644 --- a/pkg/sentry/loader/interpreter.go +++ b/pkg/sentry/loader/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index 62b39e52b..d1417c4f1 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index a06e27ac9..437cc5da1 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index dc71e1c2d..b327f0e1e 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index c9483905d..33cf16f91 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memmap/mapping_set_test.go b/pkg/sentry/memmap/mapping_set_test.go index 10668d404..49ee34548 100644 --- a/pkg/sentry/memmap/mapping_set_test.go +++ b/pkg/sentry/memmap/mapping_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index cdc5f2b27..05349a77f 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memutil/memutil.go b/pkg/sentry/memutil/memutil.go index 4f245cf3c..286d50ca4 100644 --- a/pkg/sentry/memutil/memutil.go +++ b/pkg/sentry/memutil/memutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/memutil/memutil_unsafe.go b/pkg/sentry/memutil/memutil_unsafe.go index 32c27eb2f..8d9fc64fb 100644 --- a/pkg/sentry/memutil/memutil_unsafe.go +++ b/pkg/sentry/memutil/memutil_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index 27554f163..7488f7c4a 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index b42156d45..87942af0e 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/aio_context_state.go b/pkg/sentry/mm/aio_context_state.go index 1a5e56f8e..192a6f744 100644 --- a/pkg/sentry/mm/aio_context_state.go +++ b/pkg/sentry/mm/aio_context_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/debug.go b/pkg/sentry/mm/debug.go index 56d0490f0..d341b9c07 100644 --- a/pkg/sentry/mm/debug.go +++ b/pkg/sentry/mm/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/io.go b/pkg/sentry/mm/io.go index 6741db594..6600ddd78 100644 --- a/pkg/sentry/mm/io.go +++ b/pkg/sentry/mm/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index a4b5cb443..b248b76e7 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/metadata.go b/pkg/sentry/mm/metadata.go index 32d5e2ff6..5ef1ba0b1 100644 --- a/pkg/sentry/mm/metadata.go +++ b/pkg/sentry/mm/metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index 3299ae164..aab697f9e 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/mm_test.go b/pkg/sentry/mm/mm_test.go index b47aa7263..f2db43196 100644 --- a/pkg/sentry/mm/mm_test.go +++ b/pkg/sentry/mm/mm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/pma.go b/pkg/sentry/mm/pma.go index 9febb25ac..5690fe6b4 100644 --- a/pkg/sentry/mm/pma.go +++ b/pkg/sentry/mm/pma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/proc_pid_maps.go b/pkg/sentry/mm/proc_pid_maps.go index 5840b257c..0bf1cdb51 100644 --- a/pkg/sentry/mm/proc_pid_maps.go +++ b/pkg/sentry/mm/proc_pid_maps.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/save_restore.go b/pkg/sentry/mm/save_restore.go index 36fed8f1c..6e7080a84 100644 --- a/pkg/sentry/mm/save_restore.go +++ b/pkg/sentry/mm/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/shm.go b/pkg/sentry/mm/shm.go index bab137a5a..3bc48c7e7 100644 --- a/pkg/sentry/mm/shm.go +++ b/pkg/sentry/mm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index 5d7bd33bd..e511472f4 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index b0622b0c3..a721cc456 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index b81e861f1..dafdbd0e4 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/context.go b/pkg/sentry/platform/context.go index 0d200a5e2..cca21a23e 100644 --- a/pkg/sentry/platform/context.go +++ b/pkg/sentry/platform/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem.go b/pkg/sentry/platform/filemem/filemem.go index f278c8d63..97da31e70 100644 --- a/pkg/sentry/platform/filemem/filemem.go +++ b/pkg/sentry/platform/filemem/filemem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem_state.go b/pkg/sentry/platform/filemem/filemem_state.go index e28e021c9..964e2aaaa 100644 --- a/pkg/sentry/platform/filemem/filemem_state.go +++ b/pkg/sentry/platform/filemem/filemem_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem_test.go b/pkg/sentry/platform/filemem/filemem_test.go index 4b165dc48..9becec25f 100644 --- a/pkg/sentry/platform/filemem/filemem_test.go +++ b/pkg/sentry/platform/filemem/filemem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/filemem/filemem_unsafe.go b/pkg/sentry/platform/filemem/filemem_unsafe.go index a23b9825a..776aed74d 100644 --- a/pkg/sentry/platform/filemem/filemem_unsafe.go +++ b/pkg/sentry/platform/filemem/filemem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/interrupt/interrupt.go b/pkg/sentry/platform/interrupt/interrupt.go index ca4f42087..9c83f41eb 100644 --- a/pkg/sentry/platform/interrupt/interrupt.go +++ b/pkg/sentry/platform/interrupt/interrupt.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/interrupt/interrupt_test.go b/pkg/sentry/platform/interrupt/interrupt_test.go index 7c49eeea6..fb3284395 100644 --- a/pkg/sentry/platform/interrupt/interrupt_test.go +++ b/pkg/sentry/platform/interrupt/interrupt_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/address_space.go b/pkg/sentry/platform/kvm/address_space.go index c4293c517..72e897a9a 100644 --- a/pkg/sentry/platform/kvm/address_space.go +++ b/pkg/sentry/platform/kvm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/allocator.go b/pkg/sentry/platform/kvm/allocator.go index f5cebd5b3..b25cad155 100644 --- a/pkg/sentry/platform/kvm/allocator.go +++ b/pkg/sentry/platform/kvm/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill.go b/pkg/sentry/platform/kvm/bluepill.go index ecc33d7dd..9f1c9510b 100644 --- a/pkg/sentry/platform/kvm/bluepill.go +++ b/pkg/sentry/platform/kvm/bluepill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.go b/pkg/sentry/platform/kvm/bluepill_amd64.go index b364e3ef7..f013d1dc9 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.s b/pkg/sentry/platform/kvm/bluepill_amd64.s index 0881bd5f5..ec017f6c2 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.s +++ b/pkg/sentry/platform/kvm/bluepill_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go index 61ca61dcb..cd00a47f2 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_fault.go b/pkg/sentry/platform/kvm/bluepill_fault.go index 8650cd78f..e79a30ef2 100644 --- a/pkg/sentry/platform/kvm/bluepill_fault.go +++ b/pkg/sentry/platform/kvm/bluepill_fault.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/bluepill_unsafe.go b/pkg/sentry/platform/kvm/bluepill_unsafe.go index 216d4b4b6..747a95997 100644 --- a/pkg/sentry/platform/kvm/bluepill_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/context.go b/pkg/sentry/platform/kvm/context.go index aac84febf..be902be88 100644 --- a/pkg/sentry/platform/kvm/context.go +++ b/pkg/sentry/platform/kvm/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/host_map.go b/pkg/sentry/platform/kvm/host_map.go index fc16ad2de..ee6a1a42d 100644 --- a/pkg/sentry/platform/kvm/host_map.go +++ b/pkg/sentry/platform/kvm/host_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm.go b/pkg/sentry/platform/kvm/kvm.go index 0c4dff308..d4f50024d 100644 --- a/pkg/sentry/platform/kvm/kvm.go +++ b/pkg/sentry/platform/kvm/kvm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_amd64.go b/pkg/sentry/platform/kvm/kvm_amd64.go index 3d56ed895..70d0ac63b 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64.go +++ b/pkg/sentry/platform/kvm/kvm_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go index 476e783a0..c0a0af92d 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_const.go b/pkg/sentry/platform/kvm/kvm_const.go index ca44c31b3..8c53c6f06 100644 --- a/pkg/sentry/platform/kvm/kvm_const.go +++ b/pkg/sentry/platform/kvm/kvm_const.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/kvm_test.go b/pkg/sentry/platform/kvm/kvm_test.go index 52448839f..45eeb96ff 100644 --- a/pkg/sentry/platform/kvm/kvm_test.go +++ b/pkg/sentry/platform/kvm/kvm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 9f60b6b31..fc7ad258f 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index bcd29a947..e0aec42b8 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go index 8b9041f13..50e513f3b 100644 --- a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/machine_unsafe.go b/pkg/sentry/platform/kvm/machine_unsafe.go index 86323c891..4f5b01321 100644 --- a/pkg/sentry/platform/kvm/machine_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/physical_map.go b/pkg/sentry/platform/kvm/physical_map.go index 81a98656d..b908cae6a 100644 --- a/pkg/sentry/platform/kvm/physical_map.go +++ b/pkg/sentry/platform/kvm/physical_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/testutil/testutil.go b/pkg/sentry/platform/kvm/testutil/testutil.go index 8a614e25d..0d496561d 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil.go +++ b/pkg/sentry/platform/kvm/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go index 39286a0af..fcba33813 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s index 3b5ad8817..f1da41a44 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/virtual_map.go b/pkg/sentry/platform/kvm/virtual_map.go index 0d3fbe043..0343e9267 100644 --- a/pkg/sentry/platform/kvm/virtual_map.go +++ b/pkg/sentry/platform/kvm/virtual_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/kvm/virtual_map_test.go b/pkg/sentry/platform/kvm/virtual_map_test.go index 7875bd3e9..935e0eb93 100644 --- a/pkg/sentry/platform/kvm/virtual_map_test.go +++ b/pkg/sentry/platform/kvm/virtual_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/mmap_min_addr.go b/pkg/sentry/platform/mmap_min_addr.go index 6398e5e01..1bcc1f8e9 100644 --- a/pkg/sentry/platform/mmap_min_addr.go +++ b/pkg/sentry/platform/mmap_min_addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index 8a1620d93..f16588e6e 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid.go b/pkg/sentry/platform/procid/procid.go index 5f861908f..3f49ab093 100644 --- a/pkg/sentry/platform/procid/procid.go +++ b/pkg/sentry/platform/procid/procid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid_amd64.s b/pkg/sentry/platform/procid/procid_amd64.s index 5b1ba1f24..fd88ce82e 100644 --- a/pkg/sentry/platform/procid/procid_amd64.s +++ b/pkg/sentry/platform/procid/procid_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid_net_test.go b/pkg/sentry/platform/procid/procid_net_test.go index 2d1605a08..e8dcc479d 100644 --- a/pkg/sentry/platform/procid/procid_net_test.go +++ b/pkg/sentry/platform/procid/procid_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/procid/procid_test.go b/pkg/sentry/platform/procid/procid_test.go index 5e44da36f..7a57c7cdc 100644 --- a/pkg/sentry/platform/procid/procid_test.go +++ b/pkg/sentry/platform/procid/procid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go index 4f20716f7..00d92b092 100644 --- a/pkg/sentry/platform/ptrace/ptrace.go +++ b/pkg/sentry/platform/ptrace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/ptrace_unsafe.go b/pkg/sentry/platform/ptrace/ptrace_unsafe.go index 46a8bda8e..7a3cb8f49 100644 --- a/pkg/sentry/platform/ptrace/ptrace_unsafe.go +++ b/pkg/sentry/platform/ptrace/ptrace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/stub_amd64.s b/pkg/sentry/platform/ptrace/stub_amd64.s index 9bf87b6f6..63f98e40d 100644 --- a/pkg/sentry/platform/ptrace/stub_amd64.s +++ b/pkg/sentry/platform/ptrace/stub_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/stub_unsafe.go b/pkg/sentry/platform/ptrace/stub_unsafe.go index c868a2d68..48c16c4a1 100644 --- a/pkg/sentry/platform/ptrace/stub_unsafe.go +++ b/pkg/sentry/platform/ptrace/stub_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go index 6d5ad6b71..6a9da5db8 100644 --- a/pkg/sentry/platform/ptrace/subprocess.go +++ b/pkg/sentry/platform/ptrace/subprocess.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_amd64.go b/pkg/sentry/platform/ptrace/subprocess_amd64.go index c38dc1ff8..d23a1133e 100644 --- a/pkg/sentry/platform/ptrace/subprocess_amd64.go +++ b/pkg/sentry/platform/ptrace/subprocess_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index 53adadadd..7523487e7 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go index 697431472..0c9263060 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ptrace/subprocess_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_unsafe.go index fe41641d3..ca6c4ac97 100644 --- a/pkg/sentry/platform/ptrace/subprocess_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/defs.go b/pkg/sentry/platform/ring0/defs.go index f09d045eb..18137e55d 100644 --- a/pkg/sentry/platform/ring0/defs.go +++ b/pkg/sentry/platform/ring0/defs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/defs_amd64.go b/pkg/sentry/platform/ring0/defs_amd64.go index 84819f132..67242b92b 100644 --- a/pkg/sentry/platform/ring0/defs_amd64.go +++ b/pkg/sentry/platform/ring0/defs_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/entry_amd64.go b/pkg/sentry/platform/ring0/entry_amd64.go index a3e992e0d..4a9affe64 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.go +++ b/pkg/sentry/platform/ring0/entry_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/entry_amd64.s b/pkg/sentry/platform/ring0/entry_amd64.s index 08c15ad65..d48fbd2d1 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.s +++ b/pkg/sentry/platform/ring0/entry_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/gen_offsets/main.go b/pkg/sentry/platform/ring0/gen_offsets/main.go index ffa7eaf77..11c49855f 100644 --- a/pkg/sentry/platform/ring0/gen_offsets/main.go +++ b/pkg/sentry/platform/ring0/gen_offsets/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/kernel.go b/pkg/sentry/platform/ring0/kernel.go index 62e67005e..e70eafde2 100644 --- a/pkg/sentry/platform/ring0/kernel.go +++ b/pkg/sentry/platform/ring0/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/kernel_amd64.go b/pkg/sentry/platform/ring0/kernel_amd64.go index 0d2b0f7dc..ab562bca7 100644 --- a/pkg/sentry/platform/ring0/kernel_amd64.go +++ b/pkg/sentry/platform/ring0/kernel_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/kernel_unsafe.go b/pkg/sentry/platform/ring0/kernel_unsafe.go index cfb3ad853..faf4240e5 100644 --- a/pkg/sentry/platform/ring0/kernel_unsafe.go +++ b/pkg/sentry/platform/ring0/kernel_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/lib_amd64.go b/pkg/sentry/platform/ring0/lib_amd64.go index 989e3e383..2b95a0141 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.go +++ b/pkg/sentry/platform/ring0/lib_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/lib_amd64.s b/pkg/sentry/platform/ring0/lib_amd64.s index 6f143ea5a..98a130525 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.s +++ b/pkg/sentry/platform/ring0/lib_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/offsets_amd64.go b/pkg/sentry/platform/ring0/offsets_amd64.go index ca5fd456b..753d31ef8 100644 --- a/pkg/sentry/platform/ring0/offsets_amd64.go +++ b/pkg/sentry/platform/ring0/offsets_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator.go b/pkg/sentry/platform/ring0/pagetables/allocator.go index 049fd0247..ee6e90a11 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go index aca778913..f48647b3a 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables.go b/pkg/sentry/platform/ring0/pagetables/pagetables.go index ff5787f89..c7207ec18 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go index 878463018..746f614e5 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go index a7f2ad9a4..2f82c4353 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go index dca3f69ef..3e5dc7dc7 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go index ca49d20f8..6bd8c3584 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go index fa068e35e..0d9a51aa5 100644 --- a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go index afa4d473a..c4c71d23e 100644 --- a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/ring0.go b/pkg/sentry/platform/ring0/ring0.go index 4991031c5..10c51e88d 100644 --- a/pkg/sentry/platform/ring0/ring0.go +++ b/pkg/sentry/platform/ring0/ring0.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/ring0/x86.go b/pkg/sentry/platform/ring0/x86.go index f489fcecb..7c88010d8 100644 --- a/pkg/sentry/platform/ring0/x86.go +++ b/pkg/sentry/platform/ring0/x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/atomic_amd64.s b/pkg/sentry/platform/safecopy/atomic_amd64.s index 69947dec3..873ffa046 100644 --- a/pkg/sentry/platform/safecopy/atomic_amd64.s +++ b/pkg/sentry/platform/safecopy/atomic_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/memclr_amd64.s b/pkg/sentry/platform/safecopy/memclr_amd64.s index 7d1019f60..488b6e666 100644 --- a/pkg/sentry/platform/safecopy/memclr_amd64.s +++ b/pkg/sentry/platform/safecopy/memclr_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/memcpy_amd64.s b/pkg/sentry/platform/safecopy/memcpy_amd64.s index 96ef2eefc..0bf26fd7b 100644 --- a/pkg/sentry/platform/safecopy/memcpy_amd64.s +++ b/pkg/sentry/platform/safecopy/memcpy_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/safecopy.go b/pkg/sentry/platform/safecopy/safecopy.go index 90a2aad7b..c60f73103 100644 --- a/pkg/sentry/platform/safecopy/safecopy.go +++ b/pkg/sentry/platform/safecopy/safecopy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/safecopy_test.go b/pkg/sentry/platform/safecopy/safecopy_test.go index 67df36121..1a682d28a 100644 --- a/pkg/sentry/platform/safecopy/safecopy_test.go +++ b/pkg/sentry/platform/safecopy/safecopy_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/safecopy_unsafe.go b/pkg/sentry/platform/safecopy/safecopy_unsafe.go index 72f243f8d..df1c35b66 100644 --- a/pkg/sentry/platform/safecopy/safecopy_unsafe.go +++ b/pkg/sentry/platform/safecopy/safecopy_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/platform/safecopy/sighandler_amd64.s b/pkg/sentry/platform/safecopy/sighandler_amd64.s index a65cb0c26..06614f1b4 100644 --- a/pkg/sentry/platform/safecopy/sighandler_amd64.s +++ b/pkg/sentry/platform/safecopy/sighandler_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/block_unsafe.go b/pkg/sentry/safemem/block_unsafe.go index 0b58f6497..e91ff66ae 100644 --- a/pkg/sentry/safemem/block_unsafe.go +++ b/pkg/sentry/safemem/block_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/io.go b/pkg/sentry/safemem/io.go index fd917648b..6cb52439f 100644 --- a/pkg/sentry/safemem/io.go +++ b/pkg/sentry/safemem/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/io_test.go b/pkg/sentry/safemem/io_test.go index edac4c1d7..2eda8c3bb 100644 --- a/pkg/sentry/safemem/io_test.go +++ b/pkg/sentry/safemem/io_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/safemem.go b/pkg/sentry/safemem/safemem.go index 2f8002004..090932d3e 100644 --- a/pkg/sentry/safemem/safemem.go +++ b/pkg/sentry/safemem/safemem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/seq_test.go b/pkg/sentry/safemem/seq_test.go index 3e83b3851..fddcaf714 100644 --- a/pkg/sentry/safemem/seq_test.go +++ b/pkg/sentry/safemem/seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/safemem/seq_unsafe.go b/pkg/sentry/safemem/seq_unsafe.go index e0d29a0b3..83a6b7183 100644 --- a/pkg/sentry/safemem/seq_unsafe.go +++ b/pkg/sentry/safemem/seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/sighandling/sighandling.go b/pkg/sentry/sighandling/sighandling.go index 29bcf55ab..6b5d5f993 100644 --- a/pkg/sentry/sighandling/sighandling.go +++ b/pkg/sentry/sighandling/sighandling.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/sighandling/sighandling_unsafe.go b/pkg/sentry/sighandling/sighandling_unsafe.go index a455b919f..5913d47a8 100644 --- a/pkg/sentry/sighandling/sighandling_unsafe.go +++ b/pkg/sentry/sighandling/sighandling_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index db97e95f2..d44f5e88a 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/device.go b/pkg/sentry/socket/epsocket/device.go index 17f2c9559..3cc138eb0 100644 --- a/pkg/sentry/socket/epsocket/device.go +++ b/pkg/sentry/socket/epsocket/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 47c575e7b..e90ef4835 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/provider.go b/pkg/sentry/socket/epsocket/provider.go index dbc232d26..686554437 100644 --- a/pkg/sentry/socket/epsocket/provider.go +++ b/pkg/sentry/socket/epsocket/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/save_restore.go b/pkg/sentry/socket/epsocket/save_restore.go index 2613f90de..34d9a7cf0 100644 --- a/pkg/sentry/socket/epsocket/save_restore.go +++ b/pkg/sentry/socket/epsocket/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index e4ed52fc8..c0081c819 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/device.go b/pkg/sentry/socket/hostinet/device.go index a9a673316..c5133f3bb 100644 --- a/pkg/sentry/socket/hostinet/device.go +++ b/pkg/sentry/socket/hostinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/hostinet.go b/pkg/sentry/socket/hostinet/hostinet.go index 67c6c8066..7858892ab 100644 --- a/pkg/sentry/socket/hostinet/hostinet.go +++ b/pkg/sentry/socket/hostinet/hostinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/save_restore.go b/pkg/sentry/socket/hostinet/save_restore.go index 0821a794a..3827f082a 100644 --- a/pkg/sentry/socket/hostinet/save_restore.go +++ b/pkg/sentry/socket/hostinet/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index e82624b44..e4e950fbb 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/socket_unsafe.go b/pkg/sentry/socket/hostinet/socket_unsafe.go index f8bb75636..59c8910ca 100644 --- a/pkg/sentry/socket/hostinet/socket_unsafe.go +++ b/pkg/sentry/socket/hostinet/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go index f64809d39..4ce73c1f1 100644 --- a/pkg/sentry/socket/hostinet/stack.go +++ b/pkg/sentry/socket/hostinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/message.go b/pkg/sentry/socket/netlink/message.go index b902d7ec9..a95172cba 100644 --- a/pkg/sentry/socket/netlink/message.go +++ b/pkg/sentry/socket/netlink/message.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 1c5d4c3a5..20b9a6e37 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/port/port_test.go b/pkg/sentry/socket/netlink/port/port_test.go index 34565e2f9..49b3b48ab 100644 --- a/pkg/sentry/socket/netlink/port/port_test.go +++ b/pkg/sentry/socket/netlink/port/port_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/provider.go b/pkg/sentry/socket/netlink/provider.go index 5d0a04a07..06786bd50 100644 --- a/pkg/sentry/socket/netlink/provider.go +++ b/pkg/sentry/socket/netlink/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index 70322b9ed..7e70b09b2 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 0c03997f2..4d4130a4c 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/conn/conn.go b/pkg/sentry/socket/rpcinet/conn/conn.go index f4c8489b1..9c749b888 100644 --- a/pkg/sentry/socket/rpcinet/conn/conn.go +++ b/pkg/sentry/socket/rpcinet/conn/conn.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/device.go b/pkg/sentry/socket/rpcinet/device.go index f7b63436e..d2b9f9222 100644 --- a/pkg/sentry/socket/rpcinet/device.go +++ b/pkg/sentry/socket/rpcinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/notifier/notifier.go b/pkg/sentry/socket/rpcinet/notifier/notifier.go index f88a908ed..73c255c33 100644 --- a/pkg/sentry/socket/rpcinet/notifier/notifier.go +++ b/pkg/sentry/socket/rpcinet/notifier/notifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/rpcinet.go b/pkg/sentry/socket/rpcinet/rpcinet.go index 10b0dedc2..6c98e6acb 100644 --- a/pkg/sentry/socket/rpcinet/rpcinet.go +++ b/pkg/sentry/socket/rpcinet/rpcinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index c7e761d54..44fa5c620 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/stack.go b/pkg/sentry/socket/rpcinet/stack.go index bcb89fb34..cb8344ec6 100644 --- a/pkg/sentry/socket/rpcinet/stack.go +++ b/pkg/sentry/socket/rpcinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/rpcinet/stack_unsafe.go b/pkg/sentry/socket/rpcinet/stack_unsafe.go index 9a896c623..d04fb2069 100644 --- a/pkg/sentry/socket/rpcinet/stack_unsafe.go +++ b/pkg/sentry/socket/rpcinet/stack_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 31f8d42d7..a235c5249 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/device.go b/pkg/sentry/socket/unix/device.go index e8bcc7a9f..41820dbb3 100644 --- a/pkg/sentry/socket/unix/device.go +++ b/pkg/sentry/socket/unix/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/io.go b/pkg/sentry/socket/unix/io.go index 06333e14b..7d6434696 100644 --- a/pkg/sentry/socket/unix/io.go +++ b/pkg/sentry/socket/unix/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/connectioned.go b/pkg/sentry/socket/unix/transport/connectioned.go index 566e3d57b..4c913effc 100644 --- a/pkg/sentry/socket/unix/transport/connectioned.go +++ b/pkg/sentry/socket/unix/transport/connectioned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/connectioned_state.go b/pkg/sentry/socket/unix/transport/connectioned_state.go index 7e6c73dcc..608a6a97a 100644 --- a/pkg/sentry/socket/unix/transport/connectioned_state.go +++ b/pkg/sentry/socket/unix/transport/connectioned_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/connectionless.go b/pkg/sentry/socket/unix/transport/connectionless.go index 86cd05199..cd4633106 100644 --- a/pkg/sentry/socket/unix/transport/connectionless.go +++ b/pkg/sentry/socket/unix/transport/connectionless.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/queue.go b/pkg/sentry/socket/unix/transport/queue.go index c4d7d863c..5b4dfab68 100644 --- a/pkg/sentry/socket/unix/transport/queue.go +++ b/pkg/sentry/socket/unix/transport/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go index 2934101a2..157133b65 100644 --- a/pkg/sentry/socket/unix/transport/unix.go +++ b/pkg/sentry/socket/unix/transport/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 668363864..3543dd81f 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 43e88a713..70b33f190 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/state/state_metadata.go b/pkg/sentry/state/state_metadata.go index afa21672a..7f047b808 100644 --- a/pkg/sentry/state/state_metadata.go +++ b/pkg/sentry/state/state_metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/state/state_unsafe.go b/pkg/sentry/state/state_unsafe.go index 3ff7d24c8..f02e12b2a 100644 --- a/pkg/sentry/state/state_unsafe.go +++ b/pkg/sentry/state/state_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/clone.go b/pkg/sentry/strace/clone.go index b82ca1ad1..e18ce84dc 100644 --- a/pkg/sentry/strace/clone.go +++ b/pkg/sentry/strace/clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/futex.go b/pkg/sentry/strace/futex.go index 3da108cb7..ceb3dc21d 100644 --- a/pkg/sentry/strace/futex.go +++ b/pkg/sentry/strace/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index 1df148e7d..99714f12c 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/open.go b/pkg/sentry/strace/open.go index 839d5eda7..5a72a940c 100644 --- a/pkg/sentry/strace/open.go +++ b/pkg/sentry/strace/open.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/ptrace.go b/pkg/sentry/strace/ptrace.go index fcdb7e9f4..c572aafb4 100644 --- a/pkg/sentry/strace/ptrace.go +++ b/pkg/sentry/strace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go index 26831edd6..375418dc1 100644 --- a/pkg/sentry/strace/socket.go +++ b/pkg/sentry/strace/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index f7bfa3a1f..4286f0df7 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/strace.proto b/pkg/sentry/strace/strace.proto index 914e8c7b0..f1fc539d6 100644 --- a/pkg/sentry/strace/strace.proto +++ b/pkg/sentry/strace/strace.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 8be4fa318..9eeb18a03 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/epoll.go b/pkg/sentry/syscalls/epoll.go index 01dd6fa71..b90d191b7 100644 --- a/pkg/sentry/syscalls/epoll.go +++ b/pkg/sentry/syscalls/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 013b385bc..9fd002955 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index f01483cd3..d1e0833fc 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 4465549ad..75e87f5ec 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sigset.go b/pkg/sentry/syscalls/linux/sigset.go index bfb541634..a033b7c70 100644 --- a/pkg/sentry/syscalls/linux/sigset.go +++ b/pkg/sentry/syscalls/linux/sigset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index 54e4afa9e..355071131 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_capability.go b/pkg/sentry/syscalls/linux/sys_capability.go index 89c81ac90..cf972dc28 100644 --- a/pkg/sentry/syscalls/linux/sys_capability.go +++ b/pkg/sentry/syscalls/linux/sys_capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go index e69dfc77a..62272efcd 100644 --- a/pkg/sentry/syscalls/linux/sys_epoll.go +++ b/pkg/sentry/syscalls/linux/sys_epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_eventfd.go b/pkg/sentry/syscalls/linux/sys_eventfd.go index 60fe5a133..903172890 100644 --- a/pkg/sentry/syscalls/linux/sys_eventfd.go +++ b/pkg/sentry/syscalls/linux/sys_eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 64704bb88..a70f35be0 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index d35dcecbe..cf04428bc 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_getdents.go b/pkg/sentry/syscalls/linux/sys_getdents.go index 29c0d7a39..4b441b31b 100644 --- a/pkg/sentry/syscalls/linux/sys_getdents.go +++ b/pkg/sentry/syscalls/linux/sys_getdents.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_identity.go b/pkg/sentry/syscalls/linux/sys_identity.go index 4fd0ed794..8d594aa83 100644 --- a/pkg/sentry/syscalls/linux/sys_identity.go +++ b/pkg/sentry/syscalls/linux/sys_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_inotify.go b/pkg/sentry/syscalls/linux/sys_inotify.go index 725204dff..26a505782 100644 --- a/pkg/sentry/syscalls/linux/sys_inotify.go +++ b/pkg/sentry/syscalls/linux/sys_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_lseek.go b/pkg/sentry/syscalls/linux/sys_lseek.go index 97b51ba7c..ad3bfd761 100644 --- a/pkg/sentry/syscalls/linux/sys_lseek.go +++ b/pkg/sentry/syscalls/linux/sys_lseek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 1a98328dc..f8d9c43fd 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_mount.go b/pkg/sentry/syscalls/linux/sys_mount.go index 57cedccc1..bf0df7302 100644 --- a/pkg/sentry/syscalls/linux/sys_mount.go +++ b/pkg/sentry/syscalls/linux/sys_mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_pipe.go b/pkg/sentry/syscalls/linux/sys_pipe.go index 2b544f145..3652c429e 100644 --- a/pkg/sentry/syscalls/linux/sys_pipe.go +++ b/pkg/sentry/syscalls/linux/sys_pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index b9bdefadb..bf0958435 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go index a1242acd3..c7b39ede8 100644 --- a/pkg/sentry/syscalls/linux/sys_prctl.go +++ b/pkg/sentry/syscalls/linux/sys_prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_random.go b/pkg/sentry/syscalls/linux/sys_random.go index be31e6b17..452dff058 100644 --- a/pkg/sentry/syscalls/linux/sys_random.go +++ b/pkg/sentry/syscalls/linux/sys_random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index 0be2d195a..b2e5a5449 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index d806b58ab..2f16e1791 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_rusage.go b/pkg/sentry/syscalls/linux/sys_rusage.go index 82e42b589..ab07c77f9 100644 --- a/pkg/sentry/syscalls/linux/sys_rusage.go +++ b/pkg/sentry/syscalls/linux/sys_rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sched.go b/pkg/sentry/syscalls/linux/sys_sched.go index ff9e46077..e679a6694 100644 --- a/pkg/sentry/syscalls/linux/sys_sched.go +++ b/pkg/sentry/syscalls/linux/sys_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_seccomp.go b/pkg/sentry/syscalls/linux/sys_seccomp.go index 4323a4df4..969acaa36 100644 --- a/pkg/sentry/syscalls/linux/sys_seccomp.go +++ b/pkg/sentry/syscalls/linux/sys_seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go index a8983705b..4ed52c4a7 100644 --- a/pkg/sentry/syscalls/linux/sys_sem.go +++ b/pkg/sentry/syscalls/linux/sys_sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_shm.go b/pkg/sentry/syscalls/linux/sys_shm.go index 48ff1d5f0..b13d48b98 100644 --- a/pkg/sentry/syscalls/linux/sys_shm.go +++ b/pkg/sentry/syscalls/linux/sys_shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_signal.go b/pkg/sentry/syscalls/linux/sys_signal.go index ecdec5d3a..a539354c5 100644 --- a/pkg/sentry/syscalls/linux/sys_signal.go +++ b/pkg/sentry/syscalls/linux/sys_signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index 5fa5ddce6..0a7551742 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go index 619a14d7c..9c433c45d 100644 --- a/pkg/sentry/syscalls/linux/sys_stat.go +++ b/pkg/sentry/syscalls/linux/sys_stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sync.go b/pkg/sentry/syscalls/linux/sys_sync.go index 902d210db..826c6869d 100644 --- a/pkg/sentry/syscalls/linux/sys_sync.go +++ b/pkg/sentry/syscalls/linux/sys_sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_sysinfo.go b/pkg/sentry/syscalls/linux/sys_sysinfo.go index 6560bac57..5eeb3ba58 100644 --- a/pkg/sentry/syscalls/linux/sys_sysinfo.go +++ b/pkg/sentry/syscalls/linux/sys_sysinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_syslog.go b/pkg/sentry/syscalls/linux/sys_syslog.go index 792040c81..7193b7aed 100644 --- a/pkg/sentry/syscalls/linux/sys_syslog.go +++ b/pkg/sentry/syscalls/linux/sys_syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index 550f63a43..820ca680e 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index 8e6683444..063fbb106 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go index c41074d54..6baf4599b 100644 --- a/pkg/sentry/syscalls/linux/sys_timer.go +++ b/pkg/sentry/syscalls/linux/sys_timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_timerfd.go b/pkg/sentry/syscalls/linux/sys_timerfd.go index 92c6a3d60..f70d13682 100644 --- a/pkg/sentry/syscalls/linux/sys_timerfd.go +++ b/pkg/sentry/syscalls/linux/sys_timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_tls.go b/pkg/sentry/syscalls/linux/sys_tls.go index b95d62320..27ddb3808 100644 --- a/pkg/sentry/syscalls/linux/sys_tls.go +++ b/pkg/sentry/syscalls/linux/sys_tls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_utsname.go b/pkg/sentry/syscalls/linux/sys_utsname.go index 899116374..689f2f838 100644 --- a/pkg/sentry/syscalls/linux/sys_utsname.go +++ b/pkg/sentry/syscalls/linux/sys_utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index caa7b01ea..08e263112 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/linux/timespec.go b/pkg/sentry/syscalls/linux/timespec.go index e865c6fc0..752ec326d 100644 --- a/pkg/sentry/syscalls/linux/timespec.go +++ b/pkg/sentry/syscalls/linux/timespec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/polling.go b/pkg/sentry/syscalls/polling.go index fd90184ef..2b33d6c19 100644 --- a/pkg/sentry/syscalls/polling.go +++ b/pkg/sentry/syscalls/polling.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/syscalls.go b/pkg/sentry/syscalls/syscalls.go index 1176f858d..bae32d727 100644 --- a/pkg/sentry/syscalls/syscalls.go +++ b/pkg/sentry/syscalls/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/syscalls/unimplemented_syscall.proto b/pkg/sentry/syscalls/unimplemented_syscall.proto index d6febf5b1..41579b016 100644 --- a/pkg/sentry/syscalls/unimplemented_syscall.proto +++ b/pkg/sentry/syscalls/unimplemented_syscall.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/calibrated_clock.go b/pkg/sentry/time/calibrated_clock.go index cbb95e2d7..c8cf4eca4 100644 --- a/pkg/sentry/time/calibrated_clock.go +++ b/pkg/sentry/time/calibrated_clock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/calibrated_clock_test.go b/pkg/sentry/time/calibrated_clock_test.go index 8b6dd5592..a9237630e 100644 --- a/pkg/sentry/time/calibrated_clock_test.go +++ b/pkg/sentry/time/calibrated_clock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/clock_id.go b/pkg/sentry/time/clock_id.go index 500102e58..1317a5dad 100644 --- a/pkg/sentry/time/clock_id.go +++ b/pkg/sentry/time/clock_id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/clocks.go b/pkg/sentry/time/clocks.go index 9925b407d..e26386520 100644 --- a/pkg/sentry/time/clocks.go +++ b/pkg/sentry/time/clocks.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/muldiv_amd64.s b/pkg/sentry/time/muldiv_amd64.s index 291940b1d..bfcb8c724 100644 --- a/pkg/sentry/time/muldiv_amd64.s +++ b/pkg/sentry/time/muldiv_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/parameters.go b/pkg/sentry/time/parameters.go index 594b4874b..f3ad58454 100644 --- a/pkg/sentry/time/parameters.go +++ b/pkg/sentry/time/parameters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/parameters_test.go b/pkg/sentry/time/parameters_test.go index 7394fc5ee..4a0c4e880 100644 --- a/pkg/sentry/time/parameters_test.go +++ b/pkg/sentry/time/parameters_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/sampler.go b/pkg/sentry/time/sampler.go index cf581b5fa..445690d49 100644 --- a/pkg/sentry/time/sampler.go +++ b/pkg/sentry/time/sampler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/sampler_test.go b/pkg/sentry/time/sampler_test.go index caf7e5c53..ec0e442b6 100644 --- a/pkg/sentry/time/sampler_test.go +++ b/pkg/sentry/time/sampler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/sampler_unsafe.go b/pkg/sentry/time/sampler_unsafe.go index 7ea19d387..0f8eb4fc8 100644 --- a/pkg/sentry/time/sampler_unsafe.go +++ b/pkg/sentry/time/sampler_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/time/tsc_amd64.s b/pkg/sentry/time/tsc_amd64.s index 4cc604392..e53d477f7 100644 --- a/pkg/sentry/time/tsc_amd64.s +++ b/pkg/sentry/time/tsc_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/uniqueid/context.go b/pkg/sentry/uniqueid/context.go index e48fabc2d..399d98c29 100644 --- a/pkg/sentry/uniqueid/context.go +++ b/pkg/sentry/uniqueid/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index ed7b04b9e..cbd7cfe19 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index 49faa507d..8e27a0a88 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/memory.go b/pkg/sentry/usage/memory.go index 92a478d85..7e065cb76 100644 --- a/pkg/sentry/usage/memory.go +++ b/pkg/sentry/usage/memory.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/memory_unsafe.go b/pkg/sentry/usage/memory_unsafe.go index f990a7750..a3ae668a5 100644 --- a/pkg/sentry/usage/memory_unsafe.go +++ b/pkg/sentry/usage/memory_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usage/usage.go b/pkg/sentry/usage/usage.go index 3b3118659..ab327f8e2 100644 --- a/pkg/sentry/usage/usage.go +++ b/pkg/sentry/usage/usage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 75346d854..c71d05afe 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index fc94bee80..2a75aa60c 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/addr_range_seq_test.go b/pkg/sentry/usermem/addr_range_seq_test.go index cf9d785ed..bd6a1ec8a 100644 --- a/pkg/sentry/usermem/addr_range_seq_test.go +++ b/pkg/sentry/usermem/addr_range_seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/addr_range_seq_unsafe.go b/pkg/sentry/usermem/addr_range_seq_unsafe.go index 13b2998b3..f5fd446fa 100644 --- a/pkg/sentry/usermem/addr_range_seq_unsafe.go +++ b/pkg/sentry/usermem/addr_range_seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/bytes_io.go b/pkg/sentry/usermem/bytes_io.go index 01a746404..274f568d0 100644 --- a/pkg/sentry/usermem/bytes_io.go +++ b/pkg/sentry/usermem/bytes_io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/bytes_io_unsafe.go b/pkg/sentry/usermem/bytes_io_unsafe.go index efd71fcbc..8bdf3a508 100644 --- a/pkg/sentry/usermem/bytes_io_unsafe.go +++ b/pkg/sentry/usermem/bytes_io_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/usermem.go b/pkg/sentry/usermem/usermem.go index 5d8a1c558..1d6c0b4d6 100644 --- a/pkg/sentry/usermem/usermem.go +++ b/pkg/sentry/usermem/usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/usermem_test.go b/pkg/sentry/usermem/usermem_test.go index 563560da8..1991a9641 100644 --- a/pkg/sentry/usermem/usermem_test.go +++ b/pkg/sentry/usermem/usermem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/usermem/usermem_x86.go b/pkg/sentry/usermem/usermem_x86.go index 2484b0d82..9ec90f9ff 100644 --- a/pkg/sentry/usermem/usermem_x86.go +++ b/pkg/sentry/usermem/usermem_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sentry/watchdog/watchdog.go b/pkg/sentry/watchdog/watchdog.go index 5b620693d..75b11237f 100644 --- a/pkg/sentry/watchdog/watchdog.go +++ b/pkg/sentry/watchdog/watchdog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/commit_amd64.s b/pkg/sleep/commit_amd64.s index d525e5b79..d08df7f37 100644 --- a/pkg/sleep/commit_amd64.s +++ b/pkg/sleep/commit_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/commit_asm.go b/pkg/sleep/commit_asm.go index 39a55df7e..90eef4cbc 100644 --- a/pkg/sleep/commit_asm.go +++ b/pkg/sleep/commit_asm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/commit_noasm.go b/pkg/sleep/commit_noasm.go index 584866cd8..967d22e24 100644 --- a/pkg/sleep/commit_noasm.go +++ b/pkg/sleep/commit_noasm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/empty.s b/pkg/sleep/empty.s index 8aca31bee..85d52cd9c 100644 --- a/pkg/sleep/empty.s +++ b/pkg/sleep/empty.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go index bc1738371..8feb9ffc2 100644 --- a/pkg/sleep/sleep_test.go +++ b/pkg/sleep/sleep_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sleep/sleep_unsafe.go b/pkg/sleep/sleep_unsafe.go index b12cce681..45fb6f0ea 100644 --- a/pkg/sleep/sleep_unsafe.go +++ b/pkg/sleep/sleep_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/decode.go b/pkg/state/decode.go index 3ef59610b..54b5ad8b8 100644 --- a/pkg/state/decode.go +++ b/pkg/state/decode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/encode.go b/pkg/state/encode.go index fd052db12..577aaf051 100644 --- a/pkg/state/encode.go +++ b/pkg/state/encode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/encode_unsafe.go b/pkg/state/encode_unsafe.go index d96ba56d4..be94742a8 100644 --- a/pkg/state/encode_unsafe.go +++ b/pkg/state/encode_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/map.go b/pkg/state/map.go index c3d165501..0035d7250 100644 --- a/pkg/state/map.go +++ b/pkg/state/map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/object.proto b/pkg/state/object.proto index c78efed2a..d3b46ea97 100644 --- a/pkg/state/object.proto +++ b/pkg/state/object.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/printer.go b/pkg/state/printer.go index 2c8ce60a5..aee4b69fb 100644 --- a/pkg/state/printer.go +++ b/pkg/state/printer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/state.go b/pkg/state/state.go index 23a0b5922..4b141777e 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 38ad9da9c..22bcad9e1 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/statefile/statefile.go b/pkg/state/statefile/statefile.go index 9c86c1934..99158fd02 100644 --- a/pkg/state/statefile/statefile.go +++ b/pkg/state/statefile/statefile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/statefile/statefile_test.go b/pkg/state/statefile/statefile_test.go index fa3fb9f2c..b4f400e01 100644 --- a/pkg/state/statefile/statefile_test.go +++ b/pkg/state/statefile/statefile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/state/stats.go b/pkg/state/stats.go index ddcc49f78..17ca258fc 100644 --- a/pkg/state/stats.go +++ b/pkg/state/stats.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/atomicptr_unsafe.go b/pkg/sync/atomicptr_unsafe.go index f12e9cb67..d943b7ff4 100644 --- a/pkg/sync/atomicptr_unsafe.go +++ b/pkg/sync/atomicptr_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/atomicptrtest/atomicptr_test.go b/pkg/sync/atomicptrtest/atomicptr_test.go index b458382b1..3262785ce 100644 --- a/pkg/sync/atomicptrtest/atomicptr_test.go +++ b/pkg/sync/atomicptrtest/atomicptr_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/memmove_unsafe.go b/pkg/sync/memmove_unsafe.go index 0c992d5a4..cd7a02dca 100644 --- a/pkg/sync/memmove_unsafe.go +++ b/pkg/sync/memmove_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/norace_unsafe.go b/pkg/sync/norace_unsafe.go index 968665078..1593b9e5d 100644 --- a/pkg/sync/norace_unsafe.go +++ b/pkg/sync/norace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/race_unsafe.go b/pkg/sync/race_unsafe.go index d143a21c7..473eaddc6 100644 --- a/pkg/sync/race_unsafe.go +++ b/pkg/sync/race_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqatomic_unsafe.go b/pkg/sync/seqatomic_unsafe.go index a18e1229a..bea31adc5 100644 --- a/pkg/sync/seqatomic_unsafe.go +++ b/pkg/sync/seqatomic_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqatomictest/seqatomic_test.go b/pkg/sync/seqatomictest/seqatomic_test.go index b785d2344..f5e1fbfff 100644 --- a/pkg/sync/seqatomictest/seqatomic_test.go +++ b/pkg/sync/seqatomictest/seqatomic_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqcount.go b/pkg/sync/seqcount.go index 8e3304d69..732e856a4 100644 --- a/pkg/sync/seqcount.go +++ b/pkg/sync/seqcount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/seqcount_test.go b/pkg/sync/seqcount_test.go index fa4abed1d..b14a8878e 100644 --- a/pkg/sync/seqcount_test.go +++ b/pkg/sync/seqcount_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go index 36d4c4dee..22c5348d7 100644 --- a/pkg/sync/sync.go +++ b/pkg/sync/sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserr/host_linux.go b/pkg/syserr/host_linux.go index 22009a799..74bbe9f5b 100644 --- a/pkg/syserr/host_linux.go +++ b/pkg/syserr/host_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index b9786b48f..20e756edb 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go index dba6cb7de..6a66e23a2 100644 --- a/pkg/syserr/syserr.go +++ b/pkg/syserr/syserr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserror/syserror.go b/pkg/syserror/syserror.go index 5bc74e65e..4228707f4 100644 --- a/pkg/syserror/syserror.go +++ b/pkg/syserror/syserror.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/syserror/syserror_test.go b/pkg/syserror/syserror_test.go index fb7d8d5ee..0f0da5781 100644 --- a/pkg/syserror/syserror_test.go +++ b/pkg/syserror/syserror_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index b64dce720..81428770b 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index 79b7c77ee..05a730a05 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/buffer/prependable.go b/pkg/tcpip/buffer/prependable.go index c5dd2819f..d3a9a0f88 100644 --- a/pkg/tcpip/buffer/prependable.go +++ b/pkg/tcpip/buffer/prependable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index cea4e3657..24479ea40 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go index 02c264593..74a0a96fc 100644 --- a/pkg/tcpip/buffer/view_test.go +++ b/pkg/tcpip/buffer/view_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 206531f20..5dfb3ca1d 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/arp.go b/pkg/tcpip/header/arp.go index ae373f112..22b259ccb 100644 --- a/pkg/tcpip/header/arp.go +++ b/pkg/tcpip/header/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go index e67c50f50..12f208fde 100644 --- a/pkg/tcpip/header/checksum.go +++ b/pkg/tcpip/header/checksum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/eth.go b/pkg/tcpip/header/eth.go index 99c29b750..77365bc41 100644 --- a/pkg/tcpip/header/eth.go +++ b/pkg/tcpip/header/eth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/gue.go b/pkg/tcpip/header/gue.go index aac4593c5..2ad13955a 100644 --- a/pkg/tcpip/header/gue.go +++ b/pkg/tcpip/header/gue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/icmpv4.go b/pkg/tcpip/header/icmpv4.go index af1e94b7f..3ac89cdae 100644 --- a/pkg/tcpip/header/icmpv4.go +++ b/pkg/tcpip/header/icmpv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/icmpv6.go b/pkg/tcpip/header/icmpv6.go index 7d35caff7..e317975e8 100644 --- a/pkg/tcpip/header/icmpv6.go +++ b/pkg/tcpip/header/icmpv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/interfaces.go b/pkg/tcpip/header/interfaces.go index 042006983..ac327d8a5 100644 --- a/pkg/tcpip/header/interfaces.go +++ b/pkg/tcpip/header/interfaces.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index 29570cc34..1b882d3d8 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index 66c778fe1..d985b745d 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipv6_fragment.go b/pkg/tcpip/header/ipv6_fragment.go index 44b28b326..e36d5177b 100644 --- a/pkg/tcpip/header/ipv6_fragment.go +++ b/pkg/tcpip/header/ipv6_fragment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/ipversion_test.go b/pkg/tcpip/header/ipversion_test.go index 3ae9b7e4a..8301ba5cf 100644 --- a/pkg/tcpip/header/ipversion_test.go +++ b/pkg/tcpip/header/ipversion_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index 6689a6dc5..567a21167 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/tcp_test.go b/pkg/tcpip/header/tcp_test.go index 7854d3523..7cd98df3b 100644 --- a/pkg/tcpip/header/tcp_test.go +++ b/pkg/tcpip/header/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/header/udp.go b/pkg/tcpip/header/udp.go index cf2602e50..31c8ef456 100644 --- a/pkg/tcpip/header/udp.go +++ b/pkg/tcpip/header/udp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 113cbbf5e..da34032cc 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index ee99ada07..24af428dd 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 52e532ebb..19b007a9e 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index fc3f80c01..e6585be66 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s index fc5231831..63b8c4451 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go index a0a9d4acd..6a3e956ad 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go index 1f143c0db..89a8a9954 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/link/rawfile/errors.go index de7593d9c..f42ff98db 100644 --- a/pkg/tcpip/link/rawfile/errors.go +++ b/pkg/tcpip/link/rawfile/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go index cea3cd6a1..be4a4fa9c 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe.go b/pkg/tcpip/link/sharedmem/pipe/pipe.go index 1a0edbaba..e014324cc 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go index db0737c98..30742ccb1 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go index 480dc4a23..f491d74a2 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/rx.go b/pkg/tcpip/link/sharedmem/pipe/rx.go index ff778cecd..8d641c76f 100644 --- a/pkg/tcpip/link/sharedmem/pipe/rx.go +++ b/pkg/tcpip/link/sharedmem/pipe/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/pipe/tx.go b/pkg/tcpip/link/sharedmem/pipe/tx.go index 717f5a4b1..e75175d98 100644 --- a/pkg/tcpip/link/sharedmem/pipe/tx.go +++ b/pkg/tcpip/link/sharedmem/pipe/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/queue/queue_test.go b/pkg/tcpip/link/sharedmem/queue/queue_test.go index 3d5909cef..391165bc3 100644 --- a/pkg/tcpip/link/sharedmem/queue/queue_test.go +++ b/pkg/tcpip/link/sharedmem/queue/queue_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/queue/rx.go b/pkg/tcpip/link/sharedmem/queue/rx.go index c40d62c33..d3a5da08a 100644 --- a/pkg/tcpip/link/sharedmem/queue/rx.go +++ b/pkg/tcpip/link/sharedmem/queue/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/queue/tx.go b/pkg/tcpip/link/sharedmem/queue/tx.go index 39b595e56..845108db1 100644 --- a/pkg/tcpip/link/sharedmem/queue/tx.go +++ b/pkg/tcpip/link/sharedmem/queue/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/rx.go b/pkg/tcpip/link/sharedmem/rx.go index b8e39eca1..3eeab769e 100644 --- a/pkg/tcpip/link/sharedmem/rx.go +++ b/pkg/tcpip/link/sharedmem/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index ce6e86767..27d7eb3b9 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index ad987d382..4b8061b13 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go index f0be2dc73..b91adbaf7 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sharedmem/tx.go b/pkg/tcpip/link/sharedmem/tx.go index 42a21cb43..37da34831 100644 --- a/pkg/tcpip/link/sharedmem/tx.go +++ b/pkg/tcpip/link/sharedmem/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go index 04f3d494e..3d0d8d852 100644 --- a/pkg/tcpip/link/sniffer/pcap.go +++ b/pkg/tcpip/link/sniffer/pcap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index a30e57a32..1bd174bc3 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/tun/tun_unsafe.go b/pkg/tcpip/link/tun/tun_unsafe.go index 1dec41982..e4c589dda 100644 --- a/pkg/tcpip/link/tun/tun_unsafe.go +++ b/pkg/tcpip/link/tun/tun_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index ef8c88561..9ffb7b7e9 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 0a15c40de..5ebe09664 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 9d0881e11..2e0024925 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 50628e4a2..5894f9114 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/frag_heap.go b/pkg/tcpip/network/fragmentation/frag_heap.go index 6c7faafe4..55615c8e6 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap.go +++ b/pkg/tcpip/network/fragmentation/frag_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go index a15540634..1b1b72e88 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap_test.go +++ b/pkg/tcpip/network/fragmentation/frag_heap_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/fragmentation.go b/pkg/tcpip/network/fragmentation/fragmentation.go index 885e3cca2..a5dda0398 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/fragmentation/fragmentation.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go index fc62a15dd..5bf3463a9 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_test.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/reassembler.go b/pkg/tcpip/network/fragmentation/reassembler.go index b57fe82ec..c9ad2bef6 100644 --- a/pkg/tcpip/network/fragmentation/reassembler.go +++ b/pkg/tcpip/network/fragmentation/reassembler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/fragmentation/reassembler_test.go b/pkg/tcpip/network/fragmentation/reassembler_test.go index 4c137828f..a2bc9707a 100644 --- a/pkg/tcpip/network/fragmentation/reassembler_test.go +++ b/pkg/tcpip/network/fragmentation/reassembler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/hash/hash.go b/pkg/tcpip/network/hash/hash.go index eddf7ca4d..07960ddf0 100644 --- a/pkg/tcpip/network/hash/hash.go +++ b/pkg/tcpip/network/hash/hash.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index e3c7af1f9..5c1e88e56 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index ee8172ac8..f82dc098f 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index d4eeeb5d9..d7801ec19 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 2b7067a50..190d548eb 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index 81aba0923..14107443b 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index fabbdc8c7..12c818b48 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 25bd998e5..4d0b6ee9c 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index 4e24efddb..41ef32921 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go index 4ab6a1fa2..72577dfcb 100644 --- a/pkg/tcpip/ports/ports_test.go +++ b/pkg/tcpip/ports/ports_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index c4707736e..67e8f0b9e 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index 910d1257f..ab40e9e0b 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/seqnum/seqnum.go b/pkg/tcpip/seqnum/seqnum.go index e507d02f7..f2b988839 100644 --- a/pkg/tcpip/seqnum/seqnum.go +++ b/pkg/tcpip/seqnum/seqnum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 3a147a75f..cb7b7116b 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index e46267f12..651fa17ac 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index dba95369c..3da99ac67 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 0acec2984..b6266eb55 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 6c6400c33..2b4185014 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index d1ec6a660..d4da980a9 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index b6c095efb..f2c6c9a8d 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index a0b3399a8..74bf2c99e 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index a7470d606..c8522ad9e 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 98cc3b120..f09760180 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index bf11c2175..413aee6c6 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go index d283f71c7..361e359d4 100644 --- a/pkg/tcpip/tcpip_test.go +++ b/pkg/tcpip/tcpip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/time.s b/pkg/tcpip/time.s index 8aca31bee..85d52cd9c 100644 --- a/pkg/tcpip/time.s +++ b/pkg/tcpip/time.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/time_unsafe.go b/pkg/tcpip/time_unsafe.go index 2102e9633..231151bf3 100644 --- a/pkg/tcpip/time_unsafe.go +++ b/pkg/tcpip/time_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 055daa918..b3f54cfe0 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/ping/endpoint_state.go b/pkg/tcpip/transport/ping/endpoint_state.go index a16087304..80721d227 100644 --- a/pkg/tcpip/transport/ping/endpoint_state.go +++ b/pkg/tcpip/transport/ping/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/ping/protocol.go b/pkg/tcpip/transport/ping/protocol.go index 549b1b2d3..1d504773b 100644 --- a/pkg/tcpip/transport/ping/protocol.go +++ b/pkg/tcpip/transport/ping/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index c22ed5ea7..5a88d25d0 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 27dbcace2..800d2409e 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/cubic.go b/pkg/tcpip/transport/tcp/cubic.go index 8cea416d2..003525d86 100644 --- a/pkg/tcpip/transport/tcp/cubic.go +++ b/pkg/tcpip/transport/tcp/cubic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index c88e98977..d3120c1d8 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 707d6be96..673a65c31 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index bed7ec6a6..e32c73aae 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index c80f3c7d6..2f90839e9 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index abdc825cd..753e1419e 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index 92ef9c6f7..05ff9e0d7 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index feb593234..e4f8b7d5a 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/sack.go b/pkg/tcpip/transport/tcp/sack.go index 05bac08cb..24e48fe7b 100644 --- a/pkg/tcpip/transport/tcp/sack.go +++ b/pkg/tcpip/transport/tcp/sack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index 51a3d6aba..fc87a05fd 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment_heap.go b/pkg/tcpip/transport/tcp/segment_heap.go index e3a3405ef..98422fadf 100644 --- a/pkg/tcpip/transport/tcp/segment_heap.go +++ b/pkg/tcpip/transport/tcp/segment_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 6a2d7bc0b..0c637d7ad 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go index 22f0bbf18..46b6d85a6 100644 --- a/pkg/tcpip/transport/tcp/segment_state.go +++ b/pkg/tcpip/transport/tcp/segment_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 0bd421ff4..eefe93d48 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index d536839af..86bbd643f 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go index a61d0ca64..06b0702c5 100644 --- a/pkg/tcpip/transport/tcp/tcp_sack_test.go +++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index 48852ea47..04e046257 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index ca16fc8fa..b08df0fec 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 5b25534f4..0695e8150 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcp/timer.go b/pkg/tcpip/transport/tcp/timer.go index 938c0bcef..38240d2d5 100644 --- a/pkg/tcpip/transport/tcp/timer.go +++ b/pkg/tcpip/transport/tcp/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go index 5f8f1a64d..f7b2900de 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go index 514722ab7..aaeae9b18 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 840e95302..d777a80d0 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index 70a37c7f2..db1e281ad 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index 1334fec8a..b3fbed6e4 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index c3f592bd4..58a346cd9 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tmutex/tmutex.go b/pkg/tmutex/tmutex.go index bd5c681dd..df61d89f5 100644 --- a/pkg/tmutex/tmutex.go +++ b/pkg/tmutex/tmutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/tmutex/tmutex_test.go b/pkg/tmutex/tmutex_test.go index a9dc9972f..a4537cb3b 100644 --- a/pkg/tmutex/tmutex_test.go +++ b/pkg/tmutex/tmutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/unet/unet.go b/pkg/unet/unet.go index f4800e0d9..deeea078d 100644 --- a/pkg/unet/unet.go +++ b/pkg/unet/unet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/unet/unet_test.go b/pkg/unet/unet_test.go index 6c546825f..ecc670925 100644 --- a/pkg/unet/unet_test.go +++ b/pkg/unet/unet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/unet/unet_unsafe.go b/pkg/unet/unet_unsafe.go index fa15cf744..1d69de542 100644 --- a/pkg/unet/unet_unsafe.go +++ b/pkg/unet/unet_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/urpc/urpc.go b/pkg/urpc/urpc.go index 1ec06dd4c..753366be2 100644 --- a/pkg/urpc/urpc.go +++ b/pkg/urpc/urpc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/urpc/urpc_test.go b/pkg/urpc/urpc_test.go index d9cfc512e..f1b9a85ca 100644 --- a/pkg/urpc/urpc_test.go +++ b/pkg/urpc/urpc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/fdnotifier/fdnotifier.go b/pkg/waiter/fdnotifier/fdnotifier.go index 8bb93e39b..624b1a0c5 100644 --- a/pkg/waiter/fdnotifier/fdnotifier.go +++ b/pkg/waiter/fdnotifier/fdnotifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/fdnotifier/poll_unsafe.go b/pkg/waiter/fdnotifier/poll_unsafe.go index 26bca2b53..8459d4c74 100644 --- a/pkg/waiter/fdnotifier/poll_unsafe.go +++ b/pkg/waiter/fdnotifier/poll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 832b6a5a9..93390b299 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go index c45f22889..60853f9c1 100644 --- a/pkg/waiter/waiter_test.go +++ b/pkg/waiter/waiter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index 3250cdcdc..6766953b3 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/config.go b/runsc/boot/config.go index 51d20d06d..9ebbde424 100644 --- a/runsc/boot/config.go +++ b/runsc/boot/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index bee82f344..6dd7fadd9 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/debug.go b/runsc/boot/debug.go index 971962c91..d224d08b7 100644 --- a/runsc/boot/debug.go +++ b/runsc/boot/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/events.go b/runsc/boot/events.go index 595846b10..f954b8c0b 100644 --- a/runsc/boot/events.go +++ b/runsc/boot/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/fds.go b/runsc/boot/fds.go index 9416e3a5c..a3d21d963 100644 --- a/runsc/boot/fds.go +++ b/runsc/boot/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index 92a73db9a..378396b9b 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/extra_filters.go b/runsc/boot/filter/extra_filters.go index 82cf00dfb..67f3101fe 100644 --- a/runsc/boot/filter/extra_filters.go +++ b/runsc/boot/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/extra_filters_msan.go b/runsc/boot/filter/extra_filters_msan.go index 76f3f6865..fb95283ab 100644 --- a/runsc/boot/filter/extra_filters_msan.go +++ b/runsc/boot/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/extra_filters_race.go b/runsc/boot/filter/extra_filters_race.go index ebd56c553..02a122c95 100644 --- a/runsc/boot/filter/extra_filters_race.go +++ b/runsc/boot/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index b656883ad..dc7294b1d 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index ea825e571..e52c89fe4 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/limits.go b/runsc/boot/limits.go index 510497eba..8ecda6d0e 100644 --- a/runsc/boot/limits.go +++ b/runsc/boot/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index c79b95bde..fa3de0133 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go index 41ff3681b..c342ee005 100644 --- a/runsc/boot/loader_test.go +++ b/runsc/boot/loader_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 6a2678ac9..89f186139 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/boot/strace.go b/runsc/boot/strace.go index 1e898672b..028bcc1f4 100644 --- a/runsc/boot/strace.go +++ b/runsc/boot/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index 7a75a189a..d6058a8a2 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cgroup/cgroup_test.go b/runsc/cgroup/cgroup_test.go index cde915329..4a4713d4f 100644 --- a/runsc/cgroup/cgroup_test.go +++ b/runsc/cgroup/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index 023b63dc0..7c14857ba 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/capability.go b/runsc/cmd/capability.go index 0b18c5481..e5da021e5 100644 --- a/runsc/cmd/capability.go +++ b/runsc/cmd/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/capability_test.go b/runsc/cmd/capability_test.go index 3329b308d..dd278b32d 100644 --- a/runsc/cmd/capability_test.go +++ b/runsc/cmd/capability_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index 023ab2455..d49d0169b 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go index 2937ae1c4..a1c3491a3 100644 --- a/runsc/cmd/cmd.go +++ b/runsc/cmd/cmd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index 275a96f57..b84185b43 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go index cb7d81057..288cbe435 100644 --- a/runsc/cmd/debug.go +++ b/runsc/cmd/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index 92b609c3c..ea1ca1278 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/delete_test.go b/runsc/cmd/delete_test.go index f6d164394..4a5b4774a 100644 --- a/runsc/cmd/delete_test.go +++ b/runsc/cmd/delete_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index df65ea31d..df03415ec 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 336edf3f6..9a395e6f1 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/exec_test.go b/runsc/cmd/exec_test.go index 623461e78..686c5e150 100644 --- a/runsc/cmd/exec_test.go +++ b/runsc/cmd/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index fd4eee546..3842fdf64 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index 7a98d10a2..1f1086250 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index 4d4a5cb0b..fd59b73e6 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/path.go b/runsc/cmd/path.go index c207b80da..baba937a8 100644 --- a/runsc/cmd/path.go +++ b/runsc/cmd/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index ac393b48e..5ff6f059c 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index 5d219bfdc..fd76cf975 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go index 6dc044672..cc99b3503 100644 --- a/runsc/cmd/restore.go +++ b/runsc/cmd/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index a12adf1a3..274b5d084 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index 9a87cf240..b6a12f5d6 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/spec.go b/runsc/cmd/spec.go index 6281fc49d..57ee37c86 100644 --- a/runsc/cmd/spec.go +++ b/runsc/cmd/spec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 97ea91fff..48bd4c401 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index 265014e1b..f8ce8c3d8 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index 956349140..121c54554 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/console/console.go b/runsc/console/console.go index 3df184742..9f4f9214d 100644 --- a/runsc/console/console.go +++ b/runsc/console/console.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/console_test.go b/runsc/container/console_test.go index 8f019b54a..0b0dfb4cb 100644 --- a/runsc/container/console_test.go +++ b/runsc/container/console_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/container.go b/runsc/container/container.go index f76bad1aa..cb4c9b5c1 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index 662591b3b..243528d35 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/fs.go b/runsc/container/fs.go index 2ed42fd93..41022686b 100644 --- a/runsc/container/fs.go +++ b/runsc/container/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/fs_test.go b/runsc/container/fs_test.go index 84bde18fb..87cdb078e 100644 --- a/runsc/container/fs_test.go +++ b/runsc/container/fs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/hook.go b/runsc/container/hook.go index 3d93ca0be..6b9e5550a 100644 --- a/runsc/container/hook.go +++ b/runsc/container/hook.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index 1781a4602..4548eb106 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/status.go b/runsc/container/status.go index bf177e78a..234ffb0dd 100644 --- a/runsc/container/status.go +++ b/runsc/container/status.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/container/test_app.go b/runsc/container/test_app.go index cc3b087e1..b5071ada6 100644 --- a/runsc/container/test_app.go +++ b/runsc/container/test_app.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index 35698f21f..75a087848 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/extra_filters.go b/runsc/fsgofer/filter/extra_filters.go index 82cf00dfb..67f3101fe 100644 --- a/runsc/fsgofer/filter/extra_filters.go +++ b/runsc/fsgofer/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/extra_filters_msan.go b/runsc/fsgofer/filter/extra_filters_msan.go index 169a79ed8..7e142b790 100644 --- a/runsc/fsgofer/filter/extra_filters_msan.go +++ b/runsc/fsgofer/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/extra_filters_race.go b/runsc/fsgofer/filter/extra_filters_race.go index 9e6512d8c..3cd29472a 100644 --- a/runsc/fsgofer/filter/extra_filters_race.go +++ b/runsc/fsgofer/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index 6f341f688..f50b6bc87 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index 9c4864cf1..e03bb7752 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index a500a2976..48860f952 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go index e676809ac..99bc25ec1 100644 --- a/runsc/fsgofer/fsgofer_unsafe.go +++ b/runsc/fsgofer/fsgofer_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/main.go b/runsc/main.go index 62b1f01b3..4a92db7c0 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/sandbox/chroot.go b/runsc/sandbox/chroot.go index 35b19a0b1..354049871 100644 --- a/runsc/sandbox/chroot.go +++ b/runsc/sandbox/chroot.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index 86a52c6ae..52fe8fc0f 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 923a52f7f..0fe85cfe1 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/specutils/namespace.go b/runsc/specutils/namespace.go index 00293d45b..73fab13e1 100644 --- a/runsc/specutils/namespace.go +++ b/runsc/specutils/namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index b29802fde..ab14ed1fc 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/specutils/specutils_test.go b/runsc/specutils/specutils_test.go index 64e2172c8..b61f1ca62 100644 --- a/runsc/specutils/specutils_test.go +++ b/runsc/specutils/specutils_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/image/image.go b/runsc/test/image/image.go index 069d08013..bcb6f876f 100644 --- a/runsc/test/image/image.go +++ b/runsc/test/image/image.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/image/image_test.go b/runsc/test/image/image_test.go index d89d80a86..763152b47 100644 --- a/runsc/test/image/image_test.go +++ b/runsc/test/image/image_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/image/mysql.sql b/runsc/test/image/mysql.sql index dd5bfaa4e..c1271e719 100644 --- a/runsc/test/image/mysql.sql +++ b/runsc/test/image/mysql.sql @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/image/ruby.rb b/runsc/test/image/ruby.rb index ae5de3419..25d1ac129 100644 --- a/runsc/test/image/ruby.rb +++ b/runsc/test/image/ruby.rb @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/image/ruby.sh b/runsc/test/image/ruby.sh index 54be2c931..d3a9b5656 100644 --- a/runsc/test/image/ruby.sh +++ b/runsc/test/image/ruby.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/install.sh b/runsc/test/install.sh index c239588d4..32e1e884e 100755 --- a/runsc/test/install.sh +++ b/runsc/test/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/runsc/test/integration/exec_test.go b/runsc/test/integration/exec_test.go index 3cac674d0..fac8337f4 100644 --- a/runsc/test/integration/exec_test.go +++ b/runsc/test/integration/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/integration/integration.go b/runsc/test/integration/integration.go index 49c3c893a..e15321c87 100644 --- a/runsc/test/integration/integration.go +++ b/runsc/test/integration/integration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/integration/integration_test.go b/runsc/test/integration/integration_test.go index 536bb17e0..526b3a7a1 100644 --- a/runsc/test/integration/integration_test.go +++ b/runsc/test/integration/integration_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/root/cgroup_test.go b/runsc/test/root/cgroup_test.go index 5cb4b794f..fdb94ff64 100644 --- a/runsc/test/root/cgroup_test.go +++ b/runsc/test/root/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/root/chroot_test.go b/runsc/test/root/chroot_test.go index 8831e6a78..0ffaaf87b 100644 --- a/runsc/test/root/chroot_test.go +++ b/runsc/test/root/chroot_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/root/root.go b/runsc/test/root/root.go index 790f62c29..586ea0fe3 100644 --- a/runsc/test/root/root.go +++ b/runsc/test/root/root.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go index 7d6a72e5f..3f74e0770 100644 --- a/runsc/test/testutil/docker.go +++ b/runsc/test/testutil/docker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/testutil/testutil.go b/runsc/test/testutil/testutil.go index 4d7ac3bc9..1b5a02c0f 100644 --- a/runsc/test/testutil/testutil.go +++ b/runsc/test/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/test/testutil/testutil_race.go b/runsc/test/testutil/testutil_race.go index 59cfdaa7b..9267af150 100644 --- a/runsc/test/testutil/testutil_race.go +++ b/runsc/test/testutil/testutil_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/runsc/tools/dockercfg/dockercfg.go b/runsc/tools/dockercfg/dockercfg.go index 0bd6cad93..110a581ff 100644 --- a/runsc/tools/dockercfg/dockercfg.go +++ b/runsc/tools/dockercfg/dockercfg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics.go b/tools/go_generics/generics.go index cc61a7537..eaf5c4970 100644 --- a/tools/go_generics/generics.go +++ b/tools/go_generics/generics.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_stmts/input.go b/tools/go_generics/generics_tests/all_stmts/input.go index 870af3b6c..19184a3fe 100644 --- a/tools/go_generics/generics_tests/all_stmts/input.go +++ b/tools/go_generics/generics_tests/all_stmts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_stmts/output/output.go b/tools/go_generics/generics_tests/all_stmts/output/output.go index e4e670bf1..51582346c 100644 --- a/tools/go_generics/generics_tests/all_stmts/output/output.go +++ b/tools/go_generics/generics_tests/all_stmts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_types/input.go b/tools/go_generics/generics_tests/all_types/input.go index 3a8643e3d..ed6e97c29 100644 --- a/tools/go_generics/generics_tests/all_types/input.go +++ b/tools/go_generics/generics_tests/all_types/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_types/lib/lib.go b/tools/go_generics/generics_tests/all_types/lib/lib.go index d3911d12d..7e73e678e 100644 --- a/tools/go_generics/generics_tests/all_types/lib/lib.go +++ b/tools/go_generics/generics_tests/all_types/lib/lib.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/all_types/output/output.go b/tools/go_generics/generics_tests/all_types/output/output.go index b89840936..ec09a6be4 100644 --- a/tools/go_generics/generics_tests/all_types/output/output.go +++ b/tools/go_generics/generics_tests/all_types/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/consts/input.go b/tools/go_generics/generics_tests/consts/input.go index dabf76e1e..394bcc262 100644 --- a/tools/go_generics/generics_tests/consts/input.go +++ b/tools/go_generics/generics_tests/consts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/consts/output/output.go b/tools/go_generics/generics_tests/consts/output/output.go index 72865607e..91a07fdc2 100644 --- a/tools/go_generics/generics_tests/consts/output/output.go +++ b/tools/go_generics/generics_tests/consts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/imports/input.go b/tools/go_generics/generics_tests/imports/input.go index 66b43fee5..22e6641a6 100644 --- a/tools/go_generics/generics_tests/imports/input.go +++ b/tools/go_generics/generics_tests/imports/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/imports/output/output.go b/tools/go_generics/generics_tests/imports/output/output.go index 5f20d43ce..2555c0004 100644 --- a/tools/go_generics/generics_tests/imports/output/output.go +++ b/tools/go_generics/generics_tests/imports/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/remove_typedef/input.go b/tools/go_generics/generics_tests/remove_typedef/input.go index c02307d32..d9c9b8530 100644 --- a/tools/go_generics/generics_tests/remove_typedef/input.go +++ b/tools/go_generics/generics_tests/remove_typedef/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/remove_typedef/output/output.go b/tools/go_generics/generics_tests/remove_typedef/output/output.go index d20a89abd..f111a9426 100644 --- a/tools/go_generics/generics_tests/remove_typedef/output/output.go +++ b/tools/go_generics/generics_tests/remove_typedef/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/simple/input.go b/tools/go_generics/generics_tests/simple/input.go index 670161d6e..711687cf5 100644 --- a/tools/go_generics/generics_tests/simple/input.go +++ b/tools/go_generics/generics_tests/simple/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/generics_tests/simple/output/output.go b/tools/go_generics/generics_tests/simple/output/output.go index 75b5467cd..139c9bf9d 100644 --- a/tools/go_generics/generics_tests/simple/output/output.go +++ b/tools/go_generics/generics_tests/simple/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/globals/globals_visitor.go b/tools/go_generics/globals/globals_visitor.go index fc0de4381..daaa17b1d 100644 --- a/tools/go_generics/globals/globals_visitor.go +++ b/tools/go_generics/globals/globals_visitor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/globals/scope.go b/tools/go_generics/globals/scope.go index 18743bdee..b75a91689 100644 --- a/tools/go_generics/globals/scope.go +++ b/tools/go_generics/globals/scope.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/go_generics_unittest.sh b/tools/go_generics/go_generics_unittest.sh index 699e1f631..e7553a071 100755 --- a/tools/go_generics/go_generics_unittest.sh +++ b/tools/go_generics/go_generics_unittest.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tools/go_generics/imports.go b/tools/go_generics/imports.go index 97267098b..57f7c3dce 100644 --- a/tools/go_generics/imports.go +++ b/tools/go_generics/imports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/merge.go b/tools/go_generics/merge.go index ebe7cf4e4..2f83facf8 100644 --- a/tools/go_generics/merge.go +++ b/tools/go_generics/merge.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/remove.go b/tools/go_generics/remove.go index 2a66de762..139d03955 100644 --- a/tools/go_generics/remove.go +++ b/tools/go_generics/remove.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/rules_tests/template.go b/tools/go_generics/rules_tests/template.go index 73c024f0e..f3f31ae8e 100644 --- a/tools/go_generics/rules_tests/template.go +++ b/tools/go_generics/rules_tests/template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_generics/rules_tests/template_test.go b/tools/go_generics/rules_tests/template_test.go index 76c4cdb64..3a38c8629 100644 --- a/tools/go_generics/rules_tests/template_test.go +++ b/tools/go_generics/rules_tests/template_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/go_stateify/main.go b/tools/go_stateify/main.go index 5646b879a..9e2c8e106 100644 --- a/tools/go_stateify/main.go +++ b/tools/go_stateify/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/tools/workspace_status.sh b/tools/workspace_status.sh index d89db1f99..7d44dad37 100755 --- a/tools/workspace_status.sh +++ b/tools/workspace_status.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vdso/barrier.h b/vdso/barrier.h index db8185b2e..7866af414 100644 --- a/vdso/barrier.h +++ b/vdso/barrier.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/check_vdso.py b/vdso/check_vdso.py index 9a3142ab8..6f7d7e7ec 100644 --- a/vdso/check_vdso.py +++ b/vdso/check_vdso.py @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/vdso/compiler.h b/vdso/compiler.h index a661516c3..d65f148fb 100644 --- a/vdso/compiler.h +++ b/vdso/compiler.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/cycle_clock.h b/vdso/cycle_clock.h index 93c5f2c0d..dfb5b427d 100644 --- a/vdso/cycle_clock.h +++ b/vdso/cycle_clock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/seqlock.h b/vdso/seqlock.h index b527bdbca..ab2f3fda3 100644 --- a/vdso/seqlock.h +++ b/vdso/seqlock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/syscalls.h b/vdso/syscalls.h index fd79c4642..0be8a7f9b 100644 --- a/vdso/syscalls.h +++ b/vdso/syscalls.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/vdso.cc b/vdso/vdso.cc index db3bdef01..f30dc26a2 100644 --- a/vdso/vdso.cc +++ b/vdso/vdso.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/vdso_time.cc b/vdso/vdso_time.cc index 5d5c8de65..a59771bff 100644 --- a/vdso/vdso_time.cc +++ b/vdso/vdso_time.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vdso/vdso_time.h b/vdso/vdso_time.h index 71d6e2f64..464dadff2 100644 --- a/vdso/vdso_time.h +++ b/vdso/vdso_time.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google Inc. +// Copyright 2018 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. -- cgit v1.2.3 From b2068cf5a5d43f3898cf389ab2d6151cf61908ac Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Sat, 20 Oct 2018 11:12:26 -0700 Subject: Add more unimplemented syscall events Added events for *ctl syscalls that may have multiple different commands. For runsc, each syscall event is only logged once. For *ctl syscalls, use the cmd as identifier, not only the syscall number. PiperOrigin-RevId: 218015941 Change-Id: Ie3c19131ae36124861e9b492a7dbe1765d9e5e59 --- pkg/abi/linux/ioctl.go | 75 +++++++++++++------ pkg/abi/linux/prctl.go | 99 +++++++++++++++++++++++-- pkg/sentry/fs/host/BUILD | 1 + pkg/sentry/fs/host/tty.go | 30 ++++++++ pkg/sentry/fs/tty/BUILD | 1 + pkg/sentry/fs/tty/master.go | 45 ++++++++++- pkg/sentry/fs/tty/slave.go | 3 +- pkg/sentry/kernel/BUILD | 2 + pkg/sentry/kernel/kernel.go | 17 +++++ pkg/sentry/kernel/pipe/reader_writer.go | 3 +- pkg/sentry/kernel/task.go | 3 + pkg/sentry/socket/epsocket/BUILD | 1 + pkg/sentry/socket/epsocket/epsocket.go | 3 + pkg/sentry/socket/rpcinet/BUILD | 1 + pkg/sentry/socket/rpcinet/socket.go | 5 ++ pkg/sentry/syscalls/BUILD | 18 ----- pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_prctl.go | 39 +++++++++- pkg/sentry/syscalls/linux/sys_shm.go | 1 + pkg/sentry/syscalls/linux/sys_tls.go | 3 + pkg/sentry/syscalls/syscalls.go | 15 +--- pkg/sentry/syscalls/unimplemented_syscall.proto | 27 ------- pkg/sentry/unimpl/BUILD | 30 ++++++++ pkg/sentry/unimpl/events.go | 45 +++++++++++ pkg/sentry/unimpl/unimplemented_syscall.proto | 27 +++++++ runsc/boot/BUILD | 9 ++- runsc/boot/compat.go | 72 ++++++++++++++++-- runsc/boot/compat_amd64.go | 54 ++++++++++++++ runsc/boot/compat_test.go | 66 +++++++++++++++++ 29 files changed, 596 insertions(+), 101 deletions(-) delete mode 100644 pkg/sentry/syscalls/unimplemented_syscall.proto create mode 100644 pkg/sentry/unimpl/BUILD create mode 100644 pkg/sentry/unimpl/events.go create mode 100644 pkg/sentry/unimpl/unimplemented_syscall.proto create mode 100644 runsc/boot/compat_amd64.go create mode 100644 runsc/boot/compat_test.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 9afc3d1ef..191b26e4d 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -18,28 +18,59 @@ package linux // // These are ordered by request number (low byte). const ( - TCGETS = 0x00005401 - TCSETS = 0x00005402 - TCSETSW = 0x00005403 - TCSETSF = 0x00005404 - TIOCSCTTY = 0x0000540e - TIOCGPGRP = 0x0000540f - TIOCSPGRP = 0x00005410 - TIOCOUTQ = 0x00005411 - TIOCGWINSZ = 0x00005413 - TIOCSWINSZ = 0x00005414 - TIOCINQ = 0x0000541b - FIONREAD = TIOCINQ - FIONBIO = 0x00005421 - TIOCGPTN = 0x80045430 - TIOCSPTLCK = 0x40045431 - FIONCLEX = 0x00005450 - FIOCLEX = 0x00005451 - FIOASYNC = 0x00005452 - FIOSETOWN = 0x00008901 - SIOCSPGRP = 0x00008902 - FIOGETOWN = 0x00008903 - SIOCGPGRP = 0x00008904 + TCGETS = 0x00005401 + TCSETS = 0x00005402 + TCSETSW = 0x00005403 + TCSETSF = 0x00005404 + TCSBRK = 0x00005409 + TIOCEXCL = 0x0000540c + TIOCNXCL = 0x0000540d + TIOCSCTTY = 0x0000540e + TIOCGPGRP = 0x0000540f + TIOCSPGRP = 0x00005410 + TIOCOUTQ = 0x00005411 + TIOCSTI = 0x00005412 + TIOCGWINSZ = 0x00005413 + TIOCSWINSZ = 0x00005414 + TIOCMGET = 0x00005415 + TIOCMBIS = 0x00005416 + TIOCMBIC = 0x00005417 + TIOCMSET = 0x00005418 + TIOCINQ = 0x0000541b + FIONREAD = TIOCINQ + FIONBIO = 0x00005421 + TIOCSETD = 0x00005423 + TIOCNOTTY = 0x00005422 + TIOCGETD = 0x00005424 + TCSBRKP = 0x00005425 + TIOCSBRK = 0x00005427 + TIOCCBRK = 0x00005428 + TIOCGSID = 0x00005429 + TIOCGPTN = 0x80045430 + TIOCSPTLCK = 0x40045431 + TIOCGDEV = 0x80045432 + TIOCVHANGUP = 0x00005437 + TCFLSH = 0x0000540b + TIOCCONS = 0x0000541d + TIOCSSERIAL = 0x0000541f + TIOCGEXCL = 0x80045440 + TIOCGPTPEER = 0x80045441 + TIOCGICOUNT = 0x0000545d + FIONCLEX = 0x00005450 + FIOCLEX = 0x00005451 + FIOASYNC = 0x00005452 + FIOSETOWN = 0x00008901 + SIOCSPGRP = 0x00008902 + FIOGETOWN = 0x00008903 + SIOCGPGRP = 0x00008904 +) + +// ioctl(2) requests provided by uapi/linux/sockios.h +const ( + SIOCGIFMEM = 0x891f + SIOCGIFPFLAGS = 0x8935 + SIOCGMIIPHY = 0x8947 + SIOCGMIIREG = 0x8948 ) // ioctl(2) requests provided by uapi/linux/android/binder.h diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index e152c4c27..db3206f36 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -22,26 +22,102 @@ const ( // PR_GET_PDEATHSIG will get the process' death signal. PR_GET_PDEATHSIG = 2 + // PR_GET_DUMPABLE will get the process's dumpable flag. + PR_GET_DUMPABLE = 3 + + // PR_SET_DUMPABLE will set the process's dumpable flag. + PR_SET_DUMPABLE = 4 + // PR_GET_KEEPCAPS will get the value of the keep capabilities flag. PR_GET_KEEPCAPS = 7 // PR_SET_KEEPCAPS will set the value of the keep capabilities flag. PR_SET_KEEPCAPS = 8 + // PR_GET_TIMING will get the process's timing method. + PR_GET_TIMING = 13 + + // PR_SET_TIMING will set the process's timing method. + PR_SET_TIMING = 14 + // PR_SET_NAME will set the process' name. PR_SET_NAME = 15 // PR_GET_NAME will get the process' name. PR_GET_NAME = 16 + // PR_GET_SECCOMP will get a process' seccomp mode. + PR_GET_SECCOMP = 21 + + // PR_SET_SECCOMP will set a process' seccomp mode. + PR_SET_SECCOMP = 22 + + // PR_CAPBSET_READ will get the capability bounding set. + PR_CAPBSET_READ = 23 + + // PR_CAPBSET_DROP will set the capability bounding set. + PR_CAPBSET_DROP = 24 + + // PR_GET_TSC will get the the value of the flag determining whether the + // timestamp counter can be read. + PR_GET_TSC = 25 + + // PR_SET_TSC will set the the value of the flag determining whether the + // timestamp counter can be read. + PR_SET_TSC = 26 + + // PR_SET_TIMERSLACK set the process's time slack. + PR_SET_TIMERSLACK = 29 + + // PR_GET_TIMERSLACK get the process's time slack. + PR_GET_TIMERSLACK = 30 + + // PR_TASK_PERF_EVENTS_DISABLE disable all performance counters attached to + // the calling process. + PR_TASK_PERF_EVENTS_DISABLE = 31 + + // PR_TASK_PERF_EVENTS_ENABLE enable all performance counters attached to + // the calling process. + PR_TASK_PERF_EVENTS_ENABLE = 32 + + // PR_MCE_KILL set the machine check memory corruption kill policy for the + // calling thread. + PR_MCE_KILL = 33 + + // PR_MCE_KILL_GET get the machine check memory corruption kill policy for the + // calling thread. + PR_MCE_KILL_GET = 34 + // PR_SET_MM will modify certain kernel memory map descriptor fields of the // calling process. See prctl(2) for more information. PR_SET_MM = 35 + PR_SET_MM_START_CODE = 1 + PR_SET_MM_END_CODE = 2 + PR_SET_MM_START_DATA = 3 + PR_SET_MM_END_DATA = 4 + PR_SET_MM_START_STACK = 5 + PR_SET_MM_START_BRK = 6 + PR_SET_MM_BRK = 7 + PR_SET_MM_ARG_START = 8 + PR_SET_MM_ARG_END = 9 + PR_SET_MM_ENV_START = 10 + PR_SET_MM_ENV_END = 11 + PR_SET_MM_AUXV = 12 // PR_SET_MM_EXE_FILE will supersede the /proc/pid/exe symbolic link with a // new one pointing to a new executable file identified by the file descriptor // provided in arg3 argument. See prctl(2) for more information. PR_SET_MM_EXE_FILE = 13 + PR_SET_MM_MAP = 14 + PR_SET_MM_MAP_SIZE = 15 + + // PR_SET_CHILD_SUBREAPER set the "child subreaper" attribute of the calling + // process. + PR_SET_CHILD_SUBREAPER = 36 + + // PR_GET_CHILD_SUBREAPER get the "child subreaper" attribute of the calling + // process. + PR_GET_CHILD_SUBREAPER = 37 // PR_SET_NO_NEW_PRIVS will set the calling thread's no_new_privs bit. PR_SET_NO_NEW_PRIVS = 38 @@ -49,17 +125,24 @@ const ( // PR_GET_NO_NEW_PRIVS will get the calling thread's no_new_privs bit. PR_GET_NO_NEW_PRIVS = 39 - // PR_SET_SECCOMP will set a process' seccomp mode. - PR_SET_SECCOMP = 22 + // PR_GET_TID_ADDRESS retrieve the clear_child_tid address. + PR_GET_TID_ADDRESS = 40 - // PR_GET_SECCOMP will get a process' seccomp mode. - PR_GET_SECCOMP = 21 + // PR_SET_THP_DISABLE set the state of the "THP disable" flag for the calling + // thread. + PR_SET_THP_DISABLE = 41 - // PR_CAPBSET_READ will get the capability bounding set. - PR_CAPBSET_READ = 23 + // PR_GET_THP_DISABLE get the state of the "THP disable" flag for the calling + // thread. + PR_GET_THP_DISABLE = 42 - // PR_CAPBSET_DROP will set the capability bounding set. - PR_CAPBSET_DROP = 24 + // PR_MPX_ENABLE_MANAGEMENT enable kernel management of Memory Protection + // eXtensions (MPX) bounds tables. + PR_MPX_ENABLE_MANAGEMENT = 43 + + // PR_MPX_DISABLE_MANAGEMENTdisable kernel management of Memory Protection + // eXtensions (MPX) bounds tables. + PR_MPX_DISABLE_MANAGEMENT = 44 ) // From diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 4f264a024..d1eb9bd64 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -43,6 +43,7 @@ go_library( "//pkg/sentry/socket/control", "//pkg/sentry/socket/unix", "//pkg/sentry/socket/unix/transport", + "//pkg/sentry/unimpl", "//pkg/sentry/uniqueid", "//pkg/sentry/usermem", "//pkg/syserr", diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go index cf3639c46..f0bcdc908 100644 --- a/pkg/sentry/fs/host/tty.go +++ b/pkg/sentry/fs/host/tty.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -179,6 +180,35 @@ func (t *TTYFileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch. err := ioctlSetWinsize(fd, &winsize) return 0, err + // Unimplemented commands. + case linux.TIOCSETD, + linux.TIOCSBRK, + linux.TIOCCBRK, + linux.TCSBRK, + linux.TCSBRKP, + linux.TIOCSTI, + linux.TIOCCONS, + linux.FIONBIO, + linux.TIOCEXCL, + linux.TIOCNXCL, + linux.TIOCGEXCL, + linux.TIOCNOTTY, + linux.TIOCSCTTY, + linux.TIOCGSID, + linux.TIOCGETD, + linux.TIOCVHANGUP, + linux.TIOCGDEV, + linux.TIOCMGET, + linux.TIOCMSET, + linux.TIOCMBIC, + linux.TIOCMBIS, + linux.TIOCGICOUNT, + linux.TCFLSH, + linux.TIOCSSERIAL, + linux.TIOCGPTPEER: + + unimpl.EmitUnimplementedEvent(ctx) + fallthrough default: return 0, syserror.ENOTTY } diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index d4dd20e30..2b45069a6 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -27,6 +27,7 @@ go_library( "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", "//pkg/sentry/socket/unix/transport", + "//pkg/sentry/unimpl", "//pkg/sentry/usermem", "//pkg/syserror", "//pkg/waiter", diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index dad0cad79..00bec4c2c 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -20,6 +20,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/waiter" @@ -149,7 +150,7 @@ func (mf *masterFileOperations) Write(ctx context.Context, _ *fs.File, src userm // Ioctl implements fs.FileOperations.Ioctl. func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { - switch args[1].Uint() { + switch cmd := args[1].Uint(); cmd { case linux.FIONREAD: // linux.FIONREAD == linux.TIOCINQ // Get the number of bytes in the output queue read buffer. return 0, mf.t.ld.outputQueueReadSize(ctx, io, args) @@ -177,6 +178,48 @@ func (mf *masterFileOperations) Ioctl(ctx context.Context, io usermem.IO, args a case linux.TIOCSWINSZ: return 0, mf.t.ld.setWindowSize(ctx, io, args) default: + maybeEmitUnimplementedEvent(ctx, cmd) return 0, syserror.ENOTTY } } + +// maybeEmitUnimplementedEvent emits unimplemented event if cmd is valid. +func maybeEmitUnimplementedEvent(ctx context.Context, cmd uint32) { + switch cmd { + case linux.TCGETS, + linux.TCSETS, + linux.TCSETSW, + linux.TCSETSF, + linux.TIOCGPGRP, + linux.TIOCSPGRP, + linux.TIOCGWINSZ, + linux.TIOCSWINSZ, + linux.TIOCSETD, + linux.TIOCSBRK, + linux.TIOCCBRK, + linux.TCSBRK, + linux.TCSBRKP, + linux.TIOCSTI, + linux.TIOCCONS, + linux.FIONBIO, + linux.TIOCEXCL, + linux.TIOCNXCL, + linux.TIOCGEXCL, + linux.TIOCNOTTY, + linux.TIOCSCTTY, + linux.TIOCGSID, + linux.TIOCGETD, + linux.TIOCVHANGUP, + linux.TIOCGDEV, + linux.TIOCMGET, + linux.TIOCMSET, + linux.TIOCMBIC, + linux.TIOCMBIS, + linux.TIOCGICOUNT, + linux.TCFLSH, + linux.TIOCSSERIAL, + linux.TIOCGPTPEER: + + unimpl.EmitUnimplementedEvent(ctx) + } +} diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 9de3168bf..a696fbb51 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -134,7 +134,7 @@ func (sf *slaveFileOperations) Write(ctx context.Context, _ *fs.File, src userme // Ioctl implements fs.FileOperations.Ioctl. func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { - switch args[1].Uint() { + switch cmd := args[1].Uint(); cmd { case linux.FIONREAD: // linux.FIONREAD == linux.TIOCINQ // Get the number of bytes in the input queue read buffer. return 0, sf.si.t.ld.inputQueueReadSize(ctx, io, args) @@ -161,6 +161,7 @@ func (sf *slaveFileOperations) Ioctl(ctx context.Context, io usermem.IO, args ar // control. return 0, nil default: + maybeEmitUnimplementedEvent(ctx, cmd) return 0, syserror.ENOTTY } } diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index e2fb61ba6..389824b25 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -157,6 +157,8 @@ go_library( "//pkg/sentry/socket/netlink/port", "//pkg/sentry/socket/unix/transport", "//pkg/sentry/time", + "//pkg/sentry/unimpl", + "//pkg/sentry/unimpl:unimplemented_syscall_go_proto", "//pkg/sentry/uniqueid", "//pkg/sentry/usage", "//pkg/sentry/usermem", diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index bad558d48..17425e656 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -40,6 +40,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/cpuid" + "gvisor.googlesource.com/gvisor/pkg/eventchannel" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" @@ -58,6 +59,8 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/platform" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/port" sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time" + "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl" + uspb "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl/unimplemented_syscall_go_proto" "gvisor.googlesource.com/gvisor/pkg/sentry/uniqueid" "gvisor.googlesource.com/gvisor/pkg/state" "gvisor.googlesource.com/gvisor/pkg/tcpip" @@ -595,6 +598,8 @@ func (ctx *createProcessContext) Value(key interface{}) interface{} { return ctx.k case uniqueid.CtxInotifyCookie: return ctx.k.GenerateInotifyCookie() + case unimpl.CtxEvents: + return ctx.k default: return nil } @@ -1033,6 +1038,16 @@ func (k *Kernel) SupervisorContext() context.Context { } } +// EmitUnimplementedEvent emits an UnimplementedSyscall event via the event +// channel. +func (k *Kernel) EmitUnimplementedEvent(ctx context.Context) { + t := TaskFromContext(ctx) + eventchannel.Emit(&uspb.UnimplementedSyscall{ + Tid: int32(t.ThreadID()), + Registers: t.Arch().StateData().Proto(), + }) +} + type supervisorContext struct { context.NoopSleeper log.Logger @@ -1073,6 +1088,8 @@ func (ctx supervisorContext) Value(key interface{}) interface{} { return ctx.k case uniqueid.CtxInotifyCookie: return ctx.k.GenerateInotifyCookie() + case unimpl.CtxEvents: + return ctx.k default: return nil } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 63efc5bbe..36be1efc3 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -19,6 +19,7 @@ import ( "math" "syscall" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" @@ -77,7 +78,7 @@ func (rw *ReaderWriter) Readiness(mask waiter.EventMask) waiter.EventMask { func (rw *ReaderWriter) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { // Switch on ioctl request. switch int(args[1].Int()) { - case syscall.TIOCINQ: + case linux.FIONREAD: v := rw.queuedSize() if v > math.MaxInt32 { panic(fmt.Sprintf("Impossibly large pipe queued size: %d", v)) diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index e22ec768d..73ba8bee9 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -30,6 +30,7 @@ import ( ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/platform" + "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl" "gvisor.googlesource.com/gvisor/pkg/sentry/uniqueid" "gvisor.googlesource.com/gvisor/pkg/sentry/usage" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -594,6 +595,8 @@ func (t *Task) Value(key interface{}) interface{} { return t.k case uniqueid.CtxInotifyCookie: return t.k.GenerateInotifyCookie() + case unimpl.CtxEvents: + return t.k default: return nil } diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index dbabc931c..da4aaf510 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -32,6 +32,7 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/socket", "//pkg/sentry/socket/unix/transport", + "//pkg/sentry/unimpl", "//pkg/sentry/usermem", "//pkg/syserr", "//pkg/syserror", diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index e90ef4835..39a0b9941 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -45,6 +45,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" "gvisor.googlesource.com/gvisor/pkg/sentry/socket" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" + "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserr" "gvisor.googlesource.com/gvisor/pkg/syserror" @@ -1184,6 +1185,8 @@ func Ioctl(ctx context.Context, ep commonEndpoint, io usermem.IO, args arch.Sysc }) return 0, err + case linux.SIOCGIFMEM, linux.SIOCGIFPFLAGS, linux.SIOCGMIIPHY, linux.SIOCGMIIREG: + unimpl.EmitUnimplementedEvent(ctx) } return 0, syserror.ENOTTY diff --git a/pkg/sentry/socket/rpcinet/BUILD b/pkg/sentry/socket/rpcinet/BUILD index 3ea433360..38fa54283 100644 --- a/pkg/sentry/socket/rpcinet/BUILD +++ b/pkg/sentry/socket/rpcinet/BUILD @@ -32,6 +32,7 @@ go_library( "//pkg/sentry/socket/rpcinet/conn", "//pkg/sentry/socket/rpcinet/notifier", "//pkg/sentry/socket/unix/transport", + "//pkg/sentry/unimpl", "//pkg/sentry/usermem", "//pkg/syserr", "//pkg/syserror", diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 44fa5c620..788d853c9 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -32,6 +32,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/socket/rpcinet/notifier" pb "gvisor.googlesource.com/gvisor/pkg/sentry/socket/rpcinet/syscall_rpc_go_proto" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" + "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserr" "gvisor.googlesource.com/gvisor/pkg/syserror" @@ -555,6 +556,10 @@ func (s *socketOperations) Ioctl(ctx context.Context, io usermem.IO, args arch.S }) return 0, err + + case linux.SIOCGIFMEM, linux.SIOCGIFPFLAGS, linux.SIOCGMIIPHY, linux.SIOCGMIIREG: + unimpl.EmitUnimplementedEvent(ctx) + default: return 0, syserror.ENOTTY } diff --git a/pkg/sentry/syscalls/BUILD b/pkg/sentry/syscalls/BUILD index 22a757095..2a9f0915e 100644 --- a/pkg/sentry/syscalls/BUILD +++ b/pkg/sentry/syscalls/BUILD @@ -1,7 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_stateify:defs.bzl", "go_library") -load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") go_library( name = "syscalls", @@ -13,9 +12,7 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls", visibility = ["//:sandbox"], deps = [ - ":unimplemented_syscall_go_proto", "//pkg/abi/linux", - "//pkg/eventchannel", "//pkg/sentry/arch", "//pkg/sentry/fs", "//pkg/sentry/kernel", @@ -26,18 +23,3 @@ go_library( "//pkg/waiter", ], ) - -proto_library( - name = "unimplemented_syscall_proto", - srcs = ["unimplemented_syscall.proto"], - visibility = ["//visibility:public"], - deps = ["//pkg/sentry/arch:registers_proto"], -) - -go_proto_library( - name = "unimplemented_syscall_go_proto", - importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/unimplemented_syscall_go_proto", - proto = ":unimplemented_syscall_proto", - visibility = ["//visibility:public"], - deps = ["//pkg/sentry/arch:registers_go_proto"], -) diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 75e87f5ec..11bf81f88 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -369,7 +369,7 @@ var AMD64 = &kernel.SyscallTable{ 0xffffffffff600800: 309, // vsyscall getcpu(2) }, Missing: func(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { - syscalls.UnimplementedEvent(t) + t.Kernel().EmitUnimplementedEvent(t) return 0, syserror.ENOSYS }, } diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go index c7b39ede8..91e852049 100644 --- a/pkg/sentry/syscalls/linux/sys_prctl.go +++ b/pkg/sentry/syscalls/linux/sys_prctl.go @@ -104,6 +104,22 @@ func Prctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall // Set the underlying executable. t.MemoryManager().SetExecutable(file.Dirent) + + case linux.PR_SET_MM_AUXV, + linux.PR_SET_MM_START_CODE, + linux.PR_SET_MM_END_CODE, + linux.PR_SET_MM_START_DATA, + linux.PR_SET_MM_END_DATA, + linux.PR_SET_MM_START_STACK, + linux.PR_SET_MM_START_BRK, + linux.PR_SET_MM_BRK, + linux.PR_SET_MM_ARG_START, + linux.PR_SET_MM_ARG_END, + linux.PR_SET_MM_ENV_START, + linux.PR_SET_MM_ENV_END: + + t.Kernel().EmitUnimplementedEvent(t) + fallthrough default: return 0, nil, syscall.EINVAL } @@ -151,8 +167,29 @@ func Prctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall } return 0, nil, t.DropBoundingCapability(cp) + case linux.PR_GET_DUMPABLE, + linux.PR_SET_DUMPABLE, + linux.PR_GET_TIMING, + linux.PR_SET_TIMING, + linux.PR_GET_TSC, + linux.PR_SET_TSC, + linux.PR_TASK_PERF_EVENTS_DISABLE, + linux.PR_TASK_PERF_EVENTS_ENABLE, + linux.PR_GET_TIMERSLACK, + linux.PR_SET_TIMERSLACK, + linux.PR_MCE_KILL, + linux.PR_MCE_KILL_GET, + linux.PR_GET_TID_ADDRESS, + linux.PR_SET_CHILD_SUBREAPER, + linux.PR_GET_CHILD_SUBREAPER, + linux.PR_GET_THP_DISABLE, + linux.PR_SET_THP_DISABLE, + linux.PR_MPX_ENABLE_MANAGEMENT, + linux.PR_MPX_DISABLE_MANAGEMENT: + + t.Kernel().EmitUnimplementedEvent(t) + fallthrough default: - t.Warningf("Unsupported prctl %d", option) return 0, nil, syscall.EINVAL } diff --git a/pkg/sentry/syscalls/linux/sys_shm.go b/pkg/sentry/syscalls/linux/sys_shm.go index b13d48b98..5f887523a 100644 --- a/pkg/sentry/syscalls/linux/sys_shm.go +++ b/pkg/sentry/syscalls/linux/sys_shm.go @@ -147,6 +147,7 @@ func Shmctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal // We currently do not support memmory locking anywhere. // mlock(2)/munlock(2) are currently stubbed out as no-ops so do the // same here. + t.Kernel().EmitUnimplementedEvent(t) return 0, nil, nil default: diff --git a/pkg/sentry/syscalls/linux/sys_tls.go b/pkg/sentry/syscalls/linux/sys_tls.go index 27ddb3808..40e84825b 100644 --- a/pkg/sentry/syscalls/linux/sys_tls.go +++ b/pkg/sentry/syscalls/linux/sys_tls.go @@ -45,6 +45,9 @@ func ArchPrctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys regs.Fs = 0 regs.Fs_base = fsbase + case linux.ARCH_GET_GS, linux.ARCH_SET_GS: + t.Kernel().EmitUnimplementedEvent(t) + fallthrough default: return 0, nil, syscall.EINVAL } diff --git a/pkg/sentry/syscalls/syscalls.go b/pkg/sentry/syscalls/syscalls.go index bae32d727..425ce900c 100644 --- a/pkg/sentry/syscalls/syscalls.go +++ b/pkg/sentry/syscalls/syscalls.go @@ -26,10 +26,8 @@ package syscalls import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" - "gvisor.googlesource.com/gvisor/pkg/eventchannel" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" - uspb "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/unimplemented_syscall_go_proto" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -44,7 +42,7 @@ func Error(err error) kernel.SyscallFn { // syscall event via the event channel and returns the passed error. func ErrorWithEvent(err error) kernel.SyscallFn { return func(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - UnimplementedEvent(t) + t.Kernel().EmitUnimplementedEvent(t) return 0, nil, err } } @@ -57,16 +55,7 @@ func CapError(c linux.Capability) kernel.SyscallFn { if !t.HasCapability(c) { return 0, nil, syserror.EPERM } - UnimplementedEvent(t) + t.Kernel().EmitUnimplementedEvent(t) return 0, nil, syserror.ENOSYS } } - -// UnimplementedEvent emits an UnimplementedSyscall event via the event -// channel. -func UnimplementedEvent(t *kernel.Task) { - eventchannel.Emit(&uspb.UnimplementedSyscall{ - Tid: int32(t.ThreadID()), - Registers: t.Arch().StateData().Proto(), - }) -} diff --git a/pkg/sentry/syscalls/unimplemented_syscall.proto b/pkg/sentry/syscalls/unimplemented_syscall.proto deleted file mode 100644 index 41579b016..000000000 --- a/pkg/sentry/syscalls/unimplemented_syscall.proto +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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. - -syntax = "proto3"; - -package gvisor; - -import "pkg/sentry/arch/registers.proto"; - -message UnimplementedSyscall { - // Task ID. - int32 tid = 1; - - // Registers at the time of the call. - Registers registers = 2; -} diff --git a/pkg/sentry/unimpl/BUILD b/pkg/sentry/unimpl/BUILD new file mode 100644 index 000000000..63da5e81f --- /dev/null +++ b/pkg/sentry/unimpl/BUILD @@ -0,0 +1,30 @@ +package(licenses = ["notice"]) # Apache 2.0 + +load("//tools/go_stateify:defs.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") + +proto_library( + name = "unimplemented_syscall_proto", + srcs = ["unimplemented_syscall.proto"], + visibility = ["//visibility:public"], + deps = ["//pkg/sentry/arch:registers_proto"], +) + +go_proto_library( + name = "unimplemented_syscall_go_proto", + importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl/unimplemented_syscall_go_proto", + proto = ":unimplemented_syscall_proto", + visibility = ["//visibility:public"], + deps = ["//pkg/sentry/arch:registers_go_proto"], +) + +go_library( + name = "unimpl", + srcs = ["events.go"], + importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl", + visibility = ["//:sandbox"], + deps = [ + "//pkg/log", + "//pkg/sentry/context", + ], +) diff --git a/pkg/sentry/unimpl/events.go b/pkg/sentry/unimpl/events.go new file mode 100644 index 000000000..f78f8c981 --- /dev/null +++ b/pkg/sentry/unimpl/events.go @@ -0,0 +1,45 @@ +// Copyright 2018 Google LLC +// +// 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 unimpl contains interface to emit events about unimplemented +// features. +package unimpl + +import ( + "gvisor.googlesource.com/gvisor/pkg/log" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" +) + +// contextID is the events package's type for context.Context.Value keys. +type contextID int + +const ( + // CtxEvents is a Context.Value key for a Events. + CtxEvents contextID = iota +) + +// Events interface defines method to emit unsupported events. +type Events interface { + EmitUnimplementedEvent(context.Context) +} + +// EmitUnimplementedEvent emits unsupported syscall event to the context. +func EmitUnimplementedEvent(ctx context.Context) { + e := ctx.Value(CtxEvents) + if e == nil { + log.Warningf("Context.Value(CtxEvents) not present, unimplemented syscall event not reported.") + return + } + e.(Events).EmitUnimplementedEvent(ctx) +} diff --git a/pkg/sentry/unimpl/unimplemented_syscall.proto b/pkg/sentry/unimpl/unimplemented_syscall.proto new file mode 100644 index 000000000..41579b016 --- /dev/null +++ b/pkg/sentry/unimpl/unimplemented_syscall.proto @@ -0,0 +1,27 @@ +// Copyright 2018 Google LLC +// +// 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. + +syntax = "proto3"; + +package gvisor; + +import "pkg/sentry/arch/registers.proto"; + +message UnimplementedSyscall { + // Task ID. + int32 tid = 1; + + // Registers at the time of the call. + Registers registers = 2; +} diff --git a/runsc/boot/BUILD b/runsc/boot/BUILD index f8f848ebf..04cc0e854 100644 --- a/runsc/boot/BUILD +++ b/runsc/boot/BUILD @@ -6,6 +6,7 @@ go_library( name = "boot", srcs = [ "compat.go", + "compat_amd64.go", "config.go", "controller.go", "debug.go", @@ -59,9 +60,9 @@ go_library( "//pkg/sentry/socket/unix", "//pkg/sentry/state", "//pkg/sentry/strace", - "//pkg/sentry/syscalls:unimplemented_syscall_go_proto", "//pkg/sentry/syscalls/linux", "//pkg/sentry/time", + "//pkg/sentry/unimpl:unimplemented_syscall_go_proto", "//pkg/sentry/usage", "//pkg/sentry/watchdog", "//pkg/syserror", @@ -87,12 +88,16 @@ go_library( go_test( name = "boot_test", size = "small", - srcs = ["loader_test.go"], + srcs = [ + "compat_test.go", + "loader_test.go", + ], embed = [":boot"], deps = [ "//pkg/control/server", "//pkg/log", "//pkg/p9", + "//pkg/sentry/arch:registers_go_proto", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", "//pkg/unet", diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index 6766953b3..d18c2f802 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -17,6 +17,8 @@ package boot import ( "fmt" "os" + "sync" + "syscall" "github.com/golang/protobuf/proto" "gvisor.googlesource.com/gvisor/pkg/abi" @@ -25,7 +27,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/arch" rpb "gvisor.googlesource.com/gvisor/pkg/sentry/arch/registers_go_proto" "gvisor.googlesource.com/gvisor/pkg/sentry/strace" - spb "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/unimplemented_syscall_go_proto" + spb "gvisor.googlesource.com/gvisor/pkg/sentry/unimpl/unimplemented_syscall_go_proto" ) func initCompatLogs(fd int) error { @@ -40,15 +42,27 @@ func initCompatLogs(fd int) error { type compatEmitter struct { sink *log.BasicLogger nameMap strace.SyscallMap + + // mu protects the fields below. + mu sync.Mutex + + // trackers map syscall number to the respective tracker instance. + // Protected by 'mu'. + trackers map[uint64]syscallTracker } func newCompatEmitter(logFD int) (*compatEmitter, error) { - // Always logs to default logger. nameMap, ok := strace.Lookup(abi.Linux, arch.AMD64) if !ok { return nil, fmt.Errorf("amd64 Linux syscall table not found") } - c := &compatEmitter{sink: log.Log(), nameMap: nameMap} + + c := &compatEmitter{ + // Always logs to default logger. + sink: log.Log(), + nameMap: nameMap, + trackers: make(map[uint64]syscallTracker), + } if logFD > 0 { f := os.NewFile(uintptr(logFD), "user log file") @@ -61,10 +75,33 @@ func newCompatEmitter(logFD int) (*compatEmitter, error) { // Emit implements eventchannel.Emitter. func (c *compatEmitter) Emit(msg proto.Message) (hangup bool, err error) { // Only interested in UnimplementedSyscall, skip the rest. - if us, ok := msg.(*spb.UnimplementedSyscall); ok { - regs := us.Registers.GetArch().(*rpb.Registers_Amd64).Amd64 - sysnr := regs.OrigRax + us, ok := msg.(*spb.UnimplementedSyscall) + if !ok { + return false, nil + } + regs := us.Registers.GetArch().(*rpb.Registers_Amd64).Amd64 + + c.mu.Lock() + defer c.mu.Unlock() + + sysnr := regs.OrigRax + tr := c.trackers[sysnr] + if tr == nil { + switch sysnr { + case syscall.SYS_PRCTL, syscall.SYS_ARCH_PRCTL: + tr = newCmdTracker(0) + + case syscall.SYS_IOCTL, syscall.SYS_EPOLL_CTL, syscall.SYS_SHMCTL: + tr = newCmdTracker(1) + + default: + tr = &onceTracker{} + } + c.trackers[sysnr] = tr + } + if tr.shouldReport(regs) { c.sink.Infof("Unsupported syscall: %s, regs: %+v", c.nameMap.Name(uintptr(sysnr)), regs) + tr.onReported(regs) } return false, nil } @@ -74,3 +111,26 @@ func (c *compatEmitter) Close() error { c.sink = nil return nil } + +// syscallTracker interface allows filters to apply differently depending on +// the syscall and arguments. +type syscallTracker interface { + // shouldReport returns true is the syscall should be reported. + shouldReport(regs *rpb.AMD64Registers) bool + + // onReported marks the syscall as reported. + onReported(regs *rpb.AMD64Registers) +} + +// onceTracker reports only a single time, used for most syscalls. +type onceTracker struct { + reported bool +} + +func (o *onceTracker) shouldReport(_ *rpb.AMD64Registers) bool { + return !o.reported +} + +func (o *onceTracker) onReported(_ *rpb.AMD64Registers) { + o.reported = true +} diff --git a/runsc/boot/compat_amd64.go b/runsc/boot/compat_amd64.go new file mode 100644 index 000000000..2bb769a49 --- /dev/null +++ b/runsc/boot/compat_amd64.go @@ -0,0 +1,54 @@ +// Copyright 2018 Google LLC +// +// 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 boot + +import ( + "fmt" + + rpb "gvisor.googlesource.com/gvisor/pkg/sentry/arch/registers_go_proto" +) + +// cmdTracker reports only a single time for each different command argument in +// the syscall. It's used for generic syscalls like ioctl to report once per +// 'cmd' +type cmdTracker struct { + // argIdx is the syscall argument index where the command is located. + argIdx int + cmds map[uint32]struct{} +} + +func newCmdTracker(argIdx int) *cmdTracker { + return &cmdTracker{argIdx: argIdx, cmds: make(map[uint32]struct{})} +} + +// cmd returns the command based on the syscall argument index. +func (c *cmdTracker) cmd(regs *rpb.AMD64Registers) uint32 { + switch c.argIdx { + case 0: + return uint32(regs.Rdi) + case 1: + return uint32(regs.Rsi) + } + panic(fmt.Sprintf("unsupported syscall argument index %d", c.argIdx)) +} + +func (c *cmdTracker) shouldReport(regs *rpb.AMD64Registers) bool { + _, ok := c.cmds[c.cmd(regs)] + return !ok +} + +func (c *cmdTracker) onReported(regs *rpb.AMD64Registers) { + c.cmds[c.cmd(regs)] = struct{}{} +} diff --git a/runsc/boot/compat_test.go b/runsc/boot/compat_test.go new file mode 100644 index 000000000..30b94798a --- /dev/null +++ b/runsc/boot/compat_test.go @@ -0,0 +1,66 @@ +// Copyright 2018 Google LLC +// +// 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 boot + +import ( + "testing" + + rpb "gvisor.googlesource.com/gvisor/pkg/sentry/arch/registers_go_proto" +) + +func TestOnceTracker(t *testing.T) { + o := onceTracker{} + if !o.shouldReport(nil) { + t.Error("first call to checkAndMark, got: false, want: true") + } + o.onReported(nil) + for i := 0; i < 2; i++ { + if o.shouldReport(nil) { + t.Error("after first call to checkAndMark, got: true, want: false") + } + } +} + +func TestCmdTracker(t *testing.T) { + for _, tc := range []struct { + name string + idx int + rdi1 uint64 + rdi2 uint64 + rsi1 uint64 + rsi2 uint64 + want bool + }{ + {name: "same rdi", idx: 0, rdi1: 123, rdi2: 123, want: false}, + {name: "same rsi", idx: 1, rsi1: 123, rsi2: 123, want: false}, + {name: "diff rdi", idx: 0, rdi1: 123, rdi2: 321, want: true}, + {name: "diff rsi", idx: 1, rsi1: 123, rsi2: 321, want: true}, + {name: "cmd is uint32", idx: 0, rsi1: 0xdead00000123, rsi2: 0xbeef00000123, want: false}, + } { + t.Run(tc.name, func(t *testing.T) { + c := newCmdTracker(tc.idx) + regs := &rpb.AMD64Registers{Rdi: tc.rdi1, Rsi: tc.rsi1} + if !c.shouldReport(regs) { + t.Error("first call to checkAndMark, got: false, want: true") + } + c.onReported(regs) + + regs.Rdi, regs.Rsi = tc.rdi2, tc.rsi2 + if got := c.shouldReport(regs); tc.want != got { + t.Errorf("after first call to checkAndMark, got: %t, want: %t", got, tc.want) + } + }) + } +} -- cgit v1.2.3 From 2ef122da35899591737adca296b499246b877532 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 8 Nov 2018 17:38:50 -0800 Subject: Implement sync_file_range() sync_file_range - sync a file segment with disk In Linux, sync_file_range() accepts three flags: SYNC_FILE_RANGE_WAIT_BEFORE Wait upon write-out of all pages in the specified range that have already been submitted to the device driver for write-out before performing any write. SYNC_FILE_RANGE_WRITE Initiate write-out of all dirty pages in the specified range which are not presently submitted write-out. Note that even this may block if you attempt to write more than request queue size. SYNC_FILE_RANGE_WAIT_AFTER Wait upon write-out of all pages in the range after performing any write. In this implementation: SYNC_FILE_RANGE_WAIT_BEFORE without SYNC_FILE_RANGE_WAIT_AFTER isn't supported right now. SYNC_FILE_RANGE_WRITE is skipped. It should initiate write-out of all dirty pages, but it doesn't wait, so it should be safe to do nothing while nobody uses SYNC_FILE_RANGE_WAIT_BEFORE. SYNC_FILE_RANGE_WAIT_AFTER is equal to fdatasync(). In Linux, sync_file_range() doesn't writes out the file's meta-data, but fdatasync() does if a file size is changed. PiperOrigin-RevId: 220730840 Change-Id: Iae5dfb23c2c916967d67cf1a1ad32f25eb3f6286 --- pkg/abi/linux/fs.go | 7 ++++ pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_sync.go | 63 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index 7817bfb52..0b1c9f3db 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -73,3 +73,10 @@ type Statfs struct { // Spare is unused. Spare [4]uint64 } + +// Sync_file_range flags, from include/uapi/linux/fs.h +const ( + SYNC_FILE_RANGE_WAIT_BEFORE = 1 + SYNC_FILE_RANGE_WRITE = 2 + SYNC_FILE_RANGE_WAIT_AFTER = 4 +) diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 13084c0ef..9912ab2b5 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -325,7 +325,7 @@ var AMD64 = &kernel.SyscallTable{ 274: syscalls.Error(syscall.ENOSYS), // GetRobustList, obsolete // 275: Splice, TODO // 276: Tee, TODO - // 277: SyncFileRange, TODO + 277: SyncFileRange, // 278: Vmsplice, TODO 279: syscalls.CapError(linux.CAP_SYS_NICE), // MovePages, requires cap_sys_nice (mostly) 280: Utimensat, diff --git a/pkg/sentry/syscalls/linux/sys_sync.go b/pkg/sentry/syscalls/linux/sys_sync.go index 826c6869d..68488330f 100644 --- a/pkg/sentry/syscalls/linux/sys_sync.go +++ b/pkg/sentry/syscalls/linux/sys_sync.go @@ -15,6 +15,7 @@ package linux import ( + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" @@ -73,3 +74,65 @@ func Fdatasync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys err := file.Fsync(t, 0, fs.FileMaxOffset, fs.SyncData) return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) } + +// SyncFileRange implements linux syscall sync_file_rage(2) +func SyncFileRange(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + var err error + + offset := args[1].Int64() + nbytes := args[2].Int64() + uflags := args[3].Uint() + + if offset < 0 || offset+nbytes < offset { + return 0, nil, syserror.EINVAL + } + + if uflags&^(linux.SYNC_FILE_RANGE_WAIT_BEFORE| + linux.SYNC_FILE_RANGE_WRITE| + linux.SYNC_FILE_RANGE_WAIT_AFTER) != 0 { + return 0, nil, syserror.EINVAL + } + + if nbytes == 0 { + nbytes = fs.FileMaxOffset + } + + fd := kdefs.FD(args[0].Int()) + file := t.FDMap().GetFile(fd) + if file == nil { + return 0, nil, syserror.EBADF + } + defer file.DecRef() + + // SYNC_FILE_RANGE_WAIT_BEFORE waits upon write-out of all pages in the + // specified range that have already been submitted to the device + // driver for write-out before performing any write. + if uflags&linux.SYNC_FILE_RANGE_WAIT_BEFORE != 0 && + uflags&linux.SYNC_FILE_RANGE_WAIT_AFTER == 0 { + t.Kernel().EmitUnimplementedEvent(t) + return 0, nil, syserror.ENOSYS + } + + // SYNC_FILE_RANGE_WRITE initiates write-out of all dirty pages in the + // specified range which are not presently submitted write-out. + // + // It looks impossible to implement this functionality without a + // massive rework of the vfs subsystem. file.Fsync() take a file lock + // for the entire operation, so even if it is running in a go routing, + // it blocks other file operations instead of flushing data in the + // background. + // + // It should be safe to skipped this flag while nobody uses + // SYNC_FILE_RANGE_WAIT_BEFORE. + + // SYNC_FILE_RANGE_WAIT_AFTER waits upon write-out of all pages in the + // range after performing any write. + // + // In Linux, sync_file_range() doesn't writes out the file's + // meta-data, but fdatasync() does if a file size is changed. + if uflags&linux.SYNC_FILE_RANGE_WAIT_AFTER != 0 { + err = file.Fsync(t, offset, fs.FileMaxOffset, fs.SyncData) + } + + return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) +} -- cgit v1.2.3 From fadffa2ff831034ff63146abf408ff71462b9f43 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Mon, 19 Nov 2018 15:25:00 -0800 Subject: Add unsupported syscall events for get/setsockopt PiperOrigin-RevId: 222148953 Change-Id: I21500a9f08939c45314a6414e0824490a973e5aa --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/ip.go | 107 ++++++ pkg/abi/linux/netlink.go | 14 + pkg/abi/linux/socket.go | 87 ++++- pkg/abi/linux/tcp.go | 54 +++ pkg/sentry/socket/epsocket/epsocket.go | 675 ++++++++++++++++++++++----------- pkg/sentry/socket/netlink/socket.go | 33 ++ pkg/sentry/socket/socket.go | 91 +++++ runsc/boot/compat.go | 10 +- runsc/boot/compat_amd64.go | 55 ++- runsc/boot/compat_test.go | 39 +- 11 files changed, 902 insertions(+), 264 deletions(-) create mode 100644 pkg/abi/linux/tcp.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index f8f82c0da..1f6e43605 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -43,6 +43,7 @@ go_library( "shm.go", "signal.go", "socket.go", + "tcp.go", "time.go", "timer.go", "tty.go", diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go index fcec16965..77ac1062c 100644 --- a/pkg/abi/linux/ip.go +++ b/pkg/abi/linux/ip.go @@ -42,3 +42,110 @@ const ( IPPROTO_MPLS = 137 IPPROTO_RAW = 255 ) + +// Socket options from uapi/linux/in.h +const ( + IP_TOS = 1 + IP_TTL = 2 + IP_HDRINCL = 3 + IP_OPTIONS = 4 + IP_ROUTER_ALERT = 5 + IP_RECVOPTS = 6 + IP_RETOPTS = 7 + IP_PKTINFO = 8 + IP_PKTOPTIONS = 9 + IP_MTU_DISCOVER = 10 + IP_RECVERR = 11 + IP_RECVTTL = 12 + IP_RECVTOS = 13 + IP_MTU = 14 + IP_FREEBIND = 15 + IP_IPSEC_POLICY = 16 + IP_XFRM_POLICY = 17 + IP_PASSSEC = 18 + IP_TRANSPARENT = 19 + IP_ORIGDSTADDR = 20 + IP_RECVORIGDSTADDR = IP_ORIGDSTADDR + IP_MINTTL = 21 + IP_NODEFRAG = 22 + IP_CHECKSUM = 23 + IP_BIND_ADDRESS_NO_PORT = 24 + IP_RECVFRAGSIZE = 25 + IP_MULTICAST_IF = 32 + IP_MULTICAST_TTL = 33 + IP_MULTICAST_LOOP = 34 + IP_ADD_MEMBERSHIP = 35 + IP_DROP_MEMBERSHIP = 36 + IP_UNBLOCK_SOURCE = 37 + IP_BLOCK_SOURCE = 38 + IP_ADD_SOURCE_MEMBERSHIP = 39 + IP_DROP_SOURCE_MEMBERSHIP = 40 + IP_MSFILTER = 41 + MCAST_JOIN_GROUP = 42 + MCAST_BLOCK_SOURCE = 43 + MCAST_UNBLOCK_SOURCE = 44 + MCAST_LEAVE_GROUP = 45 + MCAST_JOIN_SOURCE_GROUP = 46 + MCAST_LEAVE_SOURCE_GROUP = 47 + MCAST_MSFILTER = 48 + IP_MULTICAST_ALL = 49 + IP_UNICAST_IF = 50 +) + +// Socket options from uapi/linux/in6.h +const ( + IPV6_ADDRFORM = 1 + IPV6_2292PKTINFO = 2 + IPV6_2292HOPOPTS = 3 + IPV6_2292DSTOPTS = 4 + IPV6_2292RTHDR = 5 + IPV6_2292PKTOPTIONS = 6 + IPV6_CHECKSUM = 7 + IPV6_2292HOPLIMIT = 8 + IPV6_NEXTHOP = 9 + IPV6_FLOWINFO = 11 + IPV6_UNICAST_HOPS = 16 + IPV6_MULTICAST_IF = 17 + IPV6_MULTICAST_HOPS = 18 + IPV6_MULTICAST_LOOP = 19 + IPV6_ADD_MEMBERSHIP = 20 + IPV6_DROP_MEMBERSHIP = 21 + IPV6_ROUTER_ALERT = 22 + IPV6_MTU_DISCOVER = 23 + IPV6_MTU = 24 + IPV6_RECVERR = 25 + IPV6_V6ONLY = 26 + IPV6_JOIN_ANYCAST = 27 + IPV6_LEAVE_ANYCAST = 28 + IPV6_MULTICAST_ALL = 29 + IPV6_FLOWLABEL_MGR = 32 + IPV6_FLOWINFO_SEND = 33 + IPV6_IPSEC_POLICY = 34 + IPV6_XFRM_POLICY = 35 + IPV6_HDRINCL = 36 + IPV6_RECVPKTINFO = 49 + IPV6_PKTINFO = 50 + IPV6_RECVHOPLIMIT = 51 + IPV6_HOPLIMIT = 52 + IPV6_RECVHOPOPTS = 53 + IPV6_HOPOPTS = 54 + IPV6_RTHDRDSTOPTS = 55 + IPV6_RECVRTHDR = 56 + IPV6_RTHDR = 57 + IPV6_RECVDSTOPTS = 58 + IPV6_DSTOPTS = 59 + IPV6_RECVPATHMTU = 60 + IPV6_PATHMTU = 61 + IPV6_DONTFRAG = 62 + IPV6_RECVTCLASS = 66 + IPV6_TCLASS = 67 + IPV6_AUTOFLOWLABEL = 70 + IPV6_ADDR_PREFERENCES = 72 + IPV6_MINHOPCOUNT = 73 + IPV6_ORIGDSTADDR = 74 + IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR + IPV6_TRANSPARENT = 75 + IPV6_UNICAST_IF = 76 + IPV6_RECVFRAGSIZE = 77 + IPV6_FREEBIND = 78 +) diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go index 10ceb5bf2..25c5e17fd 100644 --- a/pkg/abi/linux/netlink.go +++ b/pkg/abi/linux/netlink.go @@ -108,3 +108,17 @@ const NetlinkAttrHeaderSize = 4 // NLA_ALIGNTO is the alignment of netlink attributes, from // uapi/linux/netlink.h. const NLA_ALIGNTO = 4 + +// Socket options, from uapi/linux/netlink.h. +const ( + NETLINK_ADD_MEMBERSHIP = 1 + NETLINK_DROP_MEMBERSHIP = 2 + NETLINK_PKTINFO = 3 + NETLINK_BROADCAST_ERROR = 4 + NETLINK_NO_ENOBUFS = 5 + NETLINK_LISTEN_ALL_NSID = 8 + NETLINK_LIST_MEMBERSHIPS = 9 + NETLINK_CAP_ACK = 10 + NETLINK_EXT_ACK = 11 + NETLINK_DUMP_STRICT_CHK = 12 +) diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index af0761a3b..929814752 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -89,8 +89,18 @@ const ( MSG_CMSG_CLOEXEC = 0x40000000 ) -// SOL_SOCKET is from socket.h -const SOL_SOCKET = 1 +// Set/get socket option levels, from socket.h. +const ( + SOL_IP = 0 + SOL_SOCKET = 1 + SOL_TCP = 6 + SOL_UDP = 17 + SOL_IPV6 = 41 + SOL_ICMPV6 = 58 + SOL_RAW = 255 + SOL_PACKET = 263 + SOL_NETLINK = 270 +) // Socket types, from linux/net.h. const ( @@ -122,22 +132,63 @@ const ( // Socket options from socket.h. const ( - SO_ERROR = 4 - SO_KEEPALIVE = 9 - SO_LINGER = 13 - SO_MARK = 36 - SO_PASSCRED = 16 - SO_PEERCRED = 17 - SO_PEERNAME = 28 - SO_PROTOCOL = 38 - SO_RCVBUF = 8 - SO_RCVTIMEO = 20 - SO_REUSEADDR = 2 - SO_SNDBUF = 7 - SO_SNDTIMEO = 21 - SO_TIMESTAMP = 29 - SO_TIMESTAMPNS = 35 - SO_TYPE = 3 + SO_DEBUG = 1 + SO_REUSEADDR = 2 + SO_TYPE = 3 + SO_ERROR = 4 + SO_DONTROUTE = 5 + SO_BROADCAST = 6 + SO_SNDBUF = 7 + SO_RCVBUF = 8 + SO_KEEPALIVE = 9 + SO_OOBINLINE = 10 + SO_NO_CHECK = 11 + SO_PRIORITY = 12 + SO_LINGER = 13 + SO_BSDCOMPAT = 14 + SO_REUSEPORT = 15 + SO_PASSCRED = 16 + SO_PEERCRED = 17 + SO_RCVLOWAT = 18 + SO_SNDLOWAT = 19 + SO_RCVTIMEO = 20 + SO_SNDTIMEO = 21 + SO_BINDTODEVICE = 25 + SO_ATTACH_FILTER = 26 + SO_DETACH_FILTER = 27 + SO_GET_FILTER = SO_ATTACH_FILTER + SO_PEERNAME = 28 + SO_TIMESTAMP = 29 + SO_ACCEPTCONN = 30 + SO_PEERSEC = 31 + SO_SNDBUFFORCE = 32 + SO_RCVBUFFORCE = 33 + SO_PASSSEC = 34 + SO_TIMESTAMPNS = 35 + SO_MARK = 36 + SO_TIMESTAMPING = 37 + SO_PROTOCOL = 38 + SO_DOMAIN = 39 + SO_RXQ_OVFL = 40 + SO_WIFI_STATUS = 41 + SO_PEEK_OFF = 42 + SO_NOFCS = 43 + SO_LOCK_FILTER = 44 + SO_SELECT_ERR_QUEUE = 45 + SO_BUSY_POLL = 46 + SO_MAX_PACING_RATE = 47 + SO_BPF_EXTENSIONS = 48 + SO_INCOMING_CPU = 49 + SO_ATTACH_BPF = 50 + SO_ATTACH_REUSEPORT_CBPF = 51 + SO_ATTACH_REUSEPORT_EBPF = 52 + SO_CNX_ADVICE = 53 + SO_MEMINFO = 55 + SO_INCOMING_NAPI_ID = 56 + SO_COOKIE = 57 + SO_PEERGROUPS = 59 + SO_ZEROCOPY = 60 + SO_TXTIME = 61 ) // SockAddrMax is the maximum size of a struct sockaddr, from diff --git a/pkg/abi/linux/tcp.go b/pkg/abi/linux/tcp.go new file mode 100644 index 000000000..7586ada42 --- /dev/null +++ b/pkg/abi/linux/tcp.go @@ -0,0 +1,54 @@ +// Copyright 2018 Google LLC +// +// 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 linux + +// Socket options from uapi/linux/tcp.h. +const ( + TCP_NODELAY = 1 + TCP_MAXSEG = 2 + TCP_CORK = 3 + TCP_KEEPIDLE = 4 + TCP_KEEPINTVL = 5 + TCP_KEEPCNT = 6 + TCP_SYNCNT = 7 + TCP_LINGER2 = 8 + TCP_DEFER_ACCEPT = 9 + TCP_WINDOW_CLAMP = 10 + TCP_INFO = 11 + TCP_QUICKACK = 12 + TCP_CONGESTION = 13 + TCP_MD5SIG = 14 + TCP_THIN_LINEAR_TIMEOUTS = 16 + TCP_THIN_DUPACK = 17 + TCP_USER_TIMEOUT = 18 + TCP_REPAIR = 19 + TCP_REPAIR_QUEUE = 20 + TCP_QUEUE_SEQ = 21 + TCP_REPAIR_OPTIONS = 22 + TCP_FASTOPEN = 23 + TCP_TIMESTAMP = 24 + TCP_NOTSENT_LOWAT = 25 + TCP_CC_INFO = 26 + TCP_SAVE_SYN = 27 + TCP_SAVED_SYN = 28 + TCP_REPAIR_WINDOW = 29 + TCP_FASTOPEN_CONNECT = 30 + TCP_ULP = 31 + TCP_MD5SIG_EXT = 32 + TCP_FASTOPEN_KEY = 33 + TCP_FASTOPEN_NO_COOKIE = 34 + TCP_ZEROCOPY_RECEIVE = 35 + TCP_INQ = 36 +) diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index d14bbad01..c5ce289b5 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -515,189 +515,233 @@ func (s *SocketOperations) GetSockOpt(t *kernel.Task, level, name, outLen int) ( func GetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, skType transport.SockType, level, name, outLen int) (interface{}, *syserr.Error) { switch level { case linux.SOL_SOCKET: - switch name { - case linux.SO_TYPE: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } - return int32(skType), nil + return getSockOptSocket(t, s, ep, family, skType, name, outLen) - case linux.SO_ERROR: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + case linux.SOL_TCP: + return getSockOptTCP(t, ep, name, outLen) - // Get the last error and convert it. - err := ep.GetSockOpt(tcpip.ErrorOption{}) - if err == nil { - return int32(0), nil - } - return int32(syserr.TranslateNetstackError(err).ToLinux().Number()), nil + case linux.SOL_IPV6: + return getSockOptIPv6(t, ep, name, outLen) - case linux.SO_PEERCRED: - if family != linux.AF_UNIX || outLen < syscall.SizeofUcred { - return nil, syserr.ErrInvalidArgument - } + case linux.SOL_IP, + linux.SOL_UDP, + linux.SOL_ICMPV6, + linux.SOL_RAW, + linux.SOL_PACKET: - tcred := t.Credentials() - return syscall.Ucred{ - Pid: int32(t.ThreadGroup().ID()), - Uid: uint32(tcred.EffectiveKUID.In(tcred.UserNamespace).OrOverflow()), - Gid: uint32(tcred.EffectiveKGID.In(tcred.UserNamespace).OrOverflow()), - }, nil + t.Kernel().EmitUnimplementedEvent(t) + } - case linux.SO_PASSCRED: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + return nil, syserr.ErrProtocolNotAvailable +} - var v tcpip.PasscredOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } +// getSockOptSocket implements GetSockOpt when level is SOL_SOCKET. +func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family int, skType transport.SockType, name, outLen int) (interface{}, *syserr.Error) { + switch name { + case linux.SO_TYPE: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + return int32(skType), nil - return int32(v), nil + case linux.SO_ERROR: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - case linux.SO_SNDBUF: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + // Get the last error and convert it. + err := ep.GetSockOpt(tcpip.ErrorOption{}) + if err == nil { + return int32(0), nil + } + return int32(syserr.TranslateNetstackError(err).ToLinux().Number()), nil - var size tcpip.SendBufferSizeOption - if err := ep.GetSockOpt(&size); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + case linux.SO_PEERCRED: + if family != linux.AF_UNIX || outLen < syscall.SizeofUcred { + return nil, syserr.ErrInvalidArgument + } - if size > math.MaxInt32 { - size = math.MaxInt32 - } + tcred := t.Credentials() + return syscall.Ucred{ + Pid: int32(t.ThreadGroup().ID()), + Uid: uint32(tcred.EffectiveKUID.In(tcred.UserNamespace).OrOverflow()), + Gid: uint32(tcred.EffectiveKGID.In(tcred.UserNamespace).OrOverflow()), + }, nil - return int32(size), nil + case linux.SO_PASSCRED: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - case linux.SO_RCVBUF: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + var v tcpip.PasscredOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - var size tcpip.ReceiveBufferSizeOption - if err := ep.GetSockOpt(&size); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + return int32(v), nil - if size > math.MaxInt32 { - size = math.MaxInt32 - } + case linux.SO_SNDBUF: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - return int32(size), nil + var size tcpip.SendBufferSizeOption + if err := ep.GetSockOpt(&size); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - case linux.SO_REUSEADDR: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + if size > math.MaxInt32 { + size = math.MaxInt32 + } - var v tcpip.ReuseAddressOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + return int32(size), nil - return int32(v), nil + case linux.SO_RCVBUF: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - case linux.SO_KEEPALIVE: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } - return int32(0), nil + var size tcpip.ReceiveBufferSizeOption + if err := ep.GetSockOpt(&size); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - case linux.SO_LINGER: - if outLen < syscall.SizeofLinger { - return nil, syserr.ErrInvalidArgument - } - return syscall.Linger{}, nil + if size > math.MaxInt32 { + size = math.MaxInt32 + } - case linux.SO_RCVTIMEO: - if outLen < linux.SizeOfTimeval { - return nil, syserr.ErrInvalidArgument - } + return int32(size), nil - return linux.NsecToTimeval(s.RecvTimeout()), nil + case linux.SO_REUSEADDR: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - case linux.SO_TIMESTAMP: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + var v tcpip.ReuseAddressOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - var v tcpip.TimestampOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + return int32(v), nil - return int32(v), nil + case linux.SO_KEEPALIVE: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument } + return int32(0), nil - case syscall.SOL_TCP: - switch name { - case syscall.TCP_NODELAY: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + case linux.SO_LINGER: + if outLen < syscall.SizeofLinger { + return nil, syserr.ErrInvalidArgument + } + return syscall.Linger{}, nil - var v tcpip.DelayOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + case linux.SO_RCVTIMEO: + if outLen < linux.SizeOfTimeval { + return nil, syserr.ErrInvalidArgument + } - if v == 0 { - return int32(1), nil - } - return int32(0), nil + return linux.NsecToTimeval(s.RecvTimeout()), nil - case syscall.TCP_CORK: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + case linux.SO_TIMESTAMP: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - var v tcpip.CorkOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + var v tcpip.TimestampOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - return int32(v), nil + return int32(v), nil - case syscall.TCP_INFO: - var v tcpip.TCPInfoOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + default: + socket.GetSockOptEmitUnimplementedEvent(t, name) + } + return nil, syserr.ErrProtocolNotAvailable +} + +// getSockOptTCP implements GetSockOpt when level is SOL_TCP. +func getSockOptTCP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interface{}, *syserr.Error) { + switch name { + case linux.TCP_NODELAY: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } - // TODO: Translate fields once they are added to - // tcpip.TCPInfoOption. - info := linux.TCPInfo{} + var v tcpip.DelayOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - // Linux truncates the output binary to outLen. - ib := binary.Marshal(nil, usermem.ByteOrder, &info) - if len(ib) > outLen { - ib = ib[:outLen] - } + if v == 0 { + return int32(1), nil + } + return int32(0), nil - return ib, nil + case linux.TCP_CORK: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument } - case syscall.SOL_IPV6: - switch name { - case syscall.IPV6_V6ONLY: - if outLen < sizeOfInt32 { - return nil, syserr.ErrInvalidArgument - } + var v tcpip.CorkOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } - var v tcpip.V6OnlyOption - if err := ep.GetSockOpt(&v); err != nil { - return nil, syserr.TranslateNetstackError(err) - } + return int32(v), nil - return int32(v), nil + case linux.TCP_INFO: + var v tcpip.TCPInfoOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + // TODO: Translate fields once they are added to + // tcpip.TCPInfoOption. + info := linux.TCPInfo{} + + // Linux truncates the output binary to outLen. + ib := binary.Marshal(nil, usermem.ByteOrder, &info) + if len(ib) > outLen { + ib = ib[:outLen] } + + return ib, nil + + case linux.TCP_CC_INFO, + linux.TCP_NOTSENT_LOWAT, + linux.TCP_ZEROCOPY_RECEIVE: + + t.Kernel().EmitUnimplementedEvent(t) + + default: + emitUmplementedEventTCP(t, name) } + return nil, syserr.ErrProtocolNotAvailable +} + +// getSockOptIPv6 implements GetSockOpt when level is SOL_IPV6. +func getSockOptIPv6(t *kernel.Task, ep commonEndpoint, name, outLen int) (interface{}, *syserr.Error) { + switch name { + case linux.IPV6_V6ONLY: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + var v tcpip.V6OnlyOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(v), nil + + case linux.IPV6_PATHMTU: + t.Kernel().EmitUnimplementedEvent(t) + + default: + emitUmplementedEventIPv6(t, name) + } return nil, syserr.ErrProtocolNotAvailable } @@ -712,109 +756,304 @@ func (s *SocketOperations) SetSockOpt(t *kernel.Task, level int, name int, optVa func SetSockOpt(t *kernel.Task, s socket.Socket, ep commonEndpoint, level int, name int, optVal []byte) *syserr.Error { switch level { case linux.SOL_SOCKET: - switch name { - case linux.SO_SNDBUF: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + return setSockOptSocket(t, s, ep, name, optVal) - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.SendBufferSizeOption(v))) + case linux.SOL_TCP: + return setSockOptTCP(t, ep, name, optVal) - case linux.SO_RCVBUF: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + case linux.SOL_IPV6: + return setSockOptIPv6(t, ep, name, optVal) - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReceiveBufferSizeOption(v))) + case linux.SOL_IP: + return setSockOptIP(t, ep, name, optVal) - case linux.SO_REUSEADDR: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + case linux.SOL_UDP, + linux.SOL_ICMPV6, + linux.SOL_RAW, + linux.SOL_PACKET: - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReuseAddressOption(v))) + t.Kernel().EmitUnimplementedEvent(t) + } - case linux.SO_PASSCRED: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + // Default to the old behavior; hand off to network stack. + return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) +} - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.PasscredOption(v))) +// setSockOptSocket implements SetSockOpt when level is SOL_SOCKET. +func setSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int, optVal []byte) *syserr.Error { + switch name { + case linux.SO_SNDBUF: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } - case linux.SO_RCVTIMEO: - if len(optVal) < linux.SizeOfTimeval { - return syserr.ErrInvalidArgument - } + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.SendBufferSizeOption(v))) - var v linux.Timeval - binary.Unmarshal(optVal[:linux.SizeOfTimeval], usermem.ByteOrder, &v) - s.SetRecvTimeout(v.ToNsecCapped()) - return nil + case linux.SO_RCVBUF: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } - case linux.SO_TIMESTAMP: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReceiveBufferSizeOption(v))) - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.TimestampOption(v))) + case linux.SO_REUSEADDR: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument } - case syscall.SOL_TCP: - switch name { - case syscall.TCP_NODELAY: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.ReuseAddressOption(v))) - v := usermem.ByteOrder.Uint32(optVal) - var o tcpip.DelayOption - if v == 0 { - o = 1 - } - return syserr.TranslateNetstackError(ep.SetSockOpt(o)) - case syscall.TCP_CORK: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } + case linux.SO_PASSCRED: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.PasscredOption(v))) - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.CorkOption(v))) + case linux.SO_RCVTIMEO: + if len(optVal) < linux.SizeOfTimeval { + return syserr.ErrInvalidArgument } - case syscall.SOL_IPV6: - switch name { - case syscall.IPV6_V6ONLY: - if len(optVal) < sizeOfInt32 { - return syserr.ErrInvalidArgument - } - v := usermem.ByteOrder.Uint32(optVal) - return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.V6OnlyOption(v))) - } - case syscall.SOL_IP: - const ( - _IP_MULTICAST_IF = 32 - _IP_ADD_MEMBERSHIP = 35 - _MCAST_JOIN_GROUP = 42 - ) - switch name { - case _IP_ADD_MEMBERSHIP, _MCAST_JOIN_GROUP, _IP_MULTICAST_IF: - // FIXME: Disallow IP-level multicast group options by - // default. These will need to be supported by appropriately plumbing - // the level through to the network stack (if at all). However, we - // still allow setting TTL, and multicast-enable/disable type options. + var v linux.Timeval + binary.Unmarshal(optVal[:linux.SizeOfTimeval], usermem.ByteOrder, &v) + s.SetRecvTimeout(v.ToNsecCapped()) + return nil + + case linux.SO_TIMESTAMP: + if len(optVal) < sizeOfInt32 { return syserr.ErrInvalidArgument } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.TimestampOption(v))) + + default: + socket.SetSockOptEmitUnimplementedEvent(t, name) } // Default to the old behavior; hand off to network stack. return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) } +// setSockOptTCP implements SetSockOpt when level is SOL_TCP. +func setSockOptTCP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { + switch name { + case linux.TCP_NODELAY: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + var o tcpip.DelayOption + if v == 0 { + o = 1 + } + return syserr.TranslateNetstackError(ep.SetSockOpt(o)) + + case linux.TCP_CORK: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.CorkOption(v))) + + case linux.TCP_REPAIR_OPTIONS: + t.Kernel().EmitUnimplementedEvent(t) + + default: + emitUmplementedEventTCP(t, name) + } + + // Default to the old behavior; hand off to network stack. + return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) +} + +// setSockOptIPv6 implements SetSockOpt when level is SOL_IPV6. +func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { + switch name { + case linux.IPV6_V6ONLY: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.V6OnlyOption(v))) + + case linux.IPV6_ADD_MEMBERSHIP, + linux.IPV6_DROP_MEMBERSHIP, + linux.IPV6_IPSEC_POLICY, + linux.IPV6_JOIN_ANYCAST, + linux.IPV6_LEAVE_ANYCAST, + linux.IPV6_PKTINFO, + linux.IPV6_ROUTER_ALERT, + linux.IPV6_XFRM_POLICY, + linux.MCAST_BLOCK_SOURCE, + linux.MCAST_JOIN_GROUP, + linux.MCAST_JOIN_SOURCE_GROUP, + linux.MCAST_LEAVE_GROUP, + linux.MCAST_LEAVE_SOURCE_GROUP, + linux.MCAST_UNBLOCK_SOURCE: + + t.Kernel().EmitUnimplementedEvent(t) + + default: + emitUmplementedEventIPv6(t, name) + } + + // Default to the old behavior; hand off to network stack. + return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) +} + +// setSockOptIP implements SetSockOpt when level is SOL_IP. +func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { + switch name { + case linux.IP_ADD_MEMBERSHIP, linux.MCAST_JOIN_GROUP, linux.IP_MULTICAST_IF: + // FIXME: Disallow IP-level multicast group options by + // default. These will need to be supported by appropriately plumbing + // the level through to the network stack (if at all). However, we + // still allow setting TTL, and multicast-enable/disable type options. + t.Kernel().EmitUnimplementedEvent(t) + return syserr.ErrInvalidArgument + + case linux.IP_ADD_SOURCE_MEMBERSHIP, + linux.IP_BIND_ADDRESS_NO_PORT, + linux.IP_BLOCK_SOURCE, + linux.IP_CHECKSUM, + linux.IP_DROP_MEMBERSHIP, + linux.IP_DROP_SOURCE_MEMBERSHIP, + linux.IP_FREEBIND, + linux.IP_HDRINCL, + linux.IP_IPSEC_POLICY, + linux.IP_MINTTL, + linux.IP_MSFILTER, + linux.IP_MTU_DISCOVER, + linux.IP_MULTICAST_ALL, + linux.IP_MULTICAST_LOOP, + linux.IP_MULTICAST_TTL, + linux.IP_NODEFRAG, + linux.IP_OPTIONS, + linux.IP_PASSSEC, + linux.IP_PKTINFO, + linux.IP_RECVERR, + linux.IP_RECVFRAGSIZE, + linux.IP_RECVOPTS, + linux.IP_RECVORIGDSTADDR, + linux.IP_RECVTOS, + linux.IP_RECVTTL, + linux.IP_RETOPTS, + linux.IP_TOS, + linux.IP_TRANSPARENT, + linux.IP_TTL, + linux.IP_UNBLOCK_SOURCE, + linux.IP_UNICAST_IF, + linux.IP_XFRM_POLICY, + linux.MCAST_BLOCK_SOURCE, + linux.MCAST_JOIN_SOURCE_GROUP, + linux.MCAST_LEAVE_GROUP, + linux.MCAST_LEAVE_SOURCE_GROUP, + linux.MCAST_MSFILTER, + linux.MCAST_UNBLOCK_SOURCE: + + t.Kernel().EmitUnimplementedEvent(t) + } + + // Default to the old behavior; hand off to network stack. + return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) +} + +// emitUmplementedEventTCP emits unimplemented event if name is valid. This +// function contains names that are common between Get and SetSockOpt when +// level is SOL_TCP. +func emitUmplementedEventTCP(t *kernel.Task, name int) { + switch name { + case linux.TCP_CONGESTION, + linux.TCP_CORK, + linux.TCP_DEFER_ACCEPT, + linux.TCP_FASTOPEN, + linux.TCP_FASTOPEN_CONNECT, + linux.TCP_FASTOPEN_KEY, + linux.TCP_FASTOPEN_NO_COOKIE, + linux.TCP_INQ, + linux.TCP_KEEPCNT, + linux.TCP_KEEPIDLE, + linux.TCP_KEEPINTVL, + linux.TCP_LINGER2, + linux.TCP_MAXSEG, + linux.TCP_QUEUE_SEQ, + linux.TCP_QUICKACK, + linux.TCP_REPAIR, + linux.TCP_REPAIR_QUEUE, + linux.TCP_REPAIR_WINDOW, + linux.TCP_SAVED_SYN, + linux.TCP_SAVE_SYN, + linux.TCP_SYNCNT, + linux.TCP_THIN_DUPACK, + linux.TCP_THIN_LINEAR_TIMEOUTS, + linux.TCP_TIMESTAMP, + linux.TCP_ULP, + linux.TCP_USER_TIMEOUT, + linux.TCP_WINDOW_CLAMP: + + t.Kernel().EmitUnimplementedEvent(t) + } +} + +// emitUmplementedEventIPv6 emits unimplemented event if name is valid. It +// contains names that are common between Get and SetSockOpt when level is +// SOL_IPV6. +func emitUmplementedEventIPv6(t *kernel.Task, name int) { + switch name { + case linux.IPV6_2292DSTOPTS, + linux.IPV6_2292HOPLIMIT, + linux.IPV6_2292HOPOPTS, + linux.IPV6_2292PKTINFO, + linux.IPV6_2292PKTOPTIONS, + linux.IPV6_2292RTHDR, + linux.IPV6_ADDR_PREFERENCES, + linux.IPV6_AUTOFLOWLABEL, + linux.IPV6_DONTFRAG, + linux.IPV6_DSTOPTS, + linux.IPV6_FLOWINFO, + linux.IPV6_FLOWINFO_SEND, + linux.IPV6_FLOWLABEL_MGR, + linux.IPV6_FREEBIND, + linux.IPV6_HOPOPTS, + linux.IPV6_MINHOPCOUNT, + linux.IPV6_MTU, + linux.IPV6_MTU_DISCOVER, + linux.IPV6_MULTICAST_ALL, + linux.IPV6_MULTICAST_HOPS, + linux.IPV6_MULTICAST_IF, + linux.IPV6_MULTICAST_LOOP, + linux.IPV6_RECVDSTOPTS, + linux.IPV6_RECVERR, + linux.IPV6_RECVFRAGSIZE, + linux.IPV6_RECVHOPLIMIT, + linux.IPV6_RECVHOPOPTS, + linux.IPV6_RECVORIGDSTADDR, + linux.IPV6_RECVPATHMTU, + linux.IPV6_RECVPKTINFO, + linux.IPV6_RECVRTHDR, + linux.IPV6_RECVTCLASS, + linux.IPV6_RTHDR, + linux.IPV6_RTHDRDSTOPTS, + linux.IPV6_TCLASS, + linux.IPV6_TRANSPARENT, + linux.IPV6_UNICAST_HOPS, + linux.IPV6_UNICAST_IF, + linux.MCAST_MSFILTER, + linux.IPV6_ADDRFORM: + + t.Kernel().EmitUnimplementedEvent(t) + } +} + // isLinkLocal determines if the given IPv6 address is link-local. This is the // case when it has the fe80::/10 prefix. This check is used to determine when // the NICID is relevant for a given IPv6 address. diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index f901cfa0b..b1f6620de 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -299,6 +299,21 @@ func (s *Socket) GetSockOpt(t *kernel.Task, level int, name int, outLen int) (in } // We don't have limit on receiving size. return math.MaxInt32, nil + + default: + socket.GetSockOptEmitUnimplementedEvent(t, name) + } + case linux.SOL_NETLINK: + switch name { + case linux.NETLINK_BROADCAST_ERROR, + linux.NETLINK_CAP_ACK, + linux.NETLINK_DUMP_STRICT_CHK, + linux.NETLINK_EXT_ACK, + linux.NETLINK_LIST_MEMBERSHIPS, + linux.NETLINK_NO_ENOBUFS, + linux.NETLINK_PKTINFO: + + t.Kernel().EmitUnimplementedEvent(t) } } // TODO: other sockopts are not supported. @@ -329,7 +344,25 @@ func (s *Socket) SetSockOpt(t *kernel.Task, level int, name int, opt []byte) *sy // We don't have limit on receiving size. So just accept anything as // valid for compatibility. return nil + default: + socket.SetSockOptEmitUnimplementedEvent(t, name) } + + case linux.SOL_NETLINK: + switch name { + case linux.NETLINK_ADD_MEMBERSHIP, + linux.NETLINK_BROADCAST_ERROR, + linux.NETLINK_CAP_ACK, + linux.NETLINK_DROP_MEMBERSHIP, + linux.NETLINK_DUMP_STRICT_CHK, + linux.NETLINK_EXT_ACK, + linux.NETLINK_LISTEN_ALL_NSID, + linux.NETLINK_NO_ENOBUFS, + linux.NETLINK_PKTINFO: + + t.Kernel().EmitUnimplementedEvent(t) + } + } // TODO: other sockopts are not supported. return syserr.ErrProtocolNotAvailable diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index a235c5249..b1dcbf7b0 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -213,3 +213,94 @@ func (rt *ReceiveTimeout) SetRecvTimeout(nanoseconds int64) { func (rt *ReceiveTimeout) RecvTimeout() int64 { return atomic.LoadInt64(&rt.ns) } + +// GetSockOptEmitUnimplementedEvent emits unimplemented event if name is valid. +// It contains names that are valid for GetSockOpt when level is SOL_SOCKET. +func GetSockOptEmitUnimplementedEvent(t *kernel.Task, name int) { + switch name { + case linux.SO_ACCEPTCONN, + linux.SO_BPF_EXTENSIONS, + linux.SO_COOKIE, + linux.SO_DOMAIN, + linux.SO_ERROR, + linux.SO_GET_FILTER, + linux.SO_INCOMING_NAPI_ID, + linux.SO_MEMINFO, + linux.SO_PEERCRED, + linux.SO_PEERGROUPS, + linux.SO_PEERNAME, + linux.SO_PEERSEC, + linux.SO_PROTOCOL, + linux.SO_SNDLOWAT, + linux.SO_TYPE: + + t.Kernel().EmitUnimplementedEvent(t) + + default: + emitUnimplementedEvent(t, name) + } +} + +// SetSockOptEmitUnimplementedEvent emits unimplemented event if name is valid. +// It contains names that are valid for SetSockOpt when level is SOL_SOCKET. +func SetSockOptEmitUnimplementedEvent(t *kernel.Task, name int) { + switch name { + case linux.SO_ATTACH_BPF, + linux.SO_ATTACH_FILTER, + linux.SO_ATTACH_REUSEPORT_CBPF, + linux.SO_ATTACH_REUSEPORT_EBPF, + linux.SO_CNX_ADVICE, + linux.SO_DETACH_FILTER, + linux.SO_RCVBUFFORCE, + linux.SO_SNDBUFFORCE: + + t.Kernel().EmitUnimplementedEvent(t) + + default: + emitUnimplementedEvent(t, name) + } +} + +// emitUnimplementedEvent emits unimplemented event if name is valid. It +// contains names that are common between Get and SetSocketOpt when level is +// SOL_SOCKET. +func emitUnimplementedEvent(t *kernel.Task, name int) { + switch name { + case linux.SO_BINDTODEVICE, + linux.SO_BROADCAST, + linux.SO_BSDCOMPAT, + linux.SO_BUSY_POLL, + linux.SO_DEBUG, + linux.SO_DONTROUTE, + linux.SO_INCOMING_CPU, + linux.SO_KEEPALIVE, + linux.SO_LINGER, + linux.SO_LOCK_FILTER, + linux.SO_MARK, + linux.SO_MAX_PACING_RATE, + linux.SO_NOFCS, + linux.SO_NO_CHECK, + linux.SO_OOBINLINE, + linux.SO_PASSCRED, + linux.SO_PASSSEC, + linux.SO_PEEK_OFF, + linux.SO_PRIORITY, + linux.SO_RCVBUF, + linux.SO_RCVLOWAT, + linux.SO_RCVTIMEO, + linux.SO_REUSEADDR, + linux.SO_REUSEPORT, + linux.SO_RXQ_OVFL, + linux.SO_SELECT_ERR_QUEUE, + linux.SO_SNDBUF, + linux.SO_SNDTIMEO, + linux.SO_TIMESTAMP, + linux.SO_TIMESTAMPING, + linux.SO_TIMESTAMPNS, + linux.SO_TXTIME, + linux.SO_WIFI_STATUS, + linux.SO_ZEROCOPY: + + t.Kernel().EmitUnimplementedEvent(t) + } +} diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index 4c49e90e3..c2a77ebf5 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -89,10 +89,16 @@ func (c *compatEmitter) Emit(msg proto.Message) (hangup bool, err error) { if tr == nil { switch sysnr { case syscall.SYS_PRCTL, syscall.SYS_ARCH_PRCTL: - tr = newCmdTracker(0) + // args: cmd, ... + tr = newArgsTracker(0) case syscall.SYS_IOCTL, syscall.SYS_EPOLL_CTL, syscall.SYS_SHMCTL: - tr = newCmdTracker(1) + // args: fd, cmd, ... + tr = newArgsTracker(1) + + case syscall.SYS_GETSOCKOPT, syscall.SYS_SETSOCKOPT: + // args: fd, level, name, ... + tr = newArgsTracker(1, 2) default: tr = &onceTracker{} diff --git a/runsc/boot/compat_amd64.go b/runsc/boot/compat_amd64.go index 2bb769a49..0c9472f18 100644 --- a/runsc/boot/compat_amd64.go +++ b/runsc/boot/compat_amd64.go @@ -20,35 +20,58 @@ import ( rpb "gvisor.googlesource.com/gvisor/pkg/sentry/arch/registers_go_proto" ) -// cmdTracker reports only a single time for each different command argument in -// the syscall. It's used for generic syscalls like ioctl to report once per -// 'cmd' -type cmdTracker struct { - // argIdx is the syscall argument index where the command is located. - argIdx int - cmds map[uint32]struct{} +// reportLimit is the max number of events that should be reported per tracker. +const reportLimit = 100 + +// argsTracker reports only once for each different combination of arguments. +// It's used for generic syscalls like ioctl to report once per 'cmd'. +type argsTracker struct { + // argsIdx is the syscall arguments to use as unique ID. + argsIdx []int + reported map[string]struct{} + count int } -func newCmdTracker(argIdx int) *cmdTracker { - return &cmdTracker{argIdx: argIdx, cmds: make(map[uint32]struct{})} +func newArgsTracker(argIdx ...int) *argsTracker { + return &argsTracker{argsIdx: argIdx, reported: make(map[string]struct{})} } // cmd returns the command based on the syscall argument index. -func (c *cmdTracker) cmd(regs *rpb.AMD64Registers) uint32 { - switch c.argIdx { +func (a *argsTracker) key(regs *rpb.AMD64Registers) string { + var rv string + for _, idx := range a.argsIdx { + rv += fmt.Sprintf("%d|", argVal(idx, regs)) + } + return rv +} + +func argVal(argIdx int, regs *rpb.AMD64Registers) uint32 { + switch argIdx { case 0: return uint32(regs.Rdi) case 1: return uint32(regs.Rsi) + case 2: + return uint32(regs.Rdx) + case 3: + return uint32(regs.R10) + case 4: + return uint32(regs.R8) + case 5: + return uint32(regs.R9) } - panic(fmt.Sprintf("unsupported syscall argument index %d", c.argIdx)) + panic(fmt.Sprintf("invalid syscall argument index %d", argIdx)) } -func (c *cmdTracker) shouldReport(regs *rpb.AMD64Registers) bool { - _, ok := c.cmds[c.cmd(regs)] +func (a *argsTracker) shouldReport(regs *rpb.AMD64Registers) bool { + if a.count >= reportLimit { + return false + } + _, ok := a.reported[a.key(regs)] return !ok } -func (c *cmdTracker) onReported(regs *rpb.AMD64Registers) { - c.cmds[c.cmd(regs)] = struct{}{} +func (a *argsTracker) onReported(regs *rpb.AMD64Registers) { + a.count++ + a.reported[a.key(regs)] = struct{}{} } diff --git a/runsc/boot/compat_test.go b/runsc/boot/compat_test.go index 30b94798a..f1940dd72 100644 --- a/runsc/boot/compat_test.go +++ b/runsc/boot/compat_test.go @@ -33,34 +33,53 @@ func TestOnceTracker(t *testing.T) { } } -func TestCmdTracker(t *testing.T) { +func TestArgsTracker(t *testing.T) { for _, tc := range []struct { name string - idx int + idx []int rdi1 uint64 rdi2 uint64 rsi1 uint64 rsi2 uint64 want bool }{ - {name: "same rdi", idx: 0, rdi1: 123, rdi2: 123, want: false}, - {name: "same rsi", idx: 1, rsi1: 123, rsi2: 123, want: false}, - {name: "diff rdi", idx: 0, rdi1: 123, rdi2: 321, want: true}, - {name: "diff rsi", idx: 1, rsi1: 123, rsi2: 321, want: true}, - {name: "cmd is uint32", idx: 0, rsi1: 0xdead00000123, rsi2: 0xbeef00000123, want: false}, + {name: "same rdi", idx: []int{0}, rdi1: 123, rdi2: 123, want: false}, + {name: "same rsi", idx: []int{1}, rsi1: 123, rsi2: 123, want: false}, + {name: "diff rdi", idx: []int{0}, rdi1: 123, rdi2: 321, want: true}, + {name: "diff rsi", idx: []int{1}, rsi1: 123, rsi2: 321, want: true}, + {name: "cmd is uint32", idx: []int{0}, rsi1: 0xdead00000123, rsi2: 0xbeef00000123, want: false}, + {name: "same 2 args", idx: []int{0, 1}, rsi1: 123, rdi1: 321, rsi2: 123, rdi2: 321, want: false}, + {name: "diff 2 args", idx: []int{0, 1}, rsi1: 123, rdi1: 321, rsi2: 789, rdi2: 987, want: true}, } { t.Run(tc.name, func(t *testing.T) { - c := newCmdTracker(tc.idx) + c := newArgsTracker(tc.idx...) regs := &rpb.AMD64Registers{Rdi: tc.rdi1, Rsi: tc.rsi1} if !c.shouldReport(regs) { - t.Error("first call to checkAndMark, got: false, want: true") + t.Error("first call to shouldReport, got: false, want: true") } c.onReported(regs) regs.Rdi, regs.Rsi = tc.rdi2, tc.rsi2 if got := c.shouldReport(regs); tc.want != got { - t.Errorf("after first call to checkAndMark, got: %t, want: %t", got, tc.want) + t.Errorf("second call to shouldReport, got: %t, want: %t", got, tc.want) } }) } } + +func TestArgsTrackerLimit(t *testing.T) { + c := newArgsTracker(0, 1) + for i := 0; i < reportLimit; i++ { + regs := &rpb.AMD64Registers{Rdi: 123, Rsi: uint64(i)} + if !c.shouldReport(regs) { + t.Error("shouldReport before limit was reached, got: false, want: true") + } + c.onReported(regs) + } + + // Should hit the count limit now. + regs := &rpb.AMD64Registers{Rdi: 123, Rsi: 123456} + if c.shouldReport(regs) { + t.Error("shouldReport after limit was reached, got: true, want: false") + } +} -- cgit v1.2.3 From eaac94d91c28b745c51c33dd352ed9bfdd671b8c Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Tue, 20 Nov 2018 22:55:41 -0800 Subject: Use RET_KILL_PROCESS if available in kernel RET_KILL_THREAD doesn't work well for Go because it will kill only the offending thread and leave the process hanging. RET_TRAP can be masked out and it's not guaranteed to kill the process. RET_KILL_PROCESS is available since 4.14. For older kernel, continue to use RET_TRAP as this is the best option (likely to kill process, easy to debug). PiperOrigin-RevId: 222357867 Change-Id: Icc1d7d731274b16c2125b7a1ba4f7883fbdb2cbd --- pkg/abi/linux/seccomp.go | 12 +++--- pkg/seccomp/seccomp.go | 52 ++++++++++++++++++++++---- pkg/seccomp/seccomp_test.go | 20 +++++++--- pkg/seccomp/seccomp_test_victim.go | 2 +- pkg/seccomp/seccomp_unsafe.go | 30 ++++++++++++--- pkg/sentry/kernel/seccomp.go | 4 +- pkg/sentry/platform/ptrace/subprocess_linux.go | 2 +- runsc/boot/filter/filter.go | 3 +- runsc/fsgofer/filter/filter.go | 3 +- 9 files changed, 95 insertions(+), 33 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index 9963ceeba..5ec01cc4a 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -19,17 +19,19 @@ const ( SECCOMP_MODE_NONE = 0 SECCOMP_MODE_FILTER = 2 - SECCOMP_RET_KILL = 0x00000000 - SECCOMP_RET_TRAP = 0x00030000 - SECCOMP_RET_ERRNO = 0x00050000 - SECCOMP_RET_TRACE = 0x7ff00000 - SECCOMP_RET_ALLOW = 0x7fff0000 + SECCOMP_RET_KILL_PROCESS = 0x80000000 + SECCOMP_RET_KILL_THREAD = 0x00000000 + SECCOMP_RET_TRAP = 0x00030000 + SECCOMP_RET_ERRNO = 0x00050000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_ALLOW = 0x7fff0000 SECCOMP_RET_ACTION = 0x7fff0000 SECCOMP_RET_DATA = 0x0000ffff SECCOMP_SET_MODE_FILTER = 1 SECCOMP_FILTER_FLAG_TSYNC = 1 + SECCOMP_GET_ACTION_AVAIL = 2 ) const ( diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index 1dfbf749e..9d714d02d 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -33,17 +33,42 @@ const ( defaultLabel = "default_action" ) +func actionName(a uint32) string { + switch a { + case linux.SECCOMP_RET_KILL_PROCESS: + return "kill process" + case linux.SECCOMP_RET_TRAP: + return "trap" + } + panic(fmt.Sprintf("invalid action: %d", a)) +} + // Install generates BPF code based on the set of syscalls provided. It only -// allows syscalls that conform to the specification and generates SIGSYS -// trap unless kill is set. +// allows syscalls that conform to the specification. Syscalls that violate the +// specification will trigger RET_KILL_PROCESS, except for the cases below. +// +// RET_TRAP is used in violations, instead of RET_KILL_PROCESS, in the +// following cases: +// 1. Kernel doesn't support RET_KILL_PROCESS: RET_KILL_THREAD only kills the +// offending thread and often keeps the sentry hanging. +// 2. Debug: RET_TRAP generates a panic followed by a stack trace which is +// much easier to debug then RET_KILL_PROCESS which can't be caught. // -// This is a convenience wrapper around BuildProgram and SetFilter. -func Install(rules SyscallRules, kill bool) error { - log.Infof("Installing seccomp filters for %d syscalls (kill=%t)", len(rules), kill) - defaultAction := uint32(linux.SECCOMP_RET_TRAP) - if kill { - defaultAction = uint32(linux.SECCOMP_RET_KILL) +// Be aware that RET_TRAP sends SIGSYS to the process and it may be ignored, +// making it possible for the process to continue running after a violation. +// However, it will leave a SECCOMP audit event trail behind. In any case, the +// syscall is still blocked from executing. +func Install(rules SyscallRules) error { + defaultAction, err := defaultAction() + if err != nil { + return err } + + // Uncomment to get stack trace when there is a violation. + // defaultAction = uint32(linux.SECCOMP_RET_TRAP) + + log.Infof("Installing seccomp filters for %d syscalls (action=%s)", len(rules), actionName(defaultAction)) + instrs, err := BuildProgram([]RuleSet{ RuleSet{ Rules: rules, @@ -70,6 +95,17 @@ func Install(rules SyscallRules, kill bool) error { return nil } +func defaultAction() (uint32, error) { + available, err := isKillProcessAvailable() + if err != nil { + return 0, err + } + if available { + return uint32(linux.SECCOMP_RET_KILL_PROCESS), nil + } + return uint32(linux.SECCOMP_RET_TRAP), nil +} + // RuleSet is a set of rules and associated action. type RuleSet struct { Rules SyscallRules diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 226f30b7b..f2b903e42 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -121,7 +121,7 @@ func TestBasic(t *testing.T) { Action: linux.SECCOMP_RET_TRAP, }, }, - defaultAction: linux.SECCOMP_RET_KILL, + defaultAction: linux.SECCOMP_RET_KILL_THREAD, specs: []spec{ { desc: "Multiple rulesets allowed (1a)", @@ -141,7 +141,7 @@ func TestBasic(t *testing.T) { { desc: "Multiple rulesets allowed (2)", data: seccompData{nr: 0, arch: linux.AUDIT_ARCH_X86_64}, - want: linux.SECCOMP_RET_KILL, + want: linux.SECCOMP_RET_KILL_THREAD, }, }, }, @@ -431,15 +431,23 @@ func TestRealDeal(t *testing.T) { t.Errorf("victim was not killed as expected, output: %s", out) continue } + // Depending on kernel version, either RET_TRAP or RET_KILL_PROCESS is + // used. RET_TRAP dumps reason for exit in output, while RET_KILL_PROCESS + // returns SIGSYS as exit status. + if !strings.Contains(string(out), test.want) && + !strings.Contains(err.Error(), test.want) { + t.Errorf("Victim error is wrong, got: %v, err: %v, want: %v", string(out), err, test.want) + continue + } } else { if err != nil { t.Errorf("victim failed to execute, err: %v", err) continue } - } - if !strings.Contains(string(out), test.want) { - t.Errorf("Victim output is wrong, got: %v, want: %v", err, test.want) - continue + if !strings.Contains(string(out), test.want) { + t.Errorf("Victim output is wrong, got: %v, want: %v", string(out), test.want) + continue + } } } } diff --git a/pkg/seccomp/seccomp_test_victim.go b/pkg/seccomp/seccomp_test_victim.go index 007038273..dd5ed0041 100644 --- a/pkg/seccomp/seccomp_test_victim.go +++ b/pkg/seccomp/seccomp_test_victim.go @@ -106,7 +106,7 @@ func main() { } } - if err := seccomp.Install(syscalls, false); err != nil { + if err := seccomp.Install(syscalls); err != nil { fmt.Printf("Failed to install seccomp: %v", err) os.Exit(1) } diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go index dd009221a..a31c6471d 100644 --- a/pkg/seccomp/seccomp_unsafe.go +++ b/pkg/seccomp/seccomp_unsafe.go @@ -36,22 +36,40 @@ type sockFprog struct { // //go:nosplit func SetFilter(instrs []linux.BPFInstruction) syscall.Errno { - // SYS_SECCOMP is not available in syscall package. - const SYS_SECCOMP = 317 - // PR_SET_NO_NEW_PRIVS is required in order to enable seccomp. See seccomp(2) for details. if _, _, errno := syscall.RawSyscall(syscall.SYS_PRCTL, linux.PR_SET_NO_NEW_PRIVS, 1, 0); errno != 0 { return errno } - // TODO: Use SECCOMP_FILTER_FLAG_KILL_PROCESS when available. sockProg := sockFprog{ Len: uint16(len(instrs)), Filter: (*linux.BPFInstruction)(unsafe.Pointer(&instrs[0])), } - if _, _, errno := syscall.RawSyscall(SYS_SECCOMP, linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, uintptr(unsafe.Pointer(&sockProg))); errno != 0 { - return errno + return seccomp(linux.SECCOMP_SET_MODE_FILTER, linux.SECCOMP_FILTER_FLAG_TSYNC, unsafe.Pointer(&sockProg)) +} + +func isKillProcessAvailable() (bool, error) { + action := uint32(linux.SECCOMP_RET_KILL_PROCESS) + if errno := seccomp(linux.SECCOMP_GET_ACTION_AVAIL, 0, unsafe.Pointer(&action)); errno != 0 { + // EINVAL: SECCOMP_GET_ACTION_AVAIL not in this kernel yet. + // EOPNOTSUPP: SECCOMP_RET_KILL_PROCESS not supported. + if errno == syscall.EINVAL || errno == syscall.EOPNOTSUPP { + return false, nil + } + return false, errno } + return true, nil +} +// seccomp calls seccomp(2). This is safe to call from an afterFork context. +// +//go:nosplit +func seccomp(op, flags uint32, ptr unsafe.Pointer) syscall.Errno { + // SYS_SECCOMP is not available in syscall package. + const SYS_SECCOMP = 317 + + if _, _, errno := syscall.RawSyscall(SYS_SECCOMP, uintptr(op), uintptr(flags), uintptr(ptr)); errno != 0 { + return errno + } return 0 } diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index 433b900c7..d6dc45bbd 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -117,7 +117,7 @@ func (t *Task) checkSeccompSyscall(sysno int32, args arch.SyscallArguments, ip u // "Results in the system call being executed." return seccompResultAllow - case linux.SECCOMP_RET_KILL: + case linux.SECCOMP_RET_KILL_THREAD: // "Results in the task exiting immediately without executing the // system call. The exit status of the task will be SIGSYS, not // SIGKILL." @@ -155,7 +155,7 @@ func (t *Task) evaluateSyscallFilters(sysno int32, args arch.SyscallArguments, i thisRet, err := bpf.Exec(f.([]bpf.Program)[i], input) if err != nil { t.Debugf("seccomp-bpf filter %d returned error: %v", i, err) - thisRet = linux.SECCOMP_RET_KILL + thisRet = linux.SECCOMP_RET_KILL_THREAD } // "If multiple filters exist, the return value for the evaluation of a // given system call will always use the highest precedent value." - diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index 885ba4b2e..25b8e8cb7 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -115,7 +115,7 @@ func createStub() (*thread, error) { var defaultAction uint32 if probeSeccomp() { log.Infof("Latest seccomp behavior found (kernel >= 4.8 likely)") - defaultAction = uint32(linux.SECCOMP_RET_KILL) + defaultAction = uint32(linux.SECCOMP_RET_KILL_THREAD) } else { // We must rely on SYSEMU behavior; tracing with SYSEMU is broken. log.Infof("Legacy seccomp behavior found (kernel < 4.8 likely)") diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index dc7294b1d..d69a6a2cc 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -57,8 +57,7 @@ func Install(opt Options) error { return fmt.Errorf("unknown platform type %T", p) } - // TODO: Set kill=true when SECCOMP_RET_KILL_PROCESS is supported. - return seccomp.Install(s, false) + return seccomp.Install(s) } // Report writes a warning message to the log. diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index f50b6bc87..c120d57a6 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -29,6 +29,5 @@ func Install() error { // when not enabled. s.Merge(instrumentationFilters()) - // TODO: Set kill=true when SECCOMP_RET_KILL_PROCESS is supported. - return seccomp.Install(s, false) + return seccomp.Install(s) } -- cgit v1.2.3 From b3b60ea29adf9415c9c7b98ba331dacd92f231b7 Mon Sep 17 00:00:00 2001 From: Zach Koopmans Date: Mon, 26 Nov 2018 09:49:53 -0800 Subject: Implementation of preadv2 for Linux 4.4 support Implement RWF_HIPRI (4.6) silently passes the read call. Implement -1 offset calls readv. PiperOrigin-RevId: 222840324 Change-Id: If9ddc1e8d086e1a632bdf5e00bae08205f95b6b0 --- pkg/abi/linux/file.go | 7 ++++ pkg/sentry/syscalls/linux/linux64.go | 3 ++ pkg/sentry/syscalls/linux/sys_read.go | 62 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 72e5c6f83..8d48e1753 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -150,6 +150,13 @@ const ( PermissionsMask = 0777 ) +// Values for preadv2/pwritev2. +const ( + RWF_HIPRI = 0x0001 + RWF_DSYNC = 0X0002 + RWF_SYNC = 0x0004 +) + // Stat represents struct stat. type Stat struct { Dev uint64 diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 9912ab2b5..2aab948da 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -373,7 +373,10 @@ var AMD64 = &kernel.SyscallTable{ // 322: Execveat, TODO // 323: Userfaultfd, TODO // 324: Membarrier, TODO + // Syscalls after 325 are backports from 4.6. 325: syscalls.Error(nil), // Mlock2, TODO + 327: Preadv2, + // 328: Pwritev2, // Pwritev2, TODO }, Emulate: map[usermem.Addr]uintptr{ diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index b2e5a5449..cbb9eb9f8 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -187,6 +187,68 @@ func Preadv(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "preadv", file) } +// Preadv2 implements linux syscall preadv2(2). +func Preadv2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + fd := kdefs.FD(args[0].Int()) + addr := args[1].Pointer() + iovcnt := int(args[2].Int()) + offset := args[3].Int64() + flags := int(args[4].Int()) + + validFlags := linux.RWF_HIPRI + + file := t.FDMap().GetFile(fd) + if file == nil { + return 0, nil, syserror.EBADF + } + defer file.DecRef() + + // Check that the offset is legitimate. + if offset < -1 { + return 0, nil, syserror.EINVAL + } + + // Is reading at an offset supported? + if offset > -1 && !file.Flags().Pread { + return 0, nil, syserror.ESPIPE + } + + // Check that the file is readable. + if !file.Flags().Read { + return 0, nil, syserror.EBADF + } + + // Check flags field. + if flags != 0 { + if flags&^validFlags != 0 { + return 0, nil, syserror.EINVAL + } + // RWF_HIPRI must be called on a file with O_DIRECT flag set. + if flags&linux.RWF_HIPRI != 0 && !file.Flags().Direct { + return 0, nil, syserror.EINVAL + } + } + + // Read the iovecs that specify the destination of the read. + dst, err := t.IovecsIOSequence(addr, iovcnt, usermem.IOOpts{ + AddressSpaceActive: true, + }) + if err != nil { + return 0, nil, err + } + + // If preadv2 is called with an offset of -1, readv is called. + if offset == -1 { + n, err := readv(t, file, dst) + t.IOUsage().AccountReadSyscall(n) + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "preadv2", file) + } + + n, err := preadv(t, file, dst, offset) + t.IOUsage().AccountReadSyscall(n) + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "preadv2", file) +} + func readv(t *kernel.Task, f *fs.File, dst usermem.IOSequence) (int64, error) { n, err := f.Readv(t, dst) if err != syserror.ErrWouldBlock || f.Flags().NonBlocking { -- cgit v1.2.3 From c3dd68cea7427af4dfdfbac4f292d0dfcdea465c Mon Sep 17 00:00:00 2001 From: Bin Lu Date: Tue, 4 Dec 2018 12:22:48 -0800 Subject: Add ARM64 support to pkg/abi/linux Signed-off-by: Bin Lu Change-Id: I73cc4c406fadccb054e8e83c9464f6bef6280b0f PiperOrigin-RevId: 224025309 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/audit.go | 23 +++++++++++++++++++++++ pkg/abi/linux/seccomp.go | 5 ----- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 pkg/abi/linux/audit.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 1f6e43605..e6043abf4 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -11,6 +11,7 @@ go_library( srcs = [ "aio.go", "ashmem.go", + "audit.go", "binder.go", "bpf.go", "capability.go", diff --git a/pkg/abi/linux/audit.go b/pkg/abi/linux/audit.go new file mode 100644 index 000000000..b39ba4515 --- /dev/null +++ b/pkg/abi/linux/audit.go @@ -0,0 +1,23 @@ +// Copyright 2018 Google LLC +// +// 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 linux + +// Audit numbers identify different system call APIs, from +const ( + // AUDIT_ARCH_X86_64 identifies AMD64. + AUDIT_ARCH_X86_64 = 0xc000003e + // AUDIT_ARCH_AARCH64 identifies ARM64. + AUDIT_ARCH_AARCH64 = 0xc00000b7 +) diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index 5ec01cc4a..785f2f284 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -33,8 +33,3 @@ const ( SECCOMP_FILTER_FLAG_TSYNC = 1 SECCOMP_GET_ACTION_AVAIL = 2 ) - -const ( - // AUDIT_ARCH_X86_64 is taken from . - AUDIT_ARCH_X86_64 = 0xc000003e -) -- cgit v1.2.3 From 666db00c262c7d6d6359fbaba28e344d015a7823 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 6 Dec 2018 11:42:23 -0800 Subject: Convert ValueSet to a map Unlike FlagSet, order doesn't matter here, so it can simply be a map. PiperOrigin-RevId: 224377910 Change-Id: I15810c698a7f02d8614bf09b59583ab73cba0514 --- pkg/abi/flag.go | 25 +-- pkg/abi/linux/file.go | 35 +--- pkg/sentry/strace/futex.go | 65 ++---- pkg/sentry/strace/open.go | 15 +- pkg/sentry/strace/ptrace.go | 190 ++++-------------- pkg/sentry/strace/socket.go | 470 +++++++++----------------------------------- pkg/sentry/strace/strace.go | 15 +- 7 files changed, 168 insertions(+), 647 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index 0698e410f..049c1b0dd 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -46,30 +46,25 @@ func (s FlagSet) Parse(val uint64) string { return strings.Join(flags, "|") } -// ValueSet is a slice of syscall values and their name. Parse will replace -// values that exactly match an entry with its name. -type ValueSet []struct { - Value uint64 - Name string -} +// ValueSet is a map of syscall values to their name. Parse will use the name +// or the value if unknown. +type ValueSet map[uint64]string // Parse returns the name of the value associated with `val`. Unknown values // are converted to hex. -func (e ValueSet) Parse(val uint64) string { - for _, f := range e { - if val == f.Value { - return f.Name - } +func (s ValueSet) Parse(val uint64) string { + if v, ok := s[val]; ok { + return v } return fmt.Sprintf("%#x", val) } // ParseName returns the flag value associated with 'name'. Returns false // if no value is found. -func (e ValueSet) ParseName(name string) (uint64, bool) { - for _, f := range e { - if name == f.Name { - return f.Value, true +func (s ValueSet) ParseName(name string) (uint64, bool) { + for k, v := range s { + if v == name { + return k, true } } return math.MaxUint64, false diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 8d48e1753..ac49ae9a6 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -223,32 +223,11 @@ var modeExtraBits = abi.FlagSet{ } var fileType = abi.ValueSet{ - { - Value: ModeSocket, - Name: "S_IFSOCK", - }, - { - Value: ModeSymlink, - Name: "S_IFLINK", - }, - { - Value: ModeRegular, - Name: "S_IFREG", - }, - { - Value: ModeBlockDevice, - Name: "S_IFBLK", - }, - { - Value: ModeDirectory, - Name: "S_IFDIR", - }, - { - Value: ModeCharacterDevice, - Name: "S_IFCHR", - }, - { - Value: ModeNamedPipe, - Name: "S_IFIFO", - }, + ModeSocket: "S_IFSOCK", + ModeSymlink: "S_IFLINK", + ModeRegular: "S_IFREG", + ModeBlockDevice: "S_IFBLK", + ModeDirectory: "S_IFDIR", + ModeCharacterDevice: "S_IFCHR", + ModeNamedPipe: "S_IFIFO", } diff --git a/pkg/sentry/strace/futex.go b/pkg/sentry/strace/futex.go index ceb3dc21d..f4aa7fcad 100644 --- a/pkg/sentry/strace/futex.go +++ b/pkg/sentry/strace/futex.go @@ -21,58 +21,19 @@ import ( // FutexCmd are the possible futex(2) commands. var FutexCmd = abi.ValueSet{ - { - Value: linux.FUTEX_WAIT, - Name: "FUTEX_WAIT", - }, - { - Value: linux.FUTEX_WAKE, - Name: "FUTEX_WAKE", - }, - { - Value: linux.FUTEX_FD, - Name: "FUTEX_FD", - }, - { - Value: linux.FUTEX_REQUEUE, - Name: "FUTEX_REQUEUE", - }, - { - Value: linux.FUTEX_CMP_REQUEUE, - Name: "FUTEX_CMP_REQUEUE", - }, - { - Value: linux.FUTEX_WAKE_OP, - Name: "FUTEX_WAKE_OP", - }, - { - Value: linux.FUTEX_LOCK_PI, - Name: "FUTEX_LOCK_PI", - }, - { - Value: linux.FUTEX_UNLOCK_PI, - Name: "FUTEX_UNLOCK_PI", - }, - { - Value: linux.FUTEX_TRYLOCK_PI, - Name: "FUTEX_TRYLOCK_PI", - }, - { - Value: linux.FUTEX_WAIT_BITSET, - Name: "FUTEX_WAIT_BITSET", - }, - { - Value: linux.FUTEX_WAKE_BITSET, - Name: "FUTEX_WAKE_BITSET", - }, - { - Value: linux.FUTEX_WAIT_REQUEUE_PI, - Name: "FUTEX_WAIT_REQUEUE_PI", - }, - { - Value: linux.FUTEX_CMP_REQUEUE_PI, - Name: "FUTEX_CMP_REQUEUE_PI", - }, + linux.FUTEX_WAIT: "FUTEX_WAIT", + linux.FUTEX_WAKE: "FUTEX_WAKE", + linux.FUTEX_FD: "FUTEX_FD", + linux.FUTEX_REQUEUE: "FUTEX_REQUEUE", + linux.FUTEX_CMP_REQUEUE: "FUTEX_CMP_REQUEUE", + linux.FUTEX_WAKE_OP: "FUTEX_WAKE_OP", + linux.FUTEX_LOCK_PI: "FUTEX_LOCK_PI", + linux.FUTEX_UNLOCK_PI: "FUTEX_UNLOCK_PI", + linux.FUTEX_TRYLOCK_PI: "FUTEX_TRYLOCK_PI", + linux.FUTEX_WAIT_BITSET: "FUTEX_WAIT_BITSET", + linux.FUTEX_WAKE_BITSET: "FUTEX_WAKE_BITSET", + linux.FUTEX_WAIT_REQUEUE_PI: "FUTEX_WAIT_REQUEUE_PI", + linux.FUTEX_CMP_REQUEUE_PI: "FUTEX_CMP_REQUEUE_PI", } func futex(op uint64) string { diff --git a/pkg/sentry/strace/open.go b/pkg/sentry/strace/open.go index 5a72a940c..3bf348d7a 100644 --- a/pkg/sentry/strace/open.go +++ b/pkg/sentry/strace/open.go @@ -22,18 +22,9 @@ import ( // OpenMode represents the mode to open(2) a file. var OpenMode = abi.ValueSet{ - { - Value: syscall.O_RDWR, - Name: "O_RDWR", - }, - { - Value: syscall.O_WRONLY, - Name: "O_WRONLY", - }, - { - Value: syscall.O_RDONLY, - Name: "O_RDONLY", - }, + syscall.O_RDWR: "O_RDWR", + syscall.O_WRONLY: "O_WRONLY", + syscall.O_RDONLY: "O_RDONLY", } // OpenFlagSet is the set of open(2) flags. diff --git a/pkg/sentry/strace/ptrace.go b/pkg/sentry/strace/ptrace.go index c572aafb4..8c4b79227 100644 --- a/pkg/sentry/strace/ptrace.go +++ b/pkg/sentry/strace/ptrace.go @@ -21,156 +21,42 @@ import ( // PtraceRequestSet are the possible ptrace(2) requests. var PtraceRequestSet = abi.ValueSet{ - { - Value: linux.PTRACE_TRACEME, - Name: "PTRACE_TRACEME", - }, - { - Value: linux.PTRACE_PEEKTEXT, - Name: "PTRACE_PEEKTEXT", - }, - { - Value: linux.PTRACE_PEEKDATA, - Name: "PTRACE_PEEKDATA", - }, - { - Value: linux.PTRACE_PEEKUSR, - Name: "PTRACE_PEEKUSR", - }, - { - Value: linux.PTRACE_POKETEXT, - Name: "PTRACE_POKETEXT", - }, - { - Value: linux.PTRACE_POKEDATA, - Name: "PTRACE_POKEDATA", - }, - { - Value: linux.PTRACE_POKEUSR, - Name: "PTRACE_POKEUSR", - }, - { - Value: linux.PTRACE_CONT, - Name: "PTRACE_CONT", - }, - { - Value: linux.PTRACE_KILL, - Name: "PTRACE_KILL", - }, - { - Value: linux.PTRACE_SINGLESTEP, - Name: "PTRACE_SINGLESTEP", - }, - { - Value: linux.PTRACE_ATTACH, - Name: "PTRACE_ATTACH", - }, - { - Value: linux.PTRACE_DETACH, - Name: "PTRACE_DETACH", - }, - { - Value: linux.PTRACE_SYSCALL, - Name: "PTRACE_SYSCALL", - }, - { - Value: linux.PTRACE_SETOPTIONS, - Name: "PTRACE_SETOPTIONS", - }, - { - Value: linux.PTRACE_GETEVENTMSG, - Name: "PTRACE_GETEVENTMSG", - }, - { - Value: linux.PTRACE_GETSIGINFO, - Name: "PTRACE_GETSIGINFO", - }, - { - Value: linux.PTRACE_SETSIGINFO, - Name: "PTRACE_SETSIGINFO", - }, - { - Value: linux.PTRACE_GETREGSET, - Name: "PTRACE_GETREGSET", - }, - { - Value: linux.PTRACE_SETREGSET, - Name: "PTRACE_SETREGSET", - }, - { - Value: linux.PTRACE_SEIZE, - Name: "PTRACE_SEIZE", - }, - { - Value: linux.PTRACE_INTERRUPT, - Name: "PTRACE_INTERRUPT", - }, - { - Value: linux.PTRACE_LISTEN, - Name: "PTRACE_LISTEN", - }, - { - Value: linux.PTRACE_PEEKSIGINFO, - Name: "PTRACE_PEEKSIGINFO", - }, - { - Value: linux.PTRACE_GETSIGMASK, - Name: "PTRACE_GETSIGMASK", - }, - { - Value: linux.PTRACE_SETSIGMASK, - Name: "PTRACE_SETSIGMASK", - }, - { - Value: linux.PTRACE_GETREGS, - Name: "PTRACE_GETREGS", - }, - { - Value: linux.PTRACE_SETREGS, - Name: "PTRACE_SETREGS", - }, - { - Value: linux.PTRACE_GETFPREGS, - Name: "PTRACE_GETFPREGS", - }, - { - Value: linux.PTRACE_SETFPREGS, - Name: "PTRACE_SETFPREGS", - }, - { - Value: linux.PTRACE_GETFPXREGS, - Name: "PTRACE_GETFPXREGS", - }, - { - Value: linux.PTRACE_SETFPXREGS, - Name: "PTRACE_SETFPXREGS", - }, - { - Value: linux.PTRACE_OLDSETOPTIONS, - Name: "PTRACE_OLDSETOPTIONS", - }, - { - Value: linux.PTRACE_GET_THREAD_AREA, - Name: "PTRACE_GET_THREAD_AREA", - }, - { - Value: linux.PTRACE_SET_THREAD_AREA, - Name: "PTRACE_SET_THREAD_AREA", - }, - { - Value: linux.PTRACE_ARCH_PRCTL, - Name: "PTRACE_ARCH_PRCTL", - }, - { - Value: linux.PTRACE_SYSEMU, - Name: "PTRACE_SYSEMU", - }, - { - Value: linux.PTRACE_SYSEMU_SINGLESTEP, - Name: "PTRACE_SYSEMU_SINGLESTEP", - }, - { - Value: linux.PTRACE_SINGLEBLOCK, - Name: "PTRACE_SINGLEBLOCK", - }, + linux.PTRACE_TRACEME: "PTRACE_TRACEME", + linux.PTRACE_PEEKTEXT: "PTRACE_PEEKTEXT", + linux.PTRACE_PEEKDATA: "PTRACE_PEEKDATA", + linux.PTRACE_PEEKUSR: "PTRACE_PEEKUSR", + linux.PTRACE_POKETEXT: "PTRACE_POKETEXT", + linux.PTRACE_POKEDATA: "PTRACE_POKEDATA", + linux.PTRACE_POKEUSR: "PTRACE_POKEUSR", + linux.PTRACE_CONT: "PTRACE_CONT", + linux.PTRACE_KILL: "PTRACE_KILL", + linux.PTRACE_SINGLESTEP: "PTRACE_SINGLESTEP", + linux.PTRACE_ATTACH: "PTRACE_ATTACH", + linux.PTRACE_DETACH: "PTRACE_DETACH", + linux.PTRACE_SYSCALL: "PTRACE_SYSCALL", + linux.PTRACE_SETOPTIONS: "PTRACE_SETOPTIONS", + linux.PTRACE_GETEVENTMSG: "PTRACE_GETEVENTMSG", + linux.PTRACE_GETSIGINFO: "PTRACE_GETSIGINFO", + linux.PTRACE_SETSIGINFO: "PTRACE_SETSIGINFO", + linux.PTRACE_GETREGSET: "PTRACE_GETREGSET", + linux.PTRACE_SETREGSET: "PTRACE_SETREGSET", + linux.PTRACE_SEIZE: "PTRACE_SEIZE", + linux.PTRACE_INTERRUPT: "PTRACE_INTERRUPT", + linux.PTRACE_LISTEN: "PTRACE_LISTEN", + linux.PTRACE_PEEKSIGINFO: "PTRACE_PEEKSIGINFO", + linux.PTRACE_GETSIGMASK: "PTRACE_GETSIGMASK", + linux.PTRACE_SETSIGMASK: "PTRACE_SETSIGMASK", + linux.PTRACE_GETREGS: "PTRACE_GETREGS", + linux.PTRACE_SETREGS: "PTRACE_SETREGS", + linux.PTRACE_GETFPREGS: "PTRACE_GETFPREGS", + linux.PTRACE_SETFPREGS: "PTRACE_SETFPREGS", + linux.PTRACE_GETFPXREGS: "PTRACE_GETFPXREGS", + linux.PTRACE_SETFPXREGS: "PTRACE_SETFPXREGS", + linux.PTRACE_OLDSETOPTIONS: "PTRACE_OLDSETOPTIONS", + linux.PTRACE_GET_THREAD_AREA: "PTRACE_GET_THREAD_AREA", + linux.PTRACE_SET_THREAD_AREA: "PTRACE_SET_THREAD_AREA", + linux.PTRACE_ARCH_PRCTL: "PTRACE_ARCH_PRCTL", + linux.PTRACE_SYSEMU: "PTRACE_SYSEMU", + linux.PTRACE_SYSEMU_SINGLESTEP: "PTRACE_SYSEMU_SINGLESTEP", + linux.PTRACE_SINGLEBLOCK: "PTRACE_SINGLEBLOCK", } diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go index 375418dc1..4c1a9d469 100644 --- a/pkg/sentry/strace/socket.go +++ b/pkg/sentry/strace/socket.go @@ -31,202 +31,58 @@ import ( // SocketFamily are the possible socket(2) families. var SocketFamily = abi.ValueSet{ - { - Value: linux.AF_UNSPEC, - Name: "AF_UNSPEC", - }, - { - Value: linux.AF_UNIX, - Name: "AF_UNIX", - }, - { - Value: linux.AF_INET, - Name: "AF_INET", - }, - { - Value: linux.AF_AX25, - Name: "AF_AX25", - }, - { - Value: linux.AF_IPX, - Name: "AF_IPX", - }, - { - Value: linux.AF_APPLETALK, - Name: "AF_APPLETALK", - }, - { - Value: linux.AF_NETROM, - Name: "AF_NETROM", - }, - { - Value: linux.AF_BRIDGE, - Name: "AF_BRIDGE", - }, - { - Value: linux.AF_ATMPVC, - Name: "AF_ATMPVC", - }, - { - Value: linux.AF_X25, - Name: "AF_X25", - }, - { - Value: linux.AF_INET6, - Name: "AF_INET6", - }, - { - Value: linux.AF_ROSE, - Name: "AF_ROSE", - }, - { - Value: linux.AF_DECnet, - Name: "AF_DECnet", - }, - { - Value: linux.AF_NETBEUI, - Name: "AF_NETBEUI", - }, - { - Value: linux.AF_SECURITY, - Name: "AF_SECURITY", - }, - { - Value: linux.AF_KEY, - Name: "AF_KEY", - }, - { - Value: linux.AF_NETLINK, - Name: "AF_NETLINK", - }, - { - Value: linux.AF_PACKET, - Name: "AF_PACKET", - }, - { - Value: linux.AF_ASH, - Name: "AF_ASH", - }, - { - Value: linux.AF_ECONET, - Name: "AF_ECONET", - }, - { - Value: linux.AF_ATMSVC, - Name: "AF_ATMSVC", - }, - { - Value: linux.AF_RDS, - Name: "AF_RDS", - }, - { - Value: linux.AF_SNA, - Name: "AF_SNA", - }, - { - Value: linux.AF_IRDA, - Name: "AF_IRDA", - }, - { - Value: linux.AF_PPPOX, - Name: "AF_PPPOX", - }, - { - Value: linux.AF_WANPIPE, - Name: "AF_WANPIPE", - }, - { - Value: linux.AF_LLC, - Name: "AF_LLC", - }, - { - Value: linux.AF_IB, - Name: "AF_IB", - }, - { - Value: linux.AF_MPLS, - Name: "AF_MPLS", - }, - { - Value: linux.AF_CAN, - Name: "AF_CAN", - }, - { - Value: linux.AF_TIPC, - Name: "AF_TIPC", - }, - { - Value: linux.AF_BLUETOOTH, - Name: "AF_BLUETOOTH", - }, - { - Value: linux.AF_IUCV, - Name: "AF_IUCV", - }, - { - Value: linux.AF_RXRPC, - Name: "AF_RXRPC", - }, - { - Value: linux.AF_ISDN, - Name: "AF_ISDN", - }, - { - Value: linux.AF_PHONET, - Name: "AF_PHONET", - }, - { - Value: linux.AF_IEEE802154, - Name: "AF_IEEE802154", - }, - { - Value: linux.AF_CAIF, - Name: "AF_CAIF", - }, - { - Value: linux.AF_ALG, - Name: "AF_ALG", - }, - { - Value: linux.AF_NFC, - Name: "AF_NFC", - }, - { - Value: linux.AF_VSOCK, - Name: "AF_VSOCK", - }, + linux.AF_UNSPEC: "AF_UNSPEC", + linux.AF_UNIX: "AF_UNIX", + linux.AF_INET: "AF_INET", + linux.AF_AX25: "AF_AX25", + linux.AF_IPX: "AF_IPX", + linux.AF_APPLETALK: "AF_APPLETALK", + linux.AF_NETROM: "AF_NETROM", + linux.AF_BRIDGE: "AF_BRIDGE", + linux.AF_ATMPVC: "AF_ATMPVC", + linux.AF_X25: "AF_X25", + linux.AF_INET6: "AF_INET6", + linux.AF_ROSE: "AF_ROSE", + linux.AF_DECnet: "AF_DECnet", + linux.AF_NETBEUI: "AF_NETBEUI", + linux.AF_SECURITY: "AF_SECURITY", + linux.AF_KEY: "AF_KEY", + linux.AF_NETLINK: "AF_NETLINK", + linux.AF_PACKET: "AF_PACKET", + linux.AF_ASH: "AF_ASH", + linux.AF_ECONET: "AF_ECONET", + linux.AF_ATMSVC: "AF_ATMSVC", + linux.AF_RDS: "AF_RDS", + linux.AF_SNA: "AF_SNA", + linux.AF_IRDA: "AF_IRDA", + linux.AF_PPPOX: "AF_PPPOX", + linux.AF_WANPIPE: "AF_WANPIPE", + linux.AF_LLC: "AF_LLC", + linux.AF_IB: "AF_IB", + linux.AF_MPLS: "AF_MPLS", + linux.AF_CAN: "AF_CAN", + linux.AF_TIPC: "AF_TIPC", + linux.AF_BLUETOOTH: "AF_BLUETOOTH", + linux.AF_IUCV: "AF_IUCV", + linux.AF_RXRPC: "AF_RXRPC", + linux.AF_ISDN: "AF_ISDN", + linux.AF_PHONET: "AF_PHONET", + linux.AF_IEEE802154: "AF_IEEE802154", + linux.AF_CAIF: "AF_CAIF", + linux.AF_ALG: "AF_ALG", + linux.AF_NFC: "AF_NFC", + linux.AF_VSOCK: "AF_VSOCK", } // SocketType are the possible socket(2) types. var SocketType = abi.ValueSet{ - { - Value: linux.SOCK_STREAM, - Name: "SOCK_STREAM", - }, - { - Value: linux.SOCK_DGRAM, - Name: "SOCK_DGRAM", - }, - { - Value: linux.SOCK_RAW, - Name: "SOCK_RAW", - }, - { - Value: linux.SOCK_RDM, - Name: "SOCK_RDM", - }, - { - Value: linux.SOCK_SEQPACKET, - Name: "SOCK_SEQPACKET", - }, - { - Value: linux.SOCK_DCCP, - Name: "SOCK_DCCP", - }, - { - Value: linux.SOCK_PACKET, - Name: "SOCK_PACKET", - }, + linux.SOCK_STREAM: "SOCK_STREAM", + linux.SOCK_DGRAM: "SOCK_DGRAM", + linux.SOCK_RAW: "SOCK_RAW", + linux.SOCK_RDM: "SOCK_RDM", + linux.SOCK_SEQPACKET: "SOCK_SEQPACKET", + linux.SOCK_DCCP: "SOCK_DCCP", + linux.SOCK_PACKET: "SOCK_PACKET", } // SocketFlagSet are the possible socket(2) flags. @@ -243,106 +99,31 @@ var SocketFlagSet = abi.FlagSet{ // ipProtocol are the possible socket(2) types for INET and INET6 sockets. var ipProtocol = abi.ValueSet{ - { - Value: linux.IPPROTO_IP, - Name: "IPPROTO_IP", - }, - { - Value: linux.IPPROTO_ICMP, - Name: "IPPROTO_ICMP", - }, - { - Value: linux.IPPROTO_IGMP, - Name: "IPPROTO_IGMP", - }, - { - Value: linux.IPPROTO_IPIP, - Name: "IPPROTO_IPIP", - }, - { - Value: linux.IPPROTO_TCP, - Name: "IPPROTO_TCP", - }, - { - Value: linux.IPPROTO_EGP, - Name: "IPPROTO_EGP", - }, - { - Value: linux.IPPROTO_PUP, - Name: "IPPROTO_PUP", - }, - { - Value: linux.IPPROTO_UDP, - Name: "IPPROTO_UDP", - }, - { - Value: linux.IPPROTO_IDP, - Name: "IPPROTO_IDP", - }, - { - Value: linux.IPPROTO_TP, - Name: "IPPROTO_TP", - }, - { - Value: linux.IPPROTO_DCCP, - Name: "IPPROTO_DCCP", - }, - { - Value: linux.IPPROTO_IPV6, - Name: "IPPROTO_IPV6", - }, - { - Value: linux.IPPROTO_RSVP, - Name: "IPPROTO_RSVP", - }, - { - Value: linux.IPPROTO_GRE, - Name: "IPPROTO_GRE", - }, - { - Value: linux.IPPROTO_ESP, - Name: "IPPROTO_ESP", - }, - { - Value: linux.IPPROTO_AH, - Name: "IPPROTO_AH", - }, - { - Value: linux.IPPROTO_MTP, - Name: "IPPROTO_MTP", - }, - { - Value: linux.IPPROTO_BEETPH, - Name: "IPPROTO_BEETPH", - }, - { - Value: linux.IPPROTO_ENCAP, - Name: "IPPROTO_ENCAP", - }, - { - Value: linux.IPPROTO_PIM, - Name: "IPPROTO_PIM", - }, - { - Value: linux.IPPROTO_COMP, - Name: "IPPROTO_COMP", - }, - { - Value: linux.IPPROTO_SCTP, - Name: "IPPROTO_SCTP", - }, - { - Value: linux.IPPROTO_UDPLITE, - Name: "IPPROTO_UDPLITE", - }, - { - Value: linux.IPPROTO_MPLS, - Name: "IPPROTO_MPLS", - }, - { - Value: linux.IPPROTO_RAW, - Name: "IPPROTO_RAW", - }, + linux.IPPROTO_IP: "IPPROTO_IP", + linux.IPPROTO_ICMP: "IPPROTO_ICMP", + linux.IPPROTO_IGMP: "IPPROTO_IGMP", + linux.IPPROTO_IPIP: "IPPROTO_IPIP", + linux.IPPROTO_TCP: "IPPROTO_TCP", + linux.IPPROTO_EGP: "IPPROTO_EGP", + linux.IPPROTO_PUP: "IPPROTO_PUP", + linux.IPPROTO_UDP: "IPPROTO_UDP", + linux.IPPROTO_IDP: "IPPROTO_IDP", + linux.IPPROTO_TP: "IPPROTO_TP", + linux.IPPROTO_DCCP: "IPPROTO_DCCP", + linux.IPPROTO_IPV6: "IPPROTO_IPV6", + linux.IPPROTO_RSVP: "IPPROTO_RSVP", + linux.IPPROTO_GRE: "IPPROTO_GRE", + linux.IPPROTO_ESP: "IPPROTO_ESP", + linux.IPPROTO_AH: "IPPROTO_AH", + linux.IPPROTO_MTP: "IPPROTO_MTP", + linux.IPPROTO_BEETPH: "IPPROTO_BEETPH", + linux.IPPROTO_ENCAP: "IPPROTO_ENCAP", + linux.IPPROTO_PIM: "IPPROTO_PIM", + linux.IPPROTO_COMP: "IPPROTO_COMP", + linux.IPPROTO_SCTP: "IPPROTO_SCTP", + linux.IPPROTO_UDPLITE: "IPPROTO_UDPLITE", + linux.IPPROTO_MPLS: "IPPROTO_MPLS", + linux.IPPROTO_RAW: "IPPROTO_RAW", } // SocketProtocol are the possible socket(2) protocols for each protocol family. @@ -350,90 +131,27 @@ var SocketProtocol = map[int32]abi.ValueSet{ linux.AF_INET: ipProtocol, linux.AF_INET6: ipProtocol, linux.AF_NETLINK: { - { - Value: linux.NETLINK_ROUTE, - Name: "NETLINK_ROUTE", - }, - { - Value: linux.NETLINK_UNUSED, - Name: "NETLINK_UNUSED", - }, - { - Value: linux.NETLINK_USERSOCK, - Name: "NETLINK_USERSOCK", - }, - { - Value: linux.NETLINK_FIREWALL, - Name: "NETLINK_FIREWALL", - }, - { - Value: linux.NETLINK_SOCK_DIAG, - Name: "NETLINK_SOCK_DIAG", - }, - { - Value: linux.NETLINK_NFLOG, - Name: "NETLINK_NFLOG", - }, - { - Value: linux.NETLINK_XFRM, - Name: "NETLINK_XFRM", - }, - { - Value: linux.NETLINK_SELINUX, - Name: "NETLINK_SELINUX", - }, - { - Value: linux.NETLINK_ISCSI, - Name: "NETLINK_ISCSI", - }, - { - Value: linux.NETLINK_AUDIT, - Name: "NETLINK_AUDIT", - }, - { - Value: linux.NETLINK_FIB_LOOKUP, - Name: "NETLINK_FIB_LOOKUP", - }, - { - Value: linux.NETLINK_CONNECTOR, - Name: "NETLINK_CONNECTOR", - }, - { - Value: linux.NETLINK_NETFILTER, - Name: "NETLINK_NETFILTER", - }, - { - Value: linux.NETLINK_IP6_FW, - Name: "NETLINK_IP6_FW", - }, - { - Value: linux.NETLINK_DNRTMSG, - Name: "NETLINK_DNRTMSG", - }, - { - Value: linux.NETLINK_KOBJECT_UEVENT, - Name: "NETLINK_KOBJECT_UEVENT", - }, - { - Value: linux.NETLINK_GENERIC, - Name: "NETLINK_GENERIC", - }, - { - Value: linux.NETLINK_SCSITRANSPORT, - Name: "NETLINK_SCSITRANSPORT", - }, - { - Value: linux.NETLINK_ECRYPTFS, - Name: "NETLINK_ECRYPTFS", - }, - { - Value: linux.NETLINK_RDMA, - Name: "NETLINK_RDMA", - }, - { - Value: linux.NETLINK_CRYPTO, - Name: "NETLINK_CRYPTO", - }, + linux.NETLINK_ROUTE: "NETLINK_ROUTE", + linux.NETLINK_UNUSED: "NETLINK_UNUSED", + linux.NETLINK_USERSOCK: "NETLINK_USERSOCK", + linux.NETLINK_FIREWALL: "NETLINK_FIREWALL", + linux.NETLINK_SOCK_DIAG: "NETLINK_SOCK_DIAG", + linux.NETLINK_NFLOG: "NETLINK_NFLOG", + linux.NETLINK_XFRM: "NETLINK_XFRM", + linux.NETLINK_SELINUX: "NETLINK_SELINUX", + linux.NETLINK_ISCSI: "NETLINK_ISCSI", + linux.NETLINK_AUDIT: "NETLINK_AUDIT", + linux.NETLINK_FIB_LOOKUP: "NETLINK_FIB_LOOKUP", + linux.NETLINK_CONNECTOR: "NETLINK_CONNECTOR", + linux.NETLINK_NETFILTER: "NETLINK_NETFILTER", + linux.NETLINK_IP6_FW: "NETLINK_IP6_FW", + linux.NETLINK_DNRTMSG: "NETLINK_DNRTMSG", + linux.NETLINK_KOBJECT_UEVENT: "NETLINK_KOBJECT_UEVENT", + linux.NETLINK_GENERIC: "NETLINK_GENERIC", + linux.NETLINK_SCSITRANSPORT: "NETLINK_SCSITRANSPORT", + linux.NETLINK_ECRYPTFS: "NETLINK_ECRYPTFS", + linux.NETLINK_RDMA: "NETLINK_RDMA", + linux.NETLINK_CRYPTO: "NETLINK_CRYPTO", }, } diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index 4286f0df7..e40e0b57c 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -50,18 +50,9 @@ var EventMaximumSize uint // ItimerTypes are the possible itimer types. var ItimerTypes = abi.ValueSet{ - { - Value: linux.ITIMER_REAL, - Name: "ITIMER_REAL", - }, - { - Value: linux.ITIMER_VIRTUAL, - Name: "ITIMER_VIRTUAL", - }, - { - Value: linux.ITIMER_PROF, - Name: "ITIMER_PROF", - }, + linux.ITIMER_REAL: "ITIMER_REAL", + linux.ITIMER_VIRTUAL: "ITIMER_VIRTUAL", + linux.ITIMER_PROF: "ITIMER_PROF", } func iovecs(t *kernel.Task, addr usermem.Addr, iovcnt int, printContent bool, maxBytes uint64) string { -- cgit v1.2.3 From 51900fe3a42ae8523c2b123343347a3215b93dc3 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 6 Dec 2018 15:46:20 -0800 Subject: Format signals, signal masks in strace Sample: I1205 16:51:49.869701 2492 x:0] [ 1] ioctl_test E rt_sigaction(SIGIO, 0x7e0e5b5e8500, 0x7e0e5b5e85a0) I1205 16:51:49.869766 2492 x:0] [ 1] ioctl_test X rt_sigaction(SIGIO, 0x7e0e5b5e8500, 0x7e0e5b5e85a0) = 0x0 (44.336?s) I1205 16:51:49.869831 2492 x:0] [ 1] ioctl_test E rt_sigprocmask(SIG_UNBLOCK, 0x7e0e5b5e8878 [SIGIO], 0x7e0e5b5e87c0, 0x8) I1205 16:51:49.869866 2492 x:0] [ 1] ioctl_test X rt_sigprocmask(SIG_UNBLOCK, 0x7e0e5b5e8878 [SIGIO], 0x7e0e5b5e87c0 [SIGIO 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], 0x8) = 0x0 (2.575?s) PiperOrigin-RevId: 224422404 Change-Id: I3ed3f2ec6b1a639baa9cacd37ce7ee325c3703e4 --- pkg/abi/flag.go | 9 +++++ pkg/sentry/strace/BUILD | 1 + pkg/sentry/strace/linux64.go | 20 +++++----- pkg/sentry/strace/signal.go | 86 +++++++++++++++++++++++++++++++++++++++++++ pkg/sentry/strace/strace.go | 8 ++++ pkg/sentry/strace/syscalls.go | 12 ++++++ 6 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 pkg/sentry/strace/signal.go (limited to 'pkg/abi') diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index 049c1b0dd..ec87c9cee 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -59,6 +59,15 @@ func (s ValueSet) Parse(val uint64) string { return fmt.Sprintf("%#x", val) } +// ParseDecimal returns the name of the value associated with `val`. Unknown +// values are converted to decimal. +func (s ValueSet) ParseDecimal(val uint64) string { + if v, ok := s[val]; ok { + return v + } + return fmt.Sprintf("%d", val) +} + // ParseName returns the flag value associated with 'name'. Returns false // if no value is found. func (s ValueSet) ParseName(name string) (uint64, bool) { diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index 52c7f325c..8517db1ac 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -11,6 +11,7 @@ go_library( "linux64.go", "open.go", "ptrace.go", + "signal.go", "socket.go", "strace.go", "syscalls.go", diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index 99714f12c..a2ca1a456 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -30,8 +30,8 @@ var linuxAMD64 = SyscallMap{ 10: makeSyscallInfo("mprotect", Hex, Hex, Hex), 11: makeSyscallInfo("munmap", Hex, Hex), 12: makeSyscallInfo("brk", Hex), - 13: makeSyscallInfo("rt_sigaction", Hex, Hex, Hex), - 14: makeSyscallInfo("rt_sigprocmask", Hex, Hex, Hex, Hex), + 13: makeSyscallInfo("rt_sigaction", Signal, Hex, Hex), + 14: makeSyscallInfo("rt_sigprocmask", SignalMaskAction, SigSet, PostSigSet, Hex), 15: makeSyscallInfo("rt_sigreturn"), 16: makeSyscallInfo("ioctl", Hex, Hex, Hex), 17: makeSyscallInfo("pread64", Hex, ReadBuffer, Hex, Hex), @@ -79,7 +79,7 @@ var linuxAMD64 = SyscallMap{ 59: makeSyscallInfo("execve", Path, ExecveStringVector, ExecveStringVector), 60: makeSyscallInfo("exit", Hex), 61: makeSyscallInfo("wait4", Hex, Hex, Hex, Rusage), - 62: makeSyscallInfo("kill", Hex, Hex), + 62: makeSyscallInfo("kill", Hex, Signal), 63: makeSyscallInfo("uname", Uname), 64: makeSyscallInfo("semget", Hex, Hex, Hex), 65: makeSyscallInfo("semop", Hex, Hex, Hex), @@ -145,8 +145,8 @@ var linuxAMD64 = SyscallMap{ 125: makeSyscallInfo("capget", Hex, Hex), 126: makeSyscallInfo("capset", Hex, Hex), 127: makeSyscallInfo("rt_sigpending", Hex), - 128: makeSyscallInfo("rt_sigtimedwait", Hex, Hex, Timespec, Hex), - 129: makeSyscallInfo("rt_sigqueueinfo", Hex, Hex, Hex), + 128: makeSyscallInfo("rt_sigtimedwait", SigSet, Hex, Timespec, Hex), + 129: makeSyscallInfo("rt_sigqueueinfo", Hex, Signal, Hex), 130: makeSyscallInfo("rt_sigsuspend", Hex), 131: makeSyscallInfo("sigaltstack", Hex, Hex), 132: makeSyscallInfo("utime", Path, Utimbuf), @@ -217,7 +217,7 @@ var linuxAMD64 = SyscallMap{ 197: makeSyscallInfo("removexattr", Path, Path), 198: makeSyscallInfo("lremovexattr", Path, Path), 199: makeSyscallInfo("fremovexattr", Hex, Path), - 200: makeSyscallInfo("tkill", Hex, Hex), + 200: makeSyscallInfo("tkill", Hex, Signal), 201: makeSyscallInfo("time", Hex), 202: makeSyscallInfo("futex", Hex, FutexOp, Hex, Timespec, Hex, Hex), 203: makeSyscallInfo("sched_setaffinity", Hex, Hex, Hex), @@ -251,7 +251,7 @@ var linuxAMD64 = SyscallMap{ 231: makeSyscallInfo("exit_group", Hex), 232: makeSyscallInfo("epoll_wait", Hex, Hex, Hex, Hex), 233: makeSyscallInfo("epoll_ctl", Hex, Hex, Hex, Hex), - 234: makeSyscallInfo("tgkill", Hex, Hex, Hex), + 234: makeSyscallInfo("tgkill", Hex, Hex, Signal), 235: makeSyscallInfo("utimes", Path, Timeval), // 236: vserver (not implemented in the Linux kernel) 237: makeSyscallInfo("mbind", Hex, Hex, Hex, Hex, Hex, Hex), @@ -288,7 +288,7 @@ var linuxAMD64 = SyscallMap{ 268: makeSyscallInfo("fchmodat", Hex, Path, Mode), 269: makeSyscallInfo("faccessat", Hex, Path, Oct, Hex), 270: makeSyscallInfo("pselect6", Hex, Hex, Hex, Hex, Hex, Hex), - 271: makeSyscallInfo("ppoll", Hex, Hex, Timespec, Hex, Hex), + 271: makeSyscallInfo("ppoll", Hex, Hex, Timespec, SigSet, Hex), 272: makeSyscallInfo("unshare", Hex), 273: makeSyscallInfo("set_robust_list", Hex, Hex), 274: makeSyscallInfo("get_robust_list", Hex, Hex, Hex), @@ -298,7 +298,7 @@ var linuxAMD64 = SyscallMap{ 278: makeSyscallInfo("vmsplice", Hex, Hex, Hex, Hex), 279: makeSyscallInfo("move_pages", Hex, Hex, Hex, Hex, Hex, Hex), 280: makeSyscallInfo("utimensat", Hex, Path, UTimeTimespec, Hex), - 281: makeSyscallInfo("epoll_pwait", Hex, Hex, Hex, Hex, Hex, Hex), + 281: makeSyscallInfo("epoll_pwait", Hex, Hex, Hex, Hex, SigSet, Hex), 282: makeSyscallInfo("signalfd", Hex, Hex, Hex), 283: makeSyscallInfo("timerfd_create", Hex, Hex), 284: makeSyscallInfo("eventfd", Hex), @@ -314,7 +314,7 @@ var linuxAMD64 = SyscallMap{ 294: makeSyscallInfo("inotify_init1", Hex), 295: makeSyscallInfo("preadv", Hex, ReadIOVec, Hex, Hex), 296: makeSyscallInfo("pwritev", Hex, WriteIOVec, Hex, Hex), - 297: makeSyscallInfo("rt_tgsigqueueinfo", Hex, Hex, Hex, Hex), + 297: makeSyscallInfo("rt_tgsigqueueinfo", Hex, Hex, Signal, Hex), 298: makeSyscallInfo("perf_event_open", Hex, Hex, Hex, Hex, Hex), 299: makeSyscallInfo("recvmmsg", Hex, Hex, Hex, Hex, Hex), 300: makeSyscallInfo("fanotify_init", Hex, Hex), diff --git a/pkg/sentry/strace/signal.go b/pkg/sentry/strace/signal.go new file mode 100644 index 000000000..00ed02a3c --- /dev/null +++ b/pkg/sentry/strace/signal.go @@ -0,0 +1,86 @@ +// Copyright 2018 Google LLC +// +// 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 ( + "fmt" + "strings" + + "gvisor.googlesource.com/gvisor/pkg/abi" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" +) + +// signalNames contains the names of all named signals. +var signalNames = abi.ValueSet{ + uint64(linux.SIGABRT): "SIGABRT", + uint64(linux.SIGALRM): "SIGALRM", + uint64(linux.SIGBUS): "SIGBUS", + uint64(linux.SIGCHLD): "SIGCHLD", + uint64(linux.SIGCONT): "SIGCONT", + uint64(linux.SIGFPE): "SIGFPE", + uint64(linux.SIGHUP): "SIGHUP", + uint64(linux.SIGILL): "SIGILL", + uint64(linux.SIGINT): "SIGINT", + uint64(linux.SIGIO): "SIGIO", + uint64(linux.SIGKILL): "SIGKILL", + uint64(linux.SIGPIPE): "SIGPIPE", + uint64(linux.SIGPROF): "SIGPROF", + uint64(linux.SIGPWR): "SIGPWR", + uint64(linux.SIGQUIT): "SIGQUIT", + uint64(linux.SIGSEGV): "SIGSEGV", + uint64(linux.SIGSTKFLT): "SIGSTKFLT", + uint64(linux.SIGSTOP): "SIGSTOP", + uint64(linux.SIGSYS): "SIGSYS", + uint64(linux.SIGTERM): "SIGTERM", + uint64(linux.SIGTRAP): "SIGTRAP", + uint64(linux.SIGTSTP): "SIGTSTP", + uint64(linux.SIGTTIN): "SIGTTIN", + uint64(linux.SIGTTOU): "SIGTTOU", + uint64(linux.SIGURG): "SIGURG", + uint64(linux.SIGUSR1): "SIGUSR1", + uint64(linux.SIGUSR2): "SIGUSR2", + uint64(linux.SIGVTALRM): "SIGVTALRM", + uint64(linux.SIGWINCH): "SIGWINCH", + uint64(linux.SIGXCPU): "SIGXCPU", + uint64(linux.SIGXFSZ): "SIGXFSZ", +} + +var signalMaskActions = abi.ValueSet{ + linux.SIG_BLOCK: "SIG_BLOCK", + linux.SIG_UNBLOCK: "SIG_UNBLOCK", + linux.SIG_SETMASK: "SIG_SETMASK", +} + +func sigSet(t *kernel.Task, addr usermem.Addr) string { + if addr == 0 { + return "null" + } + + var b [linux.SignalSetSize]byte + if _, err := t.CopyInBytes(addr, b[:]); err != nil { + return fmt.Sprintf("%#x (error copying sigset: %v)", addr, err) + } + + set := linux.SignalSet(usermem.ByteOrder.Uint64(b[:])) + + var signals []string + linux.ForEachSignal(set, func(sig linux.Signal) { + signals = append(signals, signalNames.ParseDecimal(uint64(sig))) + }) + + return fmt.Sprintf("%#x [%v]", addr, strings.Join(signals, " ")) +} diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index e40e0b57c..6df84e690 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -333,6 +333,12 @@ func (i *SyscallInfo) pre(t *kernel.Task, args arch.SyscallArguments, maximumBlo output = append(output, PtraceRequestSet.Parse(args[arg].Uint64())) case ItimerType: output = append(output, ItimerTypes.Parse(uint64(args[arg].Int()))) + case Signal: + output = append(output, signalNames.ParseDecimal(args[arg].Uint64())) + case SignalMaskAction: + output = append(output, signalMaskActions.Parse(uint64(args[arg].Int()))) + case SigSet: + output = append(output, sigSet(t, args[arg].Pointer())) case Oct: output = append(output, "0o"+strconv.FormatUint(args[arg].Uint64(), 8)) case Hex: @@ -391,6 +397,8 @@ func (i *SyscallInfo) post(t *kernel.Task, args arch.SyscallArguments, rval uint output[arg] = timeval(t, args[arg].Pointer()) case Rusage: output[arg] = rusage(t, args[arg].Pointer()) + case PostSigSet: + output[arg] = sigSet(t, args[arg].Pointer()) } } } diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 9eeb18a03..22aecc009 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -170,6 +170,18 @@ const ( // ItimerType is an itimer type (ITIMER_REAL, etc). ItimerType + + // Signal is a signal number. + Signal + + // SignalMaskAction is a signal mask action passed to rt_sigprocmask(2). + SignalMaskAction + + // SigSet is a signal set. + SigSet + + // PostSigSet is a signal set, formatted after syscall execution. + PostSigSet ) // defaultFormat is the syscall argument format to use if the actual format is -- cgit v1.2.3 From 42e2e5cae9b035a62bdbf492ad4a1e9d016c5830 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 7 Dec 2018 16:27:35 -0800 Subject: Format sigaction in strace Sample: I1206 14:24:56.768520 3700 x:0] [ 1] ioctl_test E rt_sigaction(SIGSEGV, 0x7ee6edb0c590 {Handler: 0x559c6d915cf0, Flags: SA_SIGINFO|SA_RESTORER|SA_ONSTACK|SA_NODEFER, Restorer: 0x2a9901a259a0, Mask: []}, 0x7ee6edb0c630) I1206 14:24:56.768530 3700 x:0] [ 1] ioctl_test X rt_sigaction(SIGSEGV, 0x7ee6edb0c590 {Handler: 0x559c6d915cf0, Flags: SA_SIGINFO|SA_RESTORER|SA_ONSTACK|SA_NODEFER, Restorer: 0x2a9901a259a0, Mask: []}, 0x7ee6edb0c630 {Handler: SIG_DFL, Flags: 0x0, Restorer: 0x0, Mask: []}) = 0x0 (2.701?s) PiperOrigin-RevId: 224596606 Change-Id: I3512493aed99d3d75600249263da46686b1dc0e7 --- pkg/abi/flag.go | 5 ++++ pkg/abi/linux/signal.go | 19 +++++++------ pkg/sentry/strace/linux64.go | 2 +- pkg/sentry/strace/signal.go | 64 ++++++++++++++++++++++++++++++++++++++++++- pkg/sentry/strace/strace.go | 4 +++ pkg/sentry/strace/syscalls.go | 6 ++++ 6 files changed, 89 insertions(+), 11 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index ec87c9cee..b48757da8 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -43,6 +43,11 @@ func (s FlagSet) Parse(val uint64) string { flags = append(flags, "0x"+strconv.FormatUint(val, 16)) } + if len(flags) == 0 { + // Prefer 0 to an empty string. + return "0x0" + } + return strings.Join(flags, "|") } diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index bf9bce6ed..395f9f31e 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -165,15 +165,16 @@ const ( // Signal action flags for rt_sigaction(2), from uapi/asm-generic/signal.h const ( - SA_NOCLDSTOP = 0x00000001 - SA_NOCLDWAIT = 0x00000002 - SA_SIGINFO = 0x00000004 - SA_ONSTACK = 0x08000000 - SA_RESTART = 0x10000000 - SA_NODEFER = 0x40000000 - SA_RESTARTHAND = 0x80000000 - SA_NOMASK = SA_NODEFER - SA_ONESHOT = SA_RESTARTHAND + SA_NOCLDSTOP = 0x00000001 + SA_NOCLDWAIT = 0x00000002 + SA_SIGINFO = 0x00000004 + SA_RESTORER = 0x04000000 + SA_ONSTACK = 0x08000000 + SA_RESTART = 0x10000000 + SA_NODEFER = 0x40000000 + SA_RESETHAND = 0x80000000 + SA_NOMASK = SA_NODEFER + SA_ONESHOT = SA_RESETHAND ) // Signal info types. diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index a2ca1a456..9457e24b5 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -30,7 +30,7 @@ var linuxAMD64 = SyscallMap{ 10: makeSyscallInfo("mprotect", Hex, Hex, Hex), 11: makeSyscallInfo("munmap", Hex, Hex), 12: makeSyscallInfo("brk", Hex), - 13: makeSyscallInfo("rt_sigaction", Signal, Hex, Hex), + 13: makeSyscallInfo("rt_sigaction", Signal, SigAction, PostSigAction), 14: makeSyscallInfo("rt_sigprocmask", SignalMaskAction, SigSet, PostSigSet, Hex), 15: makeSyscallInfo("rt_sigreturn"), 16: makeSyscallInfo("ioctl", Hex, Hex, Hex), diff --git a/pkg/sentry/strace/signal.go b/pkg/sentry/strace/signal.go index 00ed02a3c..524be0e15 100644 --- a/pkg/sentry/strace/signal.go +++ b/pkg/sentry/strace/signal.go @@ -65,6 +65,41 @@ var signalMaskActions = abi.ValueSet{ linux.SIG_SETMASK: "SIG_SETMASK", } +var sigActionFlags = abi.FlagSet{ + { + Flag: linux.SA_NOCLDSTOP, + Name: "SA_NOCLDSTOP", + }, + { + Flag: linux.SA_NOCLDWAIT, + Name: "SA_NOCLDWAIT", + }, + { + Flag: linux.SA_SIGINFO, + Name: "SA_SIGINFO", + }, + { + Flag: linux.SA_RESTORER, + Name: "SA_RESTORER", + }, + { + Flag: linux.SA_ONSTACK, + Name: "SA_ONSTACK", + }, + { + Flag: linux.SA_RESTART, + Name: "SA_RESTART", + }, + { + Flag: linux.SA_NODEFER, + Name: "SA_NODEFER", + }, + { + Flag: linux.SA_RESETHAND, + Name: "SA_RESETHAND", + }, +} + func sigSet(t *kernel.Task, addr usermem.Addr) string { if addr == 0 { return "null" @@ -77,10 +112,37 @@ func sigSet(t *kernel.Task, addr usermem.Addr) string { set := linux.SignalSet(usermem.ByteOrder.Uint64(b[:])) + return fmt.Sprintf("%#x %s", addr, formatSigSet(set)) +} + +func formatSigSet(set linux.SignalSet) string { var signals []string linux.ForEachSignal(set, func(sig linux.Signal) { signals = append(signals, signalNames.ParseDecimal(uint64(sig))) }) - return fmt.Sprintf("%#x [%v]", addr, strings.Join(signals, " ")) + return fmt.Sprintf("[%v]", strings.Join(signals, " ")) +} + +func sigAction(t *kernel.Task, addr usermem.Addr) string { + if addr == 0 { + return "null" + } + + sa, err := t.CopyInSignalAct(addr) + if err != nil { + return fmt.Sprintf("%#x (error copying sigaction: %v)", addr, err) + } + + var handler string + switch sa.Handler { + case linux.SIG_IGN: + handler = "SIG_IGN" + case linux.SIG_DFL: + handler = "SIG_DFL" + default: + handler = fmt.Sprintf("%#x", sa.Handler) + } + + return fmt.Sprintf("%#x {Handler: %s, Flags: %s, Restorer: %#x, Mask: %s}", addr, handler, sigActionFlags.Parse(sa.Flags), sa.Restorer, formatSigSet(sa.Mask)) } diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index 6df84e690..da27a2ae8 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -339,6 +339,8 @@ func (i *SyscallInfo) pre(t *kernel.Task, args arch.SyscallArguments, maximumBlo output = append(output, signalMaskActions.Parse(uint64(args[arg].Int()))) case SigSet: output = append(output, sigSet(t, args[arg].Pointer())) + case SigAction: + output = append(output, sigAction(t, args[arg].Pointer())) case Oct: output = append(output, "0o"+strconv.FormatUint(args[arg].Uint64(), 8)) case Hex: @@ -399,6 +401,8 @@ func (i *SyscallInfo) post(t *kernel.Task, args arch.SyscallArguments, rval uint output[arg] = rusage(t, args[arg].Pointer()) case PostSigSet: output[arg] = sigSet(t, args[arg].Pointer()) + case PostSigAction: + output[arg] = sigAction(t, args[arg].Pointer()) } } } diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 22aecc009..1ae982354 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -182,6 +182,12 @@ const ( // PostSigSet is a signal set, formatted after syscall execution. PostSigSet + + // SigAction is a struct sigaction. + SigAction + + // PostSigAction is a struct sigaction, formatted after syscall execution. + PostSigAction ) // defaultFormat is the syscall argument format to use if the actual format is -- cgit v1.2.3 From 2421006426445a1827422c2dbdd6fc6a47087147 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Mon, 17 Dec 2018 11:37:38 -0800 Subject: Implement mlock(), kind of. Currently mlock() and friends do nothing whatsoever. However, mlocking is directly application-visible in a number of ways; for example, madvise(MADV_DONTNEED) and msync(MS_INVALIDATE) both fail on mlocked regions. We handle this inconsistently: MADV_DONTNEED is too important to not work, but MS_INVALIDATE is rejected. Change MM to track mlocked regions in a manner consistent with Linux. It still will not actually pin pages into host physical memory, but: - mlock() will now cause sentry memory management to precommit mlocked pages. - MADV_DONTNEED and MS_INVALIDATE will interact with mlocked pages as described above. PiperOrigin-RevId: 225861605 Change-Id: Iee187204979ac9a4d15d0e037c152c0902c8d0ee --- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/mm.go | 12 + pkg/sentry/limits/limits.go | 2 +- pkg/sentry/limits/linux.go | 2 +- pkg/sentry/memmap/memmap.go | 37 +++ pkg/sentry/mm/BUILD | 1 + pkg/sentry/mm/address_space.go | 12 +- pkg/sentry/mm/lifecycle.go | 24 +- pkg/sentry/mm/mm.go | 24 +- pkg/sentry/mm/syscalls.go | 423 +++++++++++++++++++++++++++----- pkg/sentry/mm/vma.go | 38 +++ pkg/sentry/syscalls/linux/linux64.go | 15 +- pkg/sentry/syscalls/linux/sys_mmap.go | 106 +++++--- pkg/sentry/syscalls/linux/sys_rlimit.go | 1 + runsc/boot/limits.go | 4 +- test/syscalls/linux/BUILD | 15 ++ test/syscalls/linux/mlock.cc | 344 ++++++++++++++++++++++++++ test/syscalls/linux/msync.cc | 20 +- 18 files changed, 947 insertions(+), 135 deletions(-) create mode 100644 test/syscalls/linux/mlock.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index b2e51b9bd..e0aa5b31d 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -60,7 +60,7 @@ const ( DefaultNofileHardLimit = 4096 // DefaultMemlockLimit is called MLOCK_LIMIT in Linux. - DefaultMemlockLimit = 64 * 1094 + DefaultMemlockLimit = 64 * 1024 // DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux. DefaultMsgqueueLimit = 819200 diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index 3fcdf8235..eda8d9788 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -49,6 +49,18 @@ const ( MREMAP_FIXED = 1 << 1 ) +// Flags for mlock2(2). +const ( + MLOCK_ONFAULT = 0x01 +) + +// Flags for mlockall(2). +const ( + MCL_CURRENT = 1 + MCL_FUTURE = 2 + MCL_ONFAULT = 4 +) + // Advice for madvise(2). const ( MADV_NORMAL = 0 diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index ba0b7d4fd..eeca01876 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -33,7 +33,7 @@ const ( Rss ProcessCount NumberOfFiles - MemoryPagesLocked + MemoryLocked AS Locks SignalsPending diff --git a/pkg/sentry/limits/linux.go b/pkg/sentry/limits/linux.go index 511db6733..295f9c398 100644 --- a/pkg/sentry/limits/linux.go +++ b/pkg/sentry/limits/linux.go @@ -30,7 +30,7 @@ var FromLinuxResource = map[int]LimitType{ linux.RLIMIT_RSS: Rss, linux.RLIMIT_NPROC: ProcessCount, linux.RLIMIT_NOFILE: NumberOfFiles, - linux.RLIMIT_MEMLOCK: MemoryPagesLocked, + linux.RLIMIT_MEMLOCK: MemoryLocked, linux.RLIMIT_AS: AS, linux.RLIMIT_LOCKS: Locks, linux.RLIMIT_SIGPENDING: SignalsPending, diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index 28e2bed9b..cf20b11e3 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -243,6 +243,40 @@ type MappingIdentity interface { Msync(ctx context.Context, mr MappableRange) error } +// MLockMode specifies the memory locking behavior of a memory mapping. +type MLockMode int + +// Note that the ordering of MLockModes is significant; see +// mm.MemoryManager.defMLockMode. +const ( + // MLockNone specifies that a mapping has no memory locking behavior. + // + // This must be the zero value for MLockMode. + MLockNone MLockMode = iota + + // MLockEager specifies that a mapping is memory-locked, as by mlock() or + // similar. Pages in the mapping should be made, and kept, resident in + // physical memory as soon as possible. + // + // As of this writing, MLockEager does not cause memory-locking to be + // requested from the host; it only affects the sentry's memory management + // behavior. + // + // MLockEager is analogous to Linux's VM_LOCKED. + MLockEager + + // MLockLazy specifies that a mapping is memory-locked, as by mlock() or + // similar. Pages in the mapping should be kept resident in physical memory + // once they have been made resident due to e.g. a page fault. + // + // As of this writing, MLockLazy does not cause memory-locking to be + // requested from the host; in fact, it has virtually no effect, except for + // interactions between mlocked pages and other syscalls. + // + // MLockLazy is analogous to Linux's VM_LOCKED | VM_LOCKONFAULT. + MLockLazy +) + // MMapOpts specifies a request to create a memory mapping. type MMapOpts struct { // Length is the length of the mapping. @@ -303,6 +337,9 @@ type MMapOpts struct { // mapping (see platform.AddressSpace.MapFile). Precommit bool + // MLockMode specifies the memory locking behavior of the mapping. + MLockMode MLockMode + // Hint is the name used for the mapping in /proc/[pid]/maps. If Hint is // empty, MappingIdentity.MappedName() will be used instead. // diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 744e73a39..5a9185e5d 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -106,6 +106,7 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/seqfile", + "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/futex", "//pkg/sentry/kernel/shm", "//pkg/sentry/limits", diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index 7488f7c4a..e7aa24c69 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -149,7 +149,7 @@ func (mm *MemoryManager) Deactivate() { // for all addresses in ar should be precommitted. // // Preconditions: mm.activeMu must be locked. mm.as != nil. ar.Length() != 0. -// ar must be page-aligned. pseg.Range().Contains(ar.Start). +// ar must be page-aligned. pseg == mm.pmas.LowerBoundSegment(ar.Start). func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, precommit bool) error { // By default, map entire pmas at a time, under the assumption that there // is no cost to mapping more of a pma than necessary. @@ -173,7 +173,9 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, pre } } - for { + // Since this checks ar.End and not mapAR.End, we will never map a pma that + // is not required. + for pseg.Ok() && pseg.Start() < ar.End { pma := pseg.ValuePtr() pmaAR := pseg.Range() pmaMapAR := pmaAR.Intersect(mapAR) @@ -184,13 +186,9 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, pre if err := pma.file.MapInto(mm.as, pmaMapAR.Start, pseg.fileRangeOf(pmaMapAR), perms, precommit); err != nil { return err } - // Since this checks ar.End and not mapAR.End, we will never map a pma - // that is not required. - if ar.End <= pmaAR.End { - return nil - } pseg = pseg.NextSegment() } + return nil } // unmapASLocked removes all AddressSpace mappings for addresses in ar. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index 1613ce11d..a42e32b43 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" + "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/platform" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) @@ -58,13 +59,17 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { mm.mappingMu.RLock() defer mm.mappingMu.RUnlock() mm2 := &MemoryManager{ - p: mm.p, - haveASIO: mm.haveASIO, - layout: mm.layout, - privateRefs: mm.privateRefs, - users: 1, - usageAS: mm.usageAS, - brk: mm.brk, + p: mm.p, + haveASIO: mm.haveASIO, + layout: mm.layout, + privateRefs: mm.privateRefs, + users: 1, + brk: mm.brk, + usageAS: mm.usageAS, + // "The child does not inherit its parent's memory locks (mlock(2), + // mlockall(2))." - fork(2). So lockedAS is 0 and defMLockMode is + // MLockNone, both of which are zero values. vma.mlockMode is reset + // when copied below. captureInvalidations: true, argv: mm.argv, envv: mm.envv, @@ -77,7 +82,7 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { // Copy vmas. dstvgap := mm2.vmas.FirstGap() for srcvseg := mm.vmas.FirstSegment(); srcvseg.Ok(); srcvseg = srcvseg.NextSegment() { - vma := srcvseg.ValuePtr() + vma := srcvseg.Value() // makes a copy of the vma vmaAR := srcvseg.Range() // Inform the Mappable, if any, of the new mapping. if vma.mappable != nil { @@ -89,7 +94,8 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { if vma.id != nil { vma.id.IncRef() } - dstvgap = mm2.vmas.Insert(dstvgap, vmaAR, *vma).NextGap() + vma.mlockMode = memmap.MLockNone + dstvgap = mm2.vmas.Insert(dstvgap, vmaAR, vma).NextGap() // We don't need to update mm2.usageAS since we copied it from mm // above. } diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index b1e39e898..c0632d232 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -95,11 +95,6 @@ type MemoryManager struct { // vmas is protected by mappingMu. vmas vmaSet - // usageAS is vmas.Span(), cached to accelerate RLIMIT_AS checks. - // - // usageAS is protected by mappingMu. - usageAS uint64 - // brk is the mm's brk, which is manipulated using the brk(2) system call. // The brk is initially set up by the loader which maps an executable // binary into the mm. @@ -107,6 +102,23 @@ type MemoryManager struct { // brk is protected by mappingMu. brk usermem.AddrRange + // usageAS is vmas.Span(), cached to accelerate RLIMIT_AS checks. + // + // usageAS is protected by mappingMu. + usageAS uint64 + + // lockedAS is the combined size in bytes of all vmas with vma.mlockMode != + // memmap.MLockNone. + // + // lockedAS is protected by mappingMu. + lockedAS uint64 + + // New VMAs created by MMap use whichever of memmap.MMapOpts.MLockMode or + // defMLockMode is greater. + // + // defMLockMode is protected by mappingMu. + defMLockMode memmap.MLockMode + // activeMu is loosely analogous to Linux's struct // mm_struct::page_table_lock. activeMu ssync.DowngradableRWMutex `state:"nosave"` @@ -252,6 +264,8 @@ type vma struct { // metag, none of which we currently support. growsDown bool `state:"manual"` + mlockMode memmap.MLockMode + // If id is not nil, it controls the lifecycle of mappable and provides vma // metadata shown in /proc/[pid]/maps, and the vma holds a reference. id memmap.MappingIdentity diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index daaae4da1..383703ec3 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -20,6 +20,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" @@ -128,16 +129,24 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme // Get the new vma. mm.mappingMu.Lock() + if opts.MLockMode < mm.defMLockMode { + opts.MLockMode = mm.defMLockMode + } vseg, ar, err := mm.createVMALocked(ctx, opts) if err != nil { mm.mappingMu.Unlock() return 0, err } + // TODO: In Linux, VM_LOCKONFAULT (which may be set on the new + // vma by mlockall(MCL_FUTURE|MCL_ONFAULT) => mm_struct::def_flags) appears + // to effectively disable MAP_POPULATE by unsetting FOLL_POPULATE in + // mm/util.c:vm_mmap_pgoff() => mm/gup.c:__mm_populate() => + // populate_vma_page_range(). Confirm this behavior. switch { - case opts.Precommit: + case opts.Precommit || opts.MLockMode == memmap.MLockEager: // Get pmas and map with precommit as requested. - mm.populateAndUnlock(ctx, vseg, ar, true) + mm.populateVMAAndUnlock(ctx, vseg, ar, true) case opts.Mappable == nil && length <= privateAllocUnit: // NOTE: Get pmas and map eagerly in the hope @@ -146,7 +155,7 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme // memmap.Mappable.Translate is unknown; and only for small mappings, // to avoid needing to allocate large amounts of memory that we may // subsequently need to checkpoint. - mm.populateAndUnlock(ctx, vseg, ar, false) + mm.populateVMAAndUnlock(ctx, vseg, ar, false) default: mm.mappingMu.Unlock() @@ -155,31 +164,29 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme return ar.Start, nil } -// Preconditions: mm.mappingMu must be locked for writing. +// populateVMA obtains pmas for addresses in ar in the given vma, and maps them +// into mm.as if it is active. // -// Postconditions: mm.mappingMu will be unlocked. -func (mm *MemoryManager) populateAndUnlock(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { +// Preconditions: mm.mappingMu must be locked. vseg.Range().IsSupersetOf(ar). +func (mm *MemoryManager) populateVMA(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { if !vseg.ValuePtr().effectivePerms.Any() { // Linux doesn't populate inaccessible pages. See // mm/gup.c:populate_vma_page_range. - mm.mappingMu.Unlock() return } mm.activeMu.Lock() + // Can't defer mm.activeMu.Unlock(); see below. - // Even if we get a new pma, we can't actually map it if we don't have an + // Even if we get new pmas, we can't actually map them if we don't have an // AddressSpace. if mm.as == nil { mm.activeMu.Unlock() - mm.mappingMu.Unlock() return } // Ensure that we have usable pmas. - mm.mappingMu.DowngradeLock() pseg, _, err := mm.getPMAsLocked(ctx, vseg, ar, pmaOpts{}) - mm.mappingMu.RUnlock() if err != nil { // mm/util.c:vm_mmap_pgoff() ignores the error, if any, from // mm/gup.c:mm_populate(). If it matters, we'll get it again when @@ -197,6 +204,45 @@ func (mm *MemoryManager) populateAndUnlock(ctx context.Context, vseg vmaIterator mm.activeMu.RUnlock() } +// populateVMAAndUnlock is equivalent to populateVMA, but also unconditionally +// unlocks mm.mappingMu. In cases where populateVMAAndUnlock is usable, it is +// preferable to populateVMA since it unlocks mm.mappingMu before performing +// expensive operations that don't require it to be locked. +// +// Preconditions: mm.mappingMu must be locked for writing. +// vseg.Range().IsSupersetOf(ar). +// +// Postconditions: mm.mappingMu will be unlocked. +func (mm *MemoryManager) populateVMAAndUnlock(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { + // See populateVMA above for commentary. + if !vseg.ValuePtr().effectivePerms.Any() { + mm.mappingMu.Unlock() + return + } + + mm.activeMu.Lock() + + if mm.as == nil { + mm.activeMu.Unlock() + mm.mappingMu.Unlock() + return + } + + // mm.mappingMu doesn't need to be write-locked for getPMAsLocked, and it + // isn't needed at all for mapASLocked. + mm.mappingMu.DowngradeLock() + pseg, _, err := mm.getPMAsLocked(ctx, vseg, ar, pmaOpts{}) + mm.mappingMu.RUnlock() + if err != nil { + mm.activeMu.Unlock() + return + } + + mm.activeMu.DowngradeLock() + mm.mapASLocked(pseg, ar, precommit) + mm.activeMu.RUnlock() +} + // MapStack allocates the initial process stack. func (mm *MemoryManager) MapStack(ctx context.Context) (usermem.AddrRange, error) { // maxStackSize is the maximum supported process stack size in bytes. @@ -236,6 +282,7 @@ func (mm *MemoryManager) MapStack(ctx context.Context) (usermem.AddrRange, error MaxPerms: usermem.AnyAccess, Private: true, GrowsDown: true, + MLockMode: mm.defMLockMode, Hint: "[stack]", }) return ar, err @@ -334,6 +381,19 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi // occupies at least part of the destination. Thus the NoMove case always // fails and the MayMove case always falls back to copying. + if vma := vseg.ValuePtr(); newSize > oldSize && vma.mlockMode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. Unlike mmap, mlock, and mlockall, + // mremap in Linux does not check mm/mlock.c:can_do_mlock() and + // therefore does not return EPERM if RLIMIT_MEMLOCK is 0 and + // !CAP_IPC_LOCK. + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + if newLockedAS := mm.lockedAS - oldSize + newSize; newLockedAS > mlockLimit { + return 0, syserror.EAGAIN + } + } + } + if opts.Move != MRemapMustMove { // Handle no-ops and in-place shrinking. These cases don't care if // [oldAddr, oldEnd) maps to a single vma, or is even mapped at all @@ -360,7 +420,7 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi if vma.mappable != nil { newOffset = vseg.mappableRange().End } - _, _, err := mm.createVMALocked(ctx, memmap.MMapOpts{ + vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: newSize - oldSize, MappingIdentity: vma.id, Mappable: vma.mappable, @@ -371,9 +431,13 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi MaxPerms: vma.maxPerms, Private: vma.private, GrowsDown: vma.growsDown, + MLockMode: vma.mlockMode, Hint: vma.hint, }) if err == nil { + if vma.mlockMode == memmap.MLockEager { + mm.populateVMA(ctx, vseg, ar, true) + } return oldAddr, nil } // In-place growth failed. In the MRemapMayMove case, fall through to @@ -462,8 +526,14 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi if vma.id != nil { vma.id.IncRef() } - mm.vmas.Add(newAR, vma) + vseg := mm.vmas.Insert(mm.vmas.FindGap(newAR.Start), newAR, vma) mm.usageAS += uint64(newAR.Length()) + if vma.mlockMode != memmap.MLockNone { + mm.lockedAS += uint64(newAR.Length()) + if vma.mlockMode == memmap.MLockEager { + mm.populateVMA(ctx, vseg, newAR, true) + } + } return newAR.Start, nil } @@ -485,8 +555,11 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi vseg = mm.vmas.Isolate(vseg, oldAR) vma := vseg.Value() mm.vmas.Remove(vseg) - mm.vmas.Add(newAR, vma) + vseg = mm.vmas.Insert(mm.vmas.FindGap(newAR.Start), newAR, vma) mm.usageAS = mm.usageAS - uint64(oldAR.Length()) + uint64(newAR.Length()) + if vma.mlockMode != memmap.MLockNone { + mm.lockedAS = mm.lockedAS - uint64(oldAR.Length()) + uint64(newAR.Length()) + } // Move pmas. This is technically optional for non-private pmas, which // could just go through memmap.Mappable.Translate again, but it's required @@ -501,6 +574,10 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi vma.mappable.RemoveMapping(ctx, mm, oldAR, vma.off, vma.isMappableAsWritable()) } + if vma.mlockMode == memmap.MLockEager { + mm.populateVMA(ctx, vseg, newAR, true) + } + return newAR.Start, nil } @@ -611,9 +688,10 @@ func (mm *MemoryManager) BrkSetup(ctx context.Context, addr usermem.Addr) { // error on failure. func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Addr, error) { mm.mappingMu.Lock() - defer mm.mappingMu.Unlock() + // Can't defer mm.mappingMu.Unlock(); see below. if addr < mm.brk.Start { + mm.mappingMu.Unlock() return mm.brk.End, syserror.EINVAL } @@ -623,21 +701,24 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad // heap + data + bss. The segment sizes need to be plumbed from the // loader package to fully enforce RLIMIT_DATA. if uint64(addr-mm.brk.Start) > limits.FromContext(ctx).Get(limits.Data).Cur { + mm.mappingMu.Unlock() return mm.brk.End, syserror.ENOMEM } oldbrkpg, _ := mm.brk.End.RoundUp() newbrkpg, ok := addr.RoundUp() if !ok { + mm.mappingMu.Unlock() return mm.brk.End, syserror.EFAULT } switch { case newbrkpg < oldbrkpg: mm.unmapLocked(ctx, usermem.AddrRange{newbrkpg, oldbrkpg}) + mm.mappingMu.Unlock() case oldbrkpg < newbrkpg: - _, _, err := mm.createVMALocked(ctx, memmap.MMapOpts{ + vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: uint64(newbrkpg - oldbrkpg), Addr: oldbrkpg, Fixed: true, @@ -646,17 +727,221 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad Perms: usermem.ReadWrite, MaxPerms: usermem.AnyAccess, Private: true, - Hint: "[heap]", + // Linux: mm/mmap.c:sys_brk() => do_brk_flags() includes + // mm->def_flags. + MLockMode: mm.defMLockMode, + Hint: "[heap]", }) if err != nil { + mm.mappingMu.Unlock() return mm.brk.End, err } + if mm.defMLockMode == memmap.MLockEager { + mm.populateVMAAndUnlock(ctx, vseg, ar, true) + } else { + mm.mappingMu.Unlock() + } + + default: + // Nothing to do. + mm.mappingMu.Unlock() } mm.brk.End = addr return addr, nil } +// MLock implements the semantics of Linux's mlock()/mlock2()/munlock(), +// depending on mode. +func (mm *MemoryManager) MLock(ctx context.Context, addr usermem.Addr, length uint64, mode memmap.MLockMode) error { + // Linux allows this to overflow. + la, _ := usermem.Addr(length + addr.PageOffset()).RoundUp() + ar, ok := addr.RoundDown().ToRange(uint64(la)) + if !ok { + return syserror.EINVAL + } + + mm.mappingMu.Lock() + // Can't defer mm.mappingMu.Unlock(); see below. + + if mode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if mlockLimit == 0 { + mm.mappingMu.Unlock() + return syserror.EPERM + } + if newLockedAS := mm.lockedAS + uint64(ar.Length()) - mm.mlockedBytesRangeLocked(ar); newLockedAS > mlockLimit { + mm.mappingMu.Unlock() + return syserror.ENOMEM + } + } + } + + // Check this after RLIMIT_MEMLOCK for consistency with Linux. + if ar.Length() == 0 { + mm.mappingMu.Unlock() + return nil + } + + // Apply the new mlock mode to vmas. + var unmapped bool + vseg := mm.vmas.FindSegment(ar.Start) + for { + if !vseg.Ok() { + unmapped = true + break + } + vseg = mm.vmas.Isolate(vseg, ar) + vma := vseg.ValuePtr() + prevMode := vma.mlockMode + vma.mlockMode = mode + if mode != memmap.MLockNone && prevMode == memmap.MLockNone { + mm.lockedAS += uint64(vseg.Range().Length()) + } else if mode == memmap.MLockNone && prevMode != memmap.MLockNone { + mm.lockedAS -= uint64(vseg.Range().Length()) + } + if ar.End <= vseg.End() { + break + } + vseg, _ = vseg.NextNonEmpty() + } + mm.vmas.MergeRange(ar) + mm.vmas.MergeAdjacent(ar) + if unmapped { + mm.mappingMu.Unlock() + return syserror.ENOMEM + } + + if mode == memmap.MLockEager { + // Ensure that we have usable pmas. Since we didn't return ENOMEM + // above, ar must be fully covered by vmas, so we can just use + // NextSegment below. + mm.activeMu.Lock() + mm.mappingMu.DowngradeLock() + for vseg := mm.vmas.FindSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { + if !vseg.ValuePtr().effectivePerms.Any() { + // Linux: mm/gup.c:__get_user_pages() returns EFAULT in this + // case, which is converted to ENOMEM by mlock. + mm.activeMu.Unlock() + mm.mappingMu.RUnlock() + return syserror.ENOMEM + } + _, _, err := mm.getPMAsLocked(ctx, vseg, vseg.Range().Intersect(ar), pmaOpts{}) + if err != nil { + mm.activeMu.Unlock() + mm.mappingMu.RUnlock() + // Linux: mm/mlock.c:__mlock_posix_error_return() + if err == syserror.EFAULT { + return syserror.ENOMEM + } + if err == syserror.ENOMEM { + return syserror.EAGAIN + } + return err + } + } + + // Map pmas into the active AddressSpace, if we have one. + mm.mappingMu.RUnlock() + if mm.as != nil { + mm.activeMu.DowngradeLock() + err := mm.mapASLocked(mm.pmas.LowerBoundSegment(ar.Start), ar, true /* precommit */) + mm.activeMu.RUnlock() + if err != nil { + return err + } + } else { + mm.activeMu.Unlock() + } + } else { + mm.mappingMu.Unlock() + } + + return nil +} + +// MLockAllOpts holds options to MLockAll. +type MLockAllOpts struct { + // If Current is true, change the memory-locking behavior of all mappings + // to Mode. If Future is true, upgrade the memory-locking behavior of all + // future mappings to Mode. At least one of Current or Future must be true. + Current bool + Future bool + Mode memmap.MLockMode +} + +// MLockAll implements the semantics of Linux's mlockall()/munlockall(), +// depending on opts. +func (mm *MemoryManager) MLockAll(ctx context.Context, opts MLockAllOpts) error { + if !opts.Current && !opts.Future { + return syserror.EINVAL + } + + mm.mappingMu.Lock() + // Can't defer mm.mappingMu.Unlock(); see below. + + if opts.Current { + if opts.Mode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if mlockLimit == 0 { + mm.mappingMu.Unlock() + return syserror.EPERM + } + if uint64(mm.vmas.Span()) > mlockLimit { + mm.mappingMu.Unlock() + return syserror.ENOMEM + } + } + } + for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { + vma := vseg.ValuePtr() + prevMode := vma.mlockMode + vma.mlockMode = opts.Mode + if opts.Mode != memmap.MLockNone && prevMode == memmap.MLockNone { + mm.lockedAS += uint64(vseg.Range().Length()) + } else if opts.Mode == memmap.MLockNone && prevMode != memmap.MLockNone { + mm.lockedAS -= uint64(vseg.Range().Length()) + } + } + } + + if opts.Future { + mm.defMLockMode = opts.Mode + } + + if opts.Current && opts.Mode == memmap.MLockEager { + // Linux: mm/mlock.c:sys_mlockall() => include/linux/mm.h:mm_populate() + // ignores the return value of __mm_populate(), so all errors below are + // ignored. + // + // Try to get usable pmas. + mm.activeMu.Lock() + mm.mappingMu.DowngradeLock() + for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { + if vseg.ValuePtr().effectivePerms.Any() { + mm.getPMAsLocked(ctx, vseg, vseg.Range(), pmaOpts{}) + } + } + + // Map all pmas into the active AddressSpace, if we have one. + mm.mappingMu.RUnlock() + if mm.as != nil { + mm.activeMu.DowngradeLock() + mm.mapASLocked(mm.pmas.FirstSegment(), mm.applicationAddrRange(), true /* precommit */) + mm.activeMu.RUnlock() + } else { + mm.activeMu.Unlock() + } + } else { + mm.mappingMu.Unlock() + } + return nil +} + // Decommit implements the semantics of Linux's madvise(MADV_DONTNEED). func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { ar, ok := addr.ToRange(length) @@ -680,46 +965,49 @@ func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { // ensures that Decommit immediately reduces host memory usage. var didUnmapAS bool pseg := mm.pmas.LowerBoundSegment(ar.Start) - vseg := mm.vmas.LowerBoundSegment(ar.Start) mem := mm.p.Memory() - for pseg.Ok() && pseg.Start() < ar.End { - pma := pseg.ValuePtr() - if pma.private && !mm.isPMACopyOnWriteLocked(pseg) { - psegAR := pseg.Range().Intersect(ar) - vseg = vseg.seekNextLowerBound(psegAR.Start) - if checkInvariants { - if !vseg.Ok() { - panic(fmt.Sprintf("no vma after %#x", psegAR.Start)) - } - if psegAR.Start < vseg.Start() { - panic(fmt.Sprintf("no vma in [%#x, %#x)", psegAR.Start, vseg.Start())) - } + for vseg := mm.vmas.LowerBoundSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { + vma := vseg.ValuePtr() + if vma.mlockMode != memmap.MLockNone { + return syserror.EINVAL + } + vsegAR := vseg.Range().Intersect(ar) + // pseg should already correspond to either this vma or a later one, + // since there can't be a pma without a corresponding vma. + if checkInvariants { + if pseg.Ok() && pseg.End() <= vsegAR.Start { + panic(fmt.Sprintf("pma %v precedes vma %v", pseg.Range(), vsegAR)) } - if vseg.Range().IsSupersetOf(psegAR) && vseg.ValuePtr().mappable == nil { - if err := mem.Decommit(pseg.fileRangeOf(psegAR)); err == nil { - pseg = pseg.NextSegment() - continue + } + for pseg.Ok() && pseg.Start() < vsegAR.End { + pma := pseg.ValuePtr() + if pma.private && !mm.isPMACopyOnWriteLocked(pseg) { + psegAR := pseg.Range().Intersect(ar) + if vsegAR.IsSupersetOf(psegAR) && vma.mappable == nil { + if err := mem.Decommit(pseg.fileRangeOf(psegAR)); err == nil { + pseg = pseg.NextSegment() + continue + } + // If an error occurs, fall through to the general + // invalidation case below. } - // If an error occurs, fall through to the general - // invalidation case below. } + pseg = mm.pmas.Isolate(pseg, vsegAR) + pma = pseg.ValuePtr() + if !didUnmapAS { + // Unmap all of ar, not just pseg.Range(), to minimize host + // syscalls. AddressSpace mappings must be removed before + // mm.decPrivateRef(). + mm.unmapASLocked(ar) + didUnmapAS = true + } + if pma.private { + mm.decPrivateRef(pseg.fileRange()) + } + pma.file.DecRef(pseg.fileRange()) + mm.removeRSSLocked(pseg.Range()) + pseg = mm.pmas.Remove(pseg).NextSegment() } - pseg = mm.pmas.Isolate(pseg, ar) - pma = pseg.ValuePtr() - if !didUnmapAS { - // Unmap all of ar, not just pseg.Range(), to minimize host - // syscalls. AddressSpace mappings must be removed before - // mm.decPrivateRef(). - mm.unmapASLocked(ar) - didUnmapAS = true - } - if pma.private { - mm.decPrivateRef(pseg.fileRange()) - } - pma.file.DecRef(pseg.fileRange()) - mm.removeRSSLocked(pseg.Range()) - - pseg = mm.pmas.Remove(pseg).NextSegment() } // "If there are some parts of the specified address space that are not @@ -732,9 +1020,28 @@ func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { return nil } -// Sync implements the semantics of Linux's msync(MS_SYNC). -func (mm *MemoryManager) Sync(ctx context.Context, addr usermem.Addr, length uint64) error { - ar, ok := addr.ToRange(length) +// MSyncOpts holds options to MSync. +type MSyncOpts struct { + // Sync has the semantics of MS_SYNC. + Sync bool + + // Invalidate has the semantics of MS_INVALIDATE. + Invalidate bool +} + +// MSync implements the semantics of Linux's msync(). +func (mm *MemoryManager) MSync(ctx context.Context, addr usermem.Addr, length uint64, opts MSyncOpts) error { + if addr != addr.RoundDown() { + return syserror.EINVAL + } + if length == 0 { + return nil + } + la, ok := usermem.Addr(length).RoundUp() + if !ok { + return syserror.ENOMEM + } + ar, ok := addr.ToRange(uint64(la)) if !ok { return syserror.ENOMEM } @@ -759,10 +1066,14 @@ func (mm *MemoryManager) Sync(ctx context.Context, addr usermem.Addr, length uin } lastEnd = vseg.End() vma := vseg.ValuePtr() + if opts.Invalidate && vma.mlockMode != memmap.MLockNone { + mm.mappingMu.RUnlock() + return syserror.EBUSY + } // It's only possible to have dirtied the Mappable through a shared // mapping. Don't check if the mapping is writable, because mprotect // may have changed this, and also because Linux doesn't. - if id := vma.id; id != nil && vma.mappable != nil && !vma.private { + if id := vma.id; opts.Sync && id != nil && vma.mappable != nil && !vma.private { // We can't call memmap.MappingIdentity.Msync while holding // mm.mappingMu since it may take fs locks that precede it in the // lock order. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index 5c2c802f6..28ba9f2f5 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -17,8 +17,10 @@ package mm import ( "fmt" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -53,6 +55,23 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp return vmaIterator{}, usermem.AddrRange{}, syserror.ENOMEM } + if opts.MLockMode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if mlockLimit == 0 { + return vmaIterator{}, usermem.AddrRange{}, syserror.EPERM + } + newLockedAS := mm.lockedAS + opts.Length + if opts.Unmap { + newLockedAS -= mm.mlockedBytesRangeLocked(ar) + } + if newLockedAS > mlockLimit { + return vmaIterator{}, usermem.AddrRange{}, syserror.EAGAIN + } + } + } + // Remove overwritten mappings. This ordering is consistent with Linux: // compare Linux's mm/mmap.c:mmap_region() => do_munmap(), // file->f_op->mmap(). @@ -85,10 +104,14 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp maxPerms: opts.MaxPerms, private: opts.Private, growsDown: opts.GrowsDown, + mlockMode: opts.MLockMode, id: opts.MappingIdentity, hint: opts.Hint, }) mm.usageAS += opts.Length + if opts.MLockMode != memmap.MLockNone { + mm.lockedAS += opts.Length + } return vseg, ar, nil } @@ -201,6 +224,17 @@ func (mm *MemoryManager) findHighestAvailableLocked(length, alignment uint64, bo return 0, syserror.ENOMEM } +// Preconditions: mm.mappingMu must be locked. +func (mm *MemoryManager) mlockedBytesRangeLocked(ar usermem.AddrRange) uint64 { + var total uint64 + for vseg := mm.vmas.LowerBoundSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { + if vseg.ValuePtr().mlockMode != memmap.MLockNone { + total += uint64(vseg.Range().Intersect(ar).Length()) + } + } + return total +} + // getVMAsLocked ensures that vmas exist for all addresses in ar, and support // access of type (at, ignorePermissions). It returns: // @@ -338,6 +372,9 @@ func (mm *MemoryManager) removeVMAsLocked(ctx context.Context, ar usermem.AddrRa vma.id.DecRef() } mm.usageAS -= uint64(vmaAR.Length()) + if vma.mlockMode != memmap.MLockNone { + mm.lockedAS -= uint64(vmaAR.Length()) + } vgap = mm.vmas.Remove(vseg) vseg = vgap.NextSegment() } @@ -368,6 +405,7 @@ func (vmaSetFunctions) Merge(ar1 usermem.AddrRange, vma1 vma, ar2 usermem.AddrRa vma1.maxPerms != vma2.maxPerms || vma1.private != vma2.private || vma1.growsDown != vma2.growsDown || + vma1.mlockMode != vma2.mlockMode || vma1.id != vma2.id || vma1.hint != vma2.hint { return vma{}, false diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 2aab948da..cc5ebb955 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -196,11 +196,11 @@ var AMD64 = &kernel.SyscallTable{ 145: SchedGetscheduler, 146: SchedGetPriorityMax, 147: SchedGetPriorityMin, - 148: syscalls.ErrorWithEvent(syscall.EPERM), // SchedRrGetInterval, - 149: syscalls.Error(nil), // Mlock, TODO - 150: syscalls.Error(nil), // Munlock, TODO - 151: syscalls.Error(nil), // Mlockall, TODO - 152: syscalls.Error(nil), // Munlockall, TODO + 148: syscalls.ErrorWithEvent(syscall.EPERM), // SchedRrGetInterval, + 149: Mlock, + 150: Munlock, + 151: Mlockall, + 152: Munlockall, 153: syscalls.CapError(linux.CAP_SYS_TTY_CONFIG), // Vhangup, 154: syscalls.Error(syscall.EPERM), // ModifyLdt, 155: syscalls.Error(syscall.EPERM), // PivotRoot, @@ -373,8 +373,9 @@ var AMD64 = &kernel.SyscallTable{ // 322: Execveat, TODO // 323: Userfaultfd, TODO // 324: Membarrier, TODO - // Syscalls after 325 are backports from 4.6. - 325: syscalls.Error(nil), // Mlock2, TODO + 325: Mlock2, + // Syscalls after 325 are "backports" from versions of Linux after 4.4. + // 326: CopyFileRange, 327: Preadv2, // 328: Pwritev2, // Pwritev2, TODO }, diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 145f7846c..8732861e0 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -69,6 +69,9 @@ func Mmap(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC GrowsDown: linux.MAP_GROWSDOWN&flags != 0, Precommit: linux.MAP_POPULATE&flags != 0, } + if linux.MAP_LOCKED&flags != 0 { + opts.MLockMode = memmap.MLockEager + } defer func() { if opts.MappingIdentity != nil { opts.MappingIdentity.DecRef() @@ -384,16 +387,6 @@ func Msync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall length := args[1].SizeT() flags := args[2].Int() - if addr != addr.RoundDown() { - return 0, nil, syserror.EINVAL - } - if length == 0 { - return 0, nil, nil - } - la, ok := usermem.Addr(length).RoundUp() - if !ok { - return 0, nil, syserror.ENOMEM - } // "The flags argument should specify exactly one of MS_ASYNC and MS_SYNC, // and may additionally include the MS_INVALIDATE bit. ... However, Linux // permits a call to msync() that specifies neither of these flags, with @@ -406,39 +399,72 @@ func Msync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall if sync && flags&linux.MS_ASYNC != 0 { return 0, nil, syserror.EINVAL } + err := t.MemoryManager().MSync(t, addr, uint64(length), mm.MSyncOpts{ + Sync: sync, + Invalidate: flags&linux.MS_INVALIDATE != 0, + }) + // MSync calls fsync, the same interrupt conversion rules apply, see + // mm/msync.c, fsync POSIX.1-2008. + return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) +} + +// Mlock implements linux syscall mlock(2). +func Mlock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + length := args[1].SizeT() + + return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), memmap.MLockEager) +} - // MS_INVALIDATE "asks to invalidate other mappings of the same file (so - // that they can be updated with the fresh values just written)". This is a - // no-op given that shared memory exists. However, MS_INVALIDATE can also - // be used to detect mlocks: "EBUSY: MS_INVALIDATE was specified in flags, - // and a memory lock exists for the specified address range." Given that - // mlock is stubbed out, it's unsafe to pass MS_INVALIDATE silently since - // some user program could be using it for synchronization. - if flags&linux.MS_INVALIDATE != 0 { +// Mlock2 implements linux syscall mlock2(2). +func Mlock2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + length := args[1].SizeT() + flags := args[2].Int() + + if flags&^(linux.MLOCK_ONFAULT) != 0 { return 0, nil, syserror.EINVAL } - // MS_SYNC "requests an update and waits for it to complete." - if sync { - err := t.MemoryManager().Sync(t, addr, uint64(la)) - // Sync calls fsync, the same interrupt conversion rules apply, see - // mm/msync.c, fsync POSIX.1-2008. - return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) - } - // MS_ASYNC "specifies that an update be scheduled, but the call returns - // immediately". As long as dirty pages are tracked and eventually written - // back, this is a no-op. (Correspondingly: "Since Linux 2.6.19, MS_ASYNC - // is in fact a no-op, since the kernel properly tracks dirty pages and - // flushes them to storage as necessary.") - // - // However: "ENOMEM: The indicated memory (or part of it) was not mapped." - // This applies even for MS_ASYNC. - ar, ok := addr.ToRange(uint64(la)) - if !ok { - return 0, nil, syserror.ENOMEM + + mode := memmap.MLockEager + if flags&linux.MLOCK_ONFAULT != 0 { + mode = memmap.MLockLazy } - mapped := t.MemoryManager().VirtualMemorySizeRange(ar) - if mapped != uint64(la) { - return 0, nil, syserror.ENOMEM + return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), mode) +} + +// Munlock implements linux syscall munlock(2). +func Munlock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + length := args[1].SizeT() + + return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), memmap.MLockNone) +} + +// Mlockall implements linux syscall mlockall(2). +func Mlockall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + flags := args[0].Int() + + if flags&^(linux.MCL_CURRENT|linux.MCL_FUTURE|linux.MCL_ONFAULT) != 0 { + return 0, nil, syserror.EINVAL } - return 0, nil, nil + + mode := memmap.MLockEager + if flags&linux.MCL_ONFAULT != 0 { + mode = memmap.MLockLazy + } + return 0, nil, t.MemoryManager().MLockAll(t, mm.MLockAllOpts{ + Current: flags&linux.MCL_CURRENT != 0, + Future: flags&linux.MCL_FUTURE != 0, + Mode: mode, + }) +} + +// Munlockall implements linux syscall munlockall(2). +func Munlockall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + return 0, nil, t.MemoryManager().MLockAll(t, mm.MLockAllOpts{ + Current: true, + Future: true, + Mode: memmap.MLockNone, + }) } diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index 2f16e1791..b0b216045 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -90,6 +90,7 @@ var setableLimits = map[limits.LimitType]struct{}{ limits.CPU: {}, limits.Data: {}, limits.FileSize: {}, + limits.MemoryLocked: {}, limits.Stack: {}, // These are not enforced, but we include them here to avoid returning // EPERM, since some apps expect them to succeed. diff --git a/runsc/boot/limits.go b/runsc/boot/limits.go index 8ecda6d0e..e3e716bf9 100644 --- a/runsc/boot/limits.go +++ b/runsc/boot/limits.go @@ -29,7 +29,7 @@ var fromLinuxResource = map[string]limits.LimitType{ "RLIMIT_DATA": limits.Data, "RLIMIT_FSIZE": limits.FileSize, "RLIMIT_LOCKS": limits.Locks, - "RLIMIT_MEMLOCK": limits.MemoryPagesLocked, + "RLIMIT_MEMLOCK": limits.MemoryLocked, "RLIMIT_MSGQUEUE": limits.MessageQueueBytes, "RLIMIT_NICE": limits.Nice, "RLIMIT_NOFILE": limits.NumberOfFiles, @@ -55,7 +55,7 @@ func createLimitSet(spec *specs.Spec) (*limits.LimitSet, error) { ls.SetUnchecked(limits.Data, limits.Limit{Cur: limits.Infinity, Max: limits.Infinity}) ls.SetUnchecked(limits.FileSize, limits.Limit{Cur: limits.Infinity, Max: limits.Infinity}) ls.SetUnchecked(limits.Locks, limits.Limit{Cur: limits.Infinity, Max: limits.Infinity}) - ls.SetUnchecked(limits.MemoryPagesLocked, limits.Limit{Cur: 65536, Max: 65536}) + ls.SetUnchecked(limits.MemoryLocked, limits.Limit{Cur: 65536, Max: 65536}) ls.SetUnchecked(limits.MessageQueueBytes, limits.Limit{Cur: 819200, Max: 819200}) ls.SetUnchecked(limits.Nice, limits.Limit{Cur: 0, Max: 0}) ls.SetUnchecked(limits.NumberOfFiles, limits.Limit{Cur: 1048576, Max: 1048576}) diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 784997c18..aca55f492 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1019,6 +1019,21 @@ cc_binary( ], ) +cc_binary( + name = "mlock_test", + testonly = 1, + srcs = ["mlock.cc"], + linkstatic = 1, + deps = [ + "//test/util:capability_util", + "//test/util:cleanup", + "//test/util:memory_util", + "//test/util:multiprocess_util", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], +) + cc_binary( name = "mmap_test", testonly = 1, diff --git a/test/syscalls/linux/mlock.cc b/test/syscalls/linux/mlock.cc new file mode 100644 index 000000000..a0d876c2e --- /dev/null +++ b/test/syscalls/linux/mlock.cc @@ -0,0 +1,344 @@ +// Copyright 2018 Google LLC +// +// 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. + +#include +#include +#include +#include +#include +#include + +#include "test/util/capability_util.h" +#include "test/util/cleanup.h" +#include "test/util/memory_util.h" +#include "test/util/multiprocess_util.h" +#include "test/util/test_util.h" + +using ::testing::_; + +namespace gvisor { +namespace testing { + +namespace { + +PosixErrorOr CanMlock() { + struct rlimit rlim; + if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { + return PosixError(errno, "getrlimit(RLIMIT_MEMLOCK)"); + } + if (rlim.rlim_cur != 0) { + return true; + } + return HaveCapability(CAP_IPC_LOCK); +} + +// Returns true if the page containing addr is mlocked. +bool IsPageMlocked(uintptr_t addr) { + // This relies on msync(MS_INVALIDATE) interacting correctly with mlocked + // pages, which is tested for by the MsyncInvalidate case below. + int const rv = msync(reinterpret_cast(addr & ~(kPageSize - 1)), + kPageSize, MS_ASYNC | MS_INVALIDATE); + if (rv == 0) { + return false; + } + // This uses TEST_PCHECK_MSG since it's used in subprocesses. + TEST_PCHECK_MSG(errno == EBUSY, "msync failed with unexpected errno"); + return true; +} + +PosixErrorOr ScopedSetSoftRlimit(int resource, rlim_t newval) { + struct rlimit old_rlim; + if (getrlimit(resource, &old_rlim) != 0) { + return PosixError(errno, "getrlimit failed"); + } + struct rlimit new_rlim = old_rlim; + new_rlim.rlim_cur = newval; + if (setrlimit(resource, &new_rlim) != 0) { + return PosixError(errno, "setrlimit failed"); + } + return Cleanup([resource, old_rlim] { + TEST_PCHECK(setrlimit(resource, &old_rlim) == 0); + }); +} + +TEST(MlockTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(MlockTest, ProtNone) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = + ASSERT_NO_ERRNO_AND_VALUE(MmapAnon(kPageSize, PROT_NONE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), + SyscallFailsWithErrno(ENOMEM)); + // ENOMEM is returned because mlock can't populate the page, but it's still + // considered locked. + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(MlockTest, MadviseDontneed) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_THAT(madvise(mapping.ptr(), mapping.len(), MADV_DONTNEED), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(MlockTest, MsyncInvalidate) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_THAT(msync(mapping.ptr(), mapping.len(), MS_ASYNC | MS_INVALIDATE), + SyscallFailsWithErrno(EBUSY)); + EXPECT_THAT(msync(mapping.ptr(), mapping.len(), MS_SYNC | MS_INVALIDATE), + SyscallFailsWithErrno(EBUSY)); +} + +TEST(MlockTest, Fork) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + EXPECT_THAT( + InForkedProcess([&] { TEST_CHECK(!IsPageMlocked(mapping.addr())); }), + IsPosixErrorOkAndHolds(0)); +} + +TEST(MlockTest, RlimitMemlockZero) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), + SyscallFailsWithErrno(EPERM)); +} + +TEST(MlockTest, RlimitMemlockInsufficient) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, kPageSize)); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(2 * kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), + SyscallFailsWithErrno(ENOMEM)); +} + +TEST(MunlockTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +TEST(MunlockTest, NotLocked) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + EXPECT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +// There is currently no test for mlockall(MCL_CURRENT) because the default +// RLIMIT_MEMLOCK of 64 KB is insufficient to actually invoke +// mlockall(MCL_CURRENT). + +TEST(MlockallTest, Future) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + + // Run this test in a separate (single-threaded) subprocess to ensure that a + // background thread doesn't try to mmap a large amount of memory, fail due + // to hitting RLIMIT_MEMLOCK, and explode the process violently. + EXPECT_THAT(InForkedProcess([] { + auto const mapping = + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE) + .ValueOrDie(); + TEST_CHECK(!IsPageMlocked(mapping.addr())); + TEST_PCHECK(mlockall(MCL_FUTURE) == 0); + // Ensure that mlockall(MCL_FUTURE) is turned off before the end + // of the test, as otherwise mmaps may fail unexpectedly. + Cleanup do_munlockall([] { TEST_PCHECK(munlockall() == 0); }); + auto const mapping2 = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + TEST_CHECK(IsPageMlocked(mapping2.addr())); + // Fire munlockall() and check that it disables + // mlockall(MCL_FUTURE). + do_munlockall.Release()(); + auto const mapping3 = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + TEST_CHECK(!IsPageMlocked(mapping2.addr())); + }), + IsPosixErrorOkAndHolds(0)); +} + +TEST(MunlockallTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(munlockall(), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +#ifndef SYS_mlock2 +#ifdef __x86_64__ +#define SYS_mlock2 325 +#endif +#endif + +#ifndef MLOCK_ONFAULT +#define MLOCK_ONFAULT 0x01 // Linux: include/uapi/asm-generic/mman-common.h +#endif + +#ifdef SYS_mlock2 + +int mlock2(void const* addr, size_t len, int flags) { + return syscall(SYS_mlock2, addr, len, flags); +} + +TEST(Mlock2Test, NoFlags) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock2(mapping.ptr(), mapping.len(), 0), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(Mlock2Test, MlockOnfault) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock2(mapping.ptr(), mapping.len(), MLOCK_ONFAULT), + SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(Mlock2Test, UnknownFlags) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_THAT(mlock2(mapping.ptr(), mapping.len(), ~0), + SyscallFailsWithErrno(EINVAL)); +} + +#endif // defined(SYS_mlock2) + +TEST(MapLockedTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + EXPECT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +TEST(MapLockedTest, RlimitMemlockZero) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); + EXPECT_THAT( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED), + PosixErrorIs(EPERM, _)); +} + +TEST(MapLockedTest, RlimitMemlockInsufficient) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, kPageSize)); + EXPECT_THAT( + MmapAnon(2 * kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED), + PosixErrorIs(EAGAIN, _)); +} + +TEST(MremapLockedTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + + void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), + MREMAP_MAYMOVE, nullptr); + if (addr == MAP_FAILED) { + FAIL() << "mremap failed: " << errno << " (" << strerror(errno) << ")"; + } + mapping.release(); + mapping.reset(addr, 2 * mapping.len()); + EXPECT_TRUE(IsPageMlocked(reinterpret_cast(addr))); +} + +TEST(MremapLockedTest, RlimitMemlockZero) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); + void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), + MREMAP_MAYMOVE, nullptr); + EXPECT_TRUE(addr == MAP_FAILED && errno == EAGAIN) + << "addr = " << addr << ", errno = " << errno; +} + +TEST(MremapLockedTest, RlimitMemlockInsufficient) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = ASSERT_NO_ERRNO_AND_VALUE( + ScopedSetSoftRlimit(RLIMIT_MEMLOCK, mapping.len())); + void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), + MREMAP_MAYMOVE, nullptr); + EXPECT_TRUE(addr == MAP_FAILED && errno == EAGAIN) + << "addr = " << addr << ", errno = " << errno; +} + +} // namespace + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/msync.cc b/test/syscalls/linux/msync.cc index 0ddc621aa..72d90dc78 100644 --- a/test/syscalls/linux/msync.cc +++ b/test/syscalls/linux/msync.cc @@ -43,14 +43,13 @@ class MsyncParameterizedTest : public ::testing::TestWithParam { protected: int msync_flags() const { return std::get<0>(GetParam()); } - PosixErrorOr GetMapping() const { - auto rv = std::get<1>(GetParam())(); - return rv; - } + PosixErrorOr GetMapping() const { return std::get<1>(GetParam())(); } }; -// All valid msync(2) flag combinations (not including MS_INVALIDATE, which -// gVisor doesn't implement). +// All valid msync(2) flag combinations, not including MS_INVALIDATE. ("Linux +// permits a call to msync() that specifies neither [MS_SYNC or MS_ASYNC], with +// semantics that are (currently) equivalent to specifying MS_ASYNC." - +// msync(2)) constexpr std::initializer_list kMsyncFlags = {MS_SYNC, MS_ASYNC, 0}; // Returns functions that return mappings that should be successfully @@ -134,6 +133,15 @@ TEST_P(MsyncFullParamTest, UnalignedAddressFails) { SyscallFailsWithErrno(EINVAL)); } +TEST_P(MsyncFullParamTest, InvalidateUnlockedSucceeds) { + auto m = ASSERT_NO_ERRNO_AND_VALUE(GetMapping()); + EXPECT_THAT(msync(m.ptr(), m.len(), msync_flags() | MS_INVALIDATE), + SyscallSucceeds()); +} + +// The test for MS_INVALIDATE on mlocked pages is in mlock.cc since it requires +// probing for mlock support. + INSTANTIATE_TEST_CASE_P( All, MsyncFullParamTest, ::testing::Combine(::testing::ValuesIn(kMsyncFlags), -- cgit v1.2.3 From 03226cd95055aee73d4e4dfcb4954490b4fd8a2d Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Tue, 18 Dec 2018 10:27:16 -0800 Subject: Add BPFAction type with Stringer PiperOrigin-RevId: 226018694 Change-Id: I98965e26fe565f37e98e5df5f997363ab273c91b --- pkg/abi/linux/seccomp.go | 48 ++++++++++++++++++----- pkg/seccomp/seccomp.go | 32 ++++++---------- pkg/seccomp/seccomp_test.go | 14 +++---- pkg/sentry/kernel/seccomp.go | 53 +++++++++----------------- pkg/sentry/kernel/task_syscall.go | 18 +++++---- pkg/sentry/platform/ptrace/subprocess_linux.go | 16 ++++---- test/syscalls/linux/seccomp.cc | 19 +++++++++ 7 files changed, 112 insertions(+), 88 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index 785f2f284..8673a27bf 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -14,22 +14,52 @@ package linux +import "fmt" + // Seccomp constants taken from . const ( SECCOMP_MODE_NONE = 0 SECCOMP_MODE_FILTER = 2 - SECCOMP_RET_KILL_PROCESS = 0x80000000 - SECCOMP_RET_KILL_THREAD = 0x00000000 - SECCOMP_RET_TRAP = 0x00030000 - SECCOMP_RET_ERRNO = 0x00050000 - SECCOMP_RET_TRACE = 0x7ff00000 - SECCOMP_RET_ALLOW = 0x7fff0000 - - SECCOMP_RET_ACTION = 0x7fff0000 - SECCOMP_RET_DATA = 0x0000ffff + SECCOMP_RET_ACTION_FULL = 0xffff0000 + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_DATA = 0x0000ffff SECCOMP_SET_MODE_FILTER = 1 SECCOMP_FILTER_FLAG_TSYNC = 1 SECCOMP_GET_ACTION_AVAIL = 2 ) + +type BPFAction uint32 + +const ( + SECCOMP_RET_KILL_PROCESS BPFAction = 0x80000000 + SECCOMP_RET_KILL_THREAD = 0x00000000 + SECCOMP_RET_TRAP = 0x00030000 + SECCOMP_RET_ERRNO = 0x00050000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_ALLOW = 0x7fff0000 +) + +func (a BPFAction) String() string { + switch a & SECCOMP_RET_ACTION_FULL { + case SECCOMP_RET_KILL_PROCESS: + return "kill process" + case SECCOMP_RET_KILL_THREAD: + return "kill thread" + case SECCOMP_RET_TRAP: + return fmt.Sprintf("trap (%d)", a.Data()) + case SECCOMP_RET_ERRNO: + return fmt.Sprintf("errno (%d)", a.Data()) + case SECCOMP_RET_TRACE: + return fmt.Sprintf("trace (%d)", a.Data()) + case SECCOMP_RET_ALLOW: + return "allow" + } + return fmt.Sprintf("invalid action: %#x", a) +} + +// Data returns the SECCOMP_RET_DATA portion of the action. +func (a BPFAction) Data() uint16 { + return uint16(a & SECCOMP_RET_DATA) +} diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index 9d714d02d..ba2955752 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -33,16 +33,6 @@ const ( defaultLabel = "default_action" ) -func actionName(a uint32) string { - switch a { - case linux.SECCOMP_RET_KILL_PROCESS: - return "kill process" - case linux.SECCOMP_RET_TRAP: - return "trap" - } - panic(fmt.Sprintf("invalid action: %d", a)) -} - // Install generates BPF code based on the set of syscalls provided. It only // allows syscalls that conform to the specification. Syscalls that violate the // specification will trigger RET_KILL_PROCESS, except for the cases below. @@ -67,12 +57,12 @@ func Install(rules SyscallRules) error { // Uncomment to get stack trace when there is a violation. // defaultAction = uint32(linux.SECCOMP_RET_TRAP) - log.Infof("Installing seccomp filters for %d syscalls (action=%s)", len(rules), actionName(defaultAction)) + log.Infof("Installing seccomp filters for %d syscalls (action=%v)", len(rules), defaultAction) instrs, err := BuildProgram([]RuleSet{ RuleSet{ Rules: rules, - Action: uint32(linux.SECCOMP_RET_ALLOW), + Action: linux.SECCOMP_RET_ALLOW, }, }, defaultAction) if log.IsLogging(log.Debug) { @@ -95,21 +85,21 @@ func Install(rules SyscallRules) error { return nil } -func defaultAction() (uint32, error) { +func defaultAction() (linux.BPFAction, error) { available, err := isKillProcessAvailable() if err != nil { return 0, err } if available { - return uint32(linux.SECCOMP_RET_KILL_PROCESS), nil + return linux.SECCOMP_RET_KILL_PROCESS, nil } - return uint32(linux.SECCOMP_RET_TRAP), nil + return linux.SECCOMP_RET_TRAP, nil } // RuleSet is a set of rules and associated action. type RuleSet struct { Rules SyscallRules - Action uint32 + Action linux.BPFAction // Vsyscall indicates that a check is made for a function being called // from kernel mappings. This is where the vsyscall page is located @@ -127,7 +117,7 @@ var SyscallName = func(sysno uintptr) string { // BuildProgram builds a BPF program from the given map of actions to matching // SyscallRules. The single generated program covers all provided RuleSets. -func BuildProgram(rules []RuleSet, defaultAction uint32) ([]linux.BPFInstruction, error) { +func BuildProgram(rules []RuleSet, defaultAction linux.BPFAction) ([]linux.BPFInstruction, error) { program := bpf.NewProgramBuilder() // Be paranoid and check that syscall is done in the expected architecture. @@ -147,7 +137,7 @@ func BuildProgram(rules []RuleSet, defaultAction uint32) ([]linux.BPFInstruction if err := program.AddLabel(defaultLabel); err != nil { return nil, err } - program.AddStmt(bpf.Ret|bpf.K, defaultAction) + program.AddStmt(bpf.Ret|bpf.K, uint32(defaultAction)) return program.Instructions() } @@ -217,7 +207,7 @@ func checkArgsLabel(sysno uintptr) string { // not insert a jump to the default action at the end and it is the // responsibility of the caller to insert an appropriate jump after calling // this function. -func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, action uint32, ruleSetIdx int, sysno uintptr) error { +func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, action linux.BPFAction, ruleSetIdx int, sysno uintptr) error { for ruleidx, rule := range rules { labelled := false for i, arg := range rule { @@ -240,7 +230,7 @@ func addSyscallArgsCheck(p *bpf.ProgramBuilder, rules []Rule, action uint32, rul } // Matched, emit the given action. - p.AddStmt(bpf.Ret|bpf.K, action) + p.AddStmt(bpf.Ret|bpf.K, uint32(action)) // Label the end of the rule if necessary. This is added for // the jumps above when the argument check fails. @@ -319,7 +309,7 @@ func buildBSTProgram(n *node, rules []RuleSet, program *bpf.ProgramBuilder) erro // Emit matchers. if len(rs.Rules[sysno]) == 0 { // This is a blanket action. - program.AddStmt(bpf.Ret|bpf.K, rs.Action) + program.AddStmt(bpf.Ret|bpf.K, uint32(rs.Action)) emitted = true } else { // Add an argument check for these particular diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index f2b903e42..11ed90eb4 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -72,12 +72,12 @@ func TestBasic(t *testing.T) { data seccompData // want is the expected return value of the BPF program. - want uint32 + want linux.BPFAction } for _, test := range []struct { ruleSets []RuleSet - defaultAction uint32 + defaultAction linux.BPFAction specs []spec }{ { @@ -357,7 +357,7 @@ func TestBasic(t *testing.T) { t.Errorf("%s: bpf.Exec() got error: %v", spec.desc, err) continue } - if got != spec.want { + if got != uint32(spec.want) { t.Errorf("%s: bpd.Exec() = %d, want: %d", spec.desc, got, spec.want) } } @@ -380,9 +380,9 @@ func TestRandom(t *testing.T) { instrs, err := BuildProgram([]RuleSet{ RuleSet{ Rules: syscallRules, - Action: uint32(linux.SECCOMP_RET_ALLOW), + Action: linux.SECCOMP_RET_ALLOW, }, - }, uint32(linux.SECCOMP_RET_TRAP)) + }, linux.SECCOMP_RET_TRAP) if err != nil { t.Fatalf("buildProgram() got error: %v", err) } @@ -397,11 +397,11 @@ func TestRandom(t *testing.T) { t.Errorf("bpf.Exec() got error: %v, for syscall %d", err, i) continue } - want := uint32(linux.SECCOMP_RET_TRAP) + want := linux.SECCOMP_RET_TRAP if _, ok := syscallRules[uintptr(i)]; ok { want = linux.SECCOMP_RET_ALLOW } - if got != want { + if got != uint32(want) { t.Errorf("bpf.Exec() = %d, want: %d, for syscall %d", got, want, i) } } diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index d6dc45bbd..cec179246 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -27,24 +27,6 @@ import ( const maxSyscallFilterInstructions = 1 << 15 -type seccompResult int - -const ( - // seccompResultDeny indicates that a syscall should not be executed. - seccompResultDeny seccompResult = iota - - // seccompResultAllow indicates that a syscall should be executed. - seccompResultAllow - - // seccompResultKill indicates that the task should be killed immediately, - // with the exit status indicating that the task was killed by SIGSYS. - seccompResultKill - - // seccompResultTrace indicates that a ptracer was successfully notified as - // a result of a SECCOMP_RET_TRACE. - seccompResultTrace -) - // seccompData is equivalent to struct seccomp_data, which contains the data // passed to seccomp-bpf filters. type seccompData struct { @@ -83,48 +65,47 @@ func seccompSiginfo(t *Task, errno, sysno int32, ip usermem.Addr) *arch.SignalIn // in because vsyscalls do not use the values in t.Arch().) // // Preconditions: The caller must be running on the task goroutine. -func (t *Task) checkSeccompSyscall(sysno int32, args arch.SyscallArguments, ip usermem.Addr) seccompResult { - result := t.evaluateSyscallFilters(sysno, args, ip) - switch result & linux.SECCOMP_RET_ACTION { +func (t *Task) checkSeccompSyscall(sysno int32, args arch.SyscallArguments, ip usermem.Addr) linux.BPFAction { + result := linux.BPFAction(t.evaluateSyscallFilters(sysno, args, ip)) + action := result & linux.SECCOMP_RET_ACTION + switch action { case linux.SECCOMP_RET_TRAP: // "Results in the kernel sending a SIGSYS signal to the triggering // task without executing the system call. ... The SECCOMP_RET_DATA // portion of the return value will be passed as si_errno." - // Documentation/prctl/seccomp_filter.txt - t.SendSignal(seccompSiginfo(t, int32(result&linux.SECCOMP_RET_DATA), sysno, ip)) - return seccompResultDeny + t.SendSignal(seccompSiginfo(t, int32(result.Data()), sysno, ip)) case linux.SECCOMP_RET_ERRNO: // "Results in the lower 16-bits of the return value being passed to // userland as the errno without executing the system call." - t.Arch().SetReturn(-uintptr(result & linux.SECCOMP_RET_DATA)) - return seccompResultDeny + t.Arch().SetReturn(-uintptr(result.Data())) case linux.SECCOMP_RET_TRACE: // "When returned, this value will cause the kernel to attempt to // notify a ptrace()-based tracer prior to executing the system call. // If there is no tracer present, -ENOSYS is returned to userland and // the system call is not executed." - if t.ptraceSeccomp(uint16(result & linux.SECCOMP_RET_DATA)) { - return seccompResultTrace + if !t.ptraceSeccomp(result.Data()) { + // This useless-looking temporary is needed because Go. + tmp := uintptr(syscall.ENOSYS) + t.Arch().SetReturn(-tmp) + return linux.SECCOMP_RET_ERRNO } - // This useless-looking temporary is needed because Go. - tmp := uintptr(syscall.ENOSYS) - t.Arch().SetReturn(-tmp) - return seccompResultDeny case linux.SECCOMP_RET_ALLOW: // "Results in the system call being executed." - return seccompResultAllow case linux.SECCOMP_RET_KILL_THREAD: // "Results in the task exiting immediately without executing the // system call. The exit status of the task will be SIGSYS, not // SIGKILL." - fallthrough - default: // consistent with Linux - return seccompResultKill + + default: + // consistent with Linux + return linux.SECCOMP_RET_KILL_THREAD } + return action } func (t *Task) evaluateSyscallFilters(sysno int32, args arch.SyscallArguments, ip usermem.Addr) uint32 { @@ -155,7 +136,7 @@ func (t *Task) evaluateSyscallFilters(sysno int32, args arch.SyscallArguments, i thisRet, err := bpf.Exec(f.([]bpf.Program)[i], input) if err != nil { t.Debugf("seccomp-bpf filter %d returned error: %v", i, err) - thisRet = linux.SECCOMP_RET_KILL_THREAD + thisRet = uint32(linux.SECCOMP_RET_KILL_THREAD) } // "If multiple filters exist, the return value for the evaluation of a // given system call will always use the highest precedent value." - diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 2a39ebc68..9e43f089a 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -199,16 +199,16 @@ func (t *Task) doSyscall() taskRunState { // is rare), not needed for correctness. if t.syscallFilters.Load() != nil { switch r := t.checkSeccompSyscall(int32(sysno), args, usermem.Addr(t.Arch().IP())); r { - case seccompResultDeny: + case linux.SECCOMP_RET_ERRNO, linux.SECCOMP_RET_TRAP: t.Debugf("Syscall %d: denied by seccomp", sysno) return (*runSyscallExit)(nil) - case seccompResultAllow: + case linux.SECCOMP_RET_ALLOW: // ok - case seccompResultKill: + case linux.SECCOMP_RET_KILL_THREAD: t.Debugf("Syscall %d: killed by seccomp", sysno) t.PrepareExit(ExitStatus{Signo: int(linux.SIGSYS)}) return (*runExit)(nil) - case seccompResultTrace: + case linux.SECCOMP_RET_TRACE: t.Debugf("Syscall %d: stopping for PTRACE_EVENT_SECCOMP", sysno) return (*runSyscallAfterPtraceEventSeccomp)(nil) default: @@ -345,14 +345,18 @@ func (t *Task) doVsyscall(addr usermem.Addr, sysno uintptr) taskRunState { args := t.Arch().SyscallArgs() if t.syscallFilters.Load() != nil { switch r := t.checkSeccompSyscall(int32(sysno), args, addr); r { - case seccompResultDeny: + case linux.SECCOMP_RET_ERRNO, linux.SECCOMP_RET_TRAP: t.Debugf("vsyscall %d, caller %x: denied by seccomp", sysno, t.Arch().Value(caller)) return (*runApp)(nil) - case seccompResultAllow: + case linux.SECCOMP_RET_ALLOW: // ok - case seccompResultTrace: + case linux.SECCOMP_RET_TRACE: t.Debugf("vsyscall %d, caller %x: stopping for PTRACE_EVENT_SECCOMP", sysno, t.Arch().Value(caller)) return &runVsyscallAfterPtraceEventSeccomp{addr, sysno, caller} + case linux.SECCOMP_RET_KILL_THREAD: + t.Debugf("vsyscall %d: killed by seccomp", sysno) + t.PrepareExit(ExitStatus{Signo: int(linux.SIGSYS)}) + return (*runExit)(nil) default: panic(fmt.Sprintf("Unknown seccomp result %d", r)) } diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index 25b8e8cb7..e2aab8135 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -38,7 +38,7 @@ const syscallEvent syscall.Signal = 0x80 // Precondition: the runtime OS thread must be locked. func probeSeccomp() bool { // Create a completely new, destroyable process. - t, err := attachedThread(0, uint32(linux.SECCOMP_RET_ERRNO)) + t, err := attachedThread(0, linux.SECCOMP_RET_ERRNO) if err != nil { panic(fmt.Sprintf("seccomp probe failed: %v", err)) } @@ -112,14 +112,14 @@ func createStub() (*thread, error) { // ptrace emulation check. This simplifies using SYSEMU, since seccomp // will never run for emulation. Seccomp will only run for injected // system calls, and thus we can use RET_KILL as our violation action. - var defaultAction uint32 + var defaultAction linux.BPFAction if probeSeccomp() { log.Infof("Latest seccomp behavior found (kernel >= 4.8 likely)") - defaultAction = uint32(linux.SECCOMP_RET_KILL_THREAD) + defaultAction = linux.SECCOMP_RET_KILL_THREAD } else { // We must rely on SYSEMU behavior; tracing with SYSEMU is broken. log.Infof("Legacy seccomp behavior found (kernel < 4.8 likely)") - defaultAction = uint32(linux.SECCOMP_RET_ALLOW) + defaultAction = linux.SECCOMP_RET_ALLOW } // When creating the new child process, we specify SIGKILL as the @@ -135,7 +135,7 @@ func createStub() (*thread, error) { // attachedThread returns a new attached thread. // // Precondition: the runtime OS thread must be locked. -func attachedThread(flags uintptr, defaultAction uint32) (*thread, error) { +func attachedThread(flags uintptr, defaultAction linux.BPFAction) (*thread, error) { // Create a BPF program that allows only the system calls needed by the // stub and all its children. This is used to create child stubs // (below), so we must include the ability to fork, but otherwise lock @@ -148,11 +148,11 @@ func attachedThread(flags uintptr, defaultAction uint32) (*thread, error) { syscall.SYS_TIME: {}, 309: {}, // SYS_GETCPU. }, - Action: uint32(linux.SECCOMP_RET_TRAP), + Action: linux.SECCOMP_RET_TRAP, Vsyscall: true, }, } - if defaultAction != uint32(linux.SECCOMP_RET_ALLOW) { + if defaultAction != linux.SECCOMP_RET_ALLOW { rules = append(rules, seccomp.RuleSet{ Rules: seccomp.SyscallRules{ syscall.SYS_CLONE: []seccomp.Rule{ @@ -191,7 +191,7 @@ func attachedThread(flags uintptr, defaultAction uint32) (*thread, error) { syscall.SYS_MMAP: {}, syscall.SYS_MUNMAP: {}, }, - Action: uint32(linux.SECCOMP_RET_ALLOW), + Action: linux.SECCOMP_RET_ALLOW, }) } instrs, err := seccomp.BuildProgram(rules, defaultAction) diff --git a/test/syscalls/linux/seccomp.cc b/test/syscalls/linux/seccomp.cc index d6ac166a4..ac416b75f 100644 --- a/test/syscalls/linux/seccomp.cc +++ b/test/syscalls/linux/seccomp.cc @@ -215,6 +215,25 @@ TEST(SeccompTest, SeccompAppliesToVsyscall) { << "status " << status; } +TEST(SeccompTest, RetKillVsyscallCausesDeathBySIGSYS) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(IsVsyscallEnabled())); + + pid_t const pid = fork(); + if (pid == 0) { + // Register a signal handler for SIGSYS that we don't expect to be invoked. + RegisterSignalHandler( + SIGSYS, +[](int, siginfo_t*, void*) { _exit(1); }); + ApplySeccompFilter(SYS_time, SECCOMP_RET_KILL); + vsyscall_time(nullptr); // Should result in death. + TEST_CHECK_MSG(false, "Survived invocation of test syscall"); + } + ASSERT_THAT(pid, SyscallSucceeds()); + int status; + ASSERT_THAT(waitpid(pid, &status, 0), SyscallSucceedsWithValue(pid)); + EXPECT_TRUE(WIFSIGNALED(status) && WTERMSIG(status) == SIGSYS) + << "status " << status; +} + TEST(SeccompTest, RetTraceWithoutPtracerReturnsENOSYS) { pid_t const pid = fork(); if (pid == 0) { -- cgit v1.2.3 From ff7178a4d10f9f1fb34e54fed5ef27cfbff5d6f9 Mon Sep 17 00:00:00 2001 From: Zach Koopmans Date: Wed, 19 Dec 2018 13:14:53 -0800 Subject: Implement pwritev2. Implement pwritev2 and associated unit tests. Clean up preadv2 unit tests. Tag RWF_ flags in both preadv2 and pwritev2 with associated bug tickets. PiperOrigin-RevId: 226222119 Change-Id: Ieb22672418812894ba114bbc88e67f1dd50de620 --- pkg/abi/linux/file.go | 7 +- pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_read.go | 22 +-- pkg/sentry/syscalls/linux/sys_write.go | 66 +++++++ test/syscalls/BUILD | 2 + test/syscalls/linux/BUILD | 27 ++- test/syscalls/linux/preadv2.cc | 156 ++++++++++----- test/syscalls/linux/pwritev2.cc | 337 +++++++++++++++++++++++++++++++++ test/util/test_util.h | 7 - 9 files changed, 553 insertions(+), 73 deletions(-) create mode 100644 test/syscalls/linux/pwritev2.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index ac49ae9a6..ae33f4a4d 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -152,9 +152,10 @@ const ( // Values for preadv2/pwritev2. const ( - RWF_HIPRI = 0x0001 - RWF_DSYNC = 0X0002 - RWF_SYNC = 0x0004 + RWF_HIPRI = 0x00000001 + RWF_DSYNC = 0x00000002 + RWF_SYNC = 0x00000004 + RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC ) // Stat represents struct stat. diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index cc5ebb955..e855590e6 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -377,7 +377,7 @@ var AMD64 = &kernel.SyscallTable{ // Syscalls after 325 are "backports" from versions of Linux after 4.4. // 326: CopyFileRange, 327: Preadv2, - // 328: Pwritev2, // Pwritev2, TODO + 328: Pwritev2, }, Emulate: map[usermem.Addr]uintptr{ diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index cbb9eb9f8..b6df4d9d4 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -188,14 +188,20 @@ func Preadv(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal } // Preadv2 implements linux syscall preadv2(2). +// TODO: Implement RWF_HIPRI functionality. func Preadv2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + // While the syscall is + // preadv2(int fd, struct iovec* iov, int iov_cnt, off_t offset, int flags) + // the linux internal call + // (https://elixir.bootlin.com/linux/v4.18/source/fs/read_write.c#L1248) + // splits the offset argument into a high/low value for compatibility with + // 32-bit architectures. The flags argument is the 5th argument. + fd := kdefs.FD(args[0].Int()) addr := args[1].Pointer() iovcnt := int(args[2].Int()) offset := args[3].Int64() - flags := int(args[4].Int()) - - validFlags := linux.RWF_HIPRI + flags := int(args[5].Int()) file := t.FDMap().GetFile(fd) if file == nil { @@ -219,14 +225,8 @@ func Preadv2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca } // Check flags field. - if flags != 0 { - if flags&^validFlags != 0 { - return 0, nil, syserror.EINVAL - } - // RWF_HIPRI must be called on a file with O_DIRECT flag set. - if flags&linux.RWF_HIPRI != 0 && !file.Flags().Direct { - return 0, nil, syserror.EINVAL - } + if flags&^linux.RWF_VALID != 0 { + return 0, nil, syserror.EOPNOTSUPP } // Read the iovecs that specify the destination of the read. diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index 08e263112..750a098cd 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -187,6 +187,72 @@ func Pwritev(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysca return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "pwritev", file) } +// Pwritev2 implements linux syscall pwritev2(2). +// TODO: Implement RWF_HIPRI functionality. +// TODO: Implement O_SYNC and D_SYNC functionality. +func Pwritev2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + // While the syscall is + // pwritev2(int fd, struct iovec* iov, int iov_cnt, off_t offset, int flags) + // the linux internal call + // (https://elixir.bootlin.com/linux/v4.18/source/fs/read_write.c#L1354) + // splits the offset argument into a high/low value for compatibility with + // 32-bit architectures. The flags argument is the 5th argument. + + fd := kdefs.FD(args[0].Int()) + addr := args[1].Pointer() + iovcnt := int(args[2].Int()) + offset := args[3].Int64() + flags := int(args[5].Int()) + + if int(args[4].Int())&0x4 == 1 { + return 0, nil, syserror.EACCES + } + + file := t.FDMap().GetFile(fd) + if file == nil { + return 0, nil, syserror.EBADF + } + defer file.DecRef() + + // Check that the offset is legitimate. + if offset < -1 { + return 0, nil, syserror.EINVAL + } + + // Is writing at an offset supported? + if offset > -1 && !file.Flags().Pwrite { + return 0, nil, syserror.ESPIPE + } + + if flags&^linux.RWF_VALID != 0 { + return uintptr(flags), nil, syserror.EOPNOTSUPP + } + + // Check that the file is writeable. + if !file.Flags().Write { + return 0, nil, syserror.EBADF + } + + // Read the iovecs that specify the source of the write. + src, err := t.IovecsIOSequence(addr, iovcnt, usermem.IOOpts{ + AddressSpaceActive: true, + }) + if err != nil { + return 0, nil, err + } + + // If pwritev2 is called with an offset of -1, writev is called. + if offset == -1 { + n, err := writev(t, file, src) + t.IOUsage().AccountWriteSyscall(n) + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "pwritev2", file) + } + + n, err := pwritev(t, file, src, offset) + t.IOUsage().AccountWriteSyscall(n) + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "pwritev2", file) +} + func writev(t *kernel.Task, f *fs.File, src usermem.IOSequence) (int64, error) { n, err := f.Writev(t, src) if err != syserror.ErrWouldBlock || f.Flags().NonBlocking { diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 711b68c76..12c7049e7 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -219,6 +219,8 @@ syscall_test( test = "//test/syscalls/linux:pty_test", ) +syscall_test(test = "//test/syscalls/linux:pwritev2_test") + syscall_test(test = "//test/syscalls/linux:pwrite64_test") syscall_test(test = "//test/syscalls/linux:read_test") diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index aca55f492..f13e32daa 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1338,18 +1338,18 @@ cc_binary( name = "preadv2_test", testonly = 1, srcs = [ + "file_base.h", "preadv2.cc", - "readv_common.cc", - "readv_common.h", ], linkstatic = 1, deps = [ - ":file_base", "//test/util:file_descriptor", - "//test/util:memory_util", + "//test/util:posix_error", "//test/util:temp_path", "//test/util:test_main", "//test/util:test_util", + "@com_google_absl//absl/memory", + "@com_google_absl//absl/strings", "@com_google_googletest//:gtest", ], ) @@ -1452,6 +1452,25 @@ cc_binary( ], ) +cc_binary( + name = "pwritev2_test", + testonly = 1, + srcs = [ + "pwritev2.cc", + ], + linkstatic = 1, + deps = [ + ":file_base", + "//test/util:file_descriptor", + "//test/util:posix_error", + "//test/util:temp_path", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_absl//absl/strings", + "@com_google_googletest//:gtest", + ], +) + cc_binary( name = "read_test", testonly = 1, diff --git a/test/syscalls/linux/preadv2.cc b/test/syscalls/linux/preadv2.cc index 642eed624..58a4f9224 100644 --- a/test/syscalls/linux/preadv2.cc +++ b/test/syscalls/linux/preadv2.cc @@ -13,23 +13,18 @@ // limitations under the License. #include -#include #include #include #include -#include -#include -#include #include #include #include "gtest/gtest.h" #include "gtest/gtest.h" +#include "absl/memory/memory.h" #include "test/syscalls/linux/file_base.h" -#include "test/syscalls/linux/readv_common.h" #include "test/util/file_descriptor.h" -#include "test/util/memory_util.h" #include "test/util/temp_path.h" #include "test/util/test_util.h" @@ -60,11 +55,17 @@ std::string SetContent() { return content; } +ssize_t preadv2(unsigned long fd, const struct iovec* iov, unsigned long iovcnt, + off_t offset, unsigned long flags) { + // syscall on preadv2 does some weird things (see man syscall and search + // preadv2), so we insert a 0 to word align the flags argument on native. + return syscall(SYS_preadv2, fd, iov, iovcnt, offset, 0, flags); +} + // This test is the base case where we call preadv (no offset, no flags). TEST(Preadv2Test, TestBaseCall) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + std::string content = SetContent(); const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( @@ -73,12 +74,13 @@ TEST(Preadv2Test, TestBaseCall) { ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY)); std::vector buf(kBufSize); - struct iovec iov; - iov.iov_base = buf.data(); - iov.iov_len = buf.size(); + struct iovec iov[2]; + iov[0].iov_base = buf.data(); + iov[0].iov_len = buf.size() / 2; + iov[1].iov_base = static_cast(iov[0].iov_base) + (content.size() / 2); + iov[1].iov_len = content.size() / 2; - EXPECT_THAT(syscall(SYS_preadv2, fd.get(), &iov, /*iov_cnt*/ 1, - /*offset=*/0, /*flags=*/0), + EXPECT_THAT(preadv2(fd.get(), iov, /*iovcnt*/ 2, /*offset=*/0, /*flags=*/0), SyscallSucceedsWithValue(kBufSize)); EXPECT_EQ(content, std::string(buf.data(), buf.size())); @@ -86,9 +88,8 @@ TEST(Preadv2Test, TestBaseCall) { // This test is where we call preadv with an offset and no flags. TEST(Preadv2Test, TestValidPositiveOffset) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + std::string content = SetContent(); const std::string prefix = "0"; @@ -102,10 +103,12 @@ TEST(Preadv2Test, TestValidPositiveOffset) { iov.iov_base = buf.data(); iov.iov_len = buf.size(); - EXPECT_THAT(syscall(SYS_preadv2, fd.get(), &iov, /*iov_cnt=*/1, - /*offset=*/prefix.size(), /*flags=*/0), + EXPECT_THAT(preadv2(fd.get(), &iov, /*iovcnt=*/1, /*offset=*/prefix.size(), + /*flags=*/0), SyscallSucceedsWithValue(kBufSize)); + EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(0)); + EXPECT_EQ(content, std::string(buf.data(), buf.size())); } @@ -113,9 +116,8 @@ TEST(Preadv2Test, TestValidPositiveOffset) { // read should use the file offset, so the test increments it by one prior to // calling preadv2. TEST(Preadv2Test, TestNegativeOneOffset) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + std::string content = SetContent(); const std::string prefix = "231"; @@ -123,6 +125,7 @@ TEST(Preadv2Test, TestNegativeOneOffset) { GetAbsoluteTestTmpdir(), prefix + content, TempPath::kDefaultFileMode)); const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY)); + ASSERT_THAT(lseek(fd.get(), prefix.size(), SEEK_SET), SyscallSucceedsWithValue(prefix.size())); @@ -131,79 +134,111 @@ TEST(Preadv2Test, TestNegativeOneOffset) { iov.iov_base = buf.data(); iov.iov_len = buf.size(); - EXPECT_THAT(syscall(SYS_preadv2, fd.get(), &iov, /*iov_cnt=*/1, - /*offset=*/static_cast(-1), /*flags=*/0), + EXPECT_THAT(preadv2(fd.get(), &iov, /*iovcnt=*/1, /*offset=*/-1, /*flags=*/0), SyscallSucceedsWithValue(kBufSize)); + EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), + SyscallSucceedsWithValue(prefix.size() + buf.size())); + EXPECT_EQ(content, std::string(buf.data(), buf.size())); } +// preadv2 requires if the RWF_HIPRI flag is passed, the fd must be opened with +// O_DIRECT. This test implements a correct call with the RWF_HIPRI flag. +TEST(Preadv2Test, TestCallWithRWF_HIPRI) { + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + std::string content = SetContent(); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), content, TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY)); + + EXPECT_THAT(fsync(fd.get()), SyscallSucceeds()); + + std::vector buf(kBufSize, '0'); + struct iovec iov; + iov.iov_base = buf.data(); + iov.iov_len = buf.size(); + + EXPECT_THAT( + preadv2(fd.get(), &iov, /*iovcnt=*/1, /*offset=*/0, /*flags=*/RWF_HIPRI), + SyscallSucceedsWithValue(kBufSize)); + + EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(0)); + + EXPECT_EQ(content, std::string(buf.data(), buf.size())); +} // This test calls preadv2 with an invalid flag. TEST(Preadv2Test, TestInvalidFlag) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY | O_DIRECT)); + std::vector buf(kBufSize, '0'); struct iovec iov; + iov.iov_base = buf.data(); + iov.iov_len = buf.size(); - EXPECT_THAT(syscall(SYS_preadv2, fd.get(), &iov, /*iov_cnt=*/1, - /*offset=*/0, /*flags=*/RWF_HIPRI << 1), - SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(preadv2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/0, /*flags=*/0xF0), + SyscallFailsWithErrno(EOPNOTSUPP)); } // This test calls preadv2 with an invalid offset. TEST(Preadv2Test, TestInvalidOffset) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY | O_DIRECT)); - struct iovec iov; - EXPECT_THAT(syscall(SYS_preadv2, fd.get(), &iov, /*iov_cnt=*/1, - /*offset=*/static_cast(-8), /*flags=*/RWF_HIPRI), + auto iov = absl::make_unique(1); + iov[0].iov_base = nullptr; + iov[0].iov_len = 0; + + EXPECT_THAT(preadv2(fd.get(), iov.get(), /*iovcnt=*/1, /*offset=*/-8, + /*flags=*/RWF_HIPRI), SyscallFailsWithErrno(EINVAL)); } // This test calls preadv with a file set O_WRONLY. TEST(Preadv2Test, TestUnreadableFile) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_WRONLY)); - struct iovec iov; - EXPECT_THAT(syscall(SYS_preadv2, fd.get(), &iov, /*iov_cnt=*/1, + auto iov = absl::make_unique(1); + iov[0].iov_base = nullptr; + iov[0].iov_len = 0; + + EXPECT_THAT(preadv2(fd.get(), iov.get(), /*iovcnt=*/1, /*offset=*/0, /*flags=*/0), SyscallFailsWithErrno(EBADF)); } // Calling preadv2 with a non-negative offset calls preadv. Calling preadv with // an unseekable file is not allowed. A pipe is used for an unseekable file. -TEST(Preadv2Test, TestUnseekableFile) { - if (!IsRunningOnGvisor()) { - SKIP_BEFORE_KERNEL(/*major_version=*/4, /*minor_version=*/6); - } +TEST(Preadv2Test, TestUnseekableFileInvalid) { + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); int pipe_fds[2]; ASSERT_THAT(pipe(pipe_fds), SyscallSucceeds()); - struct iovec iov; + auto iov = absl::make_unique(1); + iov[0].iov_base = nullptr; + iov[0].iov_len = 0; - EXPECT_THAT(syscall(SYS_preadv2, pipe_fds[0], &iov, /*iov_cnt=*/1, + EXPECT_THAT(preadv2(pipe_fds[0], iov.get(), /*iovcnt=*/1, /*offset=*/2, /*flags=*/0), SyscallFailsWithErrno(ESPIPE)); @@ -211,6 +246,33 @@ TEST(Preadv2Test, TestUnseekableFile) { EXPECT_THAT(close(pipe_fds[1]), SyscallSucceeds()); } +TEST(Preadv2Test, TestUnseekableFileValid) { + SKIP_IF(preadv2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + int pipe_fds[2]; + + ASSERT_THAT(pipe(pipe_fds), SyscallSucceeds()); + + std::vector content(32, 'X'); + + EXPECT_THAT(write(pipe_fds[1], content.data(), content.size()), + SyscallSucceedsWithValue(content.size())); + + std::vector buf(content.size()); + auto iov = absl::make_unique(1); + iov[0].iov_base = buf.data(); + iov[0].iov_len = buf.size(); + + EXPECT_THAT(preadv2(pipe_fds[0], iov.get(), /*iovcnt=*/1, + /*offset=*/static_cast(-1), /*flags=*/0), + SyscallSucceedsWithValue(buf.size())); + + EXPECT_EQ(content, buf); + + EXPECT_THAT(close(pipe_fds[0]), SyscallSucceeds()); + EXPECT_THAT(close(pipe_fds[1]), SyscallSucceeds()); +} + } // namespace } // namespace testing diff --git a/test/syscalls/linux/pwritev2.cc b/test/syscalls/linux/pwritev2.cc new file mode 100644 index 000000000..a6949f08e --- /dev/null +++ b/test/syscalls/linux/pwritev2.cc @@ -0,0 +1,337 @@ +// Copyright 2018 Google LLC +// +// 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. + +#include +#include +#include +#include + +#include +#include + +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "test/syscalls/linux/file_base.h" +#include "test/util/file_descriptor.h" +#include "test/util/temp_path.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +namespace { + +#ifndef SYS_pwritev2 +#if defined(__x86_64__) +#define SYS_pwritev2 328 +#else +#error "Unknown architecture" +#endif +#endif // SYS_pwrite2 + +#ifndef RWF_HIPRI +#define RWF_HIPRI 0x1 +#endif // RWF_HIPRI + +#ifndef RWF_DSYNC +#define RWF_DSYNC 0x2 +#endif // RWF_DSYNC + +#ifndef RWF_SYNC +#define RWF_SYNC 0x4 +#endif // RWF_SYNC + +constexpr int kBufSize = 1024; + +void SetContent(std::vector& content) { + for (uint i = 0; i < content.size(); i++) { + content[i] = static_cast((i % 10) + '0'); + } +} + +ssize_t pwritev2(unsigned long fd, const struct iovec* iov, + unsigned long iovcnt, off_t offset, unsigned long flags) { + // syscall on pwritev2 does some weird things (see man syscall and search + // pwritev2), so we insert a 0 to word align the flags argument on native. + return syscall(SYS_pwritev2, fd, iov, iovcnt, offset, 0, flags); +} + +// This test is the base case where we call pwritev (no offset, no flags). +TEST(Writev2Test, TestBaseCall) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + + std::vector content(kBufSize); + SetContent(content); + struct iovec iov[2]; + iov[0].iov_base = content.data(); + iov[0].iov_len = content.size() / 2; + iov[1].iov_base = static_cast(iov[0].iov_base) + (content.size() / 2); + iov[1].iov_len = content.size() / 2; + + ASSERT_THAT(pwritev2(fd.get(), iov, /*iovcnt=*/2, + /*offset=*/0, /*flags=*/0), + SyscallSucceedsWithValue(kBufSize)); + + std::vector buf(kBufSize); + EXPECT_THAT(read(fd.get(), buf.data(), kBufSize), + SyscallSucceedsWithValue(kBufSize)); + + EXPECT_EQ(content, buf); +} + +// This test is where we call pwritev2 with a positive offset and no flags. +TEST(Pwritev2Test, TestValidPositiveOffset) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + std::string prefix(kBufSize, '0'); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), prefix, TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + + std::vector content(kBufSize); + SetContent(content); + struct iovec iov; + iov.iov_base = content.data(); + iov.iov_len = content.size(); + + ASSERT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/prefix.size(), /*flags=*/0), + SyscallSucceedsWithValue(content.size())); + + std::vector buf(prefix.size() + content.size()); + EXPECT_THAT(read(fd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(buf.size())); + + std::vector want(prefix.begin(), prefix.end()); + want.insert(want.end(), content.begin(), content.end()); + EXPECT_EQ(want, buf); +} + +// This test is the base case where we call writev by using -1 as the offset. +// The write should use the file offset, so the test increments the file offset +// prior to call pwritev2. +TEST(Pwritev2Test, TestNegativeOneOffset) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const std::string prefix = "00"; + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), prefix.data(), TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + ASSERT_THAT(lseek(fd.get(), prefix.size(), SEEK_SET), + SyscallSucceedsWithValue(prefix.size())); + + std::vector content(kBufSize); + SetContent(content); + struct iovec iov; + iov.iov_base = content.data(); + iov.iov_len = content.size(); + + ASSERT_THAT(pwritev2(fd.get(), &iov, /*iovcnt*/ 1, + /*offset=*/static_cast(-1), /*flags=*/0), + SyscallSucceedsWithValue(content.size())); + + ASSERT_THAT(lseek(fd.get(), 0, SEEK_CUR), + SyscallSucceedsWithValue(prefix.size() + content.size())); + + std::vector buf(prefix.size() + content.size()); + EXPECT_THAT(pread(fd.get(), buf.data(), buf.size(), /*offset=*/0), + SyscallSucceedsWithValue(buf.size())); + + std::vector want(prefix.begin(), prefix.end()); + want.insert(want.end(), content.begin(), content.end()); + EXPECT_EQ(want, buf); +} + +// pwritev2 requires if the RWF_HIPRI flag is passed, the fd must be opened with +// O_DIRECT. This test implements a correct call with the RWF_HIPRI flag. +TEST(Pwritev2Test, TestCallWithRWF_HIPRI) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + + std::vector content(kBufSize); + SetContent(content); + struct iovec iov; + iov.iov_base = content.data(); + iov.iov_len = content.size(); + + EXPECT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/0, /*flags=*/RWF_HIPRI), + SyscallSucceedsWithValue(kBufSize)); + + std::vector buf(content.size()); + EXPECT_THAT(read(fd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(buf.size())); + + EXPECT_EQ(buf, content); +} + +// This test checks that pwritev2 can be called with valid flags +TEST(Pwritev2Test, TestCallWithValidFlags) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + + std::vector content(kBufSize, '0'); + struct iovec iov; + iov.iov_base = content.data(); + iov.iov_len = content.size(); + + EXPECT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/0, /*flags=*/RWF_DSYNC), + SyscallSucceedsWithValue(kBufSize)); + + std::vector buf(content.size()); + EXPECT_THAT(read(fd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(buf.size())); + + EXPECT_EQ(buf, content); + + SetContent(content); + + EXPECT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/0, /*flags=*/0x4), + SyscallSucceedsWithValue(kBufSize)); + + ASSERT_THAT(lseek(fd.get(), 0, SEEK_CUR), + SyscallSucceedsWithValue(content.size())); + + EXPECT_THAT(pread(fd.get(), buf.data(), buf.size(), /*offset=*/0), + SyscallSucceedsWithValue(buf.size())); + + EXPECT_EQ(buf, content); +} + +// This test calls pwritev2 with a bad file descriptor. +TEST(Writev2Test, TestBadFile) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + ASSERT_THAT(pwritev2(/*fd=*/-1, /*iov=*/nullptr, /*iovcnt=*/0, + /*offset=*/0, /*flags=*/0), + SyscallFailsWithErrno(EBADF)); +} + +// This test calls pwrite2 with an invalid offset. +TEST(Pwritev2Test, TestInvalidOffset) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR)); + + struct iovec iov; + iov.iov_base = nullptr; + + EXPECT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/static_cast(-8), /*flags=*/0), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(Pwritev2Test, TestUnseekableFileValid) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + int pipe_fds[2]; + + ASSERT_THAT(pipe(pipe_fds), SyscallSucceeds()); + + std::vector content(32, '0'); + SetContent(content); + struct iovec iov; + iov.iov_base = content.data(); + iov.iov_len = content.size(); + + EXPECT_THAT(pwritev2(pipe_fds[1], &iov, /*iovcnt=*/1, + /*offset=*/static_cast(-1), /*flags=*/0), + SyscallSucceedsWithValue(content.size())); + + std::vector buf(content.size()); + EXPECT_THAT(read(pipe_fds[0], buf.data(), buf.size()), + SyscallSucceedsWithValue(buf.size())); + + EXPECT_EQ(content, buf); + + EXPECT_THAT(close(pipe_fds[0]), SyscallSucceeds()); + EXPECT_THAT(close(pipe_fds[1]), SyscallSucceeds()); +} + +// Calling pwritev2 with a non-negative offset calls pwritev. Calling pwritev +// with an unseekable file is not allowed. A pipe is used for an unseekable +// file. +TEST(Pwritev2Test, TestUnseekableFileInValid) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + int pipe_fds[2]; + struct iovec iov; + iov.iov_base = nullptr; + + ASSERT_THAT(pipe(pipe_fds), SyscallSucceeds()); + + EXPECT_THAT(pwritev2(pipe_fds[1], &iov, /*iovcnt=*/1, + /*offset=*/2, /*flags=*/0), + SyscallFailsWithErrno(ESPIPE)); + + EXPECT_THAT(close(pipe_fds[0]), SyscallSucceeds()); + EXPECT_THAT(close(pipe_fds[1]), SyscallSucceeds()); +} + +TEST(Pwritev2Test, TestReadOnlyFile) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY)); + + struct iovec iov; + iov.iov_base = nullptr; + + EXPECT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/0, /*flags=*/0), + SyscallFailsWithErrno(EBADF)); +} + +// This test calls pwritev2 with an invalid flag. +TEST(Pwritev2Test, TestInvalidFlag) { + SKIP_IF(pwritev2(-1, nullptr, 0, 0, 0) < 0 && errno == ENOSYS); + + const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith( + GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode)); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR | O_DIRECT)); + + struct iovec iov; + iov.iov_base = nullptr; + + EXPECT_THAT(pwritev2(fd.get(), &iov, /*iovcnt=*/1, + /*offset=*/0, /*flags=*/0xF0), + SyscallFailsWithErrno(EOPNOTSUPP)); +} + +} // namespace +} // namespace testing +} // namespace gvisor diff --git a/test/util/test_util.h b/test/util/test_util.h index 2a7609e5c..cd71fdd64 100644 --- a/test/util/test_util.h +++ b/test/util/test_util.h @@ -217,13 +217,6 @@ void TestInit(int* argc, char*** argv); } \ } while (0) -#define SKIP_BEFORE_KERNEL(maj, min) \ - do { \ - auto version = ASSERT_NO_ERRNO_AND_VALUE(GetKernelVersion()); \ - SKIP_IF(version.major < (maj) || \ - (version.major == (maj) && version.minor < (min))); \ - } while (0) - enum class Platform { kNative, kKVM, -- cgit v1.2.3 From 86c9bd254749ebf65270aa60f728d9c847ac02d4 Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 19 Dec 2018 13:29:10 -0800 Subject: Automated rollback of changelist 225861605 PiperOrigin-RevId: 226224230 Change-Id: Id24c7d3733722fd41d5fe74ef64e0ce8c68f0b12 --- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/mm.go | 12 - pkg/sentry/limits/limits.go | 2 +- pkg/sentry/limits/linux.go | 2 +- pkg/sentry/memmap/memmap.go | 37 --- pkg/sentry/mm/BUILD | 1 - pkg/sentry/mm/address_space.go | 12 +- pkg/sentry/mm/lifecycle.go | 24 +- pkg/sentry/mm/mm.go | 24 +- pkg/sentry/mm/syscalls.go | 423 +++++--------------------------- pkg/sentry/mm/vma.go | 38 --- pkg/sentry/syscalls/linux/linux64.go | 15 +- pkg/sentry/syscalls/linux/sys_mmap.go | 106 +++----- pkg/sentry/syscalls/linux/sys_rlimit.go | 1 - runsc/boot/limits.go | 4 +- test/syscalls/linux/BUILD | 15 -- test/syscalls/linux/mlock.cc | 344 -------------------------- test/syscalls/linux/msync.cc | 20 +- 18 files changed, 135 insertions(+), 947 deletions(-) delete mode 100644 test/syscalls/linux/mlock.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index e0aa5b31d..b2e51b9bd 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -60,7 +60,7 @@ const ( DefaultNofileHardLimit = 4096 // DefaultMemlockLimit is called MLOCK_LIMIT in Linux. - DefaultMemlockLimit = 64 * 1024 + DefaultMemlockLimit = 64 * 1094 // DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux. DefaultMsgqueueLimit = 819200 diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index eda8d9788..3fcdf8235 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -49,18 +49,6 @@ const ( MREMAP_FIXED = 1 << 1 ) -// Flags for mlock2(2). -const ( - MLOCK_ONFAULT = 0x01 -) - -// Flags for mlockall(2). -const ( - MCL_CURRENT = 1 - MCL_FUTURE = 2 - MCL_ONFAULT = 4 -) - // Advice for madvise(2). const ( MADV_NORMAL = 0 diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index eeca01876..ba0b7d4fd 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -33,7 +33,7 @@ const ( Rss ProcessCount NumberOfFiles - MemoryLocked + MemoryPagesLocked AS Locks SignalsPending diff --git a/pkg/sentry/limits/linux.go b/pkg/sentry/limits/linux.go index 295f9c398..511db6733 100644 --- a/pkg/sentry/limits/linux.go +++ b/pkg/sentry/limits/linux.go @@ -30,7 +30,7 @@ var FromLinuxResource = map[int]LimitType{ linux.RLIMIT_RSS: Rss, linux.RLIMIT_NPROC: ProcessCount, linux.RLIMIT_NOFILE: NumberOfFiles, - linux.RLIMIT_MEMLOCK: MemoryLocked, + linux.RLIMIT_MEMLOCK: MemoryPagesLocked, linux.RLIMIT_AS: AS, linux.RLIMIT_LOCKS: Locks, linux.RLIMIT_SIGPENDING: SignalsPending, diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index cf20b11e3..28e2bed9b 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -243,40 +243,6 @@ type MappingIdentity interface { Msync(ctx context.Context, mr MappableRange) error } -// MLockMode specifies the memory locking behavior of a memory mapping. -type MLockMode int - -// Note that the ordering of MLockModes is significant; see -// mm.MemoryManager.defMLockMode. -const ( - // MLockNone specifies that a mapping has no memory locking behavior. - // - // This must be the zero value for MLockMode. - MLockNone MLockMode = iota - - // MLockEager specifies that a mapping is memory-locked, as by mlock() or - // similar. Pages in the mapping should be made, and kept, resident in - // physical memory as soon as possible. - // - // As of this writing, MLockEager does not cause memory-locking to be - // requested from the host; it only affects the sentry's memory management - // behavior. - // - // MLockEager is analogous to Linux's VM_LOCKED. - MLockEager - - // MLockLazy specifies that a mapping is memory-locked, as by mlock() or - // similar. Pages in the mapping should be kept resident in physical memory - // once they have been made resident due to e.g. a page fault. - // - // As of this writing, MLockLazy does not cause memory-locking to be - // requested from the host; in fact, it has virtually no effect, except for - // interactions between mlocked pages and other syscalls. - // - // MLockLazy is analogous to Linux's VM_LOCKED | VM_LOCKONFAULT. - MLockLazy -) - // MMapOpts specifies a request to create a memory mapping. type MMapOpts struct { // Length is the length of the mapping. @@ -337,9 +303,6 @@ type MMapOpts struct { // mapping (see platform.AddressSpace.MapFile). Precommit bool - // MLockMode specifies the memory locking behavior of the mapping. - MLockMode MLockMode - // Hint is the name used for the mapping in /proc/[pid]/maps. If Hint is // empty, MappingIdentity.MappedName() will be used instead. // diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 5a9185e5d..744e73a39 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -106,7 +106,6 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/seqfile", - "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/futex", "//pkg/sentry/kernel/shm", "//pkg/sentry/limits", diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index e7aa24c69..7488f7c4a 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -149,7 +149,7 @@ func (mm *MemoryManager) Deactivate() { // for all addresses in ar should be precommitted. // // Preconditions: mm.activeMu must be locked. mm.as != nil. ar.Length() != 0. -// ar must be page-aligned. pseg == mm.pmas.LowerBoundSegment(ar.Start). +// ar must be page-aligned. pseg.Range().Contains(ar.Start). func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, precommit bool) error { // By default, map entire pmas at a time, under the assumption that there // is no cost to mapping more of a pma than necessary. @@ -173,9 +173,7 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, pre } } - // Since this checks ar.End and not mapAR.End, we will never map a pma that - // is not required. - for pseg.Ok() && pseg.Start() < ar.End { + for { pma := pseg.ValuePtr() pmaAR := pseg.Range() pmaMapAR := pmaAR.Intersect(mapAR) @@ -186,9 +184,13 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, pre if err := pma.file.MapInto(mm.as, pmaMapAR.Start, pseg.fileRangeOf(pmaMapAR), perms, precommit); err != nil { return err } + // Since this checks ar.End and not mapAR.End, we will never map a pma + // that is not required. + if ar.End <= pmaAR.End { + return nil + } pseg = pseg.NextSegment() } - return nil } // unmapASLocked removes all AddressSpace mappings for addresses in ar. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index a42e32b43..1613ce11d 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -22,7 +22,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" - "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/platform" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) @@ -59,17 +58,13 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { mm.mappingMu.RLock() defer mm.mappingMu.RUnlock() mm2 := &MemoryManager{ - p: mm.p, - haveASIO: mm.haveASIO, - layout: mm.layout, - privateRefs: mm.privateRefs, - users: 1, - brk: mm.brk, - usageAS: mm.usageAS, - // "The child does not inherit its parent's memory locks (mlock(2), - // mlockall(2))." - fork(2). So lockedAS is 0 and defMLockMode is - // MLockNone, both of which are zero values. vma.mlockMode is reset - // when copied below. + p: mm.p, + haveASIO: mm.haveASIO, + layout: mm.layout, + privateRefs: mm.privateRefs, + users: 1, + usageAS: mm.usageAS, + brk: mm.brk, captureInvalidations: true, argv: mm.argv, envv: mm.envv, @@ -82,7 +77,7 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { // Copy vmas. dstvgap := mm2.vmas.FirstGap() for srcvseg := mm.vmas.FirstSegment(); srcvseg.Ok(); srcvseg = srcvseg.NextSegment() { - vma := srcvseg.Value() // makes a copy of the vma + vma := srcvseg.ValuePtr() vmaAR := srcvseg.Range() // Inform the Mappable, if any, of the new mapping. if vma.mappable != nil { @@ -94,8 +89,7 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { if vma.id != nil { vma.id.IncRef() } - vma.mlockMode = memmap.MLockNone - dstvgap = mm2.vmas.Insert(dstvgap, vmaAR, vma).NextGap() + dstvgap = mm2.vmas.Insert(dstvgap, vmaAR, *vma).NextGap() // We don't need to update mm2.usageAS since we copied it from mm // above. } diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index c0632d232..b1e39e898 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -95,29 +95,17 @@ type MemoryManager struct { // vmas is protected by mappingMu. vmas vmaSet - // brk is the mm's brk, which is manipulated using the brk(2) system call. - // The brk is initially set up by the loader which maps an executable - // binary into the mm. - // - // brk is protected by mappingMu. - brk usermem.AddrRange - // usageAS is vmas.Span(), cached to accelerate RLIMIT_AS checks. // // usageAS is protected by mappingMu. usageAS uint64 - // lockedAS is the combined size in bytes of all vmas with vma.mlockMode != - // memmap.MLockNone. - // - // lockedAS is protected by mappingMu. - lockedAS uint64 - - // New VMAs created by MMap use whichever of memmap.MMapOpts.MLockMode or - // defMLockMode is greater. + // brk is the mm's brk, which is manipulated using the brk(2) system call. + // The brk is initially set up by the loader which maps an executable + // binary into the mm. // - // defMLockMode is protected by mappingMu. - defMLockMode memmap.MLockMode + // brk is protected by mappingMu. + brk usermem.AddrRange // activeMu is loosely analogous to Linux's struct // mm_struct::page_table_lock. @@ -264,8 +252,6 @@ type vma struct { // metag, none of which we currently support. growsDown bool `state:"manual"` - mlockMode memmap.MLockMode - // If id is not nil, it controls the lifecycle of mappable and provides vma // metadata shown in /proc/[pid]/maps, and the vma holds a reference. id memmap.MappingIdentity diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index 383703ec3..daaae4da1 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -20,7 +20,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" @@ -129,24 +128,16 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme // Get the new vma. mm.mappingMu.Lock() - if opts.MLockMode < mm.defMLockMode { - opts.MLockMode = mm.defMLockMode - } vseg, ar, err := mm.createVMALocked(ctx, opts) if err != nil { mm.mappingMu.Unlock() return 0, err } - // TODO: In Linux, VM_LOCKONFAULT (which may be set on the new - // vma by mlockall(MCL_FUTURE|MCL_ONFAULT) => mm_struct::def_flags) appears - // to effectively disable MAP_POPULATE by unsetting FOLL_POPULATE in - // mm/util.c:vm_mmap_pgoff() => mm/gup.c:__mm_populate() => - // populate_vma_page_range(). Confirm this behavior. switch { - case opts.Precommit || opts.MLockMode == memmap.MLockEager: + case opts.Precommit: // Get pmas and map with precommit as requested. - mm.populateVMAAndUnlock(ctx, vseg, ar, true) + mm.populateAndUnlock(ctx, vseg, ar, true) case opts.Mappable == nil && length <= privateAllocUnit: // NOTE: Get pmas and map eagerly in the hope @@ -155,7 +146,7 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme // memmap.Mappable.Translate is unknown; and only for small mappings, // to avoid needing to allocate large amounts of memory that we may // subsequently need to checkpoint. - mm.populateVMAAndUnlock(ctx, vseg, ar, false) + mm.populateAndUnlock(ctx, vseg, ar, false) default: mm.mappingMu.Unlock() @@ -164,29 +155,31 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme return ar.Start, nil } -// populateVMA obtains pmas for addresses in ar in the given vma, and maps them -// into mm.as if it is active. +// Preconditions: mm.mappingMu must be locked for writing. // -// Preconditions: mm.mappingMu must be locked. vseg.Range().IsSupersetOf(ar). -func (mm *MemoryManager) populateVMA(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { +// Postconditions: mm.mappingMu will be unlocked. +func (mm *MemoryManager) populateAndUnlock(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { if !vseg.ValuePtr().effectivePerms.Any() { // Linux doesn't populate inaccessible pages. See // mm/gup.c:populate_vma_page_range. + mm.mappingMu.Unlock() return } mm.activeMu.Lock() - // Can't defer mm.activeMu.Unlock(); see below. - // Even if we get new pmas, we can't actually map them if we don't have an + // Even if we get a new pma, we can't actually map it if we don't have an // AddressSpace. if mm.as == nil { mm.activeMu.Unlock() + mm.mappingMu.Unlock() return } // Ensure that we have usable pmas. + mm.mappingMu.DowngradeLock() pseg, _, err := mm.getPMAsLocked(ctx, vseg, ar, pmaOpts{}) + mm.mappingMu.RUnlock() if err != nil { // mm/util.c:vm_mmap_pgoff() ignores the error, if any, from // mm/gup.c:mm_populate(). If it matters, we'll get it again when @@ -204,45 +197,6 @@ func (mm *MemoryManager) populateVMA(ctx context.Context, vseg vmaIterator, ar u mm.activeMu.RUnlock() } -// populateVMAAndUnlock is equivalent to populateVMA, but also unconditionally -// unlocks mm.mappingMu. In cases where populateVMAAndUnlock is usable, it is -// preferable to populateVMA since it unlocks mm.mappingMu before performing -// expensive operations that don't require it to be locked. -// -// Preconditions: mm.mappingMu must be locked for writing. -// vseg.Range().IsSupersetOf(ar). -// -// Postconditions: mm.mappingMu will be unlocked. -func (mm *MemoryManager) populateVMAAndUnlock(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { - // See populateVMA above for commentary. - if !vseg.ValuePtr().effectivePerms.Any() { - mm.mappingMu.Unlock() - return - } - - mm.activeMu.Lock() - - if mm.as == nil { - mm.activeMu.Unlock() - mm.mappingMu.Unlock() - return - } - - // mm.mappingMu doesn't need to be write-locked for getPMAsLocked, and it - // isn't needed at all for mapASLocked. - mm.mappingMu.DowngradeLock() - pseg, _, err := mm.getPMAsLocked(ctx, vseg, ar, pmaOpts{}) - mm.mappingMu.RUnlock() - if err != nil { - mm.activeMu.Unlock() - return - } - - mm.activeMu.DowngradeLock() - mm.mapASLocked(pseg, ar, precommit) - mm.activeMu.RUnlock() -} - // MapStack allocates the initial process stack. func (mm *MemoryManager) MapStack(ctx context.Context) (usermem.AddrRange, error) { // maxStackSize is the maximum supported process stack size in bytes. @@ -282,7 +236,6 @@ func (mm *MemoryManager) MapStack(ctx context.Context) (usermem.AddrRange, error MaxPerms: usermem.AnyAccess, Private: true, GrowsDown: true, - MLockMode: mm.defMLockMode, Hint: "[stack]", }) return ar, err @@ -381,19 +334,6 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi // occupies at least part of the destination. Thus the NoMove case always // fails and the MayMove case always falls back to copying. - if vma := vseg.ValuePtr(); newSize > oldSize && vma.mlockMode != memmap.MLockNone { - // Check against RLIMIT_MEMLOCK. Unlike mmap, mlock, and mlockall, - // mremap in Linux does not check mm/mlock.c:can_do_mlock() and - // therefore does not return EPERM if RLIMIT_MEMLOCK is 0 and - // !CAP_IPC_LOCK. - mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur - if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { - if newLockedAS := mm.lockedAS - oldSize + newSize; newLockedAS > mlockLimit { - return 0, syserror.EAGAIN - } - } - } - if opts.Move != MRemapMustMove { // Handle no-ops and in-place shrinking. These cases don't care if // [oldAddr, oldEnd) maps to a single vma, or is even mapped at all @@ -420,7 +360,7 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi if vma.mappable != nil { newOffset = vseg.mappableRange().End } - vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ + _, _, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: newSize - oldSize, MappingIdentity: vma.id, Mappable: vma.mappable, @@ -431,13 +371,9 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi MaxPerms: vma.maxPerms, Private: vma.private, GrowsDown: vma.growsDown, - MLockMode: vma.mlockMode, Hint: vma.hint, }) if err == nil { - if vma.mlockMode == memmap.MLockEager { - mm.populateVMA(ctx, vseg, ar, true) - } return oldAddr, nil } // In-place growth failed. In the MRemapMayMove case, fall through to @@ -526,14 +462,8 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi if vma.id != nil { vma.id.IncRef() } - vseg := mm.vmas.Insert(mm.vmas.FindGap(newAR.Start), newAR, vma) + mm.vmas.Add(newAR, vma) mm.usageAS += uint64(newAR.Length()) - if vma.mlockMode != memmap.MLockNone { - mm.lockedAS += uint64(newAR.Length()) - if vma.mlockMode == memmap.MLockEager { - mm.populateVMA(ctx, vseg, newAR, true) - } - } return newAR.Start, nil } @@ -555,11 +485,8 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi vseg = mm.vmas.Isolate(vseg, oldAR) vma := vseg.Value() mm.vmas.Remove(vseg) - vseg = mm.vmas.Insert(mm.vmas.FindGap(newAR.Start), newAR, vma) + mm.vmas.Add(newAR, vma) mm.usageAS = mm.usageAS - uint64(oldAR.Length()) + uint64(newAR.Length()) - if vma.mlockMode != memmap.MLockNone { - mm.lockedAS = mm.lockedAS - uint64(oldAR.Length()) + uint64(newAR.Length()) - } // Move pmas. This is technically optional for non-private pmas, which // could just go through memmap.Mappable.Translate again, but it's required @@ -574,10 +501,6 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi vma.mappable.RemoveMapping(ctx, mm, oldAR, vma.off, vma.isMappableAsWritable()) } - if vma.mlockMode == memmap.MLockEager { - mm.populateVMA(ctx, vseg, newAR, true) - } - return newAR.Start, nil } @@ -688,10 +611,9 @@ func (mm *MemoryManager) BrkSetup(ctx context.Context, addr usermem.Addr) { // error on failure. func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Addr, error) { mm.mappingMu.Lock() - // Can't defer mm.mappingMu.Unlock(); see below. + defer mm.mappingMu.Unlock() if addr < mm.brk.Start { - mm.mappingMu.Unlock() return mm.brk.End, syserror.EINVAL } @@ -701,24 +623,21 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad // heap + data + bss. The segment sizes need to be plumbed from the // loader package to fully enforce RLIMIT_DATA. if uint64(addr-mm.brk.Start) > limits.FromContext(ctx).Get(limits.Data).Cur { - mm.mappingMu.Unlock() return mm.brk.End, syserror.ENOMEM } oldbrkpg, _ := mm.brk.End.RoundUp() newbrkpg, ok := addr.RoundUp() if !ok { - mm.mappingMu.Unlock() return mm.brk.End, syserror.EFAULT } switch { case newbrkpg < oldbrkpg: mm.unmapLocked(ctx, usermem.AddrRange{newbrkpg, oldbrkpg}) - mm.mappingMu.Unlock() case oldbrkpg < newbrkpg: - vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ + _, _, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: uint64(newbrkpg - oldbrkpg), Addr: oldbrkpg, Fixed: true, @@ -727,221 +646,17 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad Perms: usermem.ReadWrite, MaxPerms: usermem.AnyAccess, Private: true, - // Linux: mm/mmap.c:sys_brk() => do_brk_flags() includes - // mm->def_flags. - MLockMode: mm.defMLockMode, - Hint: "[heap]", + Hint: "[heap]", }) if err != nil { - mm.mappingMu.Unlock() return mm.brk.End, err } - if mm.defMLockMode == memmap.MLockEager { - mm.populateVMAAndUnlock(ctx, vseg, ar, true) - } else { - mm.mappingMu.Unlock() - } - - default: - // Nothing to do. - mm.mappingMu.Unlock() } mm.brk.End = addr return addr, nil } -// MLock implements the semantics of Linux's mlock()/mlock2()/munlock(), -// depending on mode. -func (mm *MemoryManager) MLock(ctx context.Context, addr usermem.Addr, length uint64, mode memmap.MLockMode) error { - // Linux allows this to overflow. - la, _ := usermem.Addr(length + addr.PageOffset()).RoundUp() - ar, ok := addr.RoundDown().ToRange(uint64(la)) - if !ok { - return syserror.EINVAL - } - - mm.mappingMu.Lock() - // Can't defer mm.mappingMu.Unlock(); see below. - - if mode != memmap.MLockNone { - // Check against RLIMIT_MEMLOCK. - if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { - mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur - if mlockLimit == 0 { - mm.mappingMu.Unlock() - return syserror.EPERM - } - if newLockedAS := mm.lockedAS + uint64(ar.Length()) - mm.mlockedBytesRangeLocked(ar); newLockedAS > mlockLimit { - mm.mappingMu.Unlock() - return syserror.ENOMEM - } - } - } - - // Check this after RLIMIT_MEMLOCK for consistency with Linux. - if ar.Length() == 0 { - mm.mappingMu.Unlock() - return nil - } - - // Apply the new mlock mode to vmas. - var unmapped bool - vseg := mm.vmas.FindSegment(ar.Start) - for { - if !vseg.Ok() { - unmapped = true - break - } - vseg = mm.vmas.Isolate(vseg, ar) - vma := vseg.ValuePtr() - prevMode := vma.mlockMode - vma.mlockMode = mode - if mode != memmap.MLockNone && prevMode == memmap.MLockNone { - mm.lockedAS += uint64(vseg.Range().Length()) - } else if mode == memmap.MLockNone && prevMode != memmap.MLockNone { - mm.lockedAS -= uint64(vseg.Range().Length()) - } - if ar.End <= vseg.End() { - break - } - vseg, _ = vseg.NextNonEmpty() - } - mm.vmas.MergeRange(ar) - mm.vmas.MergeAdjacent(ar) - if unmapped { - mm.mappingMu.Unlock() - return syserror.ENOMEM - } - - if mode == memmap.MLockEager { - // Ensure that we have usable pmas. Since we didn't return ENOMEM - // above, ar must be fully covered by vmas, so we can just use - // NextSegment below. - mm.activeMu.Lock() - mm.mappingMu.DowngradeLock() - for vseg := mm.vmas.FindSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { - if !vseg.ValuePtr().effectivePerms.Any() { - // Linux: mm/gup.c:__get_user_pages() returns EFAULT in this - // case, which is converted to ENOMEM by mlock. - mm.activeMu.Unlock() - mm.mappingMu.RUnlock() - return syserror.ENOMEM - } - _, _, err := mm.getPMAsLocked(ctx, vseg, vseg.Range().Intersect(ar), pmaOpts{}) - if err != nil { - mm.activeMu.Unlock() - mm.mappingMu.RUnlock() - // Linux: mm/mlock.c:__mlock_posix_error_return() - if err == syserror.EFAULT { - return syserror.ENOMEM - } - if err == syserror.ENOMEM { - return syserror.EAGAIN - } - return err - } - } - - // Map pmas into the active AddressSpace, if we have one. - mm.mappingMu.RUnlock() - if mm.as != nil { - mm.activeMu.DowngradeLock() - err := mm.mapASLocked(mm.pmas.LowerBoundSegment(ar.Start), ar, true /* precommit */) - mm.activeMu.RUnlock() - if err != nil { - return err - } - } else { - mm.activeMu.Unlock() - } - } else { - mm.mappingMu.Unlock() - } - - return nil -} - -// MLockAllOpts holds options to MLockAll. -type MLockAllOpts struct { - // If Current is true, change the memory-locking behavior of all mappings - // to Mode. If Future is true, upgrade the memory-locking behavior of all - // future mappings to Mode. At least one of Current or Future must be true. - Current bool - Future bool - Mode memmap.MLockMode -} - -// MLockAll implements the semantics of Linux's mlockall()/munlockall(), -// depending on opts. -func (mm *MemoryManager) MLockAll(ctx context.Context, opts MLockAllOpts) error { - if !opts.Current && !opts.Future { - return syserror.EINVAL - } - - mm.mappingMu.Lock() - // Can't defer mm.mappingMu.Unlock(); see below. - - if opts.Current { - if opts.Mode != memmap.MLockNone { - // Check against RLIMIT_MEMLOCK. - if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { - mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur - if mlockLimit == 0 { - mm.mappingMu.Unlock() - return syserror.EPERM - } - if uint64(mm.vmas.Span()) > mlockLimit { - mm.mappingMu.Unlock() - return syserror.ENOMEM - } - } - } - for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { - vma := vseg.ValuePtr() - prevMode := vma.mlockMode - vma.mlockMode = opts.Mode - if opts.Mode != memmap.MLockNone && prevMode == memmap.MLockNone { - mm.lockedAS += uint64(vseg.Range().Length()) - } else if opts.Mode == memmap.MLockNone && prevMode != memmap.MLockNone { - mm.lockedAS -= uint64(vseg.Range().Length()) - } - } - } - - if opts.Future { - mm.defMLockMode = opts.Mode - } - - if opts.Current && opts.Mode == memmap.MLockEager { - // Linux: mm/mlock.c:sys_mlockall() => include/linux/mm.h:mm_populate() - // ignores the return value of __mm_populate(), so all errors below are - // ignored. - // - // Try to get usable pmas. - mm.activeMu.Lock() - mm.mappingMu.DowngradeLock() - for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { - if vseg.ValuePtr().effectivePerms.Any() { - mm.getPMAsLocked(ctx, vseg, vseg.Range(), pmaOpts{}) - } - } - - // Map all pmas into the active AddressSpace, if we have one. - mm.mappingMu.RUnlock() - if mm.as != nil { - mm.activeMu.DowngradeLock() - mm.mapASLocked(mm.pmas.FirstSegment(), mm.applicationAddrRange(), true /* precommit */) - mm.activeMu.RUnlock() - } else { - mm.activeMu.Unlock() - } - } else { - mm.mappingMu.Unlock() - } - return nil -} - // Decommit implements the semantics of Linux's madvise(MADV_DONTNEED). func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { ar, ok := addr.ToRange(length) @@ -965,49 +680,46 @@ func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { // ensures that Decommit immediately reduces host memory usage. var didUnmapAS bool pseg := mm.pmas.LowerBoundSegment(ar.Start) + vseg := mm.vmas.LowerBoundSegment(ar.Start) mem := mm.p.Memory() - for vseg := mm.vmas.LowerBoundSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { - vma := vseg.ValuePtr() - if vma.mlockMode != memmap.MLockNone { - return syserror.EINVAL - } - vsegAR := vseg.Range().Intersect(ar) - // pseg should already correspond to either this vma or a later one, - // since there can't be a pma without a corresponding vma. - if checkInvariants { - if pseg.Ok() && pseg.End() <= vsegAR.Start { - panic(fmt.Sprintf("pma %v precedes vma %v", pseg.Range(), vsegAR)) - } - } - for pseg.Ok() && pseg.Start() < vsegAR.End { - pma := pseg.ValuePtr() - if pma.private && !mm.isPMACopyOnWriteLocked(pseg) { - psegAR := pseg.Range().Intersect(ar) - if vsegAR.IsSupersetOf(psegAR) && vma.mappable == nil { - if err := mem.Decommit(pseg.fileRangeOf(psegAR)); err == nil { - pseg = pseg.NextSegment() - continue - } - // If an error occurs, fall through to the general - // invalidation case below. + for pseg.Ok() && pseg.Start() < ar.End { + pma := pseg.ValuePtr() + if pma.private && !mm.isPMACopyOnWriteLocked(pseg) { + psegAR := pseg.Range().Intersect(ar) + vseg = vseg.seekNextLowerBound(psegAR.Start) + if checkInvariants { + if !vseg.Ok() { + panic(fmt.Sprintf("no vma after %#x", psegAR.Start)) + } + if psegAR.Start < vseg.Start() { + panic(fmt.Sprintf("no vma in [%#x, %#x)", psegAR.Start, vseg.Start())) } } - pseg = mm.pmas.Isolate(pseg, vsegAR) - pma = pseg.ValuePtr() - if !didUnmapAS { - // Unmap all of ar, not just pseg.Range(), to minimize host - // syscalls. AddressSpace mappings must be removed before - // mm.decPrivateRef(). - mm.unmapASLocked(ar) - didUnmapAS = true - } - if pma.private { - mm.decPrivateRef(pseg.fileRange()) + if vseg.Range().IsSupersetOf(psegAR) && vseg.ValuePtr().mappable == nil { + if err := mem.Decommit(pseg.fileRangeOf(psegAR)); err == nil { + pseg = pseg.NextSegment() + continue + } + // If an error occurs, fall through to the general + // invalidation case below. } - pma.file.DecRef(pseg.fileRange()) - mm.removeRSSLocked(pseg.Range()) - pseg = mm.pmas.Remove(pseg).NextSegment() } + pseg = mm.pmas.Isolate(pseg, ar) + pma = pseg.ValuePtr() + if !didUnmapAS { + // Unmap all of ar, not just pseg.Range(), to minimize host + // syscalls. AddressSpace mappings must be removed before + // mm.decPrivateRef(). + mm.unmapASLocked(ar) + didUnmapAS = true + } + if pma.private { + mm.decPrivateRef(pseg.fileRange()) + } + pma.file.DecRef(pseg.fileRange()) + mm.removeRSSLocked(pseg.Range()) + + pseg = mm.pmas.Remove(pseg).NextSegment() } // "If there are some parts of the specified address space that are not @@ -1020,28 +732,9 @@ func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { return nil } -// MSyncOpts holds options to MSync. -type MSyncOpts struct { - // Sync has the semantics of MS_SYNC. - Sync bool - - // Invalidate has the semantics of MS_INVALIDATE. - Invalidate bool -} - -// MSync implements the semantics of Linux's msync(). -func (mm *MemoryManager) MSync(ctx context.Context, addr usermem.Addr, length uint64, opts MSyncOpts) error { - if addr != addr.RoundDown() { - return syserror.EINVAL - } - if length == 0 { - return nil - } - la, ok := usermem.Addr(length).RoundUp() - if !ok { - return syserror.ENOMEM - } - ar, ok := addr.ToRange(uint64(la)) +// Sync implements the semantics of Linux's msync(MS_SYNC). +func (mm *MemoryManager) Sync(ctx context.Context, addr usermem.Addr, length uint64) error { + ar, ok := addr.ToRange(length) if !ok { return syserror.ENOMEM } @@ -1066,14 +759,10 @@ func (mm *MemoryManager) MSync(ctx context.Context, addr usermem.Addr, length ui } lastEnd = vseg.End() vma := vseg.ValuePtr() - if opts.Invalidate && vma.mlockMode != memmap.MLockNone { - mm.mappingMu.RUnlock() - return syserror.EBUSY - } // It's only possible to have dirtied the Mappable through a shared // mapping. Don't check if the mapping is writable, because mprotect // may have changed this, and also because Linux doesn't. - if id := vma.id; opts.Sync && id != nil && vma.mappable != nil && !vma.private { + if id := vma.id; id != nil && vma.mappable != nil && !vma.private { // We can't call memmap.MappingIdentity.Msync while holding // mm.mappingMu since it may take fs locks that precede it in the // lock order. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index 28ba9f2f5..5c2c802f6 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -17,10 +17,8 @@ package mm import ( "fmt" - "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -55,23 +53,6 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp return vmaIterator{}, usermem.AddrRange{}, syserror.ENOMEM } - if opts.MLockMode != memmap.MLockNone { - // Check against RLIMIT_MEMLOCK. - if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { - mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur - if mlockLimit == 0 { - return vmaIterator{}, usermem.AddrRange{}, syserror.EPERM - } - newLockedAS := mm.lockedAS + opts.Length - if opts.Unmap { - newLockedAS -= mm.mlockedBytesRangeLocked(ar) - } - if newLockedAS > mlockLimit { - return vmaIterator{}, usermem.AddrRange{}, syserror.EAGAIN - } - } - } - // Remove overwritten mappings. This ordering is consistent with Linux: // compare Linux's mm/mmap.c:mmap_region() => do_munmap(), // file->f_op->mmap(). @@ -104,14 +85,10 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp maxPerms: opts.MaxPerms, private: opts.Private, growsDown: opts.GrowsDown, - mlockMode: opts.MLockMode, id: opts.MappingIdentity, hint: opts.Hint, }) mm.usageAS += opts.Length - if opts.MLockMode != memmap.MLockNone { - mm.lockedAS += opts.Length - } return vseg, ar, nil } @@ -224,17 +201,6 @@ func (mm *MemoryManager) findHighestAvailableLocked(length, alignment uint64, bo return 0, syserror.ENOMEM } -// Preconditions: mm.mappingMu must be locked. -func (mm *MemoryManager) mlockedBytesRangeLocked(ar usermem.AddrRange) uint64 { - var total uint64 - for vseg := mm.vmas.LowerBoundSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { - if vseg.ValuePtr().mlockMode != memmap.MLockNone { - total += uint64(vseg.Range().Intersect(ar).Length()) - } - } - return total -} - // getVMAsLocked ensures that vmas exist for all addresses in ar, and support // access of type (at, ignorePermissions). It returns: // @@ -372,9 +338,6 @@ func (mm *MemoryManager) removeVMAsLocked(ctx context.Context, ar usermem.AddrRa vma.id.DecRef() } mm.usageAS -= uint64(vmaAR.Length()) - if vma.mlockMode != memmap.MLockNone { - mm.lockedAS -= uint64(vmaAR.Length()) - } vgap = mm.vmas.Remove(vseg) vseg = vgap.NextSegment() } @@ -405,7 +368,6 @@ func (vmaSetFunctions) Merge(ar1 usermem.AddrRange, vma1 vma, ar2 usermem.AddrRa vma1.maxPerms != vma2.maxPerms || vma1.private != vma2.private || vma1.growsDown != vma2.growsDown || - vma1.mlockMode != vma2.mlockMode || vma1.id != vma2.id || vma1.hint != vma2.hint { return vma{}, false diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index e855590e6..7a5c93f9b 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -196,11 +196,11 @@ var AMD64 = &kernel.SyscallTable{ 145: SchedGetscheduler, 146: SchedGetPriorityMax, 147: SchedGetPriorityMin, - 148: syscalls.ErrorWithEvent(syscall.EPERM), // SchedRrGetInterval, - 149: Mlock, - 150: Munlock, - 151: Mlockall, - 152: Munlockall, + 148: syscalls.ErrorWithEvent(syscall.EPERM), // SchedRrGetInterval, + 149: syscalls.Error(nil), // Mlock, TODO + 150: syscalls.Error(nil), // Munlock, TODO + 151: syscalls.Error(nil), // Mlockall, TODO + 152: syscalls.Error(nil), // Munlockall, TODO 153: syscalls.CapError(linux.CAP_SYS_TTY_CONFIG), // Vhangup, 154: syscalls.Error(syscall.EPERM), // ModifyLdt, 155: syscalls.Error(syscall.EPERM), // PivotRoot, @@ -373,9 +373,8 @@ var AMD64 = &kernel.SyscallTable{ // 322: Execveat, TODO // 323: Userfaultfd, TODO // 324: Membarrier, TODO - 325: Mlock2, - // Syscalls after 325 are "backports" from versions of Linux after 4.4. - // 326: CopyFileRange, + // Syscalls after 325 are backports from 4.6. + 325: syscalls.Error(nil), // Mlock2, TODO 327: Preadv2, 328: Pwritev2, }, diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 8732861e0..145f7846c 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -69,9 +69,6 @@ func Mmap(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC GrowsDown: linux.MAP_GROWSDOWN&flags != 0, Precommit: linux.MAP_POPULATE&flags != 0, } - if linux.MAP_LOCKED&flags != 0 { - opts.MLockMode = memmap.MLockEager - } defer func() { if opts.MappingIdentity != nil { opts.MappingIdentity.DecRef() @@ -387,6 +384,16 @@ func Msync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall length := args[1].SizeT() flags := args[2].Int() + if addr != addr.RoundDown() { + return 0, nil, syserror.EINVAL + } + if length == 0 { + return 0, nil, nil + } + la, ok := usermem.Addr(length).RoundUp() + if !ok { + return 0, nil, syserror.ENOMEM + } // "The flags argument should specify exactly one of MS_ASYNC and MS_SYNC, // and may additionally include the MS_INVALIDATE bit. ... However, Linux // permits a call to msync() that specifies neither of these flags, with @@ -399,72 +406,39 @@ func Msync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall if sync && flags&linux.MS_ASYNC != 0 { return 0, nil, syserror.EINVAL } - err := t.MemoryManager().MSync(t, addr, uint64(length), mm.MSyncOpts{ - Sync: sync, - Invalidate: flags&linux.MS_INVALIDATE != 0, - }) - // MSync calls fsync, the same interrupt conversion rules apply, see - // mm/msync.c, fsync POSIX.1-2008. - return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) -} - -// Mlock implements linux syscall mlock(2). -func Mlock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - addr := args[0].Pointer() - length := args[1].SizeT() - - return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), memmap.MLockEager) -} -// Mlock2 implements linux syscall mlock2(2). -func Mlock2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - addr := args[0].Pointer() - length := args[1].SizeT() - flags := args[2].Int() - - if flags&^(linux.MLOCK_ONFAULT) != 0 { + // MS_INVALIDATE "asks to invalidate other mappings of the same file (so + // that they can be updated with the fresh values just written)". This is a + // no-op given that shared memory exists. However, MS_INVALIDATE can also + // be used to detect mlocks: "EBUSY: MS_INVALIDATE was specified in flags, + // and a memory lock exists for the specified address range." Given that + // mlock is stubbed out, it's unsafe to pass MS_INVALIDATE silently since + // some user program could be using it for synchronization. + if flags&linux.MS_INVALIDATE != 0 { return 0, nil, syserror.EINVAL } - - mode := memmap.MLockEager - if flags&linux.MLOCK_ONFAULT != 0 { - mode = memmap.MLockLazy - } - return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), mode) -} - -// Munlock implements linux syscall munlock(2). -func Munlock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - addr := args[0].Pointer() - length := args[1].SizeT() - - return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), memmap.MLockNone) -} - -// Mlockall implements linux syscall mlockall(2). -func Mlockall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - flags := args[0].Int() - - if flags&^(linux.MCL_CURRENT|linux.MCL_FUTURE|linux.MCL_ONFAULT) != 0 { - return 0, nil, syserror.EINVAL + // MS_SYNC "requests an update and waits for it to complete." + if sync { + err := t.MemoryManager().Sync(t, addr, uint64(la)) + // Sync calls fsync, the same interrupt conversion rules apply, see + // mm/msync.c, fsync POSIX.1-2008. + return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) + } + // MS_ASYNC "specifies that an update be scheduled, but the call returns + // immediately". As long as dirty pages are tracked and eventually written + // back, this is a no-op. (Correspondingly: "Since Linux 2.6.19, MS_ASYNC + // is in fact a no-op, since the kernel properly tracks dirty pages and + // flushes them to storage as necessary.") + // + // However: "ENOMEM: The indicated memory (or part of it) was not mapped." + // This applies even for MS_ASYNC. + ar, ok := addr.ToRange(uint64(la)) + if !ok { + return 0, nil, syserror.ENOMEM } - - mode := memmap.MLockEager - if flags&linux.MCL_ONFAULT != 0 { - mode = memmap.MLockLazy + mapped := t.MemoryManager().VirtualMemorySizeRange(ar) + if mapped != uint64(la) { + return 0, nil, syserror.ENOMEM } - return 0, nil, t.MemoryManager().MLockAll(t, mm.MLockAllOpts{ - Current: flags&linux.MCL_CURRENT != 0, - Future: flags&linux.MCL_FUTURE != 0, - Mode: mode, - }) -} - -// Munlockall implements linux syscall munlockall(2). -func Munlockall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - return 0, nil, t.MemoryManager().MLockAll(t, mm.MLockAllOpts{ - Current: true, - Future: true, - Mode: memmap.MLockNone, - }) + return 0, nil, nil } diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index b0b216045..2f16e1791 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -90,7 +90,6 @@ var setableLimits = map[limits.LimitType]struct{}{ limits.CPU: {}, limits.Data: {}, limits.FileSize: {}, - limits.MemoryLocked: {}, limits.Stack: {}, // These are not enforced, but we include them here to avoid returning // EPERM, since some apps expect them to succeed. diff --git a/runsc/boot/limits.go b/runsc/boot/limits.go index e3e716bf9..8ecda6d0e 100644 --- a/runsc/boot/limits.go +++ b/runsc/boot/limits.go @@ -29,7 +29,7 @@ var fromLinuxResource = map[string]limits.LimitType{ "RLIMIT_DATA": limits.Data, "RLIMIT_FSIZE": limits.FileSize, "RLIMIT_LOCKS": limits.Locks, - "RLIMIT_MEMLOCK": limits.MemoryLocked, + "RLIMIT_MEMLOCK": limits.MemoryPagesLocked, "RLIMIT_MSGQUEUE": limits.MessageQueueBytes, "RLIMIT_NICE": limits.Nice, "RLIMIT_NOFILE": limits.NumberOfFiles, @@ -55,7 +55,7 @@ func createLimitSet(spec *specs.Spec) (*limits.LimitSet, error) { ls.SetUnchecked(limits.Data, limits.Limit{Cur: limits.Infinity, Max: limits.Infinity}) ls.SetUnchecked(limits.FileSize, limits.Limit{Cur: limits.Infinity, Max: limits.Infinity}) ls.SetUnchecked(limits.Locks, limits.Limit{Cur: limits.Infinity, Max: limits.Infinity}) - ls.SetUnchecked(limits.MemoryLocked, limits.Limit{Cur: 65536, Max: 65536}) + ls.SetUnchecked(limits.MemoryPagesLocked, limits.Limit{Cur: 65536, Max: 65536}) ls.SetUnchecked(limits.MessageQueueBytes, limits.Limit{Cur: 819200, Max: 819200}) ls.SetUnchecked(limits.Nice, limits.Limit{Cur: 0, Max: 0}) ls.SetUnchecked(limits.NumberOfFiles, limits.Limit{Cur: 1048576, Max: 1048576}) diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index f13e32daa..c0b8246b5 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1019,21 +1019,6 @@ cc_binary( ], ) -cc_binary( - name = "mlock_test", - testonly = 1, - srcs = ["mlock.cc"], - linkstatic = 1, - deps = [ - "//test/util:capability_util", - "//test/util:cleanup", - "//test/util:memory_util", - "//test/util:multiprocess_util", - "//test/util:test_util", - "@com_google_googletest//:gtest", - ], -) - cc_binary( name = "mmap_test", testonly = 1, diff --git a/test/syscalls/linux/mlock.cc b/test/syscalls/linux/mlock.cc deleted file mode 100644 index a0d876c2e..000000000 --- a/test/syscalls/linux/mlock.cc +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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. - -#include -#include -#include -#include -#include -#include - -#include "test/util/capability_util.h" -#include "test/util/cleanup.h" -#include "test/util/memory_util.h" -#include "test/util/multiprocess_util.h" -#include "test/util/test_util.h" - -using ::testing::_; - -namespace gvisor { -namespace testing { - -namespace { - -PosixErrorOr CanMlock() { - struct rlimit rlim; - if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { - return PosixError(errno, "getrlimit(RLIMIT_MEMLOCK)"); - } - if (rlim.rlim_cur != 0) { - return true; - } - return HaveCapability(CAP_IPC_LOCK); -} - -// Returns true if the page containing addr is mlocked. -bool IsPageMlocked(uintptr_t addr) { - // This relies on msync(MS_INVALIDATE) interacting correctly with mlocked - // pages, which is tested for by the MsyncInvalidate case below. - int const rv = msync(reinterpret_cast(addr & ~(kPageSize - 1)), - kPageSize, MS_ASYNC | MS_INVALIDATE); - if (rv == 0) { - return false; - } - // This uses TEST_PCHECK_MSG since it's used in subprocesses. - TEST_PCHECK_MSG(errno == EBUSY, "msync failed with unexpected errno"); - return true; -} - -PosixErrorOr ScopedSetSoftRlimit(int resource, rlim_t newval) { - struct rlimit old_rlim; - if (getrlimit(resource, &old_rlim) != 0) { - return PosixError(errno, "getrlimit failed"); - } - struct rlimit new_rlim = old_rlim; - new_rlim.rlim_cur = newval; - if (setrlimit(resource, &new_rlim) != 0) { - return PosixError(errno, "setrlimit failed"); - } - return Cleanup([resource, old_rlim] { - TEST_PCHECK(setrlimit(resource, &old_rlim) == 0); - }); -} - -TEST(MlockTest, Basic) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); -} - -TEST(MlockTest, ProtNone) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = - ASSERT_NO_ERRNO_AND_VALUE(MmapAnon(kPageSize, PROT_NONE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), - SyscallFailsWithErrno(ENOMEM)); - // ENOMEM is returned because mlock can't populate the page, but it's still - // considered locked. - EXPECT_TRUE(IsPageMlocked(mapping.addr())); -} - -TEST(MlockTest, MadviseDontneed) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_THAT(madvise(mapping.ptr(), mapping.len(), MADV_DONTNEED), - SyscallFailsWithErrno(EINVAL)); -} - -TEST(MlockTest, MsyncInvalidate) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_THAT(msync(mapping.ptr(), mapping.len(), MS_ASYNC | MS_INVALIDATE), - SyscallFailsWithErrno(EBUSY)); - EXPECT_THAT(msync(mapping.ptr(), mapping.len(), MS_SYNC | MS_INVALIDATE), - SyscallFailsWithErrno(EBUSY)); -} - -TEST(MlockTest, Fork) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - EXPECT_THAT( - InForkedProcess([&] { TEST_CHECK(!IsPageMlocked(mapping.addr())); }), - IsPosixErrorOkAndHolds(0)); -} - -TEST(MlockTest, RlimitMemlockZero) { - if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { - ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); - } - Cleanup reset_rlimit = - ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), - SyscallFailsWithErrno(EPERM)); -} - -TEST(MlockTest, RlimitMemlockInsufficient) { - if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { - ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); - } - Cleanup reset_rlimit = - ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, kPageSize)); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(2 * kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), - SyscallFailsWithErrno(ENOMEM)); -} - -TEST(MunlockTest, Basic) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); -} - -TEST(MunlockTest, NotLocked) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - EXPECT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); -} - -// There is currently no test for mlockall(MCL_CURRENT) because the default -// RLIMIT_MEMLOCK of 64 KB is insufficient to actually invoke -// mlockall(MCL_CURRENT). - -TEST(MlockallTest, Future) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - - // Run this test in a separate (single-threaded) subprocess to ensure that a - // background thread doesn't try to mmap a large amount of memory, fail due - // to hitting RLIMIT_MEMLOCK, and explode the process violently. - EXPECT_THAT(InForkedProcess([] { - auto const mapping = - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE) - .ValueOrDie(); - TEST_CHECK(!IsPageMlocked(mapping.addr())); - TEST_PCHECK(mlockall(MCL_FUTURE) == 0); - // Ensure that mlockall(MCL_FUTURE) is turned off before the end - // of the test, as otherwise mmaps may fail unexpectedly. - Cleanup do_munlockall([] { TEST_PCHECK(munlockall() == 0); }); - auto const mapping2 = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - TEST_CHECK(IsPageMlocked(mapping2.addr())); - // Fire munlockall() and check that it disables - // mlockall(MCL_FUTURE). - do_munlockall.Release()(); - auto const mapping3 = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - TEST_CHECK(!IsPageMlocked(mapping2.addr())); - }), - IsPosixErrorOkAndHolds(0)); -} - -TEST(MunlockallTest, Basic) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(munlockall(), SyscallSucceeds()); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); -} - -#ifndef SYS_mlock2 -#ifdef __x86_64__ -#define SYS_mlock2 325 -#endif -#endif - -#ifndef MLOCK_ONFAULT -#define MLOCK_ONFAULT 0x01 // Linux: include/uapi/asm-generic/mman-common.h -#endif - -#ifdef SYS_mlock2 - -int mlock2(void const* addr, size_t len, int flags) { - return syscall(SYS_mlock2, addr, len, flags); -} - -TEST(Mlock2Test, NoFlags) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock2(mapping.ptr(), mapping.len(), 0), SyscallSucceeds()); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); -} - -TEST(Mlock2Test, MlockOnfault) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); - ASSERT_THAT(mlock2(mapping.ptr(), mapping.len(), MLOCK_ONFAULT), - SyscallSucceeds()); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); -} - -TEST(Mlock2Test, UnknownFlags) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - EXPECT_THAT(mlock2(mapping.ptr(), mapping.len(), ~0), - SyscallFailsWithErrno(EINVAL)); -} - -#endif // defined(SYS_mlock2) - -TEST(MapLockedTest, Basic) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - EXPECT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); - EXPECT_FALSE(IsPageMlocked(mapping.addr())); -} - -TEST(MapLockedTest, RlimitMemlockZero) { - if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { - ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); - } - Cleanup reset_rlimit = - ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); - EXPECT_THAT( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED), - PosixErrorIs(EPERM, _)); -} - -TEST(MapLockedTest, RlimitMemlockInsufficient) { - if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { - ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); - } - Cleanup reset_rlimit = - ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, kPageSize)); - EXPECT_THAT( - MmapAnon(2 * kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED), - PosixErrorIs(EAGAIN, _)); -} - -TEST(MremapLockedTest, Basic) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - - void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), - MREMAP_MAYMOVE, nullptr); - if (addr == MAP_FAILED) { - FAIL() << "mremap failed: " << errno << " (" << strerror(errno) << ")"; - } - mapping.release(); - mapping.reset(addr, 2 * mapping.len()); - EXPECT_TRUE(IsPageMlocked(reinterpret_cast(addr))); -} - -TEST(MremapLockedTest, RlimitMemlockZero) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - - if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { - ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); - } - Cleanup reset_rlimit = - ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); - void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), - MREMAP_MAYMOVE, nullptr); - EXPECT_TRUE(addr == MAP_FAILED && errno == EAGAIN) - << "addr = " << addr << ", errno = " << errno; -} - -TEST(MremapLockedTest, RlimitMemlockInsufficient) { - SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); - auto mapping = ASSERT_NO_ERRNO_AND_VALUE( - MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); - EXPECT_TRUE(IsPageMlocked(mapping.addr())); - - if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { - ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); - } - Cleanup reset_rlimit = ASSERT_NO_ERRNO_AND_VALUE( - ScopedSetSoftRlimit(RLIMIT_MEMLOCK, mapping.len())); - void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), - MREMAP_MAYMOVE, nullptr); - EXPECT_TRUE(addr == MAP_FAILED && errno == EAGAIN) - << "addr = " << addr << ", errno = " << errno; -} - -} // namespace - -} // namespace testing -} // namespace gvisor diff --git a/test/syscalls/linux/msync.cc b/test/syscalls/linux/msync.cc index 72d90dc78..0ddc621aa 100644 --- a/test/syscalls/linux/msync.cc +++ b/test/syscalls/linux/msync.cc @@ -43,13 +43,14 @@ class MsyncParameterizedTest : public ::testing::TestWithParam { protected: int msync_flags() const { return std::get<0>(GetParam()); } - PosixErrorOr GetMapping() const { return std::get<1>(GetParam())(); } + PosixErrorOr GetMapping() const { + auto rv = std::get<1>(GetParam())(); + return rv; + } }; -// All valid msync(2) flag combinations, not including MS_INVALIDATE. ("Linux -// permits a call to msync() that specifies neither [MS_SYNC or MS_ASYNC], with -// semantics that are (currently) equivalent to specifying MS_ASYNC." - -// msync(2)) +// All valid msync(2) flag combinations (not including MS_INVALIDATE, which +// gVisor doesn't implement). constexpr std::initializer_list kMsyncFlags = {MS_SYNC, MS_ASYNC, 0}; // Returns functions that return mappings that should be successfully @@ -133,15 +134,6 @@ TEST_P(MsyncFullParamTest, UnalignedAddressFails) { SyscallFailsWithErrno(EINVAL)); } -TEST_P(MsyncFullParamTest, InvalidateUnlockedSucceeds) { - auto m = ASSERT_NO_ERRNO_AND_VALUE(GetMapping()); - EXPECT_THAT(msync(m.ptr(), m.len(), msync_flags() | MS_INVALIDATE), - SyscallSucceeds()); -} - -// The test for MS_INVALIDATE on mlocked pages is in mlock.cc since it requires -// probing for mlock support. - INSTANTIATE_TEST_CASE_P( All, MsyncFullParamTest, ::testing::Combine(::testing::ValuesIn(kMsyncFlags), -- cgit v1.2.3 From 9a442fa4b5f64bde6554118ed5b340e6b53e8d6e Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Fri, 21 Dec 2018 08:22:24 -0800 Subject: Automated rollback of changelist 226224230 PiperOrigin-RevId: 226493053 Change-Id: Ia98d1cb6dd0682049e4d907ef69619831de5c34a --- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/mm.go | 12 + pkg/sentry/memmap/memmap.go | 37 +++ pkg/sentry/mm/BUILD | 1 + pkg/sentry/mm/address_space.go | 12 +- pkg/sentry/mm/lifecycle.go | 24 +- pkg/sentry/mm/mm.go | 24 +- pkg/sentry/mm/syscalls.go | 423 +++++++++++++++++++++++++++----- pkg/sentry/mm/vma.go | 38 +++ pkg/sentry/syscalls/linux/linux64.go | 15 +- pkg/sentry/syscalls/linux/sys_mmap.go | 106 +++++--- pkg/sentry/syscalls/linux/sys_rlimit.go | 1 + test/syscalls/linux/BUILD | 16 ++ test/syscalls/linux/mlock.cc | 345 ++++++++++++++++++++++++++ test/syscalls/linux/msync.cc | 20 +- 15 files changed, 945 insertions(+), 131 deletions(-) create mode 100644 test/syscalls/linux/mlock.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index b2e51b9bd..e0aa5b31d 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -60,7 +60,7 @@ const ( DefaultNofileHardLimit = 4096 // DefaultMemlockLimit is called MLOCK_LIMIT in Linux. - DefaultMemlockLimit = 64 * 1094 + DefaultMemlockLimit = 64 * 1024 // DefaultMsgqueueLimit is called MQ_BYTES_MAX in Linux. DefaultMsgqueueLimit = 819200 diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index 3fcdf8235..eda8d9788 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -49,6 +49,18 @@ const ( MREMAP_FIXED = 1 << 1 ) +// Flags for mlock2(2). +const ( + MLOCK_ONFAULT = 0x01 +) + +// Flags for mlockall(2). +const ( + MCL_CURRENT = 1 + MCL_FUTURE = 2 + MCL_ONFAULT = 4 +) + // Advice for madvise(2). const ( MADV_NORMAL = 0 diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index 28e2bed9b..cf20b11e3 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -243,6 +243,40 @@ type MappingIdentity interface { Msync(ctx context.Context, mr MappableRange) error } +// MLockMode specifies the memory locking behavior of a memory mapping. +type MLockMode int + +// Note that the ordering of MLockModes is significant; see +// mm.MemoryManager.defMLockMode. +const ( + // MLockNone specifies that a mapping has no memory locking behavior. + // + // This must be the zero value for MLockMode. + MLockNone MLockMode = iota + + // MLockEager specifies that a mapping is memory-locked, as by mlock() or + // similar. Pages in the mapping should be made, and kept, resident in + // physical memory as soon as possible. + // + // As of this writing, MLockEager does not cause memory-locking to be + // requested from the host; it only affects the sentry's memory management + // behavior. + // + // MLockEager is analogous to Linux's VM_LOCKED. + MLockEager + + // MLockLazy specifies that a mapping is memory-locked, as by mlock() or + // similar. Pages in the mapping should be kept resident in physical memory + // once they have been made resident due to e.g. a page fault. + // + // As of this writing, MLockLazy does not cause memory-locking to be + // requested from the host; in fact, it has virtually no effect, except for + // interactions between mlocked pages and other syscalls. + // + // MLockLazy is analogous to Linux's VM_LOCKED | VM_LOCKONFAULT. + MLockLazy +) + // MMapOpts specifies a request to create a memory mapping. type MMapOpts struct { // Length is the length of the mapping. @@ -303,6 +337,9 @@ type MMapOpts struct { // mapping (see platform.AddressSpace.MapFile). Precommit bool + // MLockMode specifies the memory locking behavior of the mapping. + MLockMode MLockMode + // Hint is the name used for the mapping in /proc/[pid]/maps. If Hint is // empty, MappingIdentity.MappedName() will be used instead. // diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 744e73a39..5a9185e5d 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -106,6 +106,7 @@ go_library( "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/proc/seqfile", + "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/futex", "//pkg/sentry/kernel/shm", "//pkg/sentry/limits", diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index 7488f7c4a..e7aa24c69 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -149,7 +149,7 @@ func (mm *MemoryManager) Deactivate() { // for all addresses in ar should be precommitted. // // Preconditions: mm.activeMu must be locked. mm.as != nil. ar.Length() != 0. -// ar must be page-aligned. pseg.Range().Contains(ar.Start). +// ar must be page-aligned. pseg == mm.pmas.LowerBoundSegment(ar.Start). func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, precommit bool) error { // By default, map entire pmas at a time, under the assumption that there // is no cost to mapping more of a pma than necessary. @@ -173,7 +173,9 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, pre } } - for { + // Since this checks ar.End and not mapAR.End, we will never map a pma that + // is not required. + for pseg.Ok() && pseg.Start() < ar.End { pma := pseg.ValuePtr() pmaAR := pseg.Range() pmaMapAR := pmaAR.Intersect(mapAR) @@ -184,13 +186,9 @@ func (mm *MemoryManager) mapASLocked(pseg pmaIterator, ar usermem.AddrRange, pre if err := pma.file.MapInto(mm.as, pmaMapAR.Start, pseg.fileRangeOf(pmaMapAR), perms, precommit); err != nil { return err } - // Since this checks ar.End and not mapAR.End, we will never map a pma - // that is not required. - if ar.End <= pmaAR.End { - return nil - } pseg = pseg.NextSegment() } + return nil } // unmapASLocked removes all AddressSpace mappings for addresses in ar. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index 1613ce11d..a42e32b43 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" + "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/platform" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) @@ -58,13 +59,17 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { mm.mappingMu.RLock() defer mm.mappingMu.RUnlock() mm2 := &MemoryManager{ - p: mm.p, - haveASIO: mm.haveASIO, - layout: mm.layout, - privateRefs: mm.privateRefs, - users: 1, - usageAS: mm.usageAS, - brk: mm.brk, + p: mm.p, + haveASIO: mm.haveASIO, + layout: mm.layout, + privateRefs: mm.privateRefs, + users: 1, + brk: mm.brk, + usageAS: mm.usageAS, + // "The child does not inherit its parent's memory locks (mlock(2), + // mlockall(2))." - fork(2). So lockedAS is 0 and defMLockMode is + // MLockNone, both of which are zero values. vma.mlockMode is reset + // when copied below. captureInvalidations: true, argv: mm.argv, envv: mm.envv, @@ -77,7 +82,7 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { // Copy vmas. dstvgap := mm2.vmas.FirstGap() for srcvseg := mm.vmas.FirstSegment(); srcvseg.Ok(); srcvseg = srcvseg.NextSegment() { - vma := srcvseg.ValuePtr() + vma := srcvseg.Value() // makes a copy of the vma vmaAR := srcvseg.Range() // Inform the Mappable, if any, of the new mapping. if vma.mappable != nil { @@ -89,7 +94,8 @@ func (mm *MemoryManager) Fork(ctx context.Context) (*MemoryManager, error) { if vma.id != nil { vma.id.IncRef() } - dstvgap = mm2.vmas.Insert(dstvgap, vmaAR, *vma).NextGap() + vma.mlockMode = memmap.MLockNone + dstvgap = mm2.vmas.Insert(dstvgap, vmaAR, vma).NextGap() // We don't need to update mm2.usageAS since we copied it from mm // above. } diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index b1e39e898..c0632d232 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -95,11 +95,6 @@ type MemoryManager struct { // vmas is protected by mappingMu. vmas vmaSet - // usageAS is vmas.Span(), cached to accelerate RLIMIT_AS checks. - // - // usageAS is protected by mappingMu. - usageAS uint64 - // brk is the mm's brk, which is manipulated using the brk(2) system call. // The brk is initially set up by the loader which maps an executable // binary into the mm. @@ -107,6 +102,23 @@ type MemoryManager struct { // brk is protected by mappingMu. brk usermem.AddrRange + // usageAS is vmas.Span(), cached to accelerate RLIMIT_AS checks. + // + // usageAS is protected by mappingMu. + usageAS uint64 + + // lockedAS is the combined size in bytes of all vmas with vma.mlockMode != + // memmap.MLockNone. + // + // lockedAS is protected by mappingMu. + lockedAS uint64 + + // New VMAs created by MMap use whichever of memmap.MMapOpts.MLockMode or + // defMLockMode is greater. + // + // defMLockMode is protected by mappingMu. + defMLockMode memmap.MLockMode + // activeMu is loosely analogous to Linux's struct // mm_struct::page_table_lock. activeMu ssync.DowngradableRWMutex `state:"nosave"` @@ -252,6 +264,8 @@ type vma struct { // metag, none of which we currently support. growsDown bool `state:"manual"` + mlockMode memmap.MLockMode + // If id is not nil, it controls the lifecycle of mappable and provides vma // metadata shown in /proc/[pid]/maps, and the vma holds a reference. id memmap.MappingIdentity diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index daaae4da1..383703ec3 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -20,6 +20,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" @@ -128,16 +129,24 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme // Get the new vma. mm.mappingMu.Lock() + if opts.MLockMode < mm.defMLockMode { + opts.MLockMode = mm.defMLockMode + } vseg, ar, err := mm.createVMALocked(ctx, opts) if err != nil { mm.mappingMu.Unlock() return 0, err } + // TODO: In Linux, VM_LOCKONFAULT (which may be set on the new + // vma by mlockall(MCL_FUTURE|MCL_ONFAULT) => mm_struct::def_flags) appears + // to effectively disable MAP_POPULATE by unsetting FOLL_POPULATE in + // mm/util.c:vm_mmap_pgoff() => mm/gup.c:__mm_populate() => + // populate_vma_page_range(). Confirm this behavior. switch { - case opts.Precommit: + case opts.Precommit || opts.MLockMode == memmap.MLockEager: // Get pmas and map with precommit as requested. - mm.populateAndUnlock(ctx, vseg, ar, true) + mm.populateVMAAndUnlock(ctx, vseg, ar, true) case opts.Mappable == nil && length <= privateAllocUnit: // NOTE: Get pmas and map eagerly in the hope @@ -146,7 +155,7 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme // memmap.Mappable.Translate is unknown; and only for small mappings, // to avoid needing to allocate large amounts of memory that we may // subsequently need to checkpoint. - mm.populateAndUnlock(ctx, vseg, ar, false) + mm.populateVMAAndUnlock(ctx, vseg, ar, false) default: mm.mappingMu.Unlock() @@ -155,31 +164,29 @@ func (mm *MemoryManager) MMap(ctx context.Context, opts memmap.MMapOpts) (userme return ar.Start, nil } -// Preconditions: mm.mappingMu must be locked for writing. +// populateVMA obtains pmas for addresses in ar in the given vma, and maps them +// into mm.as if it is active. // -// Postconditions: mm.mappingMu will be unlocked. -func (mm *MemoryManager) populateAndUnlock(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { +// Preconditions: mm.mappingMu must be locked. vseg.Range().IsSupersetOf(ar). +func (mm *MemoryManager) populateVMA(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { if !vseg.ValuePtr().effectivePerms.Any() { // Linux doesn't populate inaccessible pages. See // mm/gup.c:populate_vma_page_range. - mm.mappingMu.Unlock() return } mm.activeMu.Lock() + // Can't defer mm.activeMu.Unlock(); see below. - // Even if we get a new pma, we can't actually map it if we don't have an + // Even if we get new pmas, we can't actually map them if we don't have an // AddressSpace. if mm.as == nil { mm.activeMu.Unlock() - mm.mappingMu.Unlock() return } // Ensure that we have usable pmas. - mm.mappingMu.DowngradeLock() pseg, _, err := mm.getPMAsLocked(ctx, vseg, ar, pmaOpts{}) - mm.mappingMu.RUnlock() if err != nil { // mm/util.c:vm_mmap_pgoff() ignores the error, if any, from // mm/gup.c:mm_populate(). If it matters, we'll get it again when @@ -197,6 +204,45 @@ func (mm *MemoryManager) populateAndUnlock(ctx context.Context, vseg vmaIterator mm.activeMu.RUnlock() } +// populateVMAAndUnlock is equivalent to populateVMA, but also unconditionally +// unlocks mm.mappingMu. In cases where populateVMAAndUnlock is usable, it is +// preferable to populateVMA since it unlocks mm.mappingMu before performing +// expensive operations that don't require it to be locked. +// +// Preconditions: mm.mappingMu must be locked for writing. +// vseg.Range().IsSupersetOf(ar). +// +// Postconditions: mm.mappingMu will be unlocked. +func (mm *MemoryManager) populateVMAAndUnlock(ctx context.Context, vseg vmaIterator, ar usermem.AddrRange, precommit bool) { + // See populateVMA above for commentary. + if !vseg.ValuePtr().effectivePerms.Any() { + mm.mappingMu.Unlock() + return + } + + mm.activeMu.Lock() + + if mm.as == nil { + mm.activeMu.Unlock() + mm.mappingMu.Unlock() + return + } + + // mm.mappingMu doesn't need to be write-locked for getPMAsLocked, and it + // isn't needed at all for mapASLocked. + mm.mappingMu.DowngradeLock() + pseg, _, err := mm.getPMAsLocked(ctx, vseg, ar, pmaOpts{}) + mm.mappingMu.RUnlock() + if err != nil { + mm.activeMu.Unlock() + return + } + + mm.activeMu.DowngradeLock() + mm.mapASLocked(pseg, ar, precommit) + mm.activeMu.RUnlock() +} + // MapStack allocates the initial process stack. func (mm *MemoryManager) MapStack(ctx context.Context) (usermem.AddrRange, error) { // maxStackSize is the maximum supported process stack size in bytes. @@ -236,6 +282,7 @@ func (mm *MemoryManager) MapStack(ctx context.Context) (usermem.AddrRange, error MaxPerms: usermem.AnyAccess, Private: true, GrowsDown: true, + MLockMode: mm.defMLockMode, Hint: "[stack]", }) return ar, err @@ -334,6 +381,19 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi // occupies at least part of the destination. Thus the NoMove case always // fails and the MayMove case always falls back to copying. + if vma := vseg.ValuePtr(); newSize > oldSize && vma.mlockMode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. Unlike mmap, mlock, and mlockall, + // mremap in Linux does not check mm/mlock.c:can_do_mlock() and + // therefore does not return EPERM if RLIMIT_MEMLOCK is 0 and + // !CAP_IPC_LOCK. + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + if newLockedAS := mm.lockedAS - oldSize + newSize; newLockedAS > mlockLimit { + return 0, syserror.EAGAIN + } + } + } + if opts.Move != MRemapMustMove { // Handle no-ops and in-place shrinking. These cases don't care if // [oldAddr, oldEnd) maps to a single vma, or is even mapped at all @@ -360,7 +420,7 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi if vma.mappable != nil { newOffset = vseg.mappableRange().End } - _, _, err := mm.createVMALocked(ctx, memmap.MMapOpts{ + vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: newSize - oldSize, MappingIdentity: vma.id, Mappable: vma.mappable, @@ -371,9 +431,13 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi MaxPerms: vma.maxPerms, Private: vma.private, GrowsDown: vma.growsDown, + MLockMode: vma.mlockMode, Hint: vma.hint, }) if err == nil { + if vma.mlockMode == memmap.MLockEager { + mm.populateVMA(ctx, vseg, ar, true) + } return oldAddr, nil } // In-place growth failed. In the MRemapMayMove case, fall through to @@ -462,8 +526,14 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi if vma.id != nil { vma.id.IncRef() } - mm.vmas.Add(newAR, vma) + vseg := mm.vmas.Insert(mm.vmas.FindGap(newAR.Start), newAR, vma) mm.usageAS += uint64(newAR.Length()) + if vma.mlockMode != memmap.MLockNone { + mm.lockedAS += uint64(newAR.Length()) + if vma.mlockMode == memmap.MLockEager { + mm.populateVMA(ctx, vseg, newAR, true) + } + } return newAR.Start, nil } @@ -485,8 +555,11 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi vseg = mm.vmas.Isolate(vseg, oldAR) vma := vseg.Value() mm.vmas.Remove(vseg) - mm.vmas.Add(newAR, vma) + vseg = mm.vmas.Insert(mm.vmas.FindGap(newAR.Start), newAR, vma) mm.usageAS = mm.usageAS - uint64(oldAR.Length()) + uint64(newAR.Length()) + if vma.mlockMode != memmap.MLockNone { + mm.lockedAS = mm.lockedAS - uint64(oldAR.Length()) + uint64(newAR.Length()) + } // Move pmas. This is technically optional for non-private pmas, which // could just go through memmap.Mappable.Translate again, but it's required @@ -501,6 +574,10 @@ func (mm *MemoryManager) MRemap(ctx context.Context, oldAddr usermem.Addr, oldSi vma.mappable.RemoveMapping(ctx, mm, oldAR, vma.off, vma.isMappableAsWritable()) } + if vma.mlockMode == memmap.MLockEager { + mm.populateVMA(ctx, vseg, newAR, true) + } + return newAR.Start, nil } @@ -611,9 +688,10 @@ func (mm *MemoryManager) BrkSetup(ctx context.Context, addr usermem.Addr) { // error on failure. func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Addr, error) { mm.mappingMu.Lock() - defer mm.mappingMu.Unlock() + // Can't defer mm.mappingMu.Unlock(); see below. if addr < mm.brk.Start { + mm.mappingMu.Unlock() return mm.brk.End, syserror.EINVAL } @@ -623,21 +701,24 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad // heap + data + bss. The segment sizes need to be plumbed from the // loader package to fully enforce RLIMIT_DATA. if uint64(addr-mm.brk.Start) > limits.FromContext(ctx).Get(limits.Data).Cur { + mm.mappingMu.Unlock() return mm.brk.End, syserror.ENOMEM } oldbrkpg, _ := mm.brk.End.RoundUp() newbrkpg, ok := addr.RoundUp() if !ok { + mm.mappingMu.Unlock() return mm.brk.End, syserror.EFAULT } switch { case newbrkpg < oldbrkpg: mm.unmapLocked(ctx, usermem.AddrRange{newbrkpg, oldbrkpg}) + mm.mappingMu.Unlock() case oldbrkpg < newbrkpg: - _, _, err := mm.createVMALocked(ctx, memmap.MMapOpts{ + vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: uint64(newbrkpg - oldbrkpg), Addr: oldbrkpg, Fixed: true, @@ -646,17 +727,221 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad Perms: usermem.ReadWrite, MaxPerms: usermem.AnyAccess, Private: true, - Hint: "[heap]", + // Linux: mm/mmap.c:sys_brk() => do_brk_flags() includes + // mm->def_flags. + MLockMode: mm.defMLockMode, + Hint: "[heap]", }) if err != nil { + mm.mappingMu.Unlock() return mm.brk.End, err } + if mm.defMLockMode == memmap.MLockEager { + mm.populateVMAAndUnlock(ctx, vseg, ar, true) + } else { + mm.mappingMu.Unlock() + } + + default: + // Nothing to do. + mm.mappingMu.Unlock() } mm.brk.End = addr return addr, nil } +// MLock implements the semantics of Linux's mlock()/mlock2()/munlock(), +// depending on mode. +func (mm *MemoryManager) MLock(ctx context.Context, addr usermem.Addr, length uint64, mode memmap.MLockMode) error { + // Linux allows this to overflow. + la, _ := usermem.Addr(length + addr.PageOffset()).RoundUp() + ar, ok := addr.RoundDown().ToRange(uint64(la)) + if !ok { + return syserror.EINVAL + } + + mm.mappingMu.Lock() + // Can't defer mm.mappingMu.Unlock(); see below. + + if mode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if mlockLimit == 0 { + mm.mappingMu.Unlock() + return syserror.EPERM + } + if newLockedAS := mm.lockedAS + uint64(ar.Length()) - mm.mlockedBytesRangeLocked(ar); newLockedAS > mlockLimit { + mm.mappingMu.Unlock() + return syserror.ENOMEM + } + } + } + + // Check this after RLIMIT_MEMLOCK for consistency with Linux. + if ar.Length() == 0 { + mm.mappingMu.Unlock() + return nil + } + + // Apply the new mlock mode to vmas. + var unmapped bool + vseg := mm.vmas.FindSegment(ar.Start) + for { + if !vseg.Ok() { + unmapped = true + break + } + vseg = mm.vmas.Isolate(vseg, ar) + vma := vseg.ValuePtr() + prevMode := vma.mlockMode + vma.mlockMode = mode + if mode != memmap.MLockNone && prevMode == memmap.MLockNone { + mm.lockedAS += uint64(vseg.Range().Length()) + } else if mode == memmap.MLockNone && prevMode != memmap.MLockNone { + mm.lockedAS -= uint64(vseg.Range().Length()) + } + if ar.End <= vseg.End() { + break + } + vseg, _ = vseg.NextNonEmpty() + } + mm.vmas.MergeRange(ar) + mm.vmas.MergeAdjacent(ar) + if unmapped { + mm.mappingMu.Unlock() + return syserror.ENOMEM + } + + if mode == memmap.MLockEager { + // Ensure that we have usable pmas. Since we didn't return ENOMEM + // above, ar must be fully covered by vmas, so we can just use + // NextSegment below. + mm.activeMu.Lock() + mm.mappingMu.DowngradeLock() + for vseg := mm.vmas.FindSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { + if !vseg.ValuePtr().effectivePerms.Any() { + // Linux: mm/gup.c:__get_user_pages() returns EFAULT in this + // case, which is converted to ENOMEM by mlock. + mm.activeMu.Unlock() + mm.mappingMu.RUnlock() + return syserror.ENOMEM + } + _, _, err := mm.getPMAsLocked(ctx, vseg, vseg.Range().Intersect(ar), pmaOpts{}) + if err != nil { + mm.activeMu.Unlock() + mm.mappingMu.RUnlock() + // Linux: mm/mlock.c:__mlock_posix_error_return() + if err == syserror.EFAULT { + return syserror.ENOMEM + } + if err == syserror.ENOMEM { + return syserror.EAGAIN + } + return err + } + } + + // Map pmas into the active AddressSpace, if we have one. + mm.mappingMu.RUnlock() + if mm.as != nil { + mm.activeMu.DowngradeLock() + err := mm.mapASLocked(mm.pmas.LowerBoundSegment(ar.Start), ar, true /* precommit */) + mm.activeMu.RUnlock() + if err != nil { + return err + } + } else { + mm.activeMu.Unlock() + } + } else { + mm.mappingMu.Unlock() + } + + return nil +} + +// MLockAllOpts holds options to MLockAll. +type MLockAllOpts struct { + // If Current is true, change the memory-locking behavior of all mappings + // to Mode. If Future is true, upgrade the memory-locking behavior of all + // future mappings to Mode. At least one of Current or Future must be true. + Current bool + Future bool + Mode memmap.MLockMode +} + +// MLockAll implements the semantics of Linux's mlockall()/munlockall(), +// depending on opts. +func (mm *MemoryManager) MLockAll(ctx context.Context, opts MLockAllOpts) error { + if !opts.Current && !opts.Future { + return syserror.EINVAL + } + + mm.mappingMu.Lock() + // Can't defer mm.mappingMu.Unlock(); see below. + + if opts.Current { + if opts.Mode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if mlockLimit == 0 { + mm.mappingMu.Unlock() + return syserror.EPERM + } + if uint64(mm.vmas.Span()) > mlockLimit { + mm.mappingMu.Unlock() + return syserror.ENOMEM + } + } + } + for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { + vma := vseg.ValuePtr() + prevMode := vma.mlockMode + vma.mlockMode = opts.Mode + if opts.Mode != memmap.MLockNone && prevMode == memmap.MLockNone { + mm.lockedAS += uint64(vseg.Range().Length()) + } else if opts.Mode == memmap.MLockNone && prevMode != memmap.MLockNone { + mm.lockedAS -= uint64(vseg.Range().Length()) + } + } + } + + if opts.Future { + mm.defMLockMode = opts.Mode + } + + if opts.Current && opts.Mode == memmap.MLockEager { + // Linux: mm/mlock.c:sys_mlockall() => include/linux/mm.h:mm_populate() + // ignores the return value of __mm_populate(), so all errors below are + // ignored. + // + // Try to get usable pmas. + mm.activeMu.Lock() + mm.mappingMu.DowngradeLock() + for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { + if vseg.ValuePtr().effectivePerms.Any() { + mm.getPMAsLocked(ctx, vseg, vseg.Range(), pmaOpts{}) + } + } + + // Map all pmas into the active AddressSpace, if we have one. + mm.mappingMu.RUnlock() + if mm.as != nil { + mm.activeMu.DowngradeLock() + mm.mapASLocked(mm.pmas.FirstSegment(), mm.applicationAddrRange(), true /* precommit */) + mm.activeMu.RUnlock() + } else { + mm.activeMu.Unlock() + } + } else { + mm.mappingMu.Unlock() + } + return nil +} + // Decommit implements the semantics of Linux's madvise(MADV_DONTNEED). func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { ar, ok := addr.ToRange(length) @@ -680,46 +965,49 @@ func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { // ensures that Decommit immediately reduces host memory usage. var didUnmapAS bool pseg := mm.pmas.LowerBoundSegment(ar.Start) - vseg := mm.vmas.LowerBoundSegment(ar.Start) mem := mm.p.Memory() - for pseg.Ok() && pseg.Start() < ar.End { - pma := pseg.ValuePtr() - if pma.private && !mm.isPMACopyOnWriteLocked(pseg) { - psegAR := pseg.Range().Intersect(ar) - vseg = vseg.seekNextLowerBound(psegAR.Start) - if checkInvariants { - if !vseg.Ok() { - panic(fmt.Sprintf("no vma after %#x", psegAR.Start)) - } - if psegAR.Start < vseg.Start() { - panic(fmt.Sprintf("no vma in [%#x, %#x)", psegAR.Start, vseg.Start())) - } + for vseg := mm.vmas.LowerBoundSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { + vma := vseg.ValuePtr() + if vma.mlockMode != memmap.MLockNone { + return syserror.EINVAL + } + vsegAR := vseg.Range().Intersect(ar) + // pseg should already correspond to either this vma or a later one, + // since there can't be a pma without a corresponding vma. + if checkInvariants { + if pseg.Ok() && pseg.End() <= vsegAR.Start { + panic(fmt.Sprintf("pma %v precedes vma %v", pseg.Range(), vsegAR)) } - if vseg.Range().IsSupersetOf(psegAR) && vseg.ValuePtr().mappable == nil { - if err := mem.Decommit(pseg.fileRangeOf(psegAR)); err == nil { - pseg = pseg.NextSegment() - continue + } + for pseg.Ok() && pseg.Start() < vsegAR.End { + pma := pseg.ValuePtr() + if pma.private && !mm.isPMACopyOnWriteLocked(pseg) { + psegAR := pseg.Range().Intersect(ar) + if vsegAR.IsSupersetOf(psegAR) && vma.mappable == nil { + if err := mem.Decommit(pseg.fileRangeOf(psegAR)); err == nil { + pseg = pseg.NextSegment() + continue + } + // If an error occurs, fall through to the general + // invalidation case below. } - // If an error occurs, fall through to the general - // invalidation case below. } + pseg = mm.pmas.Isolate(pseg, vsegAR) + pma = pseg.ValuePtr() + if !didUnmapAS { + // Unmap all of ar, not just pseg.Range(), to minimize host + // syscalls. AddressSpace mappings must be removed before + // mm.decPrivateRef(). + mm.unmapASLocked(ar) + didUnmapAS = true + } + if pma.private { + mm.decPrivateRef(pseg.fileRange()) + } + pma.file.DecRef(pseg.fileRange()) + mm.removeRSSLocked(pseg.Range()) + pseg = mm.pmas.Remove(pseg).NextSegment() } - pseg = mm.pmas.Isolate(pseg, ar) - pma = pseg.ValuePtr() - if !didUnmapAS { - // Unmap all of ar, not just pseg.Range(), to minimize host - // syscalls. AddressSpace mappings must be removed before - // mm.decPrivateRef(). - mm.unmapASLocked(ar) - didUnmapAS = true - } - if pma.private { - mm.decPrivateRef(pseg.fileRange()) - } - pma.file.DecRef(pseg.fileRange()) - mm.removeRSSLocked(pseg.Range()) - - pseg = mm.pmas.Remove(pseg).NextSegment() } // "If there are some parts of the specified address space that are not @@ -732,9 +1020,28 @@ func (mm *MemoryManager) Decommit(addr usermem.Addr, length uint64) error { return nil } -// Sync implements the semantics of Linux's msync(MS_SYNC). -func (mm *MemoryManager) Sync(ctx context.Context, addr usermem.Addr, length uint64) error { - ar, ok := addr.ToRange(length) +// MSyncOpts holds options to MSync. +type MSyncOpts struct { + // Sync has the semantics of MS_SYNC. + Sync bool + + // Invalidate has the semantics of MS_INVALIDATE. + Invalidate bool +} + +// MSync implements the semantics of Linux's msync(). +func (mm *MemoryManager) MSync(ctx context.Context, addr usermem.Addr, length uint64, opts MSyncOpts) error { + if addr != addr.RoundDown() { + return syserror.EINVAL + } + if length == 0 { + return nil + } + la, ok := usermem.Addr(length).RoundUp() + if !ok { + return syserror.ENOMEM + } + ar, ok := addr.ToRange(uint64(la)) if !ok { return syserror.ENOMEM } @@ -759,10 +1066,14 @@ func (mm *MemoryManager) Sync(ctx context.Context, addr usermem.Addr, length uin } lastEnd = vseg.End() vma := vseg.ValuePtr() + if opts.Invalidate && vma.mlockMode != memmap.MLockNone { + mm.mappingMu.RUnlock() + return syserror.EBUSY + } // It's only possible to have dirtied the Mappable through a shared // mapping. Don't check if the mapping is writable, because mprotect // may have changed this, and also because Linux doesn't. - if id := vma.id; id != nil && vma.mappable != nil && !vma.private { + if id := vma.id; opts.Sync && id != nil && vma.mappable != nil && !vma.private { // We can't call memmap.MappingIdentity.Msync while holding // mm.mappingMu since it may take fs locks that precede it in the // lock order. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index 5c2c802f6..28ba9f2f5 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -17,8 +17,10 @@ package mm import ( "fmt" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -53,6 +55,23 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp return vmaIterator{}, usermem.AddrRange{}, syserror.ENOMEM } + if opts.MLockMode != memmap.MLockNone { + // Check against RLIMIT_MEMLOCK. + if creds := auth.CredentialsFromContext(ctx); !creds.HasCapabilityIn(linux.CAP_IPC_LOCK, creds.UserNamespace.Root()) { + mlockLimit := limits.FromContext(ctx).Get(limits.MemoryLocked).Cur + if mlockLimit == 0 { + return vmaIterator{}, usermem.AddrRange{}, syserror.EPERM + } + newLockedAS := mm.lockedAS + opts.Length + if opts.Unmap { + newLockedAS -= mm.mlockedBytesRangeLocked(ar) + } + if newLockedAS > mlockLimit { + return vmaIterator{}, usermem.AddrRange{}, syserror.EAGAIN + } + } + } + // Remove overwritten mappings. This ordering is consistent with Linux: // compare Linux's mm/mmap.c:mmap_region() => do_munmap(), // file->f_op->mmap(). @@ -85,10 +104,14 @@ func (mm *MemoryManager) createVMALocked(ctx context.Context, opts memmap.MMapOp maxPerms: opts.MaxPerms, private: opts.Private, growsDown: opts.GrowsDown, + mlockMode: opts.MLockMode, id: opts.MappingIdentity, hint: opts.Hint, }) mm.usageAS += opts.Length + if opts.MLockMode != memmap.MLockNone { + mm.lockedAS += opts.Length + } return vseg, ar, nil } @@ -201,6 +224,17 @@ func (mm *MemoryManager) findHighestAvailableLocked(length, alignment uint64, bo return 0, syserror.ENOMEM } +// Preconditions: mm.mappingMu must be locked. +func (mm *MemoryManager) mlockedBytesRangeLocked(ar usermem.AddrRange) uint64 { + var total uint64 + for vseg := mm.vmas.LowerBoundSegment(ar.Start); vseg.Ok() && vseg.Start() < ar.End; vseg = vseg.NextSegment() { + if vseg.ValuePtr().mlockMode != memmap.MLockNone { + total += uint64(vseg.Range().Intersect(ar).Length()) + } + } + return total +} + // getVMAsLocked ensures that vmas exist for all addresses in ar, and support // access of type (at, ignorePermissions). It returns: // @@ -338,6 +372,9 @@ func (mm *MemoryManager) removeVMAsLocked(ctx context.Context, ar usermem.AddrRa vma.id.DecRef() } mm.usageAS -= uint64(vmaAR.Length()) + if vma.mlockMode != memmap.MLockNone { + mm.lockedAS -= uint64(vmaAR.Length()) + } vgap = mm.vmas.Remove(vseg) vseg = vgap.NextSegment() } @@ -368,6 +405,7 @@ func (vmaSetFunctions) Merge(ar1 usermem.AddrRange, vma1 vma, ar2 usermem.AddrRa vma1.maxPerms != vma2.maxPerms || vma1.private != vma2.private || vma1.growsDown != vma2.growsDown || + vma1.mlockMode != vma2.mlockMode || vma1.id != vma2.id || vma1.hint != vma2.hint { return vma{}, false diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 7a5c93f9b..e855590e6 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -196,11 +196,11 @@ var AMD64 = &kernel.SyscallTable{ 145: SchedGetscheduler, 146: SchedGetPriorityMax, 147: SchedGetPriorityMin, - 148: syscalls.ErrorWithEvent(syscall.EPERM), // SchedRrGetInterval, - 149: syscalls.Error(nil), // Mlock, TODO - 150: syscalls.Error(nil), // Munlock, TODO - 151: syscalls.Error(nil), // Mlockall, TODO - 152: syscalls.Error(nil), // Munlockall, TODO + 148: syscalls.ErrorWithEvent(syscall.EPERM), // SchedRrGetInterval, + 149: Mlock, + 150: Munlock, + 151: Mlockall, + 152: Munlockall, 153: syscalls.CapError(linux.CAP_SYS_TTY_CONFIG), // Vhangup, 154: syscalls.Error(syscall.EPERM), // ModifyLdt, 155: syscalls.Error(syscall.EPERM), // PivotRoot, @@ -373,8 +373,9 @@ var AMD64 = &kernel.SyscallTable{ // 322: Execveat, TODO // 323: Userfaultfd, TODO // 324: Membarrier, TODO - // Syscalls after 325 are backports from 4.6. - 325: syscalls.Error(nil), // Mlock2, TODO + 325: Mlock2, + // Syscalls after 325 are "backports" from versions of Linux after 4.4. + // 326: CopyFileRange, 327: Preadv2, 328: Pwritev2, }, diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 145f7846c..8732861e0 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -69,6 +69,9 @@ func Mmap(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallC GrowsDown: linux.MAP_GROWSDOWN&flags != 0, Precommit: linux.MAP_POPULATE&flags != 0, } + if linux.MAP_LOCKED&flags != 0 { + opts.MLockMode = memmap.MLockEager + } defer func() { if opts.MappingIdentity != nil { opts.MappingIdentity.DecRef() @@ -384,16 +387,6 @@ func Msync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall length := args[1].SizeT() flags := args[2].Int() - if addr != addr.RoundDown() { - return 0, nil, syserror.EINVAL - } - if length == 0 { - return 0, nil, nil - } - la, ok := usermem.Addr(length).RoundUp() - if !ok { - return 0, nil, syserror.ENOMEM - } // "The flags argument should specify exactly one of MS_ASYNC and MS_SYNC, // and may additionally include the MS_INVALIDATE bit. ... However, Linux // permits a call to msync() that specifies neither of these flags, with @@ -406,39 +399,72 @@ func Msync(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall if sync && flags&linux.MS_ASYNC != 0 { return 0, nil, syserror.EINVAL } + err := t.MemoryManager().MSync(t, addr, uint64(length), mm.MSyncOpts{ + Sync: sync, + Invalidate: flags&linux.MS_INVALIDATE != 0, + }) + // MSync calls fsync, the same interrupt conversion rules apply, see + // mm/msync.c, fsync POSIX.1-2008. + return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) +} + +// Mlock implements linux syscall mlock(2). +func Mlock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + length := args[1].SizeT() + + return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), memmap.MLockEager) +} - // MS_INVALIDATE "asks to invalidate other mappings of the same file (so - // that they can be updated with the fresh values just written)". This is a - // no-op given that shared memory exists. However, MS_INVALIDATE can also - // be used to detect mlocks: "EBUSY: MS_INVALIDATE was specified in flags, - // and a memory lock exists for the specified address range." Given that - // mlock is stubbed out, it's unsafe to pass MS_INVALIDATE silently since - // some user program could be using it for synchronization. - if flags&linux.MS_INVALIDATE != 0 { +// Mlock2 implements linux syscall mlock2(2). +func Mlock2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + length := args[1].SizeT() + flags := args[2].Int() + + if flags&^(linux.MLOCK_ONFAULT) != 0 { return 0, nil, syserror.EINVAL } - // MS_SYNC "requests an update and waits for it to complete." - if sync { - err := t.MemoryManager().Sync(t, addr, uint64(la)) - // Sync calls fsync, the same interrupt conversion rules apply, see - // mm/msync.c, fsync POSIX.1-2008. - return 0, nil, syserror.ConvertIntr(err, kernel.ERESTARTSYS) - } - // MS_ASYNC "specifies that an update be scheduled, but the call returns - // immediately". As long as dirty pages are tracked and eventually written - // back, this is a no-op. (Correspondingly: "Since Linux 2.6.19, MS_ASYNC - // is in fact a no-op, since the kernel properly tracks dirty pages and - // flushes them to storage as necessary.") - // - // However: "ENOMEM: The indicated memory (or part of it) was not mapped." - // This applies even for MS_ASYNC. - ar, ok := addr.ToRange(uint64(la)) - if !ok { - return 0, nil, syserror.ENOMEM + + mode := memmap.MLockEager + if flags&linux.MLOCK_ONFAULT != 0 { + mode = memmap.MLockLazy } - mapped := t.MemoryManager().VirtualMemorySizeRange(ar) - if mapped != uint64(la) { - return 0, nil, syserror.ENOMEM + return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), mode) +} + +// Munlock implements linux syscall munlock(2). +func Munlock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + length := args[1].SizeT() + + return 0, nil, t.MemoryManager().MLock(t, addr, uint64(length), memmap.MLockNone) +} + +// Mlockall implements linux syscall mlockall(2). +func Mlockall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + flags := args[0].Int() + + if flags&^(linux.MCL_CURRENT|linux.MCL_FUTURE|linux.MCL_ONFAULT) != 0 { + return 0, nil, syserror.EINVAL } - return 0, nil, nil + + mode := memmap.MLockEager + if flags&linux.MCL_ONFAULT != 0 { + mode = memmap.MLockLazy + } + return 0, nil, t.MemoryManager().MLockAll(t, mm.MLockAllOpts{ + Current: flags&linux.MCL_CURRENT != 0, + Future: flags&linux.MCL_FUTURE != 0, + Mode: mode, + }) +} + +// Munlockall implements linux syscall munlockall(2). +func Munlockall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + return 0, nil, t.MemoryManager().MLockAll(t, mm.MLockAllOpts{ + Current: true, + Future: true, + Mode: memmap.MLockNone, + }) } diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index 2f16e1791..b0b216045 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -90,6 +90,7 @@ var setableLimits = map[limits.LimitType]struct{}{ limits.CPU: {}, limits.Data: {}, limits.FileSize: {}, + limits.MemoryLocked: {}, limits.Stack: {}, // These are not enforced, but we include them here to avoid returning // EPERM, since some apps expect them to succeed. diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index c0b8246b5..03e586688 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1019,6 +1019,22 @@ cc_binary( ], ) +cc_binary( + name = "mlock_test", + testonly = 1, + srcs = ["mlock.cc"], + linkstatic = 1, + deps = [ + "//test/util:capability_util", + "//test/util:cleanup", + "//test/util:memory_util", + "//test/util:multiprocess_util", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], +) + cc_binary( name = "mmap_test", testonly = 1, diff --git a/test/syscalls/linux/mlock.cc b/test/syscalls/linux/mlock.cc new file mode 100644 index 000000000..1d93bff58 --- /dev/null +++ b/test/syscalls/linux/mlock.cc @@ -0,0 +1,345 @@ +// Copyright 2018 Google LLC +// +// 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. + +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "test/util/capability_util.h" +#include "test/util/cleanup.h" +#include "test/util/memory_util.h" +#include "test/util/multiprocess_util.h" +#include "test/util/test_util.h" + +using ::testing::_; + +namespace gvisor { +namespace testing { + +namespace { + +PosixErrorOr CanMlock() { + struct rlimit rlim; + if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { + return PosixError(errno, "getrlimit(RLIMIT_MEMLOCK)"); + } + if (rlim.rlim_cur != 0) { + return true; + } + return HaveCapability(CAP_IPC_LOCK); +} + +// Returns true if the page containing addr is mlocked. +bool IsPageMlocked(uintptr_t addr) { + // This relies on msync(MS_INVALIDATE) interacting correctly with mlocked + // pages, which is tested for by the MsyncInvalidate case below. + int const rv = msync(reinterpret_cast(addr & ~(kPageSize - 1)), + kPageSize, MS_ASYNC | MS_INVALIDATE); + if (rv == 0) { + return false; + } + // This uses TEST_PCHECK_MSG since it's used in subprocesses. + TEST_PCHECK_MSG(errno == EBUSY, "msync failed with unexpected errno"); + return true; +} + +PosixErrorOr ScopedSetSoftRlimit(int resource, rlim_t newval) { + struct rlimit old_rlim; + if (getrlimit(resource, &old_rlim) != 0) { + return PosixError(errno, "getrlimit failed"); + } + struct rlimit new_rlim = old_rlim; + new_rlim.rlim_cur = newval; + if (setrlimit(resource, &new_rlim) != 0) { + return PosixError(errno, "setrlimit failed"); + } + return Cleanup([resource, old_rlim] { + TEST_PCHECK(setrlimit(resource, &old_rlim) == 0); + }); +} + +TEST(MlockTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(MlockTest, ProtNone) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = + ASSERT_NO_ERRNO_AND_VALUE(MmapAnon(kPageSize, PROT_NONE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), + SyscallFailsWithErrno(ENOMEM)); + // ENOMEM is returned because mlock can't populate the page, but it's still + // considered locked. + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(MlockTest, MadviseDontneed) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_THAT(madvise(mapping.ptr(), mapping.len(), MADV_DONTNEED), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(MlockTest, MsyncInvalidate) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_THAT(msync(mapping.ptr(), mapping.len(), MS_ASYNC | MS_INVALIDATE), + SyscallFailsWithErrno(EBUSY)); + EXPECT_THAT(msync(mapping.ptr(), mapping.len(), MS_SYNC | MS_INVALIDATE), + SyscallFailsWithErrno(EBUSY)); +} + +TEST(MlockTest, Fork) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + EXPECT_THAT( + InForkedProcess([&] { TEST_CHECK(!IsPageMlocked(mapping.addr())); }), + IsPosixErrorOkAndHolds(0)); +} + +TEST(MlockTest, RlimitMemlockZero) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), + SyscallFailsWithErrno(EPERM)); +} + +TEST(MlockTest, RlimitMemlockInsufficient) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, kPageSize)); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(2 * kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), + SyscallFailsWithErrno(ENOMEM)); +} + +TEST(MunlockTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +TEST(MunlockTest, NotLocked) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + EXPECT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +// There is currently no test for mlockall(MCL_CURRENT) because the default +// RLIMIT_MEMLOCK of 64 KB is insufficient to actually invoke +// mlockall(MCL_CURRENT). + +TEST(MlockallTest, Future) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + + // Run this test in a separate (single-threaded) subprocess to ensure that a + // background thread doesn't try to mmap a large amount of memory, fail due + // to hitting RLIMIT_MEMLOCK, and explode the process violently. + EXPECT_THAT(InForkedProcess([] { + auto const mapping = + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE) + .ValueOrDie(); + TEST_CHECK(!IsPageMlocked(mapping.addr())); + TEST_PCHECK(mlockall(MCL_FUTURE) == 0); + // Ensure that mlockall(MCL_FUTURE) is turned off before the end + // of the test, as otherwise mmaps may fail unexpectedly. + Cleanup do_munlockall([] { TEST_PCHECK(munlockall() == 0); }); + auto const mapping2 = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + TEST_CHECK(IsPageMlocked(mapping2.addr())); + // Fire munlockall() and check that it disables + // mlockall(MCL_FUTURE). + do_munlockall.Release()(); + auto const mapping3 = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + TEST_CHECK(!IsPageMlocked(mapping2.addr())); + }), + IsPosixErrorOkAndHolds(0)); +} + +TEST(MunlockallTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(munlockall(), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +#ifndef SYS_mlock2 +#ifdef __x86_64__ +#define SYS_mlock2 325 +#endif +#endif + +#ifndef MLOCK_ONFAULT +#define MLOCK_ONFAULT 0x01 // Linux: include/uapi/asm-generic/mman-common.h +#endif + +#ifdef SYS_mlock2 + +int mlock2(void const* addr, size_t len, int flags) { + return syscall(SYS_mlock2, addr, len, flags); +} + +TEST(Mlock2Test, NoFlags) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock2(mapping.ptr(), mapping.len(), 0), SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(Mlock2Test, MlockOnfault) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); + ASSERT_THAT(mlock2(mapping.ptr(), mapping.len(), MLOCK_ONFAULT), + SyscallSucceeds()); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); +} + +TEST(Mlock2Test, UnknownFlags) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE)); + EXPECT_THAT(mlock2(mapping.ptr(), mapping.len(), ~0), + SyscallFailsWithErrno(EINVAL)); +} + +#endif // defined(SYS_mlock2) + +TEST(MapLockedTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto const mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + EXPECT_THAT(munlock(mapping.ptr(), mapping.len()), SyscallSucceeds()); + EXPECT_FALSE(IsPageMlocked(mapping.addr())); +} + +TEST(MapLockedTest, RlimitMemlockZero) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); + EXPECT_THAT( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED), + PosixErrorIs(EPERM, _)); +} + +TEST(MapLockedTest, RlimitMemlockInsufficient) { + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, kPageSize)); + EXPECT_THAT( + MmapAnon(2 * kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED), + PosixErrorIs(EAGAIN, _)); +} + +TEST(MremapLockedTest, Basic) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + + void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), + MREMAP_MAYMOVE, nullptr); + if (addr == MAP_FAILED) { + FAIL() << "mremap failed: " << errno << " (" << strerror(errno) << ")"; + } + mapping.release(); + mapping.reset(addr, 2 * mapping.len()); + EXPECT_TRUE(IsPageMlocked(reinterpret_cast(addr))); +} + +TEST(MremapLockedTest, RlimitMemlockZero) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = + ASSERT_NO_ERRNO_AND_VALUE(ScopedSetSoftRlimit(RLIMIT_MEMLOCK, 0)); + void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), + MREMAP_MAYMOVE, nullptr); + EXPECT_TRUE(addr == MAP_FAILED && errno == EAGAIN) + << "addr = " << addr << ", errno = " << errno; +} + +TEST(MremapLockedTest, RlimitMemlockInsufficient) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(CanMlock())); + auto mapping = ASSERT_NO_ERRNO_AND_VALUE( + MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED)); + EXPECT_TRUE(IsPageMlocked(mapping.addr())); + + if (ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_IPC_LOCK))) { + ASSERT_NO_ERRNO(SetCapability(CAP_IPC_LOCK, false)); + } + Cleanup reset_rlimit = ASSERT_NO_ERRNO_AND_VALUE( + ScopedSetSoftRlimit(RLIMIT_MEMLOCK, mapping.len())); + void* addr = mremap(mapping.ptr(), mapping.len(), 2 * mapping.len(), + MREMAP_MAYMOVE, nullptr); + EXPECT_TRUE(addr == MAP_FAILED && errno == EAGAIN) + << "addr = " << addr << ", errno = " << errno; +} + +} // namespace + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/msync.cc b/test/syscalls/linux/msync.cc index 0ddc621aa..72d90dc78 100644 --- a/test/syscalls/linux/msync.cc +++ b/test/syscalls/linux/msync.cc @@ -43,14 +43,13 @@ class MsyncParameterizedTest : public ::testing::TestWithParam { protected: int msync_flags() const { return std::get<0>(GetParam()); } - PosixErrorOr GetMapping() const { - auto rv = std::get<1>(GetParam())(); - return rv; - } + PosixErrorOr GetMapping() const { return std::get<1>(GetParam())(); } }; -// All valid msync(2) flag combinations (not including MS_INVALIDATE, which -// gVisor doesn't implement). +// All valid msync(2) flag combinations, not including MS_INVALIDATE. ("Linux +// permits a call to msync() that specifies neither [MS_SYNC or MS_ASYNC], with +// semantics that are (currently) equivalent to specifying MS_ASYNC." - +// msync(2)) constexpr std::initializer_list kMsyncFlags = {MS_SYNC, MS_ASYNC, 0}; // Returns functions that return mappings that should be successfully @@ -134,6 +133,15 @@ TEST_P(MsyncFullParamTest, UnalignedAddressFails) { SyscallFailsWithErrno(EINVAL)); } +TEST_P(MsyncFullParamTest, InvalidateUnlockedSucceeds) { + auto m = ASSERT_NO_ERRNO_AND_VALUE(GetMapping()); + EXPECT_THAT(msync(m.ptr(), m.len(), msync_flags() | MS_INVALIDATE), + SyscallSucceeds()); +} + +// The test for MS_INVALIDATE on mlocked pages is in mlock.cc since it requires +// probing for mlock support. + INSTANTIATE_TEST_CASE_P( All, MsyncFullParamTest, ::testing::Combine(::testing::ValuesIn(kMsyncFlags), -- cgit v1.2.3 From b515556519a44d4b6a23590e236bb4f30726b5bf Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Fri, 21 Dec 2018 13:12:32 -0800 Subject: Implement SO_KEEPALIVE, TCP_KEEPIDLE, and TCP_KEEPINTVL. Within gVisor, plumb new socket options to netstack. Within netstack, fix GetSockOpt and SetSockOpt return value logic. PiperOrigin-RevId: 226532229 Change-Id: If40734e119eed633335f40b4c26facbebc791c74 --- pkg/abi/linux/tcp.go | 6 ++ pkg/sentry/socket/epsocket/epsocket.go | 62 +++++++++++- pkg/sentry/socket/unix/transport/unix.go | 13 ++- pkg/tcpip/transport/ping/endpoint.go | 10 +- pkg/tcpip/transport/tcp/endpoint.go | 22 +++-- pkg/tcpip/transport/udp/endpoint.go | 10 +- test/syscalls/linux/socket_ip_tcp_generic.cc | 136 ++++++++++++++++++++++++++- 7 files changed, 243 insertions(+), 16 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/tcp.go b/pkg/abi/linux/tcp.go index 7586ada42..67908deb9 100644 --- a/pkg/abi/linux/tcp.go +++ b/pkg/abi/linux/tcp.go @@ -52,3 +52,9 @@ const ( TCP_ZEROCOPY_RECEIVE = 35 TCP_INQ = 36 ) + +// Socket constants from include/net/tcp.h. +const ( + MAX_TCP_KEEPIDLE = 32767 + MAX_TCP_KEEPINTVL = 32767 +) diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index ab5d82183..89580e83a 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -636,7 +636,13 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family if outLen < sizeOfInt32 { return nil, syserr.ErrInvalidArgument } - return int32(0), nil + + var v tcpip.KeepaliveEnabledOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(v), nil case linux.SO_LINGER: if outLen < syscall.SizeofLinger { @@ -720,6 +726,30 @@ func getSockOptTCP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interfa return int32(v), nil + case linux.TCP_KEEPIDLE: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.KeepaliveIdleOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(time.Duration(v) / time.Second), nil + + case linux.TCP_KEEPINTVL: + if outLen < sizeOfInt32 { + return nil, syserr.ErrInvalidArgument + } + + var v tcpip.KeepaliveIntervalOption + if err := ep.GetSockOpt(&v); err != nil { + return nil, syserr.TranslateNetstackError(err) + } + + return int32(time.Duration(v) / time.Second), nil + case linux.TCP_INFO: var v tcpip.TCPInfoOption if err := ep.GetSockOpt(&v); err != nil { @@ -843,6 +873,14 @@ func setSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i v := usermem.ByteOrder.Uint32(optVal) return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.PasscredOption(v))) + case linux.SO_KEEPALIVE: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.KeepaliveEnabledOption(v))) + case linux.SO_SNDTIMEO: if len(optVal) < linux.SizeOfTimeval { return syserr.ErrInvalidArgument @@ -916,6 +954,28 @@ func setSockOptTCP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) * v := usermem.ByteOrder.Uint32(optVal) return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.QuickAckOption(v))) + case linux.TCP_KEEPIDLE: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + if v < 1 || v > linux.MAX_TCP_KEEPIDLE { + return syserr.ErrInvalidArgument + } + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.KeepaliveIdleOption(time.Second * time.Duration(v)))) + + case linux.TCP_KEEPINTVL: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + if v < 1 || v > linux.MAX_TCP_KEEPINTVL { + return syserr.ErrInvalidArgument + } + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.KeepaliveIntervalOption(time.Second * time.Duration(v)))) + case linux.TCP_REPAIR_OPTIONS: t.Kernel().EmitUnimplementedEvent(t) diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go index e98096d7b..12b1576bd 100644 --- a/pkg/sentry/socket/unix/transport/unix.go +++ b/pkg/sentry/socket/unix/transport/unix.go @@ -837,6 +837,7 @@ func (e *baseEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { switch o := opt.(type) { case tcpip.ErrorOption: return nil + case *tcpip.SendQueueSizeOption: e.Lock() if !e.Connected() { @@ -850,6 +851,7 @@ func (e *baseEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { } *o = qs return nil + case *tcpip.ReceiveQueueSizeOption: e.Lock() if !e.Connected() { @@ -863,6 +865,7 @@ func (e *baseEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { } *o = qs return nil + case *tcpip.PasscredOption: if e.Passcred() { *o = tcpip.PasscredOption(1) @@ -870,6 +873,7 @@ func (e *baseEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = tcpip.PasscredOption(0) } return nil + case *tcpip.SendBufferSizeOption: e.Lock() if !e.Connected() { @@ -883,6 +887,7 @@ func (e *baseEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { } *o = qs return nil + case *tcpip.ReceiveBufferSizeOption: e.Lock() if e.receiver == nil { @@ -896,8 +901,14 @@ func (e *baseEndpoint) GetSockOpt(opt interface{}) *tcpip.Error { } *o = qs return nil + + case *tcpip.KeepaliveEnabledOption: + *o = 0 + return nil + + default: + return tcpip.ErrUnknownProtocolOption } - return tcpip.ErrUnknownProtocolOption } // Shutdown closes the read and/or write end of the endpoint connection to its diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index 10d4d138e..d1b9b136c 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -358,9 +358,15 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = 1 } e.rcvMu.Unlock() - } + return nil - return tcpip.ErrUnknownProtocolOption + case *tcpip.KeepaliveEnabledOption: + *o = 0 + return nil + + default: + return tcpip.ErrUnknownProtocolOption + } } func sendPing4(r *stack.Route, ident uint16, data buffer.View) *tcpip.Error { diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 37d4c8f9e..c549132f0 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -662,7 +662,6 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { } else { atomic.StoreUint32(&e.delay, 1) } - return nil case tcpip.CorkOption: @@ -674,7 +673,6 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { } else { atomic.StoreUint32(&e.cork, 1) } - return nil case tcpip.ReuseAddressOption: @@ -689,7 +687,6 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { } else { atomic.StoreUint32(&e.slowAck, 0) } - return nil case tcpip.ReceiveBufferSizeOption: @@ -754,7 +751,6 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { e.sndBufMu.Lock() e.sndBufSize = size e.sndBufMu.Unlock() - return nil case tcpip.V6OnlyOption: @@ -772,34 +768,39 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { } e.v6only = v != 0 + return nil case tcpip.KeepaliveEnabledOption: e.keepalive.Lock() e.keepalive.enabled = v != 0 e.keepalive.Unlock() e.notifyProtocolGoroutine(notifyKeepaliveChanged) + return nil case tcpip.KeepaliveIdleOption: e.keepalive.Lock() e.keepalive.idle = time.Duration(v) e.keepalive.Unlock() e.notifyProtocolGoroutine(notifyKeepaliveChanged) + return nil case tcpip.KeepaliveIntervalOption: e.keepalive.Lock() e.keepalive.interval = time.Duration(v) e.keepalive.Unlock() e.notifyProtocolGoroutine(notifyKeepaliveChanged) + return nil case tcpip.KeepaliveCountOption: e.keepalive.Lock() e.keepalive.count = int(v) e.keepalive.Unlock() e.notifyProtocolGoroutine(notifyKeepaliveChanged) + return nil + default: + return nil } - - return nil } // readyReceiveSize returns the number of bytes ready to be received. @@ -908,7 +909,6 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { o.RTTVar = snd.rtt.rttvar snd.rtt.Unlock() } - return nil case *tcpip.KeepaliveEnabledOption: @@ -920,25 +920,29 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { if v { *o = 1 } + return nil case *tcpip.KeepaliveIdleOption: e.keepalive.Lock() *o = tcpip.KeepaliveIdleOption(e.keepalive.idle) e.keepalive.Unlock() + return nil case *tcpip.KeepaliveIntervalOption: e.keepalive.Lock() *o = tcpip.KeepaliveIntervalOption(e.keepalive.interval) e.keepalive.Unlock() + return nil case *tcpip.KeepaliveCountOption: e.keepalive.Lock() *o = tcpip.KeepaliveCountOption(e.keepalive.count) e.keepalive.Unlock() + return nil + default: + return tcpip.ErrUnknownProtocolOption } - - return tcpip.ErrUnknownProtocolOption } func (e *endpoint) checkV4Mapped(addr *tcpip.FullAddress) (tcpip.NetworkProtocolNumber, *tcpip.Error) { diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 57b875680..67e9ca0ac 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -505,15 +505,21 @@ func (e *endpoint) GetSockOpt(opt interface{}) *tcpip.Error { *o = 1 } e.rcvMu.Unlock() + return nil case *tcpip.MulticastTTLOption: e.mu.Lock() *o = tcpip.MulticastTTLOption(e.multicastTTL) e.mu.Unlock() return nil - } - return tcpip.ErrUnknownProtocolOption + case *tcpip.KeepaliveEnabledOption: + *o = 0 + return nil + + default: + return tcpip.ErrUnknownProtocolOption + } } // sendUDP sends a UDP segment via the provided network endpoint and under the diff --git a/test/syscalls/linux/socket_ip_tcp_generic.cc b/test/syscalls/linux/socket_ip_tcp_generic.cc index bb5a83c9a..81508263b 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic.cc +++ b/test/syscalls/linux/socket_ip_tcp_generic.cc @@ -296,7 +296,7 @@ TEST_P(TCPSocketPairTest, TCPCorkDefault) { getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_CORK, &get, &get_len), SyscallSucceedsWithValue(0)); EXPECT_EQ(get_len, sizeof(get)); - EXPECT_EQ(get, 0); + EXPECT_EQ(get, kSockOptOff); } TEST_P(TCPSocketPairTest, SetTCPCork) { @@ -388,5 +388,139 @@ TEST_P(TCPSocketPairTest, SetTCPQuickAck) { EXPECT_EQ(get, kSockOptOn); } +TEST_P(TCPSocketPairTest, SoKeepaliveDefault) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + int get = -1; + socklen_t get_len = sizeof(get); + EXPECT_THAT( + getsockopt(sockets->first_fd(), SOL_SOCKET, SO_KEEPALIVE, &get, &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, kSockOptOff); +} + +TEST_P(TCPSocketPairTest, SetSoKeepalive) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_KEEPALIVE, + &kSockOptOn, sizeof(kSockOptOn)), + SyscallSucceeds()); + + int get = -1; + socklen_t get_len = sizeof(get); + EXPECT_THAT( + getsockopt(sockets->first_fd(), SOL_SOCKET, SO_KEEPALIVE, &get, &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, kSockOptOn); + + ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_KEEPALIVE, + &kSockOptOff, sizeof(kSockOptOff)), + SyscallSucceeds()); + + EXPECT_THAT( + getsockopt(sockets->first_fd(), SOL_SOCKET, SO_KEEPALIVE, &get, &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, kSockOptOff); +} + +TEST_P(TCPSocketPairTest, TCPKeepidleDefault) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + int get = -1; + socklen_t get_len = sizeof(get); + EXPECT_THAT(getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPIDLE, &get, + &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, 2 * 60 * 60); // 2 hours. +} + +TEST_P(TCPSocketPairTest, TCPKeepintvlDefault) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + int get = -1; + socklen_t get_len = sizeof(get); + EXPECT_THAT(getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPINTVL, &get, + &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, 75); // 75 seconds. +} + +TEST_P(TCPSocketPairTest, SetTCPKeepidleZero) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + constexpr int kZero = 0; + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPIDLE, &kZero, + sizeof(kZero)), + SyscallFailsWithErrno(EINVAL)); +} + +TEST_P(TCPSocketPairTest, SetTCPKeepintvlZero) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + constexpr int kZero = 0; + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPINTVL, + &kZero, sizeof(kZero)), + SyscallFailsWithErrno(EINVAL)); +} + +// Copied from include/net/tcp.h. +constexpr int MAX_TCP_KEEPIDLE = 32767; +constexpr int MAX_TCP_KEEPINTVL = 32767; + +TEST_P(TCPSocketPairTest, SetTCPKeepidleAboveMax) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + constexpr int kAboveMax = MAX_TCP_KEEPIDLE + 1; + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPIDLE, + &kAboveMax, sizeof(kAboveMax)), + SyscallFailsWithErrno(EINVAL)); +} + +TEST_P(TCPSocketPairTest, SetTCPKeepintvlAboveMax) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + constexpr int kAboveMax = MAX_TCP_KEEPINTVL + 1; + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPINTVL, + &kAboveMax, sizeof(kAboveMax)), + SyscallFailsWithErrno(EINVAL)); +} + +TEST_P(TCPSocketPairTest, SetTCPKeepidleToMax) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPIDLE, + &MAX_TCP_KEEPIDLE, sizeof(MAX_TCP_KEEPIDLE)), + SyscallSucceedsWithValue(0)); + + int get = -1; + socklen_t get_len = sizeof(get); + EXPECT_THAT(getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPIDLE, &get, + &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, MAX_TCP_KEEPIDLE); +} + +TEST_P(TCPSocketPairTest, SetTCPKeepintvlToMax) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPINTVL, + &MAX_TCP_KEEPINTVL, sizeof(MAX_TCP_KEEPINTVL)), + SyscallSucceedsWithValue(0)); + + int get = -1; + socklen_t get_len = sizeof(get); + EXPECT_THAT(getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPINTVL, &get, + &get_len), + SyscallSucceedsWithValue(0)); + EXPECT_EQ(get_len, sizeof(get)); + EXPECT_EQ(get, MAX_TCP_KEEPINTVL); +} + } // namespace testing } // namespace gvisor -- cgit v1.2.3 From b709997d78a9504d1d9a14eb2dffae327cd69238 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 3 Jan 2019 13:52:30 -0800 Subject: Rename linux.Errno.Error to linux.Errno.String. Using linux.Errno as an error doesn't work very well as none of the sentry code expects error to contain a linux.Errno. This moves using syserr.Error.ToLinux as an error in a syscall handler from a runtime error to a compile error. PiperOrigin-RevId: 227744312 Change-Id: Iea63108a5b198296c908614e09c01733dd684da0 --- pkg/abi/linux/errors.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go index 01e4095b8..e5f6f3f07 100644 --- a/pkg/abi/linux/errors.go +++ b/pkg/abi/linux/errors.go @@ -25,8 +25,8 @@ func (e *Errno) Number() int { return e.number } -// Error implements error.Error. -func (e *Errno) Error() string { +// String implements fmt.Stringer.String. +func (e *Errno) String() string { return e.name } -- cgit v1.2.3 From dc8450b5676d4c4ac9bcfa23cabd862e0060527d Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Mon, 14 Jan 2019 20:33:29 -0800 Subject: Remove fs.Handle, ramfs.Entry, and all the DeprecatedFileOperations. More helper structs have been added to the fsutil package to make it easier to implement fs.InodeOperations and fs.FileOperations. PiperOrigin-RevId: 229305982 Change-Id: Ib6f8d3862f4216745116857913dbfa351530223b --- pkg/abi/linux/fs.go | 2 + pkg/sentry/fs/BUILD | 3 +- pkg/sentry/fs/anon/anon.go | 16 +- pkg/sentry/fs/ashmem/BUILD | 1 + pkg/sentry/fs/ashmem/area.go | 16 +- pkg/sentry/fs/ashmem/device.go | 133 +-------- pkg/sentry/fs/attr.go | 47 +++ pkg/sentry/fs/binder/BUILD | 2 +- pkg/sentry/fs/binder/binder.go | 135 +-------- pkg/sentry/fs/dev/BUILD | 1 + pkg/sentry/fs/dev/dev.go | 29 +- pkg/sentry/fs/dev/fs.go | 2 + pkg/sentry/fs/dev/full.go | 55 ++-- pkg/sentry/fs/dev/null.go | 88 ++++-- pkg/sentry/fs/dev/random.go | 55 ++-- pkg/sentry/fs/dirent.go | 8 +- pkg/sentry/fs/fdpipe/pipe.go | 14 +- pkg/sentry/fs/file_operations.go | 2 +- pkg/sentry/fs/file_overlay_test.go | 7 +- pkg/sentry/fs/filetest/filetest.go | 16 +- pkg/sentry/fs/fsutil/BUILD | 15 - pkg/sentry/fs/fsutil/file.go | 226 ++++++++++----- pkg/sentry/fs/fsutil/fsutil.go | 2 - pkg/sentry/fs/fsutil/handle.go | 128 --------- pkg/sentry/fs/fsutil/handle_test.go | 227 --------------- pkg/sentry/fs/fsutil/inode.go | 409 ++++++++++++++------------ pkg/sentry/fs/fsutil/inode_cached_test.go | 14 +- pkg/sentry/fs/gofer/file.go | 2 +- pkg/sentry/fs/gofer/fs.go | 14 +- pkg/sentry/fs/gofer/inode.go | 1 - pkg/sentry/fs/host/file.go | 4 +- pkg/sentry/fs/host/fs.go | 2 + pkg/sentry/fs/host/inode.go | 1 - pkg/sentry/fs/inode.go | 29 +- pkg/sentry/fs/inode_operations.go | 80 ------ pkg/sentry/fs/inode_overlay.go | 13 - pkg/sentry/fs/inode_overlay_test.go | 62 +++- pkg/sentry/fs/mock.go | 11 - pkg/sentry/fs/mount.go | 14 +- pkg/sentry/fs/mounts_test.go | 15 +- pkg/sentry/fs/proc/BUILD | 4 +- pkg/sentry/fs/proc/cpuinfo.go | 41 +-- pkg/sentry/fs/proc/exec_args.go | 57 +++- pkg/sentry/fs/proc/fds.go | 138 +++++---- pkg/sentry/fs/proc/file.go | 58 ---- pkg/sentry/fs/proc/inode.go | 96 +++++++ pkg/sentry/fs/proc/net.go | 55 ++-- pkg/sentry/fs/proc/proc.go | 152 +++++----- pkg/sentry/fs/proc/rpcinet_proc.go | 246 ++++++++-------- pkg/sentry/fs/proc/seqfile/BUILD | 7 +- pkg/sentry/fs/proc/seqfile/seqfile.go | 133 ++++++--- pkg/sentry/fs/proc/seqfile/seqfile_test.go | 45 +-- pkg/sentry/fs/proc/sys.go | 116 +++++--- pkg/sentry/fs/proc/sys_net.go | 325 +++++++++++++-------- pkg/sentry/fs/proc/sys_net_state.go | 17 +- pkg/sentry/fs/proc/sys_net_test.go | 28 +- pkg/sentry/fs/proc/task.go | 264 +++++++++++------ pkg/sentry/fs/proc/uid_gid_map.go | 17 +- pkg/sentry/fs/proc/uptime.go | 40 ++- pkg/sentry/fs/ramfs/BUILD | 6 +- pkg/sentry/fs/ramfs/dir.go | 223 +++++++++++---- pkg/sentry/fs/ramfs/file.go | 150 ---------- pkg/sentry/fs/ramfs/ramfs.go | 441 ----------------------------- pkg/sentry/fs/ramfs/socket.go | 48 +++- pkg/sentry/fs/ramfs/symlink.go | 67 +++-- pkg/sentry/fs/ramfs/test/BUILD | 16 -- pkg/sentry/fs/ramfs/test/test.go | 46 --- pkg/sentry/fs/ramfs/tree.go | 3 +- pkg/sentry/fs/ramfs/tree_test.go | 2 +- pkg/sentry/fs/sys/BUILD | 3 +- pkg/sentry/fs/sys/devices.go | 51 ++-- pkg/sentry/fs/sys/fs.go | 2 + pkg/sentry/fs/sys/sys.go | 10 +- pkg/sentry/fs/timerfd/timerfd.go | 12 +- pkg/sentry/fs/tmpfs/BUILD | 2 + pkg/sentry/fs/tmpfs/file_regular.go | 14 +- pkg/sentry/fs/tmpfs/file_test.go | 6 +- pkg/sentry/fs/tmpfs/fs.go | 2 + pkg/sentry/fs/tmpfs/inode_file.go | 112 ++++---- pkg/sentry/fs/tmpfs/tmpfs.go | 164 +++++++++-- pkg/sentry/fs/tty/BUILD | 2 - pkg/sentry/fs/tty/dir.go | 108 ++----- pkg/sentry/fs/tty/inode.go | 145 ---------- pkg/sentry/fs/tty/master.go | 23 +- pkg/sentry/fs/tty/slave.go | 25 +- pkg/sentry/kernel/epoll/epoll.go | 12 +- pkg/sentry/kernel/eventfd/eventfd.go | 14 +- pkg/sentry/kernel/pipe/node.go | 40 +-- pkg/sentry/kernel/pipe/node_test.go | 36 +-- pkg/sentry/kernel/pipe/pipe.go | 31 +- pkg/sentry/kernel/pipe/reader_writer.go | 10 +- pkg/sentry/loader/vdso.go | 48 ++-- pkg/sentry/socket/epsocket/epsocket.go | 10 +- pkg/sentry/socket/hostinet/socket.go | 10 +- pkg/sentry/socket/netlink/socket.go | 10 +- pkg/sentry/socket/rpcinet/socket.go | 10 +- pkg/sentry/socket/socket.go | 18 +- pkg/sentry/socket/unix/unix.go | 10 +- runsc/boot/fs.go | 4 +- test/syscalls/linux/proc.cc | 5 + 100 files changed, 2547 insertions(+), 3144 deletions(-) delete mode 100644 pkg/sentry/fs/fsutil/handle.go delete mode 100644 pkg/sentry/fs/fsutil/handle_test.go delete mode 100644 pkg/sentry/fs/proc/file.go create mode 100644 pkg/sentry/fs/proc/inode.go delete mode 100644 pkg/sentry/fs/ramfs/file.go delete mode 100644 pkg/sentry/fs/ramfs/ramfs.go delete mode 100644 pkg/sentry/fs/ramfs/test/BUILD delete mode 100644 pkg/sentry/fs/ramfs/test/test.go delete mode 100644 pkg/sentry/fs/tty/inode.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index 0b1c9f3db..a9f2ba132 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -22,8 +22,10 @@ const ( DEVPTS_SUPER_MAGIC = 0x00001cd1 OVERLAYFS_SUPER_MAGIC = 0x794c7630 PIPEFS_MAGIC = 0x50495045 + PROC_SUPER_MAGIC = 0x9fa0 RAMFS_MAGIC = 0x09041934 SOCKFS_MAGIC = 0x534F434B + SYSFS_MAGIC = 0x62656572 TMPFS_MAGIC = 0x01021994 V9FS_MAGIC = 0x01021997 ) diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 0fe2b14bf..6f368b0da 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -94,7 +94,8 @@ go_test( deps = [ ":fs", "//pkg/sentry/context", - "//pkg/sentry/fs/ramfs/test", + "//pkg/sentry/fs/fsutil", + "//pkg/sentry/fs/ramfs", "//pkg/sentry/fs/tmpfs", "//pkg/sentry/kernel/contexttest", "//pkg/sentry/usermem", diff --git a/pkg/sentry/fs/anon/anon.go b/pkg/sentry/fs/anon/anon.go index 743cf511f..a5e8c4f0d 100644 --- a/pkg/sentry/fs/anon/anon.go +++ b/pkg/sentry/fs/anon/anon.go @@ -28,16 +28,12 @@ import ( // with any real filesystem. Some types depend on completely pseudo // "anon" inodes (eventfds, epollfds, etc). func NewInode(ctx context.Context) *fs.Inode { - return fs.NewInode(fsutil.NewSimpleInodeOperations(fsutil.InodeSimpleAttributes{ - FSType: linux.ANON_INODE_FS_MAGIC, - UAttr: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: fs.FileOwnerFromContext(ctx), - Perms: fs.FilePermissions{ - User: fs.PermMask{Read: true, Write: true}, - }, - Links: 1, - }), - }), fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{ + iops := &fsutil.SimpleFileInode{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.RootOwner, fs.FilePermissions{ + User: fs.PermMask{Read: true, Write: true}, + }, linux.ANON_INODE_FS_MAGIC), + } + return fs.NewInode(iops, fs.NewPseudoMountSource(), fs.StableAttr{ Type: fs.Anonymous, DeviceID: PseudoDevice.DeviceID(), InodeID: PseudoDevice.NextIno(), diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index 44ef82e64..2463111a8 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -28,6 +28,7 @@ go_library( "//pkg/sentry/usage", "//pkg/sentry/usermem", "//pkg/syserror", + "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index d7dd2c084..7c1b11464 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -28,6 +28,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usage" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) const ( @@ -42,9 +43,10 @@ const ( // // +stateify savable type Area struct { - fsutil.NoFsync `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` ad *Device @@ -98,11 +100,6 @@ func (a *Area) Write(ctx context.Context, file *fs.File, src usermem.IOSequence, return 0, syserror.ENOSYS } -// Flush implements fs.FileOperations.Flush. -func (a *Area) Flush(ctx context.Context, file *fs.File) error { - return nil -} - // ConfigureMMap implements fs.FileOperations.ConfigureMMap. func (a *Area) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.MMapOpts) error { a.mu.Lock() @@ -122,8 +119,7 @@ func (a *Area) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.MM return syserror.ENOMEM } tmpfsInodeOps := tmpfs.NewInMemoryFile(ctx, usage.Tmpfs, fs.UnstableAttr{}, k) - // This is not backed by a real filesystem, so we pass in nil. - tmpfsInode := fs.NewInode(tmpfsInodeOps, fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{}) + tmpfsInode := fs.NewInode(tmpfsInodeOps, fs.NewPseudoMountSource(), fs.StableAttr{}) dirent := fs.NewDirent(tmpfsInode, namePrefix+"/"+a.name) tmpfsFile, err := tmpfsInode.GetFile(ctx, dirent, fs.FileFlags{Read: true, Write: true}) // Drop the extra reference on the Dirent. diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index 962da141b..5369d1b0d 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -16,49 +16,40 @@ package ashmem import ( - "sync" - + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" ) // Device implements fs.InodeOperations. // // +stateify savable type Device struct { - fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` - fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` fsutil.InodeNotSymlink `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` - mu sync.Mutex `state:"nosave"` - unstable fs.UnstableAttr + fsutil.InodeSimpleAttributes } +var _ fs.InodeOperations = (*Device)(nil) + // NewDevice creates and intializes a Device structure. func NewDevice(ctx context.Context, owner fs.FileOwner, fp fs.FilePermissions) *Device { return &Device{ - unstable: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: owner, - Perms: fp, - Links: 1, - }), + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fp, linux.ANON_INODE_FS_MAGIC), } } -// Release implements fs.InodeOperations.Release. -func (ad *Device) Release(context.Context) {} - // GetFile implements fs.InodeOperations.GetFile. func (ad *Device) GetFile(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { return fs.NewFile(ctx, d, flags, &Area{ @@ -67,105 +58,3 @@ func (ad *Device) GetFile(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) perms: usermem.AnyAccess, }), nil } - -// UnstableAttr implements fs.InodeOperations.UnstableAttr. -func (ad *Device) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - ad.mu.Lock() - defer ad.mu.Unlock() - return ad.unstable, nil -} - -// Check implements fs.InodeOperations.Check. -func (ad *Device) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - -// SetPermissions implements fs.InodeOperations.SetPermissions. -func (ad *Device) SetPermissions(ctx context.Context, inode *fs.Inode, fp fs.FilePermissions) bool { - ad.mu.Lock() - defer ad.mu.Unlock() - ad.unstable.Perms = fp - ad.unstable.StatusChangeTime = time.NowFromContext(ctx) - return true -} - -// SetOwner implements fs.InodeOperations.SetOwner. -func (ad *Device) SetOwner(ctx context.Context, inode *fs.Inode, owner fs.FileOwner) error { - ad.mu.Lock() - defer ad.mu.Unlock() - if owner.UID.Ok() { - ad.unstable.Owner.UID = owner.UID - } - if owner.GID.Ok() { - ad.unstable.Owner.GID = owner.GID - } - return nil -} - -// SetTimestamps implements fs.InodeOperations.SetTimestamps. -func (ad *Device) SetTimestamps(ctx context.Context, inode *fs.Inode, ts fs.TimeSpec) error { - if ts.ATimeOmit && ts.MTimeOmit { - return nil - } - - ad.mu.Lock() - defer ad.mu.Unlock() - - now := time.NowFromContext(ctx) - if !ts.ATimeOmit { - if ts.ATimeSetSystemTime { - ad.unstable.AccessTime = now - } else { - ad.unstable.AccessTime = ts.ATime - } - } - if !ts.MTimeOmit { - if ts.MTimeSetSystemTime { - ad.unstable.ModificationTime = now - } else { - ad.unstable.ModificationTime = ts.MTime - } - } - ad.unstable.StatusChangeTime = now - return nil -} - -// Truncate implements fs.InodeOperations.WriteOut. -// -// Ignored by ashmem. -func (ad *Device) Truncate(ctx context.Context, inode *fs.Inode, size int64) error { - return nil -} - -// AddLink implements fs.InodeOperations.AddLink. -// -// Ashmem doesn't support links, no-op. -func (ad *Device) AddLink() {} - -// DropLink implements fs.InodeOperations.DropLink. -// -// Ashmem doesn't support links, no-op. -func (ad *Device) DropLink() {} - -// NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. -func (ad *Device) NotifyStatusChange(ctx context.Context) { - ad.mu.Lock() - defer ad.mu.Unlock() - now := time.NowFromContext(ctx) - ad.unstable.ModificationTime = now - ad.unstable.StatusChangeTime = now -} - -// IsVirtual implements fs.InodeOperations.IsVirtual. -// -// Ashmem is virtual. -func (ad *Device) IsVirtual() bool { - return true -} - -// StatFS implements fs.InodeOperations.StatFS. -// -// Ashmem doesn't support querying for filesystem info. -func (ad *Device) StatFS(context.Context) (fs.Info, error) { - return fs.Info{}, syserror.ENOSYS -} diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 59e060e3c..3523b068a 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -180,6 +180,53 @@ type UnstableAttr struct { Links uint64 } +// SetOwner sets the owner and group if they are valid. +// +// This method is NOT thread-safe. Callers must prevent concurrent calls. +func (ua *UnstableAttr) SetOwner(ctx context.Context, owner FileOwner) { + if owner.UID.Ok() { + ua.Owner.UID = owner.UID + } + if owner.GID.Ok() { + ua.Owner.GID = owner.GID + } + ua.StatusChangeTime = ktime.NowFromContext(ctx) +} + +// SetPermissions sets the permissions. +// +// This method is NOT thread-safe. Callers must prevent concurrent calls. +func (ua *UnstableAttr) SetPermissions(ctx context.Context, p FilePermissions) { + ua.Perms = p + ua.StatusChangeTime = ktime.NowFromContext(ctx) +} + +// SetTimestamps sets the timestamps according to the TimeSpec. +// +// This method is NOT thread-safe. Callers must prevent concurrent calls. +func (ua *UnstableAttr) SetTimestamps(ctx context.Context, ts TimeSpec) { + if ts.ATimeOmit && ts.MTimeOmit { + return + } + + now := ktime.NowFromContext(ctx) + if !ts.ATimeOmit { + if ts.ATimeSetSystemTime { + ua.AccessTime = now + } else { + ua.AccessTime = ts.ATime + } + } + if !ts.MTimeOmit { + if ts.MTimeSetSystemTime { + ua.ModificationTime = now + } else { + ua.ModificationTime = ts.MTime + } + } + ua.StatusChangeTime = now +} + // WithCurrentTime returns u with AccessTime == ModificationTime == current time. func WithCurrentTime(ctx context.Context, u UnstableAttr) UnstableAttr { t := ktime.NowFromContext(ctx) diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index a077b91d2..27155819e 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -16,11 +16,11 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel", - "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", "//pkg/syserror", + "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index e642c7f22..19cd55e65 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -24,12 +24,12 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/platform" "gvisor.googlesource.com/gvisor/pkg/sentry/usage" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) const ( @@ -43,34 +43,29 @@ const ( // // +stateify savable type Device struct { + fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` - fsutil.InodeNotRenameable `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` fsutil.InodeNotSymlink `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` - // mu protects unstable. - mu sync.Mutex `state:"nosave"` - unstable fs.UnstableAttr + fsutil.InodeSimpleAttributes } +var _ fs.InodeOperations = (*Device)(nil) + // NewDevice creates and intializes a Device structure. func NewDevice(ctx context.Context, owner fs.FileOwner, fp fs.FilePermissions) *Device { return &Device{ - unstable: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: owner, - Perms: fp, - Links: 1, - }), + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fp, 0), } } -// Release implements fs.InodeOperations.Release. -func (bd *Device) Release(context.Context) {} - // GetFile implements fs.InodeOperations.GetFile. // // TODO: Add functionality to GetFile: Additional fields will be @@ -85,115 +80,13 @@ func (bd *Device) GetFile(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) }), nil } -// UnstableAttr implements fs.InodeOperations.UnstableAttr. -func (bd *Device) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - bd.mu.Lock() - defer bd.mu.Unlock() - return bd.unstable, nil -} - -// Check implements fs.InodeOperations.Check. -func (bd *Device) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - -// SetPermissions implements fs.InodeOperations.SetPermissions. -func (bd *Device) SetPermissions(ctx context.Context, inode *fs.Inode, fp fs.FilePermissions) bool { - bd.mu.Lock() - defer bd.mu.Unlock() - bd.unstable.Perms = fp - bd.unstable.StatusChangeTime = time.NowFromContext(ctx) - return true -} - -// SetOwner implements fs.InodeOperations.SetOwner. -func (bd *Device) SetOwner(ctx context.Context, inode *fs.Inode, owner fs.FileOwner) error { - bd.mu.Lock() - defer bd.mu.Unlock() - if owner.UID.Ok() { - bd.unstable.Owner.UID = owner.UID - } - if owner.GID.Ok() { - bd.unstable.Owner.GID = owner.GID - } - return nil -} - -// SetTimestamps implements fs.InodeOperations.SetTimestamps. -func (bd *Device) SetTimestamps(ctx context.Context, inode *fs.Inode, ts fs.TimeSpec) error { - if ts.ATimeOmit && ts.MTimeOmit { - return nil - } - - bd.mu.Lock() - defer bd.mu.Unlock() - - now := time.NowFromContext(ctx) - if !ts.ATimeOmit { - if ts.ATimeSetSystemTime { - bd.unstable.AccessTime = now - } else { - bd.unstable.AccessTime = ts.ATime - } - } - if !ts.MTimeOmit { - if ts.MTimeSetSystemTime { - bd.unstable.ModificationTime = now - } else { - bd.unstable.ModificationTime = ts.MTime - } - } - bd.unstable.StatusChangeTime = now - return nil -} - -// Truncate implements fs.InodeOperations.WriteOut. -// -// Ignored for a character device, such as Binder. -func (bd *Device) Truncate(ctx context.Context, inode *fs.Inode, size int64) error { - return nil -} - -// AddLink implements fs.InodeOperations.AddLink. -// -// Binder doesn't support links, no-op. -func (bd *Device) AddLink() {} - -// DropLink implements fs.InodeOperations.DropLink. -// -// Binder doesn't support links, no-op. -func (bd *Device) DropLink() {} - -// NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. -func (bd *Device) NotifyStatusChange(ctx context.Context) { - bd.mu.Lock() - defer bd.mu.Unlock() - now := time.NowFromContext(ctx) - bd.unstable.ModificationTime = now - bd.unstable.StatusChangeTime = now -} - -// IsVirtual implements fs.InodeOperations.IsVirtual. -// -// Binder is virtual. -func (bd *Device) IsVirtual() bool { - return true -} - -// StatFS implements fs.InodeOperations.StatFS. -// -// Binder doesn't support querying for filesystem info. -func (bd *Device) StatFS(context.Context) (fs.Info, error) { - return fs.Info{}, syserror.ENOSYS -} - // Proc implements fs.FileOperations and fs.IoctlGetter. // // +stateify savable type Proc struct { - fsutil.NoFsync `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` bd *Device task *kernel.Task diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index b17b5202c..b9cfae05f 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -32,5 +32,6 @@ go_library( "//pkg/sentry/safemem", "//pkg/sentry/usermem", "//pkg/syserror", + "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index 3e127bf04..f8e8099f7 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -16,6 +16,8 @@ package dev import ( + "math" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ashmem" @@ -26,13 +28,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// Dev is the root node. -// -// +stateify savable -type Dev struct { - ramfs.Dir -} - func newCharacterDevice(iops fs.InodeOperations, msrc *fs.MountSource) *fs.Inode { return fs.NewInode(iops, msrc, fs.StableAttr{ DeviceID: devDevice.DeviceID(), @@ -43,8 +38,7 @@ func newCharacterDevice(iops fs.InodeOperations, msrc *fs.MountSource) *fs.Inode } func newDirectory(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - iops := &ramfs.Dir{} - iops.InitDir(ctx, map[string]*fs.Inode{}, fs.RootOwner, fs.FilePermsFromMode(0555)) + iops := ramfs.NewDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(iops, msrc, fs.StableAttr{ DeviceID: devDevice.DeviceID(), InodeID: devDevice.NextIno(), @@ -54,8 +48,7 @@ func newDirectory(ctx context.Context, msrc *fs.MountSource) *fs.Inode { } func newSymlink(ctx context.Context, target string, msrc *fs.MountSource) *fs.Inode { - iops := &ramfs.Symlink{} - iops.InitSymlink(ctx, fs.RootOwner, target) + iops := ramfs.NewSymlink(ctx, fs.RootOwner, target) return fs.NewInode(iops, msrc, fs.StableAttr{ DeviceID: devDevice.DeviceID(), InodeID: devDevice.NextIno(), @@ -66,8 +59,6 @@ func newSymlink(ctx context.Context, target string, msrc *fs.MountSource) *fs.In // New returns the root node of a device filesystem. func New(ctx context.Context, msrc *fs.MountSource, binderEnabled bool, ashmemEnabled bool) *fs.Inode { - d := &Dev{} - contents := map[string]*fs.Inode{ "fd": newSymlink(ctx, "/proc/self/fd", msrc), "stdin": newSymlink(ctx, "/proc/self/fd/0", msrc), @@ -114,11 +105,19 @@ func New(ctx context.Context, msrc *fs.MountSource, binderEnabled bool, ashmemEn contents["ashmem"] = newCharacterDevice(ashmem, msrc) } - d.InitDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) - return fs.NewInode(d, msrc, fs.StableAttr{ + iops := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return fs.NewInode(iops, msrc, fs.StableAttr{ DeviceID: devDevice.DeviceID(), InodeID: devDevice.NextIno(), BlockSize: usermem.PageSize, Type: fs.Directory, }) } + +// readZeros implements fs.FileOperations.Read with infinite null bytes. +type readZeros struct{} + +// Read implements fs.FileOperations.Read. +func (readZeros) Read(ctx context.Context, file *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { + return dst.ZeroOut(ctx, math.MaxInt64) +} diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index d96f4f423..abfe689f0 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -33,6 +33,8 @@ const ashmemEnabledKey = "ashmem_enabled" // +stateify savable type filesystem struct{} +var _ fs.Filesystem = (*filesystem)(nil) + func init() { fs.RegisterFilesystem(&filesystem{}) } diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index eeda646ab..cbdd40161 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -15,41 +15,64 @@ package dev import ( - "math" - "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // fullDevice is used to implement /dev/full. // // +stateify savable type fullDevice struct { - ramfs.Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes } +var _ fs.InodeOperations = (*fullDevice)(nil) + func newFullDevice(ctx context.Context, owner fs.FileOwner, mode linux.FileMode) *fullDevice { - f := &fullDevice{} - f.InitEntry(ctx, owner, fs.FilePermsFromMode(mode)) + f := &fullDevice{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fs.FilePermsFromMode(mode), linux.TMPFS_MAGIC), + } return f } -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev by -// returining ENOSPC. -func (f *fullDevice) DeprecatedPwritev(_ context.Context, _ usermem.IOSequence, _ int64) (int64, error) { - return 0, syserror.ENOSPC +// GetFile implements fs.InodeOperations.GetFile. +func (f *fullDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + flags.Pread = true + return fs.NewFile(ctx, dirent, flags, &fullFileOperations{}), nil } -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (f *fullDevice) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, _ int64) (int64, error) { - return dst.ZeroOut(ctx, math.MaxInt64) +// +stateify savable +type fullFileOperations struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + readZeros `state:"nosave"` } -// Truncate should be simply ignored for character devices on linux. -func (f *fullDevice) Truncate(context.Context, *fs.Inode, int64) error { - return nil +var _ fs.FileOperations = (*fullFileOperations)(nil) + +// Write implements FileOperations.Write. +func (fullFileOperations) Write(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, syserror.ENOSPC } diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 68090f353..73fd09058 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -15,78 +15,104 @@ package dev import ( - "io" - "math" - "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/mm" "gvisor.googlesource.com/gvisor/pkg/sentry/platform" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // +stateify savable type nullDevice struct { - ramfs.Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes } +var _ fs.InodeOperations = (*nullDevice)(nil) + func newNullDevice(ctx context.Context, owner fs.FileOwner, mode linux.FileMode) *nullDevice { - n := &nullDevice{} - n.InitEntry(ctx, owner, fs.FilePermsFromMode(mode)) + n := &nullDevice{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fs.FilePermsFromMode(mode), linux.TMPFS_MAGIC), + } return n } -// DeprecatedPreadv reads data from the device. -func (n *nullDevice) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - return 0, io.EOF -} +// GetFile implements fs.FileOperations.GetFile. +func (n *nullDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + flags.Pread = true + flags.Pwrite = true -// DeprecatedPwritev discards writes. -func (n *nullDevice) DeprecatedPwritev(_ context.Context, src usermem.IOSequence, offset int64) (int64, error) { - return src.NumBytes(), nil + return fs.NewFile(ctx, dirent, flags, &nullFileOperations{}), nil } -// Truncate should be simply ignored for character devices on linux. -func (n *nullDevice) Truncate(context.Context, *fs.Inode, int64) error { - return nil +// +stateify savable +type nullFileOperations struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRead `state:"nosave"` + fsutil.FileNoopWrite `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` } +var _ fs.FileOperations = (*nullFileOperations)(nil) + // +stateify savable type zeroDevice struct { nullDevice } +var _ fs.InodeOperations = (*zeroDevice)(nil) + func newZeroDevice(ctx context.Context, owner fs.FileOwner, mode linux.FileMode) *zeroDevice { - zd := &zeroDevice{} - zd.InitEntry(ctx, owner, fs.FilePermsFromMode(mode)) + zd := &zeroDevice{ + nullDevice: nullDevice{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fs.FilePermsFromMode(mode), linux.TMPFS_MAGIC), + }, + } return zd } -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (zd *zeroDevice) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - return dst.ZeroOut(ctx, math.MaxInt64) -} - -// GetFile overrides ramfs.Entry.GetFile and returns a zeroFile instead. +// GetFile implements fs.FileOperations.GetFile. func (zd *zeroDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { - // Allow pread(2) and pwrite(2) on this file. flags.Pread = true flags.Pwrite = true - return fs.NewFile(ctx, dirent, flags, &zeroFileOperations{ - FileOperations: &fsutil.Handle{HandleOperations: dirent.Inode.HandleOps()}, - }), nil + return fs.NewFile(ctx, dirent, flags, &zeroFileOperations{}), nil } // +stateify savable type zeroFileOperations struct { - fs.FileOperations + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoopWrite `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + readZeros `state:"nosave"` } +var _ fs.FileOperations = (*zeroFileOperations)(nil) + // ConfigureMMap implements fs.FileOperations.ConfigureMMap. func (*zeroFileOperations) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.MMapOpts) error { m, err := mm.NewSharedAnonMappable(opts.Length, platform.FromContext(ctx)) diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index 33e4913e4..837b7793a 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -19,37 +19,58 @@ import ( "gvisor.googlesource.com/gvisor/pkg/rand" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // +stateify savable type randomDevice struct { - ramfs.Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes } +var _ fs.InodeOperations = (*randomDevice)(nil) + func newRandomDevice(ctx context.Context, owner fs.FileOwner, mode linux.FileMode) *randomDevice { - r := &randomDevice{} - r.InitEntry(ctx, owner, fs.FilePermsFromMode(mode)) + r := &randomDevice{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fs.FilePermsFromMode(mode), linux.TMPFS_MAGIC), + } return r } -// DeprecatedPreadv reads random data. -func (*randomDevice) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - return dst.CopyOutFrom(ctx, safemem.FromIOReader{rand.Reader}) +// GetFile implements fs.InodeOperations.GetFile. +func (randomDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &randomFileOperations{}), nil } -// DeprecatedPwritev implements fs.HandleOperations.DeprecatedPwritev. -func (*randomDevice) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { - // On Linux, "Writing to /dev/random or /dev/urandom will update the - // entropy pool with the data written, but this will not result in a higher - // entropy count" - random(4). We don't need to support this, but we do - // need to support the write, so just make it a no-op a la /dev/null. - return src.NumBytes(), nil +// +stateify savable +type randomFileOperations struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoopWrite `state:"nosave"` } -// Truncate should be simply ignored for character devices on linux. -func (r *randomDevice) Truncate(context.Context, *fs.Inode, int64) error { - return nil +var _ fs.FileOperations = (*randomFileOperations)(nil) + +// Read implements fs.FileOperations.Read. +func (randomFileOperations) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, _ int64) (int64, error) { + return dst.CopyOutFrom(ctx, safemem.FromIOReader{rand.Reader}) } diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index c4918a11b..d6a19dc81 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -837,8 +837,8 @@ func (d *Dirent) CreateFifo(ctx context.Context, root *Dirent, name string, perm }) } -// getDotAttrs returns the DentAttrs corresponding to "." and ".." directories. -func (d *Dirent) getDotAttrs(root *Dirent) (DentAttr, DentAttr) { +// GetDotAttrs returns the DentAttrs corresponding to "." and ".." directories. +func (d *Dirent) GetDotAttrs(root *Dirent) (DentAttr, DentAttr) { // Get '.'. sattr := d.Inode.StableAttr dot := DentAttr{ @@ -870,7 +870,7 @@ func (d *Dirent) readdirFrozen(root *Dirent, offset int64, dirCtx *DirCtx) (int6 // Collect attrs for "." and "..". attrs := make(map[string]DentAttr) names := []string{".", ".."} - attrs["."], attrs[".."] = d.getDotAttrs(root) + attrs["."], attrs[".."] = d.GetDotAttrs(root) // Get info from all children. d.mu.Lock() @@ -965,7 +965,7 @@ func direntReaddir(ctx context.Context, d *Dirent, it DirIterator, root *Dirent, } // Collect attrs for "." and "..". - dot, dotdot := d.getDotAttrs(root) + dot, dotdot := d.GetDotAttrs(root) // Emit "." and ".." if the offset is low enough. if offset == 0 { diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index e3b830747..b4d11cb45 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -37,13 +37,13 @@ import ( // // +stateify savable type pipeOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` - fsutil.NoIoctl `state:"nosave"` - waiter.Queue `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + waiter.Queue `state:"nosave"` // flags are the flags used to open the pipe. flags fs.FileFlags `state:".(fs.FileFlags)"` diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go index 28e8e233d..81c6e2b5d 100644 --- a/pkg/sentry/fs/file_operations.go +++ b/pkg/sentry/fs/file_operations.go @@ -91,7 +91,7 @@ type FileOperations interface { Flush(ctx context.Context, file *File) error // ConfigureMMap mutates opts to implement mmap(2) for the file. Most - // implementations can either embed fsutil.NoMMap (if they don't support + // implementations can either embed fsutil.FileNoMMap (if they don't support // memory mapping) or call fsutil.GenericConfigureMMap with the appropriate // memmap.Mappable. ConfigureMMap(ctx context.Context, file *File, opts *memmap.MMapOpts) error diff --git a/pkg/sentry/fs/file_overlay_test.go b/pkg/sentry/fs/file_overlay_test.go index f121cbdda..a4ac58763 100644 --- a/pkg/sentry/fs/file_overlay_test.go +++ b/pkg/sentry/fs/file_overlay_test.go @@ -20,7 +20,8 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - ramfstest "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/contexttest" ) @@ -135,7 +136,7 @@ func TestReaddirRevalidation(t *testing.T) { // Get a handle to the dirent in the upper filesystem so that we can // modify it without going through the dirent. - upperDir := upper.InodeOperations.(*dir).InodeOperations.(*ramfstest.Dir) + upperDir := upper.InodeOperations.(*dir).InodeOperations.(*ramfs.Dir) // Check that overlay returns the files from both upper and lower. openDir, err := overlay.GetFile(ctx, fs.NewDirent(overlay, "stub"), fs.FileFlags{Read: true}) @@ -155,7 +156,7 @@ func TestReaddirRevalidation(t *testing.T) { if err := upperDir.Remove(ctx, upper, "a"); err != nil { t.Fatalf("error removing child: %v", err) } - upperDir.AddChild(ctx, "c", fs.NewInode(ramfstest.NewFile(ctx, fs.FilePermissions{}), + upperDir.AddChild(ctx, "c", fs.NewInode(fsutil.NewSimpleFileInode(ctx, fs.RootOwner, fs.FilePermissions{}, 0), upper.MountSource, fs.StableAttr{Type: fs.RegularFile})) // Seek to beginning of the directory and do the readdir again. diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go index 65ca196d9..40d84d9f2 100644 --- a/pkg/sentry/fs/filetest/filetest.go +++ b/pkg/sentry/fs/filetest/filetest.go @@ -31,14 +31,14 @@ import ( // TestFileOperations is an implementation of the File interface. It provides all // required methods. type TestFileOperations struct { - fsutil.NoopRelease `state:"nosave"` - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` - fsutil.NoIoctl `state:"nosave"` - waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } // NewTestFile creates and initializes a new test file. diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 6834e1272..4965e1a5f 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -67,7 +67,6 @@ go_library( "frame_ref_set.go", "frame_ref_set_impl.go", "fsutil.go", - "handle.go", "host_file_mapper.go", "host_file_mapper_state.go", "host_file_mapper_unsafe.go", @@ -96,20 +95,6 @@ go_library( ], ) -go_test( - name = "fsutil_x_test", - size = "small", - srcs = ["handle_test.go"], - deps = [ - ":fsutil", - "//pkg/sentry/context", - "//pkg/sentry/context/contexttest", - "//pkg/sentry/fs", - "//pkg/sentry/fs/ramfs/test", - "//pkg/sentry/usermem", - ], -) - go_test( name = "fsutil_test", size = "small", diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index 46db2e51c..0970f782b 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -24,12 +24,12 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// NoopRelease implements FileOperations.Release for files that have no +// FileNoopRelease implements fs.FileOperations.Release for files that have no // resources to release. -type NoopRelease struct{} +type FileNoopRelease struct{} // Release is a no-op. -func (NoopRelease) Release() {} +func (FileNoopRelease) Release() {} // SeekWithDirCursor is used to implement fs.FileOperations.Seek. If dirCursor // is not nil and the seek was on a directory, the cursor will be updated. @@ -127,71 +127,81 @@ func SeekWithDirCursor(ctx context.Context, file *fs.File, whence fs.SeekWhence, return current, syserror.EINVAL } -// GenericSeek implements FileOperations.Seek for files that use a generic -// seek implementation. -type GenericSeek struct{} +// FileGenericSeek implements fs.FileOperations.Seek for files that use a +// generic seek implementation. +type FileGenericSeek struct{} // Seek implements fs.FileOperations.Seek. -func (GenericSeek) Seek(ctx context.Context, file *fs.File, whence fs.SeekWhence, offset int64) (int64, error) { +func (FileGenericSeek) Seek(ctx context.Context, file *fs.File, whence fs.SeekWhence, offset int64) (int64, error) { return SeekWithDirCursor(ctx, file, whence, offset, nil) } -// ZeroSeek implements FileOperations.Seek for files that maintain a constant -// zero-value offset and require a no-op Seek. -type ZeroSeek struct{} +// FileZeroSeek implements fs.FileOperations.Seek for files that maintain a +// constant zero-value offset and require a no-op Seek. +type FileZeroSeek struct{} -// Seek implements FileOperations.Seek. -func (ZeroSeek) Seek(context.Context, *fs.File, fs.SeekWhence, int64) (int64, error) { +// Seek implements fs.FileOperations.Seek. +func (FileZeroSeek) Seek(context.Context, *fs.File, fs.SeekWhence, int64) (int64, error) { return 0, nil } -// PipeSeek implements FileOperations.Seek and can be used for files that behave -// like pipes (seeking is not supported). -type PipeSeek struct{} +// FileNoSeek implements fs.FileOperations.Seek to return EINVAL. +type FileNoSeek struct{} + +// Seek implements fs.FileOperations.Seek. +func (FileNoSeek) Seek(context.Context, *fs.File, fs.SeekWhence, int64) (int64, error) { + return 0, syserror.EINVAL +} -// Seek implements FileOperations.Seek. -func (PipeSeek) Seek(context.Context, *fs.File, fs.SeekWhence, int64) (int64, error) { +// FilePipeSeek implements fs.FileOperations.Seek and can be used for files +// that behave like pipes (seeking is not supported). +type FilePipeSeek struct{} + +// Seek implements fs.FileOperations.Seek. +func (FilePipeSeek) Seek(context.Context, *fs.File, fs.SeekWhence, int64) (int64, error) { return 0, syserror.ESPIPE } -// NotDirReaddir implements FileOperations.Readdir for non-directories. -type NotDirReaddir struct{} +// FileNotDirReaddir implements fs.FileOperations.Readdir for non-directories. +type FileNotDirReaddir struct{} -// Readdir implements FileOperations.NotDirReaddir. -func (NotDirReaddir) Readdir(context.Context, *fs.File, fs.DentrySerializer) (int64, error) { +// Readdir implements fs.FileOperations.FileNotDirReaddir. +func (FileNotDirReaddir) Readdir(context.Context, *fs.File, fs.DentrySerializer) (int64, error) { return 0, syserror.ENOTDIR } -// NoFsync implements FileOperations.Fsync for files that don't support syncing. -type NoFsync struct{} +// FileNoFsync implements fs.FileOperations.Fsync for files that don't support +// syncing. +type FileNoFsync struct{} -// Fsync implements FileOperations.Fsync. -func (NoFsync) Fsync(context.Context, *fs.File, int64, int64, fs.SyncType) error { +// Fsync implements fs.FileOperations.Fsync. +func (FileNoFsync) Fsync(context.Context, *fs.File, int64, int64, fs.SyncType) error { return syserror.EINVAL } -// NoopFsync implements FileOperations.Fsync for files that don't need to synced. -type NoopFsync struct{} +// FileNoopFsync implements fs.FileOperations.Fsync for files that don't need +// to synced. +type FileNoopFsync struct{} -// Fsync implements FileOperations.Fsync. -func (NoopFsync) Fsync(context.Context, *fs.File, int64, int64, fs.SyncType) error { +// Fsync implements fs.FileOperations.Fsync. +func (FileNoopFsync) Fsync(context.Context, *fs.File, int64, int64, fs.SyncType) error { return nil } -// NoopFlush implements FileOperations.Flush as a no-op. -type NoopFlush struct{} +// FileNoopFlush implements fs.FileOperations.Flush as a no-op. +type FileNoopFlush struct{} -// Flush implements FileOperations.Flush. -func (NoopFlush) Flush(context.Context, *fs.File) error { +// Flush implements fs.FileOperations.Flush. +func (FileNoopFlush) Flush(context.Context, *fs.File) error { return nil } -// NoMMap implements fs.FileOperations.Mappable for files that cannot +// FileNoMMap implements fs.FileOperations.Mappable for files that cannot // be memory mapped. -type NoMMap struct{} +type FileNoMMap struct{} // ConfigureMMap implements fs.FileOperations.ConfigureMMap. -func (NoMMap) ConfigureMMap(context.Context, *fs.File, *memmap.MMapOpts) error { +func (FileNoMMap) ConfigureMMap(context.Context, *fs.File, *memmap.MMapOpts) error { return syserror.ENODEV } @@ -204,26 +214,43 @@ func GenericConfigureMMap(file *fs.File, m memmap.Mappable, opts *memmap.MMapOpt return nil } -// NoIoctl implements fs.FileOperations.Ioctl for files that don't implement -// the ioctl syscall. -type NoIoctl struct{} +// FileNoIoctl implements fs.FileOperations.Ioctl for files that don't +// implement the ioctl syscall. +type FileNoIoctl struct{} // Ioctl implements fs.FileOperations.Ioctl. -func (NoIoctl) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (FileNoIoctl) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { return 0, syserror.ENOTTY } -// DirFileOperations implements FileOperations for directories. +// DirFileOperations implements most of fs.FileOperations for directories, +// except for Readdir which the embedding type must implement. +type DirFileOperations struct { + waiter.AlwaysReady + FileGenericSeek + FileNoFsync + FileNoIoctl + FileNoMMap + FileNoopFlush + FileNoopRelease +} + +// Read implements fs.FileOperations.Read +func (*DirFileOperations) Read(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, syserror.EISDIR +} + +// Write implements fs.FileOperations.Write. +func (*DirFileOperations) Write(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, syserror.EISDIR +} + +// StaticDirFileOperations implements fs.FileOperations for directories with +// static children. // // +stateify savable -type DirFileOperations struct { - waiter.AlwaysReady `state:"nosave"` - NoopRelease `state:"nosave"` - GenericSeek `state:"nosave"` - NoFsync `state:"nosave"` - NoopFlush `state:"nosave"` - NoMMap `state:"nosave"` - NoIoctl `state:"nosave"` +type StaticDirFileOperations struct { + DirFileOperations // dentryMap is a SortedDentryMap used to implement Readdir. dentryMap *fs.SortedDentryMap @@ -233,37 +260,106 @@ type DirFileOperations struct { dirCursor string } -// NewDirFileOperations returns a new DirFileOperations that will iterate the -// given denty map. -func NewDirFileOperations(dentries *fs.SortedDentryMap) *DirFileOperations { - return &DirFileOperations{ +// NewStaticDirFileOperations returns a new StaticDirFileOperations that will +// iterate the given denty map. +func NewStaticDirFileOperations(dentries *fs.SortedDentryMap) *StaticDirFileOperations { + return &StaticDirFileOperations{ dentryMap: dentries, } } // IterateDir implements DirIterator.IterateDir. -func (dfo *DirFileOperations) IterateDir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - n, err := fs.GenericReaddir(dirCtx, dfo.dentryMap) +func (sdfo *StaticDirFileOperations) IterateDir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { + n, err := fs.GenericReaddir(dirCtx, sdfo.dentryMap) return offset + n, err } -// Readdir implements FileOperations.Readdir. -func (dfo *DirFileOperations) Readdir(ctx context.Context, file *fs.File, serializer fs.DentrySerializer) (int64, error) { +// Readdir implements fs.FileOperations.Readdir. +func (sdfo *StaticDirFileOperations) Readdir(ctx context.Context, file *fs.File, serializer fs.DentrySerializer) (int64, error) { root := fs.RootFromContext(ctx) defer root.DecRef() dirCtx := &fs.DirCtx{ Serializer: serializer, - DirCursor: &dfo.dirCursor, + DirCursor: &sdfo.dirCursor, } - return fs.DirentReaddir(ctx, file.Dirent, dfo, root, dirCtx, file.Offset()) + return fs.DirentReaddir(ctx, file.Dirent, sdfo, root, dirCtx, file.Offset()) } -// Read implements FileOperations.Read -func (*DirFileOperations) Read(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { - return 0, syserror.EISDIR +// NoReadWriteFile is a file that does not support reading or writing. +// +// +stateify savable +type NoReadWriteFile struct { + waiter.AlwaysReady `state:"nosave"` + FileGenericSeek `state:"nosave"` + FileNoIoctl `state:"nosave"` + FileNoMMap `state:"nosave"` + FileNoopFsync `state:"nosave"` + FileNoopFlush `state:"nosave"` + FileNoopRelease `state:"nosave"` + FileNoRead `state:"nosave"` + FileNoWrite `state:"nosave"` + FileNotDirReaddir `state:"nosave"` } -// Write implements FileOperations.Write. -func (*DirFileOperations) Write(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { - return 0, syserror.EISDIR +var _ fs.FileOperations = (*NoReadWriteFile)(nil) + +// FileStaticContentReader is a helper to implement fs.FileOperations.Read with +// static content. +// +// +stateify savable +type FileStaticContentReader struct { + // content is immutable. + content []byte +} + +// NewFileStaticContentReader initializes a FileStaticContentReader with the +// given content. +func NewFileStaticContentReader(b []byte) FileStaticContentReader { + return FileStaticContentReader{ + content: b, + } +} + +// Read implements fs.FileOperations.Read. +func (scr *FileStaticContentReader) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { + if offset < 0 { + return 0, syserror.EINVAL + } + if offset >= int64(len(scr.content)) { + return 0, nil + } + n, err := dst.CopyOut(ctx, scr.content[offset:]) + return int64(n), err +} + +// FileNoopWrite implements fs.FileOperations.Write as a noop. +type FileNoopWrite struct{} + +// Write implements fs.FileOperations.Write. +func (FileNoopWrite) Write(_ context.Context, _ *fs.File, src usermem.IOSequence, _ int64) (int64, error) { + return src.NumBytes(), nil +} + +// FileNoRead implements fs.FileOperations.Read to return EINVAL. +type FileNoRead struct{} + +// Read implements fs.FileOperations.Read. +func (FileNoRead) Read(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, syserror.EINVAL +} + +// FileNoWrite implements fs.FileOperations.Write to return EINVAL. +type FileNoWrite struct{} + +// Write implements fs.FileOperations.Write. +func (FileNoWrite) Write(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, syserror.EINVAL +} + +// FileNoopRead implement fs.FileOperations.Read as a noop. +type FileNoopRead struct{} + +// Read implements fs.FileOperations.Read. +func (FileNoopRead) Read(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, nil } diff --git a/pkg/sentry/fs/fsutil/fsutil.go b/pkg/sentry/fs/fsutil/fsutil.go index 3d7f3732d..319c4841b 100644 --- a/pkg/sentry/fs/fsutil/fsutil.go +++ b/pkg/sentry/fs/fsutil/fsutil.go @@ -20,7 +20,5 @@ // - For fs.Inodes that require a page cache to be memory mapped, see // inode_cache.go. // -// - For fs.Files that implement fs.HandleOps, see handle.go. -// // - For anon fs.Inodes, see anon.go. package fsutil diff --git a/pkg/sentry/fs/fsutil/handle.go b/pkg/sentry/fs/fsutil/handle.go deleted file mode 100644 index 8920b72ee..000000000 --- a/pkg/sentry/fs/fsutil/handle.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 fsutil - -import ( - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" - "gvisor.googlesource.com/gvisor/pkg/waiter" -) - -// Handle implements FileOperations. -// -// FIXME: Remove Handle entirely in favor of individual fs.File -// implementations using simple generic utilities. -// -// +stateify savable -type Handle struct { - NoopRelease `state:"nosave"` - NoIoctl `state:"nosave"` - HandleOperations fs.HandleOperations - - // dirCursor is the directory cursor. - dirCursor string -} - -// NewHandle returns a File backed by the Dirent and FileFlags. -func NewHandle(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags, hops fs.HandleOperations) *fs.File { - if !fs.IsPipe(dirent.Inode.StableAttr) && !fs.IsSocket(dirent.Inode.StableAttr) { - // Allow reading/writing at an arbitrary offset for non-pipes - // and non-sockets. - flags.Pread = true - flags.Pwrite = true - } - - return fs.NewFile(ctx, dirent, flags, &Handle{HandleOperations: hops}) -} - -// Readiness implements waiter.Waitable.Readiness. -func (h *Handle) Readiness(mask waiter.EventMask) waiter.EventMask { - return h.HandleOperations.Readiness(mask) -} - -// EventRegister implements waiter.Waitable.EventRegister. -func (h *Handle) EventRegister(e *waiter.Entry, mask waiter.EventMask) { - h.HandleOperations.EventRegister(e, mask) -} - -// EventUnregister implements waiter.Waitable.EventUnregister. -func (h *Handle) EventUnregister(e *waiter.Entry) { - h.HandleOperations.EventUnregister(e) -} - -// Readdir implements FileOperations.Readdir. -func (h *Handle) Readdir(ctx context.Context, file *fs.File, serializer fs.DentrySerializer) (int64, error) { - root := fs.RootFromContext(ctx) - defer root.DecRef() - dirCtx := &fs.DirCtx{ - Serializer: serializer, - DirCursor: &h.dirCursor, - } - n, err := fs.DirentReaddir(ctx, file.Dirent, h, root, dirCtx, file.Offset()) - return n, err -} - -// Seek implements FileOperations.Seek. -func (h *Handle) Seek(ctx context.Context, file *fs.File, whence fs.SeekWhence, offset int64) (int64, error) { - return SeekWithDirCursor(ctx, file, whence, offset, &h.dirCursor) -} - -// IterateDir implements DirIterator.IterateDir. -func (h *Handle) IterateDir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - return h.HandleOperations.DeprecatedReaddir(ctx, dirCtx, offset) -} - -// Read implements FileOperations.Read. -func (h *Handle) Read(ctx context.Context, file *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { - return h.HandleOperations.DeprecatedPreadv(ctx, dst, offset) -} - -// Write implements FileOperations.Write. -func (h *Handle) Write(ctx context.Context, file *fs.File, src usermem.IOSequence, offset int64) (int64, error) { - return h.HandleOperations.DeprecatedPwritev(ctx, src, offset) -} - -// Fsync implements FileOperations.Fsync. -func (h *Handle) Fsync(ctx context.Context, file *fs.File, start int64, end int64, syncType fs.SyncType) error { - switch syncType { - case fs.SyncAll, fs.SyncData: - // Write out metadata. - if err := file.Dirent.Inode.WriteOut(ctx); err != nil { - return err - } - fallthrough - case fs.SyncBackingStorage: - // Use DeprecatedFsync to sync disks. - return h.HandleOperations.DeprecatedFsync() - } - panic("invalid sync type") -} - -// Flush implements FileOperations.Flush. -func (h *Handle) Flush(context.Context, *fs.File) error { - return h.HandleOperations.DeprecatedFlush() -} - -// ConfigureMMap implements FileOperations.ConfigureMMap. -func (h *Handle) ConfigureMMap(ctx context.Context, file *fs.File, opts *memmap.MMapOpts) error { - mappable := file.Dirent.Inode.Mappable() - if mappable == nil { - return syserror.ENODEV - } - return GenericConfigureMMap(file, mappable, opts) -} diff --git a/pkg/sentry/fs/fsutil/handle_test.go b/pkg/sentry/fs/fsutil/handle_test.go deleted file mode 100644 index 43e1a3bdf..000000000 --- a/pkg/sentry/fs/fsutil/handle_test.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 fsutil_test - -import ( - "io" - "syscall" - "testing" - - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" - ramfstest "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" -) - -type testInodeOperations struct { - fs.InodeOperations - fs.InodeType - FileSize int64 - writes uint - reads uint -} - -func (t *testInodeOperations) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - return fs.UnstableAttr{Size: t.FileSize}, nil -} - -// Check implements InodeOperations.Check. -func (t *testInodeOperations) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - -func (t *testInodeOperations) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - t.reads++ - return t.InodeOperations.DeprecatedPreadv(ctx, dst, offset) -} - -func (t *testInodeOperations) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { - t.writes++ - return t.InodeOperations.DeprecatedPwritev(ctx, src, offset) -} - -// testHandle returns a handle for a test node. -// -// The size of the node is fixed at 20 bytes. -func testHandle(t *testing.T, flags fs.FileFlags, nt fs.InodeType) (*fs.File, *testInodeOperations) { - ctx := contexttest.Context(t) - m := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) - n := &testInodeOperations{ - InodeOperations: ramfstest.NewFile(ctx, fs.FilePermissions{User: fs.PermMask{Read: true, Write: true}}), - FileSize: 20, - } - d := fs.NewDirent(fs.NewInode(n, m, fs.StableAttr{Type: nt}), "test") - return fsutil.NewHandle(ctx, d, flags, d.Inode.HandleOps()), n -} - -func TestHandleOps(t *testing.T) { - h, n := testHandle(t, fs.FileFlags{Read: true, Write: true}, fs.RegularFile) - defer h.DecRef() - - // Make sure a write request works. - if n, err := h.Writev(contexttest.Context(t), usermem.BytesIOSequence([]byte("a"))); n != 1 || err != nil { - t.Fatalf("Writev: got (%d, %v), wanted (1, nil)", n, err) - } - if n.writes != 1 { - t.Errorf("found %d writes, expected 1", n.writes) - } - - // Make sure a read request works. - dst := make([]byte, 1) - if n, err := h.Preadv(contexttest.Context(t), usermem.BytesIOSequence(dst), 0); n != 1 || (err != nil && err != io.EOF) { - t.Errorf("Preadv: got (%d, %v), wanted (1, nil or EOF)", n, err) - } - if dst[0] != 'a' { - t.Errorf("Preadv: read %q, wanted 'a'", dst[0]) - } - if n.reads != 1 { - t.Errorf("found %d reads, expected 1", n.reads) - } -} - -type seekTest struct { - whence fs.SeekWhence - offset int64 - result int64 - err error -} - -type seekSuite struct { - nodeType fs.InodeType - cases []seekTest -} - -// FIXME: This is currently missing fs.SeekEnd tests due to the -// fact that NullInodeOperations returns an error on stat. -func TestHandleSeek(t *testing.T) { - ts := []seekSuite{ - { - nodeType: fs.RegularFile, - cases: []seekTest{ - {fs.SeekSet, 0, 0, nil}, - {fs.SeekSet, 10, 10, nil}, - {fs.SeekSet, -5, 10, syscall.EINVAL}, - {fs.SeekCurrent, -1, 9, nil}, - {fs.SeekCurrent, 2, 11, nil}, - {fs.SeekCurrent, -12, 11, syscall.EINVAL}, - {fs.SeekEnd, -1, 19, nil}, - {fs.SeekEnd, 0, 20, nil}, - {fs.SeekEnd, 2, 22, nil}, - }, - }, - { - nodeType: fs.Directory, - cases: []seekTest{ - {fs.SeekSet, 0, 0, nil}, - {fs.SeekSet, 10, 0, syscall.EINVAL}, - {fs.SeekSet, -5, 0, syscall.EINVAL}, - {fs.SeekCurrent, 0, 0, nil}, - {fs.SeekCurrent, 11, 0, syscall.EINVAL}, - {fs.SeekCurrent, -6, 0, syscall.EINVAL}, - {fs.SeekEnd, 0, 0, syscall.EINVAL}, - {fs.SeekEnd, -1, 0, syscall.EINVAL}, - {fs.SeekEnd, 2, 0, syscall.EINVAL}, - }, - }, - { - nodeType: fs.Symlink, - cases: []seekTest{ - {fs.SeekSet, 5, 0, syscall.EINVAL}, - {fs.SeekSet, -5, 0, syscall.EINVAL}, - {fs.SeekSet, 0, 0, syscall.EINVAL}, - {fs.SeekCurrent, 5, 0, syscall.EINVAL}, - {fs.SeekCurrent, -5, 0, syscall.EINVAL}, - {fs.SeekCurrent, 0, 0, syscall.EINVAL}, - {fs.SeekEnd, 5, 0, syscall.EINVAL}, - {fs.SeekEnd, -5, 0, syscall.EINVAL}, - {fs.SeekEnd, 0, 0, syscall.EINVAL}, - }, - }, - { - nodeType: fs.Pipe, - cases: []seekTest{ - {fs.SeekSet, 5, 0, syscall.ESPIPE}, - {fs.SeekSet, -5, 0, syscall.ESPIPE}, - {fs.SeekSet, 0, 0, syscall.ESPIPE}, - {fs.SeekCurrent, 5, 0, syscall.ESPIPE}, - {fs.SeekCurrent, -5, 0, syscall.ESPIPE}, - {fs.SeekCurrent, 0, 0, syscall.ESPIPE}, - {fs.SeekEnd, 5, 0, syscall.ESPIPE}, - {fs.SeekEnd, -5, 0, syscall.ESPIPE}, - {fs.SeekEnd, 0, 0, syscall.ESPIPE}, - }, - }, - { - nodeType: fs.Socket, - cases: []seekTest{ - {fs.SeekSet, 5, 0, syscall.ESPIPE}, - {fs.SeekSet, -5, 0, syscall.ESPIPE}, - {fs.SeekSet, 0, 0, syscall.ESPIPE}, - {fs.SeekCurrent, 5, 0, syscall.ESPIPE}, - {fs.SeekCurrent, -5, 0, syscall.ESPIPE}, - {fs.SeekCurrent, 0, 0, syscall.ESPIPE}, - {fs.SeekEnd, 5, 0, syscall.ESPIPE}, - {fs.SeekEnd, -5, 0, syscall.ESPIPE}, - {fs.SeekEnd, 0, 0, syscall.ESPIPE}, - }, - }, - { - nodeType: fs.CharacterDevice, - cases: []seekTest{ - {fs.SeekSet, 5, 0, nil}, - {fs.SeekSet, -5, 0, nil}, - {fs.SeekSet, 0, 0, nil}, - {fs.SeekCurrent, 5, 0, nil}, - {fs.SeekCurrent, -5, 0, nil}, - {fs.SeekCurrent, 0, 0, nil}, - {fs.SeekEnd, 5, 0, nil}, - {fs.SeekEnd, -5, 0, nil}, - {fs.SeekEnd, 0, 0, nil}, - }, - }, - { - nodeType: fs.BlockDevice, - cases: []seekTest{ - {fs.SeekSet, 0, 0, nil}, - {fs.SeekSet, 10, 10, nil}, - {fs.SeekSet, -5, 10, syscall.EINVAL}, - {fs.SeekCurrent, -1, 9, nil}, - {fs.SeekCurrent, 2, 11, nil}, - {fs.SeekCurrent, -12, 11, syscall.EINVAL}, - {fs.SeekEnd, -1, 19, nil}, - {fs.SeekEnd, 0, 20, nil}, - {fs.SeekEnd, 2, 22, nil}, - }, - }, - } - - for _, s := range ts { - h, _ := testHandle(t, fs.FileFlags{Read: true, Write: true}, s.nodeType) - defer h.DecRef() - - for _, c := range s.cases { - // Try the given seek. - offset, err := h.Seek(contexttest.Context(t), c.whence, c.offset) - if err != c.err { - t.Errorf("seek(%s, %d) on %s had unexpected error: expected %v, got %v", c.whence, c.offset, s.nodeType, c.err, err) - } - if err == nil && offset != c.result { - t.Errorf("seek(%s, %d) on %s had bad result: expected %v, got %v", c.whence, c.offset, s.nodeType, c.result, offset) - } - } - } -} diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index d4db1c2de..f1f5ec1de 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -15,213 +15,270 @@ package fsutil import ( + "sync" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// NewSimpleInodeOperations constructs fs.InodeOperations from InodeSimpleAttributes. -func NewSimpleInodeOperations(i InodeSimpleAttributes) fs.InodeOperations { - return &simpleInodeOperations{InodeSimpleAttributes: i} +// SimpleFileInode is a simple implementation of InodeOperations. +// +// +stateify savable +type SimpleFileInode struct { + InodeGenericChecker `state:"nosave"` + InodeNoExtendedAttributes `state:"nosave"` + InodeNoopRelease `state:"nosave"` + InodeNoopWriteOut `state:"nosave"` + InodeNotDirectory `state:"nosave"` + InodeNotMappable `state:"nosave"` + InodeNotOpenable `state:"nosave"` + InodeNotSocket `state:"nosave"` + InodeNotSymlink `state:"nosave"` + InodeNotTruncatable `state:"nosave"` + InodeNotVirtual `state:"nosave"` + + InodeSimpleAttributes +} + +// NewSimpleFileInode returns a new SimpleFileInode. +func NewSimpleFileInode(ctx context.Context, owner fs.FileOwner, perms fs.FilePermissions, typ uint64) *SimpleFileInode { + return &SimpleFileInode{ + InodeSimpleAttributes: NewInodeSimpleAttributes(ctx, owner, perms, typ), + } } -// simpleInodeOperations is a simple implementation of Inode. +// NoReadWriteFileInode is an implementation of InodeOperations that supports +// opening files that are not readable or writeable. // // +stateify savable -type simpleInodeOperations struct { - DeprecatedFileOperations `state:"nosave"` +type NoReadWriteFileInode struct { + InodeGenericChecker `state:"nosave"` + InodeNoExtendedAttributes `state:"nosave"` + InodeNoopRelease `state:"nosave"` + InodeNoopWriteOut `state:"nosave"` InodeNotDirectory `state:"nosave"` + InodeNotMappable `state:"nosave"` InodeNotSocket `state:"nosave"` - InodeNotRenameable `state:"nosave"` - InodeNotOpenable `state:"nosave"` - InodeNotVirtual `state:"nosave"` InodeNotSymlink `state:"nosave"` - InodeNoExtendedAttributes `state:"nosave"` - NoMappable `state:"nosave"` - NoopWriteOut `state:"nosave"` + InodeNotTruncatable `state:"nosave"` + InodeNotVirtual `state:"nosave"` InodeSimpleAttributes } -// InodeSimpleAttributes implements a subset of the Inode interface. It provides -// read-only access to attributes. +// NewNoReadWriteFileInode returns a new NoReadWriteFileInode. +func NewNoReadWriteFileInode(ctx context.Context, owner fs.FileOwner, perms fs.FilePermissions, typ uint64) *NoReadWriteFileInode { + return &NoReadWriteFileInode{ + InodeSimpleAttributes: NewInodeSimpleAttributes(ctx, owner, perms, typ), + } +} + +// GetFile implements fs.InodeOperations.GetFile. +func (*NoReadWriteFileInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &NoReadWriteFile{}), nil +} + +// InodeSimpleAttributes implements methods for updating in-memory unstable +// attributes. // // +stateify savable type InodeSimpleAttributes struct { - // FSType is the filesystem type reported by StatFS. + // FSType is the immutable filesystem type that will be returned by + // StatFS. FSType uint64 - // UAttr are the unstable attributes of the Inode. - UAttr fs.UnstableAttr + // mu protects unstable. + mu sync.RWMutex `state:"nosave"` + Unstable fs.UnstableAttr } -// Release implements fs.InodeOperations.Release. -func (i *InodeSimpleAttributes) Release(context.Context) {} - -// StatFS implements fs.InodeOperations.StatFS. -func (i *InodeSimpleAttributes) StatFS(context.Context) (fs.Info, error) { - return fs.Info{Type: i.FSType}, nil +// NewInodeSimpleAttributes returns a new InodeSimpleAttributes. +func NewInodeSimpleAttributes(ctx context.Context, owner fs.FileOwner, perms fs.FilePermissions, typ uint64) InodeSimpleAttributes { + return InodeSimpleAttributes{ + FSType: typ, + Unstable: fs.WithCurrentTime(ctx, fs.UnstableAttr{ + Owner: owner, + Perms: perms, + }), + } } // UnstableAttr implements fs.InodeOperations.UnstableAttr. -func (i *InodeSimpleAttributes) UnstableAttr(context.Context, *fs.Inode) (fs.UnstableAttr, error) { - return i.UAttr, nil +func (i *InodeSimpleAttributes) UnstableAttr(ctx context.Context, _ *fs.Inode) (fs.UnstableAttr, error) { + i.mu.RLock() + u := i.Unstable + i.mu.RUnlock() + return u, nil } -// Check implements fs.InodeOperations.Check. -func (i *InodeSimpleAttributes) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) +// SetPermissions implements fs.InodeOperations.SetPermissions. +func (i *InodeSimpleAttributes) SetPermissions(ctx context.Context, _ *fs.Inode, p fs.FilePermissions) bool { + i.mu.Lock() + i.Unstable.SetPermissions(ctx, p) + i.mu.Unlock() + return true +} + +// SetOwner implements fs.InodeOperations.SetOwner. +func (i *InodeSimpleAttributes) SetOwner(ctx context.Context, _ *fs.Inode, owner fs.FileOwner) error { + i.mu.Lock() + i.Unstable.SetOwner(ctx, owner) + i.mu.Unlock() + return nil +} + +// SetTimestamps implements fs.InodeOperations.SetTimestamps. +func (i *InodeSimpleAttributes) SetTimestamps(ctx context.Context, _ *fs.Inode, ts fs.TimeSpec) error { + i.mu.Lock() + i.Unstable.SetTimestamps(ctx, ts) + i.mu.Unlock() + return nil } // AddLink implements fs.InodeOperations.AddLink. -func (*InodeSimpleAttributes) AddLink() {} +func (i *InodeSimpleAttributes) AddLink() { + i.mu.Lock() + i.Unstable.Links++ + i.mu.Unlock() +} // DropLink implements fs.InodeOperations.DropLink. -func (*InodeSimpleAttributes) DropLink() {} - -// NotifyStatusChange implements fs.fs.InodeOperations. -func (i *InodeSimpleAttributes) NotifyStatusChange(ctx context.Context) { - i.UAttr.StatusChangeTime = ktime.NowFromContext(ctx) +func (i *InodeSimpleAttributes) DropLink() { + i.mu.Lock() + i.Unstable.Links-- + i.mu.Unlock() } -// SetPermissions implements fs.InodeOperations.SetPermissions. -func (*InodeSimpleAttributes) SetPermissions(context.Context, *fs.Inode, fs.FilePermissions) bool { - return false +// StatFS implements fs.InodeOperations.StatFS. +func (i *InodeSimpleAttributes) StatFS(context.Context) (fs.Info, error) { + if i.FSType == 0 { + return fs.Info{}, syserror.ENOSYS + } + return fs.Info{Type: i.FSType}, nil } -// SetOwner implements fs.InodeOperations.SetOwner. -func (*InodeSimpleAttributes) SetOwner(context.Context, *fs.Inode, fs.FileOwner) error { - return syserror.EINVAL +// NotifyAccess updates the access time. +func (i *InodeSimpleAttributes) NotifyAccess(ctx context.Context) { + i.mu.Lock() + i.Unstable.AccessTime = ktime.NowFromContext(ctx) + i.mu.Unlock() } -// SetTimestamps implements fs.InodeOperations.SetTimestamps. -func (*InodeSimpleAttributes) SetTimestamps(context.Context, *fs.Inode, fs.TimeSpec) error { - return syserror.EINVAL +// NotifyModification updates the modification time. +func (i *InodeSimpleAttributes) NotifyModification(ctx context.Context) { + i.mu.Lock() + i.Unstable.ModificationTime = ktime.NowFromContext(ctx) + i.mu.Unlock() } -// Truncate implements fs.InodeOperations.Truncate. -func (*InodeSimpleAttributes) Truncate(context.Context, *fs.Inode, int64) error { - return syserror.EINVAL +// NotifyStatusChange updates the status change time. +func (i *InodeSimpleAttributes) NotifyStatusChange(ctx context.Context) { + i.mu.Lock() + i.Unstable.StatusChangeTime = ktime.NowFromContext(ctx) + i.mu.Unlock() } -// InMemoryAttributes implements utilities for updating in-memory unstable -// attributes and extended attributes. It is not thread-safe. -// -// Users need not initialize Xattrs to non-nil (it will be initialized -// when the first extended attribute is set. +// InodeSimpleExtendedAttributes implements +// fs.InodeOperations.{Get,Set,List}xattr. // // +stateify savable -type InMemoryAttributes struct { - Unstable fs.UnstableAttr - Xattrs map[string][]byte +type InodeSimpleExtendedAttributes struct { + // mu protects xattrs. + mu sync.RWMutex `state:"nosave"` + xattrs map[string][]byte } -// SetPermissions updates the permissions to p. -func (i *InMemoryAttributes) SetPermissions(ctx context.Context, p fs.FilePermissions) bool { - i.Unstable.Perms = p - i.Unstable.StatusChangeTime = ktime.NowFromContext(ctx) - return true +// Getxattr implements fs.InodeOperations.Getxattr. +func (i *InodeSimpleExtendedAttributes) Getxattr(_ *fs.Inode, name string) ([]byte, error) { + i.mu.RLock() + value, ok := i.xattrs[name] + i.mu.RUnlock() + if !ok { + return nil, syserror.ENOATTR + } + return value, nil } -// SetOwner updates the file owner to owner. -func (i *InMemoryAttributes) SetOwner(ctx context.Context, owner fs.FileOwner) error { - if owner.UID.Ok() { - i.Unstable.Owner.UID = owner.UID - } - if owner.GID.Ok() { - i.Unstable.Owner.GID = owner.GID +// Setxattr implements fs.InodeOperations.Setxattr. +func (i *InodeSimpleExtendedAttributes) Setxattr(_ *fs.Inode, name string, value []byte) error { + i.mu.Lock() + if i.xattrs == nil { + i.xattrs = make(map[string][]byte) } + i.xattrs[name] = value + i.mu.Unlock() return nil } -// SetTimestamps sets the timestamps to ts. -func (i *InMemoryAttributes) SetTimestamps(ctx context.Context, ts fs.TimeSpec) error { - if ts.ATimeOmit && ts.MTimeOmit { - return nil - } - - now := ktime.NowFromContext(ctx) - if !ts.ATimeOmit { - if ts.ATimeSetSystemTime { - i.Unstable.AccessTime = now - } else { - i.Unstable.AccessTime = ts.ATime - } - } - if !ts.MTimeOmit { - if ts.MTimeSetSystemTime { - i.Unstable.ModificationTime = now - } else { - i.Unstable.ModificationTime = ts.MTime - } +// Listxattr implements fs.InodeOperations.Listxattr. +func (i *InodeSimpleExtendedAttributes) Listxattr(_ *fs.Inode) (map[string]struct{}, error) { + i.mu.RLock() + names := make(map[string]struct{}, len(i.xattrs)) + for name := range i.xattrs { + names[name] = struct{}{} } - i.Unstable.StatusChangeTime = now - return nil + i.mu.RUnlock() + return names, nil } -// TouchAccessTime updates access time to the current time. -func (i *InMemoryAttributes) TouchAccessTime(ctx context.Context) { - i.Unstable.AccessTime = ktime.NowFromContext(ctx) -} +// staticFile is a file with static contents. It is returned by +// InodeStaticFileGetter.GetFile. +// +// +stateify savable +type staticFile struct { + waiter.AlwaysReady `state:"nosave"` + FileGenericSeek `state:"nosave"` + FileNoIoctl `state:"nosave"` + FileNoMMap `state:"nosave"` + FileNoopFsync `state:"nosave"` + FileNoopFlush `state:"nosave"` + FileNoopRelease `state:"nosave"` + FileNoopWrite `state:"nosave"` + FileNotDirReaddir `state:"nosave"` -// TouchModificationTime updates modification and status change -// time to the current time. -func (i *InMemoryAttributes) TouchModificationTime(ctx context.Context) { - now := ktime.NowFromContext(ctx) - i.Unstable.ModificationTime = now - i.Unstable.StatusChangeTime = now + FileStaticContentReader } -// TouchStatusChangeTime updates status change time to the current time. -func (i *InMemoryAttributes) TouchStatusChangeTime(ctx context.Context) { - i.Unstable.StatusChangeTime = ktime.NowFromContext(ctx) -} +// InodeNoStatFS implement StatFS by retuning ENOSYS. +type InodeNoStatFS struct{} -// Getxattr returns the extended attribute at name or ENOATTR if -// it isn't set. -func (i *InMemoryAttributes) Getxattr(name string) ([]byte, error) { - if value, ok := i.Xattrs[name]; ok { - return value, nil - } - return nil, syserror.ENOATTR +// StatFS implements fs.InodeOperations.StatFS. +func (InodeNoStatFS) StatFS(context.Context) (fs.Info, error) { + return fs.Info{}, syserror.ENOSYS } -// Setxattr sets the extended attribute at name to value. -func (i *InMemoryAttributes) Setxattr(name string, value []byte) error { - if i.Xattrs == nil { - i.Xattrs = make(map[string][]byte) - } - i.Xattrs[name] = value - return nil +// InodeStaticFileGetter implements GetFile for a file with static contents. +// +// +stateify savable +type InodeStaticFileGetter struct { + Contents []byte } -// Listxattr returns the set of all currently set extended attributes. -func (i *InMemoryAttributes) Listxattr() (map[string]struct{}, error) { - names := make(map[string]struct{}, len(i.Xattrs)) - for name := range i.Xattrs { - names[name] = struct{}{} - } - return names, nil +// GetFile implements fs.InodeOperations.GetFile. +func (i *InodeStaticFileGetter) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &staticFile{ + FileStaticContentReader: NewFileStaticContentReader(i.Contents), + }), nil } -// NoMappable returns a nil memmap.Mappable. -type NoMappable struct{} +// InodeNotMappable returns a nil memmap.Mappable. +type InodeNotMappable struct{} // Mappable implements fs.InodeOperations.Mappable. -func (NoMappable) Mappable(*fs.Inode) memmap.Mappable { +func (InodeNotMappable) Mappable(*fs.Inode) memmap.Mappable { return nil } -// NoopWriteOut is a no-op implementation of Inode.WriteOut. -type NoopWriteOut struct{} +// InodeNoopWriteOut is a no-op implementation of fs.InodeOperations.WriteOut. +type InodeNoopWriteOut struct{} // WriteOut is a no-op. -func (NoopWriteOut) WriteOut(context.Context, *fs.Inode) error { +func (InodeNoopWriteOut) WriteOut(context.Context, *fs.Inode) error { return nil } @@ -273,6 +330,11 @@ func (InodeNotDirectory) RemoveDirectory(context.Context, *fs.Inode, string) err return syserror.ENOTDIR } +// Rename implements fs.FileOperations.Rename. +func (InodeNotDirectory) Rename(context.Context, *fs.Inode, string, *fs.Inode, string) error { + return syserror.EINVAL +} + // InodeNotSocket can be used by Inodes that are not sockets. type InodeNotSocket struct{} @@ -281,7 +343,31 @@ func (InodeNotSocket) BoundEndpoint(*fs.Inode, string) transport.BoundEndpoint { return nil } -// InodeNotRenameable can be used by Inodes that cannot be renamed. +// InodeNotTruncatable can be used by Inodes that cannot be truncated. +type InodeNotTruncatable struct{} + +// Truncate implements fs.InodeOperations.Truncate. +func (InodeNotTruncatable) Truncate(context.Context, *fs.Inode, int64) error { + return syserror.EINVAL +} + +// InodeIsDirTruncate implements fs.InodeOperations.Truncate for directories. +type InodeIsDirTruncate struct{} + +// Truncate implements fs.InodeOperations.Truncate. +func (InodeIsDirTruncate) Truncate(context.Context, *fs.Inode, int64) error { + return syserror.EISDIR +} + +// InodeNoopTruncate implements fs.InodeOperations.Truncate as a noop. +type InodeNoopTruncate struct{} + +// Truncate implements fs.InodeOperations.Truncate. +func (InodeNoopTruncate) Truncate(context.Context, *fs.Inode, int64) error { + return nil +} + +// InodeNotRenameable can be used by Inodes that cannot be truncated. type InodeNotRenameable struct{} // Rename implements fs.InodeOperations.Rename. @@ -305,6 +391,14 @@ func (InodeNotVirtual) IsVirtual() bool { return false } +// InodeVirtual can be used by Inodes that are virtual. +type InodeVirtual struct{} + +// IsVirtual implements fs.InodeOperations.IsVirtual. +func (InodeVirtual) IsVirtual() bool { + return true +} + // InodeNotSymlink can be used by Inodes that are not symlinks. type InodeNotSymlink struct{} @@ -337,50 +431,17 @@ func (InodeNoExtendedAttributes) Listxattr(*fs.Inode) (map[string]struct{}, erro return nil, syserror.EOPNOTSUPP } -// DeprecatedFileOperations panics if any deprecated Inode method is called. -type DeprecatedFileOperations struct{} +// InodeNoopRelease implements fs.InodeOperations.Release as a noop. +type InodeNoopRelease struct{} -// Readiness implements fs.InodeOperations.Waitable.Readiness. -func (DeprecatedFileOperations) Readiness(waiter.EventMask) waiter.EventMask { - panic("not implemented") -} - -// EventRegister implements fs.InodeOperations.Waitable.EventRegister. -func (DeprecatedFileOperations) EventRegister(*waiter.Entry, waiter.EventMask) { - panic("not implemented") -} - -// EventUnregister implements fs.InodeOperations.Waitable.EventUnregister. -func (DeprecatedFileOperations) EventUnregister(*waiter.Entry) { - panic("not implemented") -} - -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (DeprecatedFileOperations) DeprecatedPreadv(context.Context, usermem.IOSequence, int64) (int64, error) { - panic("not implemented") -} - -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev. -func (DeprecatedFileOperations) DeprecatedPwritev(context.Context, usermem.IOSequence, int64) (int64, error) { - panic("not implemented") -} - -// DeprecatedReaddir implements fs.InodeOperations.DeprecatedReaddir. -func (DeprecatedFileOperations) DeprecatedReaddir(context.Context, *fs.DirCtx, int) (int, error) { - panic("not implemented") -} - -// DeprecatedFsync implements fs.InodeOperations.DeprecatedFsync. -func (DeprecatedFileOperations) DeprecatedFsync() error { - panic("not implemented") -} +// Release implements fs.InodeOperations.Release. +func (InodeNoopRelease) Release(context.Context) {} -// DeprecatedFlush implements fs.InodeOperations.DeprecatedFlush. -func (DeprecatedFileOperations) DeprecatedFlush() error { - panic("not implemented") -} +// InodeGenericChecker implements fs.InodeOperations.Check with a generic +// implementation. +type InodeGenericChecker struct{} -// DeprecatedMappable implements fs.InodeOperations.DeprecatedMappable. -func (DeprecatedFileOperations) DeprecatedMappable(context.Context, *fs.Inode) (memmap.Mappable, bool) { - panic("not implemented") +// Check implements fs.InodeOperations.Check. +func (InodeGenericChecker) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { + return fs.ContextCanAccessFile(ctx, inode, p) } diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go index ce5201a40..9c9391511 100644 --- a/pkg/sentry/fs/fsutil/inode_cached_test.go +++ b/pkg/sentry/fs/fsutil/inode_cached_test.go @@ -261,15 +261,11 @@ func (noopMappingSpace) Invalidate(ar usermem.AddrRange, opts memmap.InvalidateO } func anonInode(ctx context.Context) *fs.Inode { - return fs.NewInode(NewSimpleInodeOperations(InodeSimpleAttributes{ - UAttr: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: fs.FileOwnerFromContext(ctx), - Perms: fs.FilePermissions{ - User: fs.PermMask{Read: true, Write: true}, - }, - Links: 1, - }), - }), fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{ + return fs.NewInode(&SimpleFileInode{ + InodeSimpleAttributes: NewInodeSimpleAttributes(ctx, fs.FileOwnerFromContext(ctx), fs.FilePermissions{ + User: fs.PermMask{Read: true, Write: true}, + }, 0), + }, fs.NewPseudoMountSource(), fs.StableAttr{ Type: fs.Anonymous, BlockSize: usermem.PageSize, }) diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 6d961813d..3578b07a0 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -37,7 +37,7 @@ var openedWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_fil // // +stateify savable type fileOperations struct { - fsutil.NoIoctl `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` waiter.AlwaysReady `state:"nosave"` // inodeOperations is the inodeOperations backing the file. It is protected diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index ed30cb1f1..2dc000c6f 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -75,11 +75,11 @@ var ( // ErrNoTransport is returned when there is no 'trans' option. ErrNoTransport = errors.New("missing required option: 'trans='") - // ErrNoReadFD is returned when there is no 'rfdno' option. - ErrNoReadFD = errors.New("missing required option: 'rfdno='") + // ErrFileNoReadFD is returned when there is no 'rfdno' option. + ErrFileNoReadFD = errors.New("missing required option: 'rfdno='") - // ErrNoWriteFD is returned when there is no 'wfdno' option. - ErrNoWriteFD = errors.New("missing required option: 'wfdno='") + // ErrFileNoWriteFD is returned when there is no 'wfdno' option. + ErrFileNoWriteFD = errors.New("missing required option: 'wfdno='") ) // filesystem is a 9p client. @@ -87,6 +87,8 @@ var ( // +stateify savable type filesystem struct{} +var _ fs.Filesystem = (*filesystem)(nil) + func init() { fs.RegisterFilesystem(&filesystem{}) } @@ -160,14 +162,14 @@ func options(data string) (opts, error) { // Check for the required 'rfdno=' option. srfd, ok := options[readFDKey] if !ok { - return o, ErrNoReadFD + return o, ErrFileNoReadFD } delete(options, readFDKey) // Check for the required 'wfdno=' option. swfd, ok := options[writeFDKey] if !ok { - return o, ErrNoWriteFD + return o, ErrFileNoWriteFD } delete(options, writeFDKey) diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 7c6e5b025..f0dc99fd0 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -40,7 +40,6 @@ import ( type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` // fileState implements fs.CachedFileObject. It exists // to break a circular load dependency between inodeOperations diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index bc6ee7aa4..4e84d1d6c 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -36,8 +36,8 @@ import ( // // +stateify savable type fileOperations struct { - fsutil.NoIoctl `state:"nosave"` - fsutil.NoopRelease `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` // iops are the Inode operations for this file. iops *inodeOperations `state:"wait"` diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index 54cbb94f9..d2ba38449 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -58,6 +58,8 @@ type Filesystem struct { paths []string } +var _ fs.Filesystem = (*Filesystem)(nil) + // Name is the identifier of this file system. func (*Filesystem) Name() string { return FilesystemName diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 08754bd6b..6ff6c3254 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -39,7 +39,6 @@ import ( type inodeOperations struct { fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.DeprecatedFileOperations `state:"nosave"` // fileState implements fs.CachedFileObject. It exists // to break a circular load dependency between inodeOperations diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index fa3beb111..d32f52d55 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -356,11 +356,10 @@ func (i *Inode) AddLink() { if i.overlay != nil { // FIXME: Remove this from InodeOperations altogether. // - // This interface (including DropLink and NotifyStatusChange) - // is only used by ramfs to update metadata of children. These - // filesystems should _never_ have overlay Inodes cached as - // children. So explicitly disallow this scenario and avoid plumbing - // Dirents through to do copy up. + // This interface is only used by ramfs to update metadata of + // children. These filesystems should _never_ have overlay + // Inodes cached as children. So explicitly disallow this + // scenario and avoid plumbing Dirents through to do copy up. panic("overlay Inodes cached in ramfs directories are not supported") } i.InodeOperations.AddLink() @@ -375,15 +374,6 @@ func (i *Inode) DropLink() { i.InodeOperations.DropLink() } -// NotifyStatusChange calls i.InodeOperations.NotifyStatusChange. -func (i *Inode) NotifyStatusChange(ctx context.Context) { - if i.overlay != nil { - // Same as AddLink. - panic("overlay Inodes cached in ramfs directories are not supported") - } - i.InodeOperations.NotifyStatusChange(ctx) -} - // IsVirtual calls i.InodeOperations.IsVirtual. func (i *Inode) IsVirtual() bool { if i.overlay != nil { @@ -401,17 +391,6 @@ func (i *Inode) StatFS(ctx context.Context) (Info, error) { return i.InodeOperations.StatFS(ctx) } -// HandleOps extracts HandleOperations from i. -func (i *Inode) HandleOps() HandleOperations { - if i.overlay != nil { - return overlayHandleOps(i.overlay) - } - if h, ok := i.InodeOperations.(HandleOperations); ok { - return h - } - return nil -} - // CheckOwnership checks whether `ctx` owns this Inode or may act as its owner. // Compare Linux's fs/inode.c:inode_owner_or_capable(). func (i *Inode) CheckOwnership(ctx context.Context) bool { diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index 77973ce79..db40b5256 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -21,8 +21,6 @@ import ( ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/waiter" ) var ( @@ -303,83 +301,5 @@ type InodeOperations interface { // StatFS returns a filesystem Info implementation or an error. If // the filesystem does not support this operation (maybe in the future // it will), then ENOSYS should be returned. - // - // Move to MountSourceOperations. StatFS(context.Context) (Info, error) - - HandleOperations -} - -// HandleOperations are extended InodeOperations that are only implemented -// for file systems that use fs/handle.go:Handle to generate open Files. -// -// Handle is deprecated; these methods are deprecated as well. -// -// Filesystems are encouraged to implement the File interface directly -// instead of using Handle. To indicate that the below methods should never -// be called, embed DeprecatedFileOperations to satisfy this interface. -type HandleOperations interface { - waiter.Waitable - - // DeprecatedPreadv is deprecated in favor of filesystems - // implementing File.Preadv directly. - // - // DeprecatedPreadv reads up to dst.NumBytes() bytes into dst, starting at - // the given offset, and returns the number of bytes read. - // - // Preadv may return a partial read result before EOF is reached. - // - // If a symlink, Preadv reads the target value of the symlink. - // - // Preadv should not check for readable permissions. - DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) - - // DeprecatedPwritev is deprecated in favor of filesystems - // implementing File.Pwritev directly. - // - // DeprecatedPwritev writes up to src.NumBytes() bytes from src to the - // Inode, starting at the given offset and returns the number of bytes - // written. - // - // Pwritev should not check that the Inode has writable permissions. - DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) - - // DeprecatedReaddir is deprecated in favor of filesystems - // implementing File.Readdir directly. - // - // DeprecatedReaddir emits directory entries by calling dirCtx.EmitDir, - // beginning with the entry at offset. - // - // Entries for "." and ".." must *not* be included. - // - // If the offset returned is the same as the argument offset, then - // nothing has been serialized. This is equivalent to reaching EOF. - // In this case serializer.Written() should return 0. - // - // The order of entries to emit must be consistent between Readdir - // calls, and must start with the given offset. - // - // The caller must ensure that this operation is permitted. - DeprecatedReaddir(ctx context.Context, dirCtx *DirCtx, offset int) (int, error) - - // DeprecatedFsync is deprecated in favor of filesystems implementing - // File.Fsync directly. - // - // DeprecatedFsync syncs a file. - DeprecatedFsync() error - - // DeprecatedMappable is deprecated in favor of filesystems implementing - // File.Mappable directly. - // - // DeprecatedMappable returns a Mappable if the Inode can be mapped. - DeprecatedMappable(ctx context.Context, inode *Inode) (memmap.Mappable, bool) - - // DeprecatedFlush is deprecated in favor of filesystems implementing - // File.Flush directly. - // - // DeprecatedFlush flushes a file. - // - // Implementations may choose to free up memory or complete pending I/O - // but also may implement Flush as a no-op. - DeprecatedFlush() error } diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index 512a0da28..77a2623ef 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -596,19 +596,6 @@ func overlayStatFS(ctx context.Context, o *overlayEntry) (Info, error) { return i, nil } -func overlayHandleOps(o *overlayEntry) HandleOperations { - // Hot path. Avoid defers. - var hops HandleOperations - o.copyMu.RLock() - if o.upper != nil { - hops = o.upper.HandleOps() - } else { - hops = o.lower.HandleOps() - } - o.copyMu.RUnlock() - return hops -} - // NewTestOverlayDir returns an overlay Inode for tests. // // If `revalidate` is true, then the upper filesystem will require diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go index 9e922d008..bc91be226 100644 --- a/pkg/sentry/fs/inode_overlay_test.go +++ b/pkg/sentry/fs/inode_overlay_test.go @@ -19,7 +19,8 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - ramfstest "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/contexttest" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -376,7 +377,8 @@ type dir struct { // List of negative child names. negative []string - // Whether DeprecatedReaddir has been called on this dir. + // ReaddirCalled records whether Readdir was called on a file + // corresponding to this inode. ReaddirCalled bool } @@ -390,10 +392,19 @@ func (d *dir) Getxattr(inode *fs.Inode, name string) ([]byte, error) { return nil, syserror.ENOATTR } -// DeprecatedReaddir implements InodeOperations.DeprecatedReaddir. -func (d *dir) DeprecatedReaddir(ctx context.Context, dirctx *fs.DirCtx, offset int) (int, error) { - d.ReaddirCalled = true - return d.InodeOperations.DeprecatedReaddir(ctx, dirctx, offset) +// GetFile implements InodeOperations.GetFile. +func (d *dir) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + file, err := d.InodeOperations.GetFile(ctx, dirent, flags) + if err != nil { + return nil, err + } + defer file.DecRef() + // Wrap the file's FileOperations in a dirFile. + fops := &dirFile{ + FileOperations: file.FileOperations, + inode: d, + } + return fs.NewFile(ctx, dirent, flags, fops), nil } type dirContent struct { @@ -401,12 +412,45 @@ type dirContent struct { dir bool } +type dirFile struct { + fs.FileOperations + inode *dir +} + +type inode struct { + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeNotVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes + fsutil.InodeStaticFileGetter +} + +// Readdir implements fs.FileOperations.Readdir. It sets the ReaddirCalled +// field on the inode. +func (f *dirFile) Readdir(ctx context.Context, file *fs.File, ser fs.DentrySerializer) (int64, error) { + f.inode.ReaddirCalled = true + return f.FileOperations.Readdir(ctx, file, ser) +} + func newTestRamfsInode(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - return fs.NewInode(ramfstest.NewFile(ctx, fs.FilePermissions{}), msrc, fs.StableAttr{Type: fs.RegularFile}) + inode := fs.NewInode(&inode{ + InodeStaticFileGetter: fsutil.InodeStaticFileGetter{ + Contents: []byte("foobar"), + }, + }, msrc, fs.StableAttr{Type: fs.RegularFile}) + return inode } func newTestRamfsDir(ctx context.Context, contains []dirContent, negative []string) *fs.Inode { - msrc := fs.NewCachingMountSource(nil, fs.MountSourceFlags{}) + msrc := fs.NewPseudoMountSource() contents := make(map[string]*fs.Inode) for _, c := range contains { if c.dir { @@ -415,7 +459,7 @@ func newTestRamfsDir(ctx context.Context, contains []dirContent, negative []stri contents[c.name] = newTestRamfsInode(ctx, msrc) } } - dops := ramfstest.NewDir(ctx, contents, fs.FilePermissions{ + dops := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermissions{ User: fs.PermMask{Read: true, Execute: true}, }) return fs.NewInode(&dir{ diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go index 6bfcda6bb..abfdc6a25 100644 --- a/pkg/sentry/fs/mock.go +++ b/pkg/sentry/fs/mock.go @@ -16,7 +16,6 @@ package fs import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -151,16 +150,6 @@ func (n *MockInodeOperations) Truncate(ctx context.Context, inode *Inode, size i return nil } -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev. -func (n *MockInodeOperations) DeprecatedPwritev(context.Context, usermem.IOSequence, int64) (int64, error) { - return 0, nil -} - -// DeprecatedReaddir implements fs.InodeOperations.DeprecatedReaddir. -func (n *MockInodeOperations) DeprecatedReaddir(context.Context, *DirCtx, int) (int, error) { - return 0, nil -} - // Remove implements fs.InodeOperations.Remove. func (n *MockInodeOperations) Remove(context.Context, *Inode, string) error { return nil diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 24e28ddb2..dd6e64b4c 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -43,8 +43,6 @@ type DirentOperations interface { // MountSourceOperations contains filesystem specific operations. type MountSourceOperations interface { // TODO: Add: - // - // StatFS() (Info, error) // BlockSize() int64 // FS() Filesystem @@ -249,7 +247,7 @@ func (msrc *MountSource) FlushDirentRefs() { } // NewCachingMountSource returns a generic mount that will cache dirents -// aggressively. Filesystem may be nil if there is no backing filesystem. +// aggressively. func NewCachingMountSource(filesystem Filesystem, flags MountSourceFlags) *MountSource { return NewMountSource(&SimpleMountSourceOperations{ keep: true, @@ -258,7 +256,6 @@ func NewCachingMountSource(filesystem Filesystem, flags MountSourceFlags) *Mount } // NewNonCachingMountSource returns a generic mount that will never cache dirents. -// Filesystem may be nil if there is no backing filesystem. func NewNonCachingMountSource(filesystem Filesystem, flags MountSourceFlags) *MountSource { return NewMountSource(&SimpleMountSourceOperations{ keep: false, @@ -275,6 +272,15 @@ func NewRevalidatingMountSource(filesystem Filesystem, flags MountSourceFlags) * }, filesystem, flags) } +// NewPseudoMountSource returns a "pseudo" mount source that is not backed by +// an actual filesystem. It is always non-caching. +func NewPseudoMountSource() *MountSource { + return NewMountSource(&SimpleMountSourceOperations{ + keep: false, + revalidate: false, + }, nil, MountSourceFlags{}) +} + // SimpleMountSourceOperations implements MountSourceOperations. // // +stateify savable diff --git a/pkg/sentry/fs/mounts_test.go b/pkg/sentry/fs/mounts_test.go index 7d682d99b..54000614f 100644 --- a/pkg/sentry/fs/mounts_test.go +++ b/pkg/sentry/fs/mounts_test.go @@ -19,7 +19,8 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - ramfstest "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/contexttest" ) @@ -29,15 +30,15 @@ import ( // |-bar (file) func createMountNamespace(ctx context.Context) (*fs.MountNamespace, error) { perms := fs.FilePermsFromMode(0777) - m := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) + m := fs.NewPseudoMountSource() - barFile := ramfstest.NewFile(ctx, perms) - fooDir := ramfstest.NewDir(ctx, map[string]*fs.Inode{ + barFile := fsutil.NewSimpleFileInode(ctx, fs.RootOwner, perms, 0) + fooDir := ramfs.NewDir(ctx, map[string]*fs.Inode{ "bar": fs.NewInode(barFile, m, fs.StableAttr{Type: fs.RegularFile}), - }, perms) - rootDir := ramfstest.NewDir(ctx, map[string]*fs.Inode{ + }, fs.RootOwner, perms) + rootDir := ramfs.NewDir(ctx, map[string]*fs.Inode{ "foo": fs.NewInode(fooDir, m, fs.StableAttr{Type: fs.Directory}), - }, perms) + }, fs.RootOwner, perms) return fs.NewMountNamespace(ctx, fs.NewInode(rootDir, m, fs.StableAttr{Type: fs.Directory})) } diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index aff3c3c01..74954f213 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -8,9 +8,9 @@ go_library( "cpuinfo.go", "exec_args.go", "fds.go", - "file.go", "filesystems.go", "fs.go", + "inode.go", "loadavg.go", "meminfo.go", "mounts.go", @@ -32,6 +32,7 @@ go_library( "//pkg/abi/linux", "//pkg/sentry/context", "//pkg/sentry/fs", + "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/proc/device", "//pkg/sentry/fs/proc/seqfile", "//pkg/sentry/fs/ramfs", @@ -45,6 +46,7 @@ go_library( "//pkg/sentry/usage", "//pkg/sentry/usermem", "//pkg/syserror", + "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index f8be06dc3..f756c45bf 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -15,52 +15,21 @@ package proc import ( - "io" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// cpuinfo is a file describing the CPU capabilities. -// -// Presently cpuinfo never changes, so it doesn't need to be a SeqFile. -// -// +stateify savable -type cpuinfo struct { - ramfs.Entry - - // k is the system kernel. - k *kernel.Kernel -} - -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (c *cpuinfo) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - features := c.k.FeatureSet() +func newCPUInfo(ctx context.Context, msrc *fs.MountSource) *fs.Inode { + k := kernel.KernelFromContext(ctx) + features := k.FeatureSet() if features == nil { // Kernel is always initialized with a FeatureSet. panic("cpuinfo read with nil FeatureSet") } - contents := make([]byte, 0, 1024) - for i, max := uint(0), c.k.ApplicationCores(); i < max; i++ { + for i, max := uint(0), k.ApplicationCores(); i < max; i++ { contents = append(contents, []byte(features.CPUInfo(i))...) } - if offset >= int64(len(contents)) { - return 0, io.EOF - } - - n, err := dst.CopyOut(ctx, contents[offset:]) - return int64(n), err -} - -func (p *proc) newCPUInfo(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - f := &cpuinfo{ - k: p.k, - } - f.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0444)) - - return newFile(f, msrc, fs.SpecialFile, nil) + return newStaticProcInode(ctx, msrc, contents) } diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index b4896053f..ddda67f54 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -18,12 +18,14 @@ import ( "fmt" "io" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // execArgType enumerates the types of exec arguments that are exposed through @@ -35,12 +37,12 @@ const ( environExecArg ) -// execArgFile is a file containing the exec args (either cmdline or environ) +// execArgInode is a inode containing the exec args (either cmdline or environ) // for a given task. // // +stateify savable -type execArgFile struct { - ramfs.Entry +type execArgInode struct { + fsutil.SimpleFileInode // arg is the type of exec argument this file contains. arg execArgType @@ -49,21 +51,52 @@ type execArgFile struct { t *kernel.Task } +var _ fs.InodeOperations = (*execArgInode)(nil) + // newExecArgFile creates a file containing the exec args of the given type. -func newExecArgFile(t *kernel.Task, msrc *fs.MountSource, arg execArgType) *fs.Inode { +func newExecArgInode(t *kernel.Task, msrc *fs.MountSource, arg execArgType) *fs.Inode { if arg != cmdlineExecArg && arg != environExecArg { panic(fmt.Sprintf("unknown exec arg type %v", arg)) } - f := &execArgFile{ - arg: arg, - t: t, + f := &execArgInode{ + SimpleFileInode: *fsutil.NewSimpleFileInode(t, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + arg: arg, + t: t, } - f.InitEntry(t, fs.RootOwner, fs.FilePermsFromMode(0444)) - return newFile(f, msrc, fs.SpecialFile, t) + return newProcInode(f, msrc, fs.SpecialFile, t) +} + +// GetFile implements fs.InodeOperations.GetFile. +func (i *execArgInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &execArgFile{ + arg: i.arg, + t: i.t, + }), nil } -// DeprecatedPreadv reads the exec arg from the process's address space.. -func (f *execArgFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { +// +stateify savable +type execArgFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopWrite `state:"nosave"` + + // arg is the type of exec argument this file contains. + arg execArgType + + // t is the Task to read the exec arg line from. + t *kernel.Task +} + +var _ fs.FileOperations = (*execArgFile)(nil) + +// Read reads the exec arg from the process's address space.. +func (f *execArgFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { if offset < 0 { return 0, syserror.EINVAL } diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index 5acbce75e..b8a0a5eff 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -21,11 +21,11 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -55,7 +55,7 @@ func walkDescriptors(t *kernel.Task, p string, toInode func(*fs.File, kernel.FDF // readDescriptors reads fds in the task starting at offset, and calls the // toDentAttr callback for each to get a DentAttr, which it then emits. This is // a helper for implementing fs.InodeOperations.Readdir. -func readDescriptors(t *kernel.Task, c *fs.DirCtx, offset int, toDentAttr func(int) fs.DentAttr) (int, error) { +func readDescriptors(t *kernel.Task, c *fs.DirCtx, offset int64, toDentAttr func(int) fs.DentAttr) (int64, error) { var fds kernel.FDs t.WithMuLocked(func(t *kernel.Task) { if fdm := t.FDMap(); fdm != nil { @@ -69,7 +69,7 @@ func readDescriptors(t *kernel.Task, c *fs.DirCtx, offset int, toDentAttr func(i } // Find the fd to start at. - idx := sort.SearchInts(fdInts, offset) + idx := sort.SearchInts(fdInts, int(offset)) if idx == len(fdInts) { return offset, nil } @@ -80,28 +80,32 @@ func readDescriptors(t *kernel.Task, c *fs.DirCtx, offset int, toDentAttr func(i name := strconv.FormatUint(uint64(fd), 10) if err := c.DirEmit(name, toDentAttr(fd)); err != nil { // Returned offset is the next fd to serialize. - return fd, err + return int64(fd), err } } // We serialized them all. Next offset should be higher than last // serialized fd. - return fd + 1, nil + return int64(fd + 1), nil } -// fd is a single file in /proc/TID/fd/. +// fd implements fs.InodeOperations for a file in /proc/TID/fd/. type fd struct { ramfs.Symlink *fs.File } +var _ fs.InodeOperations = (*fd)(nil) + // newFd returns a new fd based on an existing file. // // This inherits one reference to the file. func newFd(t *kernel.Task, f *fs.File, msrc *fs.MountSource) *fs.Inode { - fd := &fd{File: f} - // RootOwner by default, is overridden in UnstableAttr() - fd.InitSymlink(t, fs.RootOwner, "") - return newFile(fd, msrc, fs.Symlink, t) + fd := &fd{ + // RootOwner overridden by taskOwnedInodeOps.UnstableAttrs(). + Symlink: *ramfs.NewSymlink(t, fs.RootOwner, ""), + File: f, + } + return newProcInode(fd, msrc, fs.Symlink, t) } // GetFile returns the fs.File backing this fd. The dirent and flags @@ -142,7 +146,7 @@ func (f *fd) Close() error { return nil } -// fdDir implements /proc/TID/fd. +// fdDir is an InodeOperations for /proc/TID/fd. // // +stateify savable type fdDir struct { @@ -154,11 +158,15 @@ type fdDir struct { t *kernel.Task } +var _ fs.InodeOperations = (*fdDir)(nil) + // newFdDir creates a new fdDir. func newFdDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - f := &fdDir{t: t} - f.InitDir(t, nil, fs.RootOwner, fs.FilePermissions{User: fs.PermMask{Read: true, Execute: true}}) - return newFile(f, msrc, fs.SpecialDirectory, t) + f := &fdDir{ + Dir: *ramfs.NewDir(t, nil, fs.RootOwner, fs.FilePermissions{User: fs.PermMask{Read: true, Execute: true}}), + t: t, + } + return newProcInode(f, msrc, fs.SpecialDirectory, t) } // Check implements InodeOperations.Check. @@ -191,49 +199,55 @@ func (f *fdDir) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent return fs.NewDirent(n, p), nil } -// DeprecatedReaddir lists fds in /proc/TID/fd. -func (f *fdDir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - return readDescriptors(f.t, dirCtx, offset, func(fd int) fs.DentAttr { - return fs.GenericDentAttr(fs.Symlink, device.ProcDevice) +// GetFile implements fs.FileOperations.GetFile. +func (f *fdDir) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + fops := &fdDirFile{ + isInfoFile: false, + t: f.t, + } + return fs.NewFile(ctx, dirent, flags, fops), nil +} + +// +stateify savable +type fdDirFile struct { + fsutil.DirFileOperations `state:"nosave"` + + isInfoFile bool + + t *kernel.Task +} + +var _ fs.FileOperations = (*fdDirFile)(nil) + +// Readdir implements fs.FileOperations.Readdir. +func (f *fdDirFile) Readdir(ctx context.Context, file *fs.File, ser fs.DentrySerializer) (int64, error) { + dirCtx := &fs.DirCtx{ + Serializer: ser, + } + typ := fs.RegularFile + if f.isInfoFile { + typ = fs.Symlink + } + return readDescriptors(f.t, dirCtx, file.Offset(), func(fd int) fs.DentAttr { + return fs.GenericDentAttr(typ, device.ProcDevice) }) } -// fdInfo is a single file in /proc/TID/fdinfo/. +// fdInfoInode is a single file in /proc/TID/fdinfo/. // // +stateify savable -type fdInfo struct { - ramfs.File +type fdInfoInode struct { + staticFileInodeOps file *fs.File flags fs.FileFlags fdFlags kernel.FDFlags } -// newFdInfo returns a new fdInfo based on an existing file. -func newFdInfo(t *kernel.Task, file *fs.File, fdFlags kernel.FDFlags, msrc *fs.MountSource) *fs.Inode { - fdi := &fdInfo{file: file, flags: file.Flags(), fdFlags: fdFlags} - fdi.InitFile(t, fs.RootOwner, fs.FilePermissions{User: fs.PermMask{Read: true}}) - // TODO: Get pos, locks, and other data. For now we only - // have flags. - // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt - - flags := file.Flags().ToLinux() | fdFlags.ToLinuxFileFlags() - fdi.Append([]byte(fmt.Sprintf("flags:\t0%o\n", flags))) - return newFile(fdi, msrc, fs.SpecialFile, t) -} - -// DeprecatedPwritev implements fs.HandleOperations.DeprecatedPwritev. -func (*fdInfo) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { - return 0, ramfs.ErrInvalidOp -} - -// Truncate implements fs.InodeOperations.Truncate. -func (*fdInfo) Truncate(ctx context.Context, inode *fs.Inode, size int64) error { - return ramfs.ErrInvalidOp -} +var _ fs.InodeOperations = (*fdInfoInode)(nil) -func (f *fdInfo) Release(ctx context.Context) { - f.File.Release(ctx) +// Release implements fs.InodeOperations.Release. +func (f *fdInfoInode) Release(ctx context.Context) { f.file.DecRef() } @@ -249,25 +263,37 @@ type fdInfoDir struct { // newFdInfoDir creates a new fdInfoDir. func newFdInfoDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - fdid := &fdInfoDir{t: t} - fdid.InitDir(t, nil, fs.RootOwner, fs.FilePermsFromMode(0500)) - return newFile(fdid, msrc, fs.SpecialDirectory, t) + fdid := &fdInfoDir{ + Dir: *ramfs.NewDir(t, nil, fs.RootOwner, fs.FilePermsFromMode(0500)), + t: t, + } + return newProcInode(fdid, msrc, fs.SpecialDirectory, t) } // Lookup loads an fd in /proc/TID/fdinfo into a Dirent. func (fdid *fdInfoDir) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, error) { - n, err := walkDescriptors(fdid.t, p, func(file *fs.File, fdFlags kernel.FDFlags) *fs.Inode { - return newFdInfo(fdid.t, file, fdFlags, dir.MountSource) + inode, err := walkDescriptors(fdid.t, p, func(file *fs.File, fdFlags kernel.FDFlags) *fs.Inode { + // TODO: Using a static inode here means that the + // data can be out-of-date if, for instance, the flags on the + // FD change before we read this file. We should switch to + // generating the data on Read(). Also, we should include pos, + // locks, and other data. For now we only have flags. + // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt + flags := file.Flags().ToLinux() | fdFlags.ToLinuxFileFlags() + contents := []byte(fmt.Sprintf("flags:\t0%o\n", flags)) + return newStaticProcInode(ctx, dir.MountSource, contents) }) if err != nil { return nil, err } - return fs.NewDirent(n, p), nil + return fs.NewDirent(inode, p), nil } -// DeprecatedReaddir lists fds in /proc/TID/fdinfo. -func (fdid *fdInfoDir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - return readDescriptors(fdid.t, dirCtx, offset, func(fd int) fs.DentAttr { - return fs.GenericDentAttr(fs.RegularFile, device.ProcDevice) - }) +// GetFile implements fs.FileOperations.GetFile. +func (fdid *fdInfoDir) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + fops := &fdDirFile{ + isInfoFile: true, + t: fdid.t, + } + return fs.NewFile(ctx, dirent, flags, fops), nil } diff --git a/pkg/sentry/fs/proc/file.go b/pkg/sentry/fs/proc/file.go deleted file mode 100644 index f659e590a..000000000 --- a/pkg/sentry/fs/proc/file.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 proc - -import ( - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" -) - -// +stateify savable -type file struct { - fs.InodeOperations - - // nodeType is the file type of this file. - nodeType fs.InodeType - - // t is the associated kernel task that owns this file. - t *kernel.Task -} - -func newFile(node fs.InodeOperations, msrc *fs.MountSource, nodeType fs.InodeType, t *kernel.Task) *fs.Inode { - iops := &file{node, nodeType, t} - sattr := fs.StableAttr{ - DeviceID: device.ProcDevice.DeviceID(), - InodeID: device.ProcDevice.NextIno(), - BlockSize: usermem.PageSize, - Type: nodeType, - } - return fs.NewInode(iops, msrc, sattr) -} - -// UnstableAttr returns all attributes of this file. -func (f *file) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - uattr, err := f.InodeOperations.UnstableAttr(ctx, inode) - if err != nil { - return fs.UnstableAttr{}, err - } - if f.t != nil { - creds := f.t.Credentials() - uattr.Owner = fs.FileOwner{creds.EffectiveKUID, creds.EffectiveKGID} - } - return uattr, nil -} diff --git a/pkg/sentry/fs/proc/inode.go b/pkg/sentry/fs/proc/inode.go new file mode 100644 index 000000000..3c36af5ea --- /dev/null +++ b/pkg/sentry/fs/proc/inode.go @@ -0,0 +1,96 @@ +// Copyright 2018 Google LLC +// +// 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 proc + +import ( + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" +) + +// taskOwnedInodeOps wraps an fs.InodeOperations and overrides the UnstableAttr +// method to return the task as the owner. +// +// +stateify savable +type taskOwnedInodeOps struct { + fs.InodeOperations + + // t is the task that owns this file. + t *kernel.Task +} + +// UnstableAttr implement fs.InodeOperations.UnstableAttr. +func (i *taskOwnedInodeOps) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { + uattr, err := i.InodeOperations.UnstableAttr(ctx, inode) + if err != nil { + return fs.UnstableAttr{}, err + } + // Set the task owner as the file owner. + creds := i.t.Credentials() + uattr.Owner = fs.FileOwner{creds.EffectiveKUID, creds.EffectiveKGID} + return uattr, nil +} + +// staticFileInodeOps is an InodeOperations implementation that can be used to +// return file contents which are constant. This file is not writable and will +// always have mode 0444. +// +// +stateify savable +type staticFileInodeOps struct { + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes + fsutil.InodeStaticFileGetter +} + +var _ fs.InodeOperations = (*staticFileInodeOps)(nil) + +// newStaticFileInode returns a procfs InodeOperations with static contents. +func newStaticProcInode(ctx context.Context, msrc *fs.MountSource, contents []byte) *fs.Inode { + iops := &staticFileInodeOps{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + InodeStaticFileGetter: fsutil.InodeStaticFileGetter{ + Contents: contents, + }, + } + return newProcInode(iops, msrc, fs.SpecialFile, nil) +} + +// newProcInode creates a new inode from the given inode operations. +func newProcInode(iops fs.InodeOperations, msrc *fs.MountSource, typ fs.InodeType, t *kernel.Task) *fs.Inode { + sattr := fs.StableAttr{ + DeviceID: device.ProcDevice.DeviceID(), + InodeID: device.ProcDevice.NextIno(), + BlockSize: usermem.PageSize, + Type: typ, + } + if t != nil { + iops = &taskOwnedInodeOps{iops, t} + } + return fs.NewInode(iops, msrc, sattr) +} diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index 2806d6035..3ed85a538 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -28,35 +28,36 @@ import ( // newNet creates a new proc net entry. func (p *proc) newNetDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) + var contents map[string]*fs.Inode if s := p.k.NetworkStack(); s != nil && s.SupportsIPv6() { - d.AddChild(ctx, "dev", seqfile.NewSeqFileInode(ctx, &netDev{s: s}, msrc)) - d.AddChild(ctx, "if_inet6", seqfile.NewSeqFileInode(ctx, &ifinet6{s: s}, msrc)) - - // The following files are simple stubs until they are implemented in - // netstack, if the file contains a header the stub is just the header - // otherwise it is an empty file. - d.AddChild(ctx, "arp", p.newStubProcFSFile(ctx, msrc, []byte("IP address HW type Flags HW address Mask Device"))) - d.AddChild(ctx, "ipv6_route", p.newStubProcFSFile(ctx, msrc, []byte(""))) - d.AddChild(ctx, "netlink", p.newStubProcFSFile(ctx, msrc, []byte("sk Eth Pid Groups Rmem Wmem Dump Locks Drops Inode"))) - d.AddChild(ctx, "netstat", p.newStubProcFSFile(ctx, msrc, []byte("TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPMD5Failure TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow TCPFastOpenCookieReqd TCPSpuriousRtxHostQueues BusyPollRxPackets TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge TCPWinProbe TCPKeepAlive TCPMTUPFail TCPMTUPSuccess"))) - d.AddChild(ctx, "packet", p.newStubProcFSFile(ctx, msrc, []byte("sk RefCnt Type Proto Iface R Rmem User Inode"))) - d.AddChild(ctx, "protocols", p.newStubProcFSFile(ctx, msrc, []byte("protocol size sockets memory press maxhdr slab module cl co di ac io in de sh ss gs se re sp bi br ha uh gp em"))) - - // Linux sets these values to: nsec per usec, psched tick in ns, 1000000, - // high res timer ticks per sec (ClockGetres returns 1ns resolution). - psched := fmt.Sprintf("%08x %08x %08x %08x\n", uint64(time.Microsecond/time.Nanosecond), 64, 1000000, uint64(time.Second/time.Nanosecond)) - d.AddChild(ctx, "psched", p.newStubProcFSFile(ctx, msrc, []byte(psched))) - - d.AddChild(ctx, "ptype", p.newStubProcFSFile(ctx, msrc, []byte("Type Device Function"))) - d.AddChild(ctx, "route", p.newStubProcFSFile(ctx, msrc, []byte("Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT"))) - d.AddChild(ctx, "tcp", p.newStubProcFSFile(ctx, msrc, []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode"))) - d.AddChild(ctx, "tcp6", p.newStubProcFSFile(ctx, msrc, []byte(" sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode"))) - d.AddChild(ctx, "udp", p.newStubProcFSFile(ctx, msrc, []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops"))) - d.AddChild(ctx, "udp6", p.newStubProcFSFile(ctx, msrc, []byte(" sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode"))) + contents = map[string]*fs.Inode{ + "dev": seqfile.NewSeqFileInode(ctx, &netDev{s: s}, msrc), + "if_inet6": seqfile.NewSeqFileInode(ctx, &ifinet6{s: s}, msrc), + + // The following files are simple stubs until they are + // implemented in netstack, if the file contains a + // header the stub is just the header otherwise it is + // an empty file. + "arp": newStaticProcInode(ctx, msrc, []byte("IP address HW type Flags HW address Mask Device")), + "ipv6_route": newStaticProcInode(ctx, msrc, []byte("")), + "netlink": newStaticProcInode(ctx, msrc, []byte("sk Eth Pid Groups Rmem Wmem Dump Locks Drops Inode")), + "netstat": newStaticProcInode(ctx, msrc, []byte("TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPMD5Failure TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow TCPFastOpenCookieReqd TCPSpuriousRtxHostQueues BusyPollRxPackets TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge TCPWinProbe TCPKeepAlive TCPMTUPFail TCPMTUPSuccess")), + "packet": newStaticProcInode(ctx, msrc, []byte("sk RefCnt Type Proto Iface R Rmem User Inode")), + "protocols": newStaticProcInode(ctx, msrc, []byte("protocol size sockets memory press maxhdr slab module cl co di ac io in de sh ss gs se re sp bi br ha uh gp em")), + // Linux sets psched values to: nsec per usec, psched + // tick in ns, 1000000, high res timer ticks per sec + // (ClockGetres returns 1ns resolution). + "psched": newStaticProcInode(ctx, msrc, []byte(fmt.Sprintf("%08x %08x %08x %08x\n", uint64(time.Microsecond/time.Nanosecond), 64, 1000000, uint64(time.Second/time.Nanosecond)))), + "ptype": newStaticProcInode(ctx, msrc, []byte("Type Device Function")), + "route": newStaticProcInode(ctx, msrc, []byte("Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT")), + "tcp": newStaticProcInode(ctx, msrc, []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode")), + "tcp6": newStaticProcInode(ctx, msrc, []byte(" sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode")), + "udp": newStaticProcInode(ctx, msrc, []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops")), + "udp6": newStaticProcInode(ctx, msrc, []byte(" sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode")), + } } - return newFile(d, msrc, fs.SpecialDirectory, nil) + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } // ifinet6 implements seqfile.SeqSource for /proc/net/if_inet6. diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index 70e549c31..d1c699418 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -17,18 +17,17 @@ package proc import ( "fmt" - "io" "sort" "strconv" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/rpcinet" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -46,32 +45,6 @@ type proc struct { pidns *kernel.PIDNamespace } -// stubProcFSFile is a file type that can be used to return file contents -// which are constant. This file is not writable and will always have mode -// 0444. -// -// +stateify savable -type stubProcFSFile struct { - ramfs.Entry - - // contents are the immutable file contents that will always be returned. - contents []byte -} - -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (s *stubProcFSFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - if offset < 0 { - return 0, syserror.EINVAL - } - - if offset >= int64(len(s.contents)) { - return 0, io.EOF - } - - n, err := dst.CopyOut(ctx, s.contents[offset:]) - return int64(n), err -} - // New returns the root node of a partial simple procfs. func New(ctx context.Context, msrc *fs.MountSource) (*fs.Inode, error) { k := kernel.KernelFromContext(ctx) @@ -83,29 +56,39 @@ func New(ctx context.Context, msrc *fs.MountSource) (*fs.Inode, error) { return nil, fmt.Errorf("procfs requires a PID namespace") } - p := &proc{k: k, pidns: pidns} - p.InitDir(ctx, map[string]*fs.Inode{ + // Note that these are just the static members. There are dynamic + // members populated in Readdir and Lookup below. + contents := map[string]*fs.Inode{ + "cpuinfo": newCPUInfo(ctx, msrc), "filesystems": seqfile.NewSeqFileInode(ctx, &filesystemsData{}, msrc), "loadavg": seqfile.NewSeqFileInode(ctx, &loadavgData{}, msrc), "meminfo": seqfile.NewSeqFileInode(ctx, &meminfoData{k}, msrc), - "mounts": newMountsSymlink(ctx, msrc), + "mounts": newProcInode(ramfs.NewSymlink(ctx, fs.RootOwner, "self/mounts"), msrc, fs.Symlink, nil), + "self": newSelf(ctx, pidns, msrc), "stat": seqfile.NewSeqFileInode(ctx, &statData{k}, msrc), + "thread-self": newThreadSelf(ctx, pidns, msrc), + "uptime": newUptime(ctx, msrc), "version": seqfile.NewSeqFileInode(ctx, &versionData{k}, msrc), - }, fs.RootOwner, fs.FilePermsFromMode(0555)) + } + + // Construct the proc InodeOperations. + p := &proc{ + Dir: *ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)), + k: k, + pidns: pidns, + } + + // Add more contents that need proc to be initialized. + p.AddChild(ctx, "sys", p.newSysDir(ctx, msrc)) - p.AddChild(ctx, "cpuinfo", p.newCPUInfo(ctx, msrc)) // If we're using rpcinet we will let it manage /proc/net. if _, ok := p.k.NetworkStack().(*rpcinet.Stack); ok { - p.AddChild(ctx, "net", newRPCInetProcNet(ctx, msrc)) + contents["net"] = newRPCInetProcNet(ctx, msrc) } else { - p.AddChild(ctx, "net", p.newNetDir(ctx, msrc)) + contents["net"] = p.newNetDir(ctx, msrc) } - p.AddChild(ctx, "self", p.newSelf(ctx, msrc)) - p.AddChild(ctx, "sys", p.newSysDir(ctx, msrc)) - p.AddChild(ctx, "thread-self", p.newThreadSelf(ctx, msrc)) - p.AddChild(ctx, "uptime", p.newUptime(ctx, msrc)) - return newFile(p, msrc, fs.SpecialDirectory, nil), nil + return newProcInode(p, msrc, fs.SpecialDirectory, nil), nil } // self is a magical link. @@ -118,26 +101,21 @@ type self struct { } // newSelf returns a new "self" node. -func (p *proc) newSelf(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - s := &self{pidns: p.pidns} - s.InitSymlink(ctx, fs.RootOwner, "") - return newFile(s, msrc, fs.Symlink, nil) +func newSelf(ctx context.Context, pidns *kernel.PIDNamespace, msrc *fs.MountSource) *fs.Inode { + s := &self{ + Symlink: *ramfs.NewSymlink(ctx, fs.RootOwner, ""), + pidns: pidns, + } + return newProcInode(s, msrc, fs.Symlink, nil) } // newThreadSelf returns a new "threadSelf" node. -func (p *proc) newThreadSelf(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - s := &threadSelf{pidns: p.pidns} - s.InitSymlink(ctx, fs.RootOwner, "") - return newFile(s, msrc, fs.Symlink, nil) -} - -// newStubProcFsFile returns a procfs file with constant contents. -func (p *proc) newStubProcFSFile(ctx context.Context, msrc *fs.MountSource, c []byte) *fs.Inode { - u := &stubProcFSFile{ - contents: c, +func newThreadSelf(ctx context.Context, pidns *kernel.PIDNamespace, msrc *fs.MountSource) *fs.Inode { + s := &threadSelf{ + Symlink: *ramfs.NewSymlink(ctx, fs.RootOwner, ""), + pidns: pidns, } - u.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0444)) - return newFile(u, msrc, fs.SpecialFile, nil) + return newProcInode(s, msrc, fs.Symlink, nil) } // Readlink implements fs.InodeOperations.Readlink. @@ -145,13 +123,13 @@ func (s *self) Readlink(ctx context.Context, inode *fs.Inode) (string, error) { if t := kernel.TaskFromContext(ctx); t != nil { tgid := s.pidns.IDOfThreadGroup(t.ThreadGroup()) if tgid == 0 { - return "", ramfs.ErrNotFound + return "", syserror.ENOENT } return strconv.FormatUint(uint64(tgid), 10), nil } // Who is reading this link? - return "", ramfs.ErrInvalidOp + return "", syserror.EINVAL } // threadSelf is more magical than "self" link. @@ -169,13 +147,13 @@ func (s *threadSelf) Readlink(ctx context.Context, inode *fs.Inode) (string, err tgid := s.pidns.IDOfThreadGroup(t.ThreadGroup()) tid := s.pidns.IDOfTask(t) if tid == 0 || tgid == 0 { - return "", ramfs.ErrNotFound + return "", syserror.ENOENT } return fmt.Sprintf("%d/task/%d", tgid, tid), nil } // Who is reading this link? - return "", ramfs.ErrInvalidOp + return "", syserror.EINVAL } // Lookup loads an Inode at name into a Dirent. @@ -204,25 +182,44 @@ func (p *proc) Lookup(ctx context.Context, dir *fs.Inode, name string) (*fs.Dire return fs.NewDirent(td, name), nil } -// Readdir synthesizes proc contents. -func (p *proc) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - // Serialize normal contents. - _, err := p.Dir.DeprecatedReaddir(ctx, dirCtx, offset) - if err != nil { - return offset, err +// GetFile implements fs.InodeOperations. +func (p *proc) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &rootProcFile{iops: p}), nil +} + +// rootProcFile implements fs.FileOperations for the proc directory. +// +// +stateify savable +type rootProcFile struct { + fsutil.DirFileOperations `state:"nosave"` + + iops *proc +} + +var _ fs.FileOperations = (*rootProcFile)(nil) + +// Readdir implements fs.FileOperations.Readdir. +func (rpf *rootProcFile) Readdir(ctx context.Context, file *fs.File, ser fs.DentrySerializer) (int64, error) { + offset := file.Offset() + dirCtx := &fs.DirCtx{ + Serializer: ser, } - m := make(map[string]fs.DentAttr) - var names []string + // Get normal directory contents from ramfs dir. + names, m := rpf.iops.Dir.Children() - // Add special files. - m["sys"] = fs.GenericDentAttr(fs.SpecialFile, device.ProcDevice) - names = append(names, "sys") + // Add dot and dotdot. + root := fs.RootFromContext(ctx) + defer root.DecRef() + dot, dotdot := file.Dirent.GetDotAttrs(root) + names = append(names, ".", "..") + m["."] = dot + m[".."] = dotdot // Collect tasks. // Per linux we only include it in directory listings if it's the leader. // But for whatever crazy reason, you can still walk to the given node. - for _, tg := range p.pidns.ThreadGroups() { + for _, tg := range rpf.iops.pidns.ThreadGroups() { if leader := tg.Leader(); leader != nil { name := strconv.FormatUint(uint64(tg.ID()), 10) m[name] = fs.GenericDentAttr(fs.SpecialDirectory, device.ProcDevice) @@ -230,7 +227,7 @@ func (p *proc) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset } } - if offset >= len(m) { + if offset >= int64(len(m)) { return offset, nil } sort.Strings(names) @@ -241,12 +238,5 @@ func (p *proc) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset } offset++ } - return offset, err -} - -// newMountsSymlink returns a symlink to "self/mounts". -func newMountsSymlink(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - s := &ramfs.Symlink{} - s.InitSymlink(ctx, fs.RootOwner, "self/mounts") - return newFile(s, msrc, fs.Symlink, nil) + return offset, nil } diff --git a/pkg/sentry/fs/proc/rpcinet_proc.go b/pkg/sentry/fs/proc/rpcinet_proc.go index d025069df..65faa21f2 100644 --- a/pkg/sentry/fs/proc/rpcinet_proc.go +++ b/pkg/sentry/fs/proc/rpcinet_proc.go @@ -20,32 +20,72 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/rpcinet" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// rpcinetFile implments fs.InodeOperations as RPCs. -type rpcinetFile struct { - ramfs.Entry +// rpcInetInode implments fs.InodeOperations. +type rpcInetInode struct { + fsutil.SimpleFileInode - // filepath is the full path of this rpcinetFile. + // filepath is the full path of this rpcInetInode. filepath string k *kernel.Kernel } -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -// This method can panic if an rpcinetFile was created without an rpcinet +func newRPCInetInode(ctx context.Context, msrc *fs.MountSource, filepath string, mode linux.FileMode) *fs.Inode { + f := &rpcInetInode{ + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, fs.RootOwner, fs.FilePermsFromMode(mode), linux.PROC_SUPER_MAGIC), + filepath: filepath, + k: kernel.KernelFromContext(ctx), + } + return newProcInode(f, msrc, fs.SpecialFile, nil) +} + +// GetFile implements fs.InodeOperations.GetFile. +func (i *rpcInetInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + flags.Pread = true + flags.Pwrite = true + fops := &rpcInetFile{ + inode: i, + } + return fs.NewFile(ctx, dirent, flags, fops), nil +} + +// rpcInetFile implements fs.FileOperations as RPCs. +type rpcInetFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + + inode *rpcInetInode +} + +// Read implements fs.FileOperations.Read. +// +// This method can panic if an rpcInetInode was created without an rpcinet // stack. -func (r rpcinetFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - s, ok := r.k.NetworkStack().(*rpcinet.Stack) +func (f *rpcInetFile) Read(ctx context.Context, file *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { + if offset < 0 { + return 0, syserror.EINVAL + } + s, ok := f.inode.k.NetworkStack().(*rpcinet.Stack) if !ok { panic("Network stack is not a rpcinet.") } - contents, se := s.RPCReadFile(r.filepath) + contents, se := s.RPCReadFile(f.inode.filepath) if se != nil || offset >= int64(len(contents)) { return 0, io.EOF } @@ -54,16 +94,12 @@ func (r rpcinetFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequenc return int64(n), err } -// Truncate implements fs.InodeOperations.Truncate. -func (r rpcinetFile) Truncate(context.Context, *fs.Inode, int64) error { - return nil -} - -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev. -// This method can panic if an rpcinetFile was created without an rpcinet +// Write implements fs.FileOperations.Write. +// +// This method can panic if an rpcInetInode was created without an rpcInet // stack. -func (r rpcinetFile) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { - s, ok := r.k.NetworkStack().(*rpcinet.Stack) +func (f *rpcInetFile) Write(ctx context.Context, file *fs.File, src usermem.IOSequence, offset int64) (int64, error) { + s, ok := f.inode.k.NetworkStack().(*rpcinet.Stack) if !ok { panic("Network stack is not a rpcinet.") } @@ -78,116 +114,102 @@ func (r rpcinetFile) DeprecatedPwritev(ctx context.Context, src usermem.IOSequen return int64(n), err } - written, se := s.RPCWriteFile(r.filepath, b) + written, se := s.RPCWriteFile(f.inode.filepath, b) return int64(written), se.ToError() } -func newRPCProcFSFile(ctx context.Context, msrc *fs.MountSource, filepath string, mode linux.FileMode) *fs.Inode { - f := &rpcinetFile{ - filepath: filepath, - k: kernel.KernelFromContext(ctx), - } - f.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(mode)) - - fi := newFile(f, msrc, fs.SpecialFile, nil) - return fi -} - // newRPCInetProcNet will build an inode for /proc/net. func newRPCInetProcNet(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - - // Add all the files we want to forward for /proc/net. - d.AddChild(ctx, "arp", newRPCProcFSFile(ctx, msrc, "/proc/net/arp", 0444)) - d.AddChild(ctx, "dev", newRPCProcFSFile(ctx, msrc, "/proc/net/dev", 0444)) - d.AddChild(ctx, "if_inet6", newRPCProcFSFile(ctx, msrc, "/proc/net/if_inet6", 0444)) - d.AddChild(ctx, "ipv6_route", newRPCProcFSFile(ctx, msrc, "/proc/net/ipv6_route", 0444)) - d.AddChild(ctx, "netlink", newRPCProcFSFile(ctx, msrc, "/proc/net/netlink", 0444)) - d.AddChild(ctx, "netstat", newRPCProcFSFile(ctx, msrc, "/proc/net/netstat", 0444)) - d.AddChild(ctx, "packet", newRPCProcFSFile(ctx, msrc, "/proc/net/packet", 0444)) - d.AddChild(ctx, "protocols", newRPCProcFSFile(ctx, msrc, "/proc/net/protocols", 0444)) - d.AddChild(ctx, "psched", newRPCProcFSFile(ctx, msrc, "/proc/net/psched", 0444)) - d.AddChild(ctx, "ptype", newRPCProcFSFile(ctx, msrc, "/proc/net/ptype", 0444)) - d.AddChild(ctx, "route", newRPCProcFSFile(ctx, msrc, "/proc/net/route", 0444)) - d.AddChild(ctx, "tcp", newRPCProcFSFile(ctx, msrc, "/proc/net/tcp", 0444)) - d.AddChild(ctx, "tcp6", newRPCProcFSFile(ctx, msrc, "/proc/net/tcp6", 0444)) - d.AddChild(ctx, "udp", newRPCProcFSFile(ctx, msrc, "/proc/net/udp", 0444)) - d.AddChild(ctx, "udp6", newRPCProcFSFile(ctx, msrc, "/proc/net/udp6", 0444)) - - return newFile(d, msrc, fs.SpecialDirectory, nil) + contents := map[string]*fs.Inode{ + "arp": newRPCInetInode(ctx, msrc, "/proc/net/arp", 0444), + "dev": newRPCInetInode(ctx, msrc, "/proc/net/dev", 0444), + "if_inet6": newRPCInetInode(ctx, msrc, "/proc/net/if_inet6", 0444), + "ipv6_route": newRPCInetInode(ctx, msrc, "/proc/net/ipv6_route", 0444), + "netlink": newRPCInetInode(ctx, msrc, "/proc/net/netlink", 0444), + "netstat": newRPCInetInode(ctx, msrc, "/proc/net/netstat", 0444), + "packet": newRPCInetInode(ctx, msrc, "/proc/net/packet", 0444), + "protocols": newRPCInetInode(ctx, msrc, "/proc/net/protocols", 0444), + "psched": newRPCInetInode(ctx, msrc, "/proc/net/psched", 0444), + "ptype": newRPCInetInode(ctx, msrc, "/proc/net/ptype", 0444), + "route": newRPCInetInode(ctx, msrc, "/proc/net/route", 0444), + "tcp": newRPCInetInode(ctx, msrc, "/proc/net/tcp", 0444), + "tcp6": newRPCInetInode(ctx, msrc, "/proc/net/tcp6", 0444), + "udp": newRPCInetInode(ctx, msrc, "/proc/net/udp", 0444), + "udp6": newRPCInetInode(ctx, msrc, "/proc/net/udp6", 0444), + } + + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } // newRPCInetProcSysNet will build an inode for /proc/sys/net. func newRPCInetProcSysNet(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - d.AddChild(ctx, "ipv4", newRPCInetSysNetIPv4Dir(ctx, msrc)) - d.AddChild(ctx, "core", newRPCInetSysNetCore(ctx, msrc)) + contents := map[string]*fs.Inode{ + "ipv4": newRPCInetSysNetIPv4Dir(ctx, msrc), + "core": newRPCInetSysNetCore(ctx, msrc), + } - return newFile(d, msrc, fs.SpecialDirectory, nil) + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } // newRPCInetSysNetCore builds the /proc/sys/net/core directory. func newRPCInetSysNetCore(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - - // Add all the files we want to forward over RPC for /proc/sys/net/core - d.AddChild(ctx, "default_qdisc", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/default_qdisc", 0444)) - d.AddChild(ctx, "message_burst", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/message_burst", 0444)) - d.AddChild(ctx, "message_cost", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/message_cost", 0444)) - d.AddChild(ctx, "optmem_max", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/optmem_max", 0444)) - d.AddChild(ctx, "rmem_default", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/rmem_default", 0444)) - d.AddChild(ctx, "rmem_max", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/rmem_max", 0444)) - d.AddChild(ctx, "somaxconn", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/somaxconn", 0444)) - d.AddChild(ctx, "wmem_default", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/wmem_default", 0444)) - d.AddChild(ctx, "wmem_max", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/core/wmem_max", 0444)) - - return newFile(d, msrc, fs.SpecialDirectory, nil) + contents := map[string]*fs.Inode{ + "default_qdisc": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/default_qdisc", 0444), + "message_burst": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/message_burst", 0444), + "message_cost": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/message_cost", 0444), + "optmem_max": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/optmem_max", 0444), + "rmem_default": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/rmem_default", 0444), + "rmem_max": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/rmem_max", 0444), + "somaxconn": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/somaxconn", 0444), + "wmem_default": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/wmem_default", 0444), + "wmem_max": newRPCInetInode(ctx, msrc, "/proc/sys/net/core/wmem_max", 0444), + } + + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } // newRPCInetSysNetIPv4Dir builds the /proc/sys/net/ipv4 directory. func newRPCInetSysNetIPv4Dir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - - // Add all the files we want to forward over RPC for /proc/sys/net/ipv4. - d.AddChild(ctx, "ip_local_port_range", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/ip_local_port_range", 0444)) - d.AddChild(ctx, "ip_local_reserved_ports", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/ip_local_reserved_ports", 0444)) - d.AddChild(ctx, "ipfrag_time", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/ipfrag_time", 0444)) - d.AddChild(ctx, "ip_nonlocal_bind", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/ip_nonlocal_bind", 0444)) - d.AddChild(ctx, "ip_no_pmtu_disc", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/ip_no_pmtu_disc", 0444)) - - d.AddChild(ctx, "tcp_allowed_congestion_control", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_allowed_congestion_control", 0444)) - d.AddChild(ctx, "tcp_available_congestion_control", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_available_congestion_control", 0444)) - d.AddChild(ctx, "tcp_base_mss", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_base_mss", 0444)) - d.AddChild(ctx, "tcp_congestion_control", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_congestion_control", 0644)) - d.AddChild(ctx, "tcp_dsack", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_dsack", 0644)) - d.AddChild(ctx, "tcp_early_retrans", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_early_retrans", 0644)) - d.AddChild(ctx, "tcp_fack", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_fack", 0644)) - d.AddChild(ctx, "tcp_fastopen", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_fastopen", 0644)) - d.AddChild(ctx, "tcp_fastopen_key", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_fastopen_key", 0444)) - d.AddChild(ctx, "tcp_fin_timeout", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_fin_timeout", 0644)) - d.AddChild(ctx, "tcp_invalid_ratelimit", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_invalid_ratelimit", 0444)) - d.AddChild(ctx, "tcp_keepalive_intvl", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_keepalive_intvl", 0644)) - d.AddChild(ctx, "tcp_keepalive_probes", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_keepalive_probes", 0644)) - d.AddChild(ctx, "tcp_keepalive_time", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_keepalive_time", 0644)) - d.AddChild(ctx, "tcp_mem", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_mem", 0444)) - d.AddChild(ctx, "tcp_mtu_probing", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_mtu_probing", 0644)) - d.AddChild(ctx, "tcp_no_metrics_save", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_no_metrics_save", 0444)) - d.AddChild(ctx, "tcp_probe_interval", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_probe_interval", 0444)) - d.AddChild(ctx, "tcp_probe_threshold", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_probe_threshold", 0444)) - d.AddChild(ctx, "tcp_retries1", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_retries1", 0644)) - d.AddChild(ctx, "tcp_retries2", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_retries2", 0644)) - d.AddChild(ctx, "tcp_rfc1337", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_rfc1337", 0444)) - d.AddChild(ctx, "tcp_rmem", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_rmem", 0444)) - d.AddChild(ctx, "tcp_sack", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_sack", 0644)) - d.AddChild(ctx, "tcp_slow_start_after_idle", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_slow_start_after_idle", 0644)) - d.AddChild(ctx, "tcp_synack_retries", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_synack_retries", 0644)) - d.AddChild(ctx, "tcp_syn_retries", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_syn_retries", 0644)) - d.AddChild(ctx, "tcp_timestamps", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_timestamps", 0644)) - d.AddChild(ctx, "tcp_wmem", newRPCProcFSFile(ctx, msrc, "/proc/sys/net/ipv4/tcp_wmem", 0444)) - - return newFile(d, msrc, fs.SpecialDirectory, nil) + contents := map[string]*fs.Inode{ + "ip_local_port_range": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/ip_local_port_range", 0444), + "ip_local_reserved_ports": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/ip_local_reserved_ports", 0444), + "ipfrag_time": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/ipfrag_time", 0444), + "ip_nonlocal_bind": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/ip_nonlocal_bind", 0444), + "ip_no_pmtu_disc": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/ip_no_pmtu_disc", 0444), + "tcp_allowed_congestion_control": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_allowed_congestion_control", 0444), + "tcp_available_congestion_control": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_available_congestion_control", 0444), + "tcp_base_mss": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_base_mss", 0444), + "tcp_congestion_control": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_congestion_control", 0644), + "tcp_dsack": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_dsack", 0644), + "tcp_early_retrans": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_early_retrans", 0644), + "tcp_fack": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_fack", 0644), + "tcp_fastopen": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_fastopen", 0644), + "tcp_fastopen_key": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_fastopen_key", 0444), + "tcp_fin_timeout": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_fin_timeout", 0644), + "tcp_invalid_ratelimit": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_invalid_ratelimit", 0444), + "tcp_keepalive_intvl": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_keepalive_intvl", 0644), + "tcp_keepalive_probes": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_keepalive_probes", 0644), + "tcp_keepalive_time": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_keepalive_time", 0644), + "tcp_mem": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_mem", 0444), + "tcp_mtu_probing": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_mtu_probing", 0644), + "tcp_no_metrics_save": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_no_metrics_save", 0444), + "tcp_probe_interval": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_probe_interval", 0444), + "tcp_probe_threshold": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_probe_threshold", 0444), + "tcp_retries1": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_retries1", 0644), + "tcp_retries2": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_retries2", 0644), + "tcp_rfc1337": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_rfc1337", 0444), + "tcp_rmem": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_rmem", 0444), + "tcp_sack": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_sack", 0644), + "tcp_slow_start_after_idle": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_slow_start_after_idle", 0644), + "tcp_synack_retries": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_synack_retries", 0644), + "tcp_syn_retries": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_syn_retries", 0644), + "tcp_timestamps": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_timestamps", 0644), + "tcp_wmem": newRPCInetInode(ctx, msrc, "/proc/sys/net/ipv4/tcp_wmem", 0444), + } + + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index 53c475652..b4ba64e10 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -8,12 +8,15 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/abi/linux", "//pkg/sentry/context", "//pkg/sentry/fs", + "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/proc/device", - "//pkg/sentry/fs/ramfs", "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", + "//pkg/syserror", + "//pkg/waiter", ], ) @@ -26,7 +29,7 @@ go_test( "//pkg/sentry/context", "//pkg/sentry/context/contexttest", "//pkg/sentry/fs", - "//pkg/sentry/fs/ramfs/test", + "//pkg/sentry/fs/ramfs", "//pkg/sentry/usermem", ], ) diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 0499ba65b..16fc6789e 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -18,12 +18,15 @@ import ( "io" "sync" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // SeqHandle is a helper handle to seek in the file. @@ -87,7 +90,18 @@ func (s *SeqGenerationCounter) IsCurrent(generation int64) bool { // // +stateify savable type SeqFile struct { - ramfs.Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleExtendedAttributes + fsutil.InodeSimpleAttributes // mu protects the fields below. mu sync.Mutex `state:"nosave"` @@ -99,11 +113,14 @@ type SeqFile struct { lastRead int64 } +var _ fs.InodeOperations = (*SeqFile)(nil) + // NewSeqFile returns a seqfile suitable for use by external consumers. func NewSeqFile(ctx context.Context, source SeqSource) *SeqFile { - s := &SeqFile{SeqSource: source} - s.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0444)) - return s + return &SeqFile{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + SeqSource: source, + } } // NewSeqFileInode returns an Inode with SeqFile InodeOperations. @@ -120,11 +137,19 @@ func NewSeqFileInode(ctx context.Context, source SeqSource, msrc *fs.MountSource // UnstableAttr returns unstable attributes of the SeqFile. func (s *SeqFile) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - uattr, _ := s.Entry.UnstableAttr(ctx, inode) + uattr, err := s.InodeSimpleAttributes.UnstableAttr(ctx, inode) + if err != nil { + return fs.UnstableAttr{}, err + } uattr.ModificationTime = ktime.NowFromContext(ctx) return uattr, nil } +// GetFile implements fs.InodeOperations.GetFile. +func (s *SeqFile) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &seqFileOperations{seqFile: s}), nil +} + // findIndexAndOffset finds the unit that corresponds to a certain offset. // Returns the unit and the offset within the unit. If there are not enough // units len(data) and leftover offset is returned. @@ -139,36 +164,74 @@ func findIndexAndOffset(data []SeqData, offset int64) (int, int64) { return len(data), offset } -// DeprecatedPreadv reads from the file at the given offset. -func (s *SeqFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - s.mu.Lock() - defer s.mu.Unlock() +// updateSourceLocked requires that s.mu is held. +func (s *SeqFile) updateSourceLocked(ctx context.Context, record int) { + var h SeqHandle + if record == 0 { + h = nil + } else { + h = s.source[record-1].Handle + } + // Save what we have previously read. + s.source = s.source[:record] + var newSource []SeqData + newSource, s.generation = s.SeqSource.ReadSeqFileData(ctx, h) + s.source = append(s.source, newSource...) +} + +// seqFileOperations implements fs.FileOperations. +// +// +stateify savable +type seqFileOperations struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + + seqFile *SeqFile +} + +var _ fs.FileOperations = (*seqFileOperations)(nil) + +// Write implements fs.FileOperations.Write. +func (*seqFileOperations) Write(context.Context, *fs.File, usermem.IOSequence, int64) (int64, error) { + return 0, syserror.EACCES +} + +// Read implements fs.FileOperations.Read. +func (sfo *seqFileOperations) Read(ctx context.Context, file *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { + sfo.seqFile.mu.Lock() + defer sfo.seqFile.mu.Unlock() - s.Entry.NotifyAccess(ctx) - defer func() { s.lastRead = offset }() + sfo.seqFile.NotifyAccess(ctx) + defer func() { sfo.seqFile.lastRead = offset }() updated := false // Try to find where we should start reading this file. - i, recordOffset := findIndexAndOffset(s.source, offset) - if i == len(s.source) { + i, recordOffset := findIndexAndOffset(sfo.seqFile.source, offset) + if i == len(sfo.seqFile.source) { // Ok, we're at EOF. Let's first check to see if there might be // more data available to us. If there is more data, add it to // the end and try reading again. - if !s.SeqSource.NeedsUpdate(s.generation) { + if !sfo.seqFile.SeqSource.NeedsUpdate(sfo.seqFile.generation) { return 0, io.EOF } - oldLen := len(s.source) - s.updateSourceLocked(ctx, len(s.source)) + oldLen := len(sfo.seqFile.source) + sfo.seqFile.updateSourceLocked(ctx, len(sfo.seqFile.source)) updated = true // We know that we had consumed everything up until this point // so we search in the new slice instead of starting over. - i, recordOffset = findIndexAndOffset(s.source[oldLen:], recordOffset) + i, recordOffset = findIndexAndOffset(sfo.seqFile.source[oldLen:], recordOffset) i += oldLen // i is at most the length of the slice which is - // len(s.source) - oldLen. So at most i will be equal to - // len(s.source). - if i == len(s.source) { + // len(sfo.seqFile.source) - oldLen. So at most i will be equal to + // len(sfo.seqFile.source). + if i == len(sfo.seqFile.source) { return 0, io.EOF } } @@ -178,7 +241,7 @@ func (s *SeqFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, // before continuing on to the next. We don't refresh our data source // before this record is completed. if recordOffset != 0 { - n, err := dst.CopyOut(ctx, s.source[i].Buf[recordOffset:]) + n, err := dst.CopyOut(ctx, sfo.seqFile.source[i].Buf[recordOffset:]) done += int64(n) dst = dst.DropFirst(n) if dst.NumBytes() == 0 || err != nil { @@ -190,15 +253,15 @@ func (s *SeqFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, // Next/New unit, update the source file if necessary. Make an extra // check to see if we've seeked backwards and if so always update our // data source. - if !updated && (s.SeqSource.NeedsUpdate(s.generation) || s.lastRead > offset) { - s.updateSourceLocked(ctx, i) + if !updated && (sfo.seqFile.SeqSource.NeedsUpdate(sfo.seqFile.generation) || sfo.seqFile.lastRead > offset) { + sfo.seqFile.updateSourceLocked(ctx, i) // recordOffset is 0 here and we won't update records behind the // current one so recordOffset is still 0 even though source // just got updated. Just read the next record. } // Finish by reading all the available data. - for _, buf := range s.source[i:] { + for _, buf := range sfo.seqFile.source[i:] { n, err := dst.CopyOut(ctx, buf.Buf) done += int64(n) dst = dst.DropFirst(n) @@ -214,23 +277,3 @@ func (s *SeqFile) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, } return done, nil } - -// updateSourceLocked requires that s.mu is held. -func (s *SeqFile) updateSourceLocked(ctx context.Context, record int) { - var h SeqHandle - if record == 0 { - h = nil - } else { - h = s.source[record-1].Handle - } - // Save what we have previously read. - s.source = s.source[:record] - var newSource []SeqData - newSource, s.generation = s.SeqSource.ReadSeqFileData(ctx, h) - s.source = append(s.source, newSource...) -} - -// DeprecatedPwritev is always denied. -func (*SeqFile) DeprecatedPwritev(context.Context, usermem.IOSequence, int64) (int64, error) { - return 0, ramfs.ErrDenied -} diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go index f9a2ca38e..35403ab7f 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile_test.go @@ -23,7 +23,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - ramfstest "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) @@ -91,10 +91,15 @@ type testTable struct { expectedError error } -func runTableTests(ctx context.Context, table []testTable, n fs.InodeOperations) error { +func runTableTests(ctx context.Context, table []testTable, dirent *fs.Dirent) error { for _, tt := range table { + file, err := dirent.Inode.InodeOperations.GetFile(ctx, dirent, fs.FileFlags{Read: true}) + if err != nil { + return fmt.Errorf("GetFile returned error: %v", err) + } + data := make([]byte, tt.readBufferSize) - resultLen, err := n.DeprecatedPreadv(ctx, usermem.BytesIOSequence(data), tt.offset) + resultLen, err := file.Preadv(ctx, usermem.BytesIOSequence(data), tt.offset) if err != tt.expectedError { return fmt.Errorf("t.Preadv(len: %v, offset: %v) (error) => %v expected %v", tt.readBufferSize, tt.offset, err, tt.expectedError) } @@ -115,12 +120,12 @@ func TestSeqFile(t *testing.T) { testSource.Init() // Create a file that can be R/W. - m := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) + m := fs.NewPseudoMountSource() ctx := contexttest.Context(t) contents := map[string]*fs.Inode{ "foo": NewSeqFileInode(ctx, testSource, m), } - root := ramfstest.NewDir(ctx, contents, fs.FilePermsFromMode(0777)) + root := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0777)) // How about opening it? inode := fs.NewInode(root, m, fs.StableAttr{Type: fs.Directory}) @@ -129,9 +134,13 @@ func TestSeqFile(t *testing.T) { t.Fatalf("failed to walk to foo for n2: %v", err) } n2 := dirent2.Inode.InodeOperations + file2, err := n2.GetFile(ctx, dirent2, fs.FileFlags{Read: true, Write: true}) + if err != nil { + t.Fatalf("GetFile returned error: %v", err) + } // Writing? - if _, err := n2.DeprecatedPwritev(nil, usermem.BytesIOSequence([]byte("test")), 0); err == nil { + if _, err := file2.Writev(ctx, usermem.BytesIOSequence([]byte("test"))); err == nil { t.Fatalf("managed to write to n2: %v", err) } @@ -141,7 +150,6 @@ func TestSeqFile(t *testing.T) { t.Fatalf("failed to walk to foo: %v", err) } n3 := dirent3.Inode.InodeOperations - if n2 != n3 { t.Error("got n2 != n3, want same") } @@ -170,13 +178,13 @@ func TestSeqFile(t *testing.T) { // Read the last 3 bytes. {97, 10, testSource.actual[9].Buf[7:], nil}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed with testSource.update = %v : %v", testSource.update, err) } // Disable updates and do it again. testSource.update = false - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed with testSource.update = %v: %v", testSource.update, err) } } @@ -188,25 +196,24 @@ func TestSeqFileFileUpdated(t *testing.T) { testSource.update = true // Create a file that can be R/W. - m := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) + m := fs.NewPseudoMountSource() ctx := contexttest.Context(t) contents := map[string]*fs.Inode{ "foo": NewSeqFileInode(ctx, testSource, m), } - root := ramfstest.NewDir(ctx, contents, fs.FilePermsFromMode(0777)) + root := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0777)) // How about opening it? inode := fs.NewInode(root, m, fs.StableAttr{Type: fs.Directory}) dirent2, err := root.Lookup(ctx, inode, "foo") if err != nil { - t.Fatalf("failed to walk to foo for n2: %v", err) + t.Fatalf("failed to walk to foo for dirent2: %v", err) } - n2 := dirent2.Inode.InodeOperations table := []testTable{ {0, 16, flatten(testSource.actual[0].Buf, testSource.actual[1].Buf[:6]), nil}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed: %v", err) } // Delete the first entry. @@ -224,7 +231,7 @@ func TestSeqFileFileUpdated(t *testing.T) { // Read the following two lines. {30, 20, flatten(testSource.actual[3].Buf, testSource.actual[4].Buf), nil}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed after removing first entry: %v", err) } @@ -238,7 +245,7 @@ func TestSeqFileFileUpdated(t *testing.T) { table = []testTable{ {50, 20, flatten(testSource.actual[4].Buf, testSource.actual[5].Buf), nil}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed after adding middle entry: %v", err) } // This will be used in a later test. @@ -249,7 +256,7 @@ func TestSeqFileFileUpdated(t *testing.T) { table = []testTable{ {20, 20, []byte{}, io.EOF}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed after removing all entries: %v", err) } // Restore some of the data. @@ -257,7 +264,7 @@ func TestSeqFileFileUpdated(t *testing.T) { table = []testTable{ {6, 20, testSource.actual[0].Buf[6:], nil}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed after adding first entry back: %v", err) } @@ -266,7 +273,7 @@ func TestSeqFileFileUpdated(t *testing.T) { table = []testTable{ {30, 20, flatten(testSource.actual[3].Buf, testSource.actual[4].Buf), nil}, } - if err := runTableTests(ctx, table, n2); err != nil { + if err := runTableTests(ctx, table, dirent2); err != nil { t.Errorf("runTableTest failed after extending testSource: %v", err) } } diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index 54562508d..ee6b9f262 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -22,39 +22,15 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/rpcinet" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// hostname is a file containing the system hostname. -// -// +stateify savable -type hostname struct { - ramfs.Entry -} - -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (hostname) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - utsns := kernel.UTSNamespaceFromContext(ctx) - contents := []byte(utsns.HostName() + "\n") - - if offset >= int64(len(contents)) { - return 0, io.EOF - } - - n, err := dst.CopyOut(ctx, contents[offset:]) - return int64(n), err -} - -func (p *proc) newHostname(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - h := &hostname{} - h.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0444)) - return newFile(h, msrc, fs.SpecialFile, nil) -} - // mmapMinAddrData backs /proc/sys/vm/mmap_min_addr. // // +stateify savable @@ -101,36 +77,84 @@ func (*overcommitMemory) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandl } func (p *proc) newKernelDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - d.AddChild(ctx, "hostname", p.newHostname(ctx, msrc)) - - d.AddChild(ctx, "shmmax", p.newStubProcFSFile(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMAX, 10)))) - d.AddChild(ctx, "shmall", p.newStubProcFSFile(ctx, msrc, []byte(strconv.FormatUint(linux.SHMALL, 10)))) - d.AddChild(ctx, "shmmni", p.newStubProcFSFile(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMNI, 10)))) - return newFile(d, msrc, fs.SpecialDirectory, nil) + h := hostname{ + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + } + + children := map[string]*fs.Inode{ + "hostname": newProcInode(&h, msrc, fs.SpecialFile, nil), + "shmall": newStaticProcInode(ctx, msrc, []byte(strconv.FormatUint(linux.SHMALL, 10))), + "shmmax": newStaticProcInode(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMAX, 10))), + "shmmni": newStaticProcInode(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMNI, 10))), + } + + d := ramfs.NewDir(ctx, children, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } func (p *proc) newVMDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - d.AddChild(ctx, "mmap_min_addr", seqfile.NewSeqFileInode(ctx, &mmapMinAddrData{p.k}, msrc)) - d.AddChild(ctx, "overcommit_memory", seqfile.NewSeqFileInode(ctx, &overcommitMemory{}, msrc)) - return newFile(d, msrc, fs.SpecialDirectory, nil) + children := map[string]*fs.Inode{ + "mmap_min_addr": seqfile.NewSeqFileInode(ctx, &mmapMinAddrData{p.k}, msrc), + "overcommit_memory": seqfile.NewSeqFileInode(ctx, &overcommitMemory{}, msrc), + } + d := ramfs.NewDir(ctx, children, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } func (p *proc) newSysDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - d.AddChild(ctx, "kernel", p.newKernelDir(ctx, msrc)) - d.AddChild(ctx, "vm", p.newVMDir(ctx, msrc)) + children := map[string]*fs.Inode{ + "kernel": p.newKernelDir(ctx, msrc), + "vm": p.newVMDir(ctx, msrc), + } // If we're using rpcinet we will let it manage /proc/sys/net. if _, ok := p.k.NetworkStack().(*rpcinet.Stack); ok { - d.AddChild(ctx, "net", newRPCInetProcSysNet(ctx, msrc)) + children["net"] = newRPCInetProcSysNet(ctx, msrc) } else { - d.AddChild(ctx, "net", p.newSysNetDir(ctx, msrc)) + children["net"] = p.newSysNetDir(ctx, msrc) } - return newFile(d, msrc, fs.SpecialDirectory, nil) + d := ramfs.NewDir(ctx, children, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) +} + +// hostname is the inode for a file containing the system hostname. +// +// +stateify savable +type hostname struct { + fsutil.SimpleFileInode +} + +// GetFile implements fs.InodeOperations.GetFile. +func (h *hostname) GetFile(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, d, flags, &hostnameFile{}), nil +} + +var _ fs.InodeOperations = (*hostname)(nil) + +// +stateify savable +type hostnameFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSeek `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` } + +// Read implements fs.FileOperations.Read. +func (hf *hostnameFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { + utsns := kernel.UTSNamespaceFromContext(ctx) + contents := []byte(utsns.HostName() + "\n") + if offset >= int64(len(contents)) { + return 0, io.EOF + } + n, err := dst.CopyOut(ctx, contents[offset:]) + return int64(n), err + +} + +var _ fs.FileOperations = (*hostnameFile)(nil) diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index b50d43d70..42e9bc47f 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -17,13 +17,17 @@ package proc import ( "fmt" "io" + "sync" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/inet" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) type tcpMemDir int @@ -33,21 +37,37 @@ const ( tcpWMem ) +// tcpMemInode is used to read/write the size of netstack tcp buffers. +// +// TODO: If we have multiple proc mounts, concurrent writes can +// leave netstack and the proc files in an inconsistent state. Since we set the +// buffer size from these proc files on restore, we may also race and end up in +// an inconsistent state on restore. +// // +stateify savable -type tcpMem struct { - ramfs.Entry - s inet.Stack `state:"wait"` +type tcpMemInode struct { + fsutil.SimpleFileInode + dir tcpMemDir + s inet.Stack `state:"wait"` + + // size stores the tcp buffer size during save, and sets the buffer + // size in netstack in restore. We must save/restore this here, since + // netstack itself is stateless. size inet.TCPBufferSize - dir tcpMemDir -} -func newTCPMem(s inet.Stack, size inet.TCPBufferSize, dir tcpMemDir) *tcpMem { - return &tcpMem{s: s, size: size, dir: dir} + // mu protects against concurrent reads/writes to files based on this + // inode. + mu sync.Mutex `state:"nosave"` } -func newTCPMemInode(ctx context.Context, msrc *fs.MountSource, s inet.Stack, size inet.TCPBufferSize, dir tcpMemDir) *fs.Inode { - tm := newTCPMem(s, size, dir) - tm.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0644)) +var _ fs.InodeOperations = (*tcpMemInode)(nil) + +func newTCPMemInode(ctx context.Context, msrc *fs.MountSource, s inet.Stack, dir tcpMemDir) *fs.Inode { + tm := &tcpMemInode{ + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + s: s, + dir: dir, + } sattr := fs.StableAttr{ DeviceID: device.ProcDevice.DeviceID(), InodeID: device.ProcDevice.NextIno(), @@ -57,62 +77,105 @@ func newTCPMemInode(ctx context.Context, msrc *fs.MountSource, s inet.Stack, siz return fs.NewInode(tm, msrc, sattr) } -// DeprecatedPreadv implements fs.InodeOperations.DeprecatedPreadv. -func (m *tcpMem) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { +// GetFile implements fs.InodeOperations.GetFile. +func (m *tcpMemInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + flags.Pread = true + return fs.NewFile(ctx, dirent, flags, &tcpMemFile{tcpMemInode: m}), nil +} + +// +stateify savable +type tcpMemFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + + tcpMemInode *tcpMemInode +} + +var _ fs.FileOperations = (*tcpMemFile)(nil) + +// Read implements fs.FileOperations.Read. +func (f *tcpMemFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { if offset != 0 { return 0, io.EOF } - s := fmt.Sprintf("%d\t%d\t%d\n", m.size.Min, m.size.Default, m.size.Max) + f.tcpMemInode.mu.Lock() + defer f.tcpMemInode.mu.Unlock() + + size, err := readSize(f.tcpMemInode.dir, f.tcpMemInode.s) + if err != nil { + return 0, err + } + s := fmt.Sprintf("%d\t%d\t%d\n", size.Min, size.Default, size.Max) n, err := dst.CopyOut(ctx, []byte(s)) return int64(n), err } -// Truncate implements fs.InodeOperations.Truncate. -func (*tcpMem) Truncate(context.Context, *fs.Inode, int64) error { - return nil -} - -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev. -func (m *tcpMem) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { +// Write implements fs.FileOperations.Write. +func (f *tcpMemFile) Write(ctx context.Context, _ *fs.File, src usermem.IOSequence, offset int64) (int64, error) { if src.NumBytes() == 0 { return 0, nil } - src = src.TakeFirst(usermem.PageSize - 1) + f.tcpMemInode.mu.Lock() + defer f.tcpMemInode.mu.Unlock() - buf := []int32{int32(m.size.Min), int32(m.size.Default), int32(m.size.Max)} + src = src.TakeFirst(usermem.PageSize - 1) + size, err := readSize(f.tcpMemInode.dir, f.tcpMemInode.s) + if err != nil { + return 0, err + } + buf := []int32{int32(size.Min), int32(size.Default), int32(size.Max)} n, cperr := usermem.CopyInt32StringsInVec(ctx, src.IO, src.Addrs, buf, src.Opts) - m.size = inet.TCPBufferSize{ + newSize := inet.TCPBufferSize{ Min: int(buf[0]), Default: int(buf[1]), Max: int(buf[2]), } - if err := m.writeSize(); err != nil { + if err := writeSize(f.tcpMemInode.dir, f.tcpMemInode.s, newSize); err != nil { return n, err } return n, cperr } -func (m *tcpMem) writeSize() error { - switch m.dir { +func readSize(dirType tcpMemDir, s inet.Stack) (inet.TCPBufferSize, error) { + switch dirType { + case tcpRMem: + return s.TCPReceiveBufferSize() + case tcpWMem: + return s.TCPSendBufferSize() + default: + panic(fmt.Sprintf("unknown tcpMemFile type: %v", dirType)) + } +} + +func writeSize(dirType tcpMemDir, s inet.Stack, size inet.TCPBufferSize) error { + switch dirType { case tcpRMem: - return m.s.SetTCPReceiveBufferSize(m.size) + return s.SetTCPReceiveBufferSize(size) case tcpWMem: - return m.s.SetTCPSendBufferSize(m.size) + return s.SetTCPSendBufferSize(size) default: - panic(fmt.Sprintf("unknown tcpMem.dir: %v", m.dir)) + panic(fmt.Sprintf("unknown tcpMemFile type: %v", dirType)) } } // +stateify savable type tcpSack struct { - ramfs.Entry - s inet.Stack `state:"wait"` + stack inet.Stack `state:"wait"` enabled *bool + fsutil.SimpleFileInode } func newTCPSackInode(ctx context.Context, msrc *fs.MountSource, s inet.Stack) *fs.Inode { - ts := &tcpSack{s: s} - ts.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0644)) + ts := &tcpSack{ + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + stack: s, + } sattr := fs.StableAttr{ DeviceID: device.ProcDevice.DeviceID(), InodeID: device.ProcDevice.NextIno(), @@ -122,21 +185,48 @@ func newTCPSackInode(ctx context.Context, msrc *fs.MountSource, s inet.Stack) *f return fs.NewInode(ts, msrc, sattr) } -func (s *tcpSack) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { +// GetFile implements fs.InodeOperations.GetFile. +func (s *tcpSack) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + flags.Pread = true + flags.Pwrite = true + return fs.NewFile(ctx, dirent, flags, &tcpSackFile{ + tcpSack: s, + stack: s.stack, + }), nil +} + +// +stateify savable +type tcpSackFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + + tcpSack *tcpSack + + stack inet.Stack `state:"wait"` +} + +// Read implements fs.FileOperations.Read. +func (f *tcpSackFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { if offset != 0 { return 0, io.EOF } - if s.enabled == nil { - sack, err := s.s.TCPSACKEnabled() + if f.tcpSack.enabled == nil { + sack, err := f.stack.TCPSACKEnabled() if err != nil { return 0, err } - s.enabled = &sack + f.tcpSack.enabled = &sack } val := "0\n" - if *s.enabled { + if *f.tcpSack.enabled { // Technically, this is not quite compatible with Linux. Linux // stores these as an integer, so if you write "2" into // tcp_sack, you should get 2 back. Tough luck. @@ -146,13 +236,8 @@ func (s *tcpSack) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, return int64(n), err } -// Truncate implements fs.InodeOperations.Truncate. -func (*tcpSack) Truncate(context.Context, *fs.Inode, int64) error { - return nil -} - -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev. -func (s *tcpSack) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { +// Write implements fs.FileOperations.Write. +func (f *tcpSackFile) Write(ctx context.Context, _ *fs.File, src usermem.IOSequence, offset int64) (int64, error) { if src.NumBytes() == 0 { return 0, nil } @@ -163,100 +248,104 @@ func (s *tcpSack) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, if err != nil { return n, err } - if s.enabled == nil { - s.enabled = new(bool) + if f.tcpSack.enabled == nil { + f.tcpSack.enabled = new(bool) } - *s.enabled = v != 0 - return n, s.s.SetTCPSACKEnabled(*s.enabled) + *f.tcpSack.enabled = v != 0 + return n, f.tcpSack.stack.SetTCPSACKEnabled(*f.tcpSack.enabled) } func (p *proc) newSysNetCore(ctx context.Context, msrc *fs.MountSource, s inet.Stack) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - // The following files are simple stubs until they are implemented in // netstack, most of these files are configuration related. We use the // value closest to the actual netstack behavior or any empty file, // all of these files will have mode 0444 (read-only for all users). - d.AddChild(ctx, "default_qdisc", p.newStubProcFSFile(ctx, msrc, []byte("pfifo_fast"))) - d.AddChild(ctx, "message_burst", p.newStubProcFSFile(ctx, msrc, []byte("10"))) - d.AddChild(ctx, "message_cost", p.newStubProcFSFile(ctx, msrc, []byte("5"))) - d.AddChild(ctx, "optmem_max", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "rmem_default", p.newStubProcFSFile(ctx, msrc, []byte("212992"))) - d.AddChild(ctx, "rmem_max", p.newStubProcFSFile(ctx, msrc, []byte("212992"))) - d.AddChild(ctx, "somaxconn", p.newStubProcFSFile(ctx, msrc, []byte("128"))) - d.AddChild(ctx, "wmem_default", p.newStubProcFSFile(ctx, msrc, []byte("212992"))) - d.AddChild(ctx, "wmem_max", p.newStubProcFSFile(ctx, msrc, []byte("212992"))) - - return newFile(d, msrc, fs.SpecialDirectory, nil) + contents := map[string]*fs.Inode{ + "default_qdisc": newStaticProcInode(ctx, msrc, []byte("pfifo_fast")), + "message_burst": newStaticProcInode(ctx, msrc, []byte("10")), + "message_cost": newStaticProcInode(ctx, msrc, []byte("5")), + "optmem_max": newStaticProcInode(ctx, msrc, []byte("0")), + "rmem_default": newStaticProcInode(ctx, msrc, []byte("212992")), + "rmem_max": newStaticProcInode(ctx, msrc, []byte("212992")), + "somaxconn": newStaticProcInode(ctx, msrc, []byte("128")), + "wmem_default": newStaticProcInode(ctx, msrc, []byte("212992")), + "wmem_max": newStaticProcInode(ctx, msrc, []byte("212992")), + } + + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } func (p *proc) newSysNetIPv4Dir(ctx context.Context, msrc *fs.MountSource, s inet.Stack) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) + contents := map[string]*fs.Inode{ + // Add tcp_sack. + "tcp_sack": newTCPSackInode(ctx, msrc, s), + + // The following files are simple stubs until they are + // implemented in netstack, most of these files are + // configuration related. We use the value closest to the + // actual netstack behavior or any empty file, all of these + // files will have mode 0444 (read-only for all users). + "ip_local_port_range": newStaticProcInode(ctx, msrc, []byte("16000 65535")), + "ip_local_reserved_ports": newStaticProcInode(ctx, msrc, []byte("")), + "ipfrag_time": newStaticProcInode(ctx, msrc, []byte("30")), + "ip_nonlocal_bind": newStaticProcInode(ctx, msrc, []byte("0")), + "ip_no_pmtu_disc": newStaticProcInode(ctx, msrc, []byte("1")), + + // tcp_allowed_congestion_control tell the user what they are + // able to do as an unprivledged process so we leave it empty. + "tcp_allowed_congestion_control": newStaticProcInode(ctx, msrc, []byte("")), + "tcp_available_congestion_control": newStaticProcInode(ctx, msrc, []byte("reno")), + "tcp_congestion_control": newStaticProcInode(ctx, msrc, []byte("reno")), + + // Many of the following stub files are features netstack + // doesn't support. The unsupported features return "0" to + // indicate they are disabled. + "tcp_base_mss": newStaticProcInode(ctx, msrc, []byte("1280")), + "tcp_dsack": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_early_retrans": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_fack": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_fastopen": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_fastopen_key": newStaticProcInode(ctx, msrc, []byte("")), + "tcp_invalid_ratelimit": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_keepalive_intvl": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_keepalive_probes": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_keepalive_time": newStaticProcInode(ctx, msrc, []byte("7200")), + "tcp_mtu_probing": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_no_metrics_save": newStaticProcInode(ctx, msrc, []byte("1")), + "tcp_probe_interval": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_probe_threshold": newStaticProcInode(ctx, msrc, []byte("0")), + "tcp_retries1": newStaticProcInode(ctx, msrc, []byte("3")), + "tcp_retries2": newStaticProcInode(ctx, msrc, []byte("15")), + "tcp_rfc1337": newStaticProcInode(ctx, msrc, []byte("1")), + "tcp_slow_start_after_idle": newStaticProcInode(ctx, msrc, []byte("1")), + "tcp_synack_retries": newStaticProcInode(ctx, msrc, []byte("5")), + "tcp_syn_retries": newStaticProcInode(ctx, msrc, []byte("3")), + "tcp_timestamps": newStaticProcInode(ctx, msrc, []byte("1")), + } // Add tcp_rmem. - if rs, err := s.TCPReceiveBufferSize(); err == nil { - d.AddChild(ctx, "tcp_rmem", newTCPMemInode(ctx, msrc, s, rs, tcpRMem)) + if _, err := s.TCPReceiveBufferSize(); err == nil { + contents["tcp_rmem"] = newTCPMemInode(ctx, msrc, s, tcpRMem) } // Add tcp_wmem. - if ss, err := s.TCPSendBufferSize(); err == nil { - d.AddChild(ctx, "tcp_wmem", newTCPMemInode(ctx, msrc, s, ss, tcpWMem)) + if _, err := s.TCPSendBufferSize(); err == nil { + contents["tcp_wmem"] = newTCPMemInode(ctx, msrc, s, tcpWMem) } - // Add tcp_sack. - d.AddChild(ctx, "tcp_sack", newTCPSackInode(ctx, msrc, s)) - - // The following files are simple stubs until they are implemented in - // netstack, most of these files are configuration related. We use the - // value closest to the actual netstack behavior or any empty file, - // all of these files will have mode 0444 (read-only for all users). - d.AddChild(ctx, "ip_local_port_range", p.newStubProcFSFile(ctx, msrc, []byte("16000 65535"))) - d.AddChild(ctx, "ip_local_reserved_ports", p.newStubProcFSFile(ctx, msrc, []byte(""))) - d.AddChild(ctx, "ipfrag_time", p.newStubProcFSFile(ctx, msrc, []byte("30"))) - d.AddChild(ctx, "ip_nonlocal_bind", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "ip_no_pmtu_disc", p.newStubProcFSFile(ctx, msrc, []byte("1"))) - - // tcp_allowed_congestion_control tell the user what they are able to do as an - // unprivledged process so we leave it empty. - d.AddChild(ctx, "tcp_allowed_congestion_control", p.newStubProcFSFile(ctx, msrc, []byte(""))) - d.AddChild(ctx, "tcp_available_congestion_control", p.newStubProcFSFile(ctx, msrc, []byte("reno"))) - d.AddChild(ctx, "tcp_congestion_control", p.newStubProcFSFile(ctx, msrc, []byte("reno"))) - - // Many of the following stub files are features netstack doesn't support - // and are therefore "0" for disabled. - d.AddChild(ctx, "tcp_base_mss", p.newStubProcFSFile(ctx, msrc, []byte("1280"))) - d.AddChild(ctx, "tcp_dsack", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_early_retrans", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_fack", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_fastopen", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_fastopen_key", p.newStubProcFSFile(ctx, msrc, []byte(""))) - d.AddChild(ctx, "tcp_invalid_ratelimit", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_keepalive_intvl", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_keepalive_probes", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_keepalive_time", p.newStubProcFSFile(ctx, msrc, []byte("7200"))) - d.AddChild(ctx, "tcp_mtu_probing", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_no_metrics_save", p.newStubProcFSFile(ctx, msrc, []byte("1"))) - d.AddChild(ctx, "tcp_probe_interval", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_probe_threshold", p.newStubProcFSFile(ctx, msrc, []byte("0"))) - d.AddChild(ctx, "tcp_retries1", p.newStubProcFSFile(ctx, msrc, []byte("3"))) - d.AddChild(ctx, "tcp_retries2", p.newStubProcFSFile(ctx, msrc, []byte("15"))) - d.AddChild(ctx, "tcp_rfc1337", p.newStubProcFSFile(ctx, msrc, []byte("1"))) - d.AddChild(ctx, "tcp_slow_start_after_idle", p.newStubProcFSFile(ctx, msrc, []byte("1"))) - d.AddChild(ctx, "tcp_synack_retries", p.newStubProcFSFile(ctx, msrc, []byte("5"))) - d.AddChild(ctx, "tcp_syn_retries", p.newStubProcFSFile(ctx, msrc, []byte("3"))) - d.AddChild(ctx, "tcp_timestamps", p.newStubProcFSFile(ctx, msrc, []byte("1"))) - - return newFile(d, msrc, fs.SpecialDirectory, nil) + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } func (p *proc) newSysNetDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) + var contents map[string]*fs.Inode if s := p.k.NetworkStack(); s != nil { - d.AddChild(ctx, "ipv4", p.newSysNetIPv4Dir(ctx, msrc, s)) - d.AddChild(ctx, "core", p.newSysNetCore(ctx, msrc, s)) + contents = map[string]*fs.Inode{ + "ipv4": p.newSysNetIPv4Dir(ctx, msrc, s), + "core": p.newSysNetCore(ctx, msrc, s), + } } - return newFile(d, msrc, fs.SpecialDirectory, nil) + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + return newProcInode(d, msrc, fs.SpecialDirectory, nil) } diff --git a/pkg/sentry/fs/proc/sys_net_state.go b/pkg/sentry/fs/proc/sys_net_state.go index 7f46776c0..5f481a1cf 100644 --- a/pkg/sentry/fs/proc/sys_net_state.go +++ b/pkg/sentry/fs/proc/sys_net_state.go @@ -16,17 +16,26 @@ package proc import "fmt" +// beforeSave is invoked by stateify. +func (t *tcpMemInode) beforeSave() { + size, err := readSize(t.dir, t.s) + if err != nil { + panic(fmt.Sprintf("failed to read TCP send / receive buffer sizes: %v", err)) + } + t.size = size +} + // afterLoad is invoked by stateify. -func (m *tcpMem) afterLoad() { - if err := m.writeSize(); err != nil { - panic(fmt.Sprintf("failed to write previous TCP send / receive buffer sizes [%v]: %v", m.size, err)) +func (t *tcpMemInode) afterLoad() { + if err := writeSize(t.dir, t.s, t.size); err != nil { + panic(fmt.Sprintf("failed to write previous TCP send / receive buffer sizes [%v]: %v", t.size, err)) } } // afterLoad is invoked by stateify. func (s *tcpSack) afterLoad() { if s.enabled != nil { - if err := s.s.SetTCPSACKEnabled(*s.enabled); err != nil { + if err := s.stack.SetTCPSACKEnabled(*s.enabled); err != nil { panic(fmt.Sprintf("failed to set previous TCP sack configuration [%v]: %v", *s.enabled, err)) } } diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go index 0ce9d30f1..ea0d94fce 100644 --- a/pkg/sentry/fs/proc/sys_net_test.go +++ b/pkg/sentry/fs/proc/sys_net_test.go @@ -26,13 +26,14 @@ func TestQuerySendBufferSize(t *testing.T) { ctx := context.Background() s := inet.NewTestStack() s.TCPSendBufSize = inet.TCPBufferSize{100, 200, 300} - tm := newTCPMem(s, s.TCPSendBufSize, tcpWMem) + tmi := &tcpMemInode{s: s, dir: tcpWMem} + tmf := &tcpMemFile{tcpMemInode: tmi} buf := make([]byte, 100) dst := usermem.BytesIOSequence(buf) - n, err := tm.DeprecatedPreadv(ctx, dst, 0) + n, err := tmf.Read(ctx, nil, dst, 0) if err != nil { - t.Fatalf("DeprecatedPreadv failed: %v", err) + t.Fatalf("Read failed: %v", err) } if got, want := string(buf[:n]), "100\t200\t300\n"; got != want { @@ -44,13 +45,14 @@ func TestQueryRecvBufferSize(t *testing.T) { ctx := context.Background() s := inet.NewTestStack() s.TCPRecvBufSize = inet.TCPBufferSize{100, 200, 300} - tm := newTCPMem(s, s.TCPRecvBufSize, tcpRMem) + tmi := &tcpMemInode{s: s, dir: tcpRMem} + tmf := &tcpMemFile{tcpMemInode: tmi} buf := make([]byte, 100) dst := usermem.BytesIOSequence(buf) - n, err := tm.DeprecatedPreadv(ctx, dst, 0) + n, err := tmf.Read(ctx, nil, dst, 0) if err != nil { - t.Fatalf("DeprecatedPreadv failed: %v", err) + t.Fatalf("Read failed: %v", err) } if got, want := string(buf[:n]), "100\t200\t300\n"; got != want { @@ -85,12 +87,13 @@ func TestConfigureSendBufferSize(t *testing.T) { s := inet.NewTestStack() for _, c := range cases { s.TCPSendBufSize = c.initial - tm := newTCPMem(s, c.initial, tcpWMem) + tmi := &tcpMemInode{s: s, dir: tcpWMem} + tmf := &tcpMemFile{tcpMemInode: tmi} // Write the values. src := usermem.BytesIOSequence([]byte(c.str)) - if n, err := tm.DeprecatedPwritev(ctx, src, 0); n != int64(len(c.str)) || err != nil { - t.Errorf("DeprecatedPwritev, case = %q: got (%d, %v), wanted (%d, nil)", c.str, n, err, len(c.str)) + if n, err := tmf.Write(ctx, nil, src, 0); n != int64(len(c.str)) || err != nil { + t.Errorf("Write, case = %q: got (%d, %v), wanted (%d, nil)", c.str, n, err, len(c.str)) } // Read the values from the stack and check them. @@ -105,12 +108,13 @@ func TestConfigureRecvBufferSize(t *testing.T) { s := inet.NewTestStack() for _, c := range cases { s.TCPRecvBufSize = c.initial - tm := newTCPMem(s, c.initial, tcpRMem) + tmi := &tcpMemInode{s: s, dir: tcpRMem} + tmf := &tcpMemFile{tcpMemInode: tmi} // Write the values. src := usermem.BytesIOSequence([]byte(c.str)) - if n, err := tm.DeprecatedPwritev(ctx, src, 0); n != int64(len(c.str)) || err != nil { - t.Errorf("DeprecatedPwritev, case = %q: got (%d, %v), wanted (%d, nil)", c.str, n, err, len(c.str)) + if n, err := tmf.Write(ctx, nil, src, 0); n != int64(len(c.str)) || err != nil { + t.Errorf("Write, case = %q: got (%d, %v), wanted (%d, nil)", c.str, n, err, len(c.str)) } // Read the values from the stack and check them. diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 91bda8a95..41981a973 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -24,6 +24,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/device" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" @@ -32,6 +33,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usage" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // getTaskMM returns t's MemoryManager. If getTaskMM succeeds, the MemoryManager's @@ -57,19 +59,19 @@ func getTaskMM(t *kernel.Task) (*mm.MemoryManager, error) { type taskDir struct { ramfs.Dir - // t is the associated kernel task that owns this file. - t *kernel.Task + t *kernel.Task + pidns *kernel.PIDNamespace } +var _ fs.InodeOperations = (*taskDir)(nil) + // newTaskDir creates a new proc task entry. func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace, showSubtasks bool) *fs.Inode { - d := &taskDir{t: t} - // TODO: Set EUID/EGID based on dumpability. - d.InitDir(t, map[string]*fs.Inode{ + contents := map[string]*fs.Inode{ "auxv": newAuxvec(t, msrc), - "cmdline": newExecArgFile(t, msrc, cmdlineExecArg), + "cmdline": newExecArgInode(t, msrc, cmdlineExecArg), "comm": newComm(t, msrc), - "environ": newExecArgFile(t, msrc, environExecArg), + "environ": newExecArgInode(t, msrc, environExecArg), "exe": newExe(t, msrc), "fd": newFdDir(t, msrc), "fdinfo": newFdInfoDir(t, msrc), @@ -87,11 +89,18 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace "statm": newStatm(t, msrc), "status": newStatus(t, msrc, pidns), "uid_map": newUIDMap(t, msrc), - }, fs.RootOwner, fs.FilePermsFromMode(0555)) + } if showSubtasks { - d.AddChild(t, "task", newSubtasks(t, msrc, pidns)) + contents["task"] = newSubtasks(t, msrc, pidns) } - return newFile(d, msrc, fs.SpecialDirectory, t) + + // TODO: Set EUID/EGID based on dumpability. + d := &taskDir{ + Dir: *ramfs.NewDir(t, contents, fs.RootOwner, fs.FilePermsFromMode(0555)), + t: t, + pidns: pidns, + } + return newProcInode(d, msrc, fs.SpecialDirectory, t) } // subtasks represents a /proc/TID/task directory. @@ -100,15 +109,19 @@ func newTaskDir(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace type subtasks struct { ramfs.Dir - t *kernel.Task - + t *kernel.Task pidns *kernel.PIDNamespace } +var _ fs.InodeOperations = (*subtasks)(nil) + func newSubtasks(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace) *fs.Inode { - s := &subtasks{t: t, pidns: pidns} - s.InitDir(t, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) - return newFile(s, msrc, fs.SpecialDirectory, t) + s := &subtasks{ + Dir: *ramfs.NewDir(t, nil, fs.RootOwner, fs.FilePermsFromMode(0555)), + t: t, + pidns: pidns, + } + return newProcInode(s, msrc, fs.SpecialDirectory, t) } // UnstableAttr returns unstable attributes of the subtasks. @@ -123,35 +136,52 @@ func (s *subtasks) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.Unstab return uattr, nil } -// Lookup loads an Inode in a task's subtask directory into a Dirent. -func (s *subtasks) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, error) { - tid, err := strconv.ParseUint(p, 10, 32) - if err != nil { - return nil, syserror.ENOENT - } +// GetFile implements fs.InodeOperations.GetFile. +func (s *subtasks) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &subtasksFile{t: s.t, pidns: s.pidns}), nil +} - task := s.pidns.TaskWithID(kernel.ThreadID(tid)) - if task == nil { - return nil, syserror.ENOENT - } - if task.ThreadGroup() != s.t.ThreadGroup() { - return nil, syserror.ENOENT - } +// +stateify savable +type subtasksFile struct { + fsutil.DirFileOperations `state:"nosave"` - td := newTaskDir(task, dir.MountSource, s.pidns, false) - return fs.NewDirent(td, p), nil + t *kernel.Task + pidns *kernel.PIDNamespace } -// DeprecatedReaddir lists a task's subtask directory. -func (s *subtasks) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - tasks := s.t.ThreadGroup().MemberIDs(s.pidns) +// Readdir implements fs.FileOperations.Readdir. +func (f *subtasksFile) Readdir(ctx context.Context, file *fs.File, ser fs.DentrySerializer) (int64, error) { + dirCtx := fs.DirCtx{ + Serializer: ser, + } + + // Note that unlike most Readdir implementations, the offset here is + // not an index into the subtasks, but rather the TID of the next + // subtask to emit. + offset := file.Offset() + + if offset == 0 { + // Serialize "." and "..". + root := fs.RootFromContext(ctx) + defer root.DecRef() + dot, dotdot := file.Dirent.GetDotAttrs(root) + if err := dirCtx.DirEmit(".", dot); err != nil { + return offset, err + } + if err := dirCtx.DirEmit("..", dotdot); err != nil { + return offset, err + } + } + + // Serialize tasks. + tasks := f.t.ThreadGroup().MemberIDs(f.pidns) taskInts := make([]int, 0, len(tasks)) for _, tid := range tasks { taskInts = append(taskInts, int(tid)) } // Find the task to start at. - idx := sort.SearchInts(taskInts, offset) + idx := sort.SearchInts(taskInts, int(offset)) if idx == len(taskInts) { return offset, nil } @@ -163,12 +193,33 @@ func (s *subtasks) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, off attr := fs.GenericDentAttr(fs.SpecialDirectory, device.ProcDevice) if err := dirCtx.DirEmit(name, attr); err != nil { // Returned offset is next tid to serialize. - return tid, err + return int64(tid), err } } // We serialized them all. Next offset should be higher than last // serialized tid. - return tid + 1, nil + return int64(tid) + 1, nil +} + +var _ fs.FileOperations = (*subtasksFile)(nil) + +// Lookup loads an Inode in a task's subtask directory into a Dirent. +func (s *subtasks) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, error) { + tid, err := strconv.ParseUint(p, 10, 32) + if err != nil { + return nil, syserror.ENOENT + } + + task := s.pidns.TaskWithID(kernel.ThreadID(tid)) + if task == nil { + return nil, syserror.ENOENT + } + if task.ThreadGroup() != s.t.ThreadGroup() { + return nil, syserror.ENOENT + } + + td := newTaskDir(task, dir.MountSource, s.pidns, false) + return fs.NewDirent(td, p), nil } // exe is an fs.InodeOperations symlink for the /proc/PID/exe file. @@ -181,9 +232,11 @@ type exe struct { } func newExe(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - exeSymlink := &exe{t: t} - exeSymlink.InitSymlink(t, fs.RootOwner, "") - return newFile(exeSymlink, msrc, fs.Symlink, t) + exeSymlink := &exe{ + Symlink: *ramfs.NewSymlink(t, fs.RootOwner, ""), + t: t, + } + return newProcInode(exeSymlink, msrc, fs.Symlink, t) } func (e *exe) executable() (d *fs.Dirent, err error) { @@ -231,55 +284,48 @@ func (e *exe) Readlink(ctx context.Context, inode *fs.Inode) (string, error) { return n, nil } -// namespaceFile represents a file in the namespacefs, such as the files in -// /proc//ns. +// namespaceSymlink represents a symlink in the namespacefs, such as the files +// in /proc//ns. // // +stateify savable -type namespaceFile struct { +type namespaceSymlink struct { ramfs.Symlink t *kernel.Task } -func newNamespaceFile(t *kernel.Task, msrc *fs.MountSource, name string) *fs.Inode { - n := &namespaceFile{t: t} - n.InitSymlink(t, fs.RootOwner, "") - +func newNamespaceSymlink(t *kernel.Task, msrc *fs.MountSource, name string) *fs.Inode { // TODO: Namespace symlinks should contain the namespace name and the // inode number for the namespace instance, so for example user:[123456]. We // currently fake the inode number by sticking the symlink inode in its // place. - n.Target = fmt.Sprintf("%s:[%d]", name, device.ProcDevice.NextIno()) - - return newFile(n, msrc, fs.Symlink, t) + target := fmt.Sprintf("%s:[%d]", name, device.ProcDevice.NextIno()) + n := &namespaceSymlink{ + Symlink: *ramfs.NewSymlink(t, fs.RootOwner, target), + t: t, + } + return newProcInode(n, msrc, fs.Symlink, t) } // Getlink implements fs.InodeOperations.Getlink. -func (n *namespaceFile) Getlink(ctx context.Context, inode *fs.Inode) (*fs.Dirent, error) { +func (n *namespaceSymlink) Getlink(ctx context.Context, inode *fs.Inode) (*fs.Dirent, error) { if !kernel.ContextCanTrace(ctx, n.t, false) { return nil, syserror.EACCES } // Create a new regular file to fake the namespace file. - node := &ramfs.Entry{} - node.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0777)) - sattr := fs.StableAttr{ - DeviceID: device.ProcDevice.DeviceID(), - InodeID: device.ProcDevice.NextIno(), - BlockSize: usermem.PageSize, - Type: fs.RegularFile, - } - return fs.NewDirent(fs.NewInode(node, inode.MountSource, sattr), n.Symlink.Target), nil + iops := fsutil.NewNoReadWriteFileInode(ctx, fs.RootOwner, fs.FilePermsFromMode(0777), linux.PROC_SUPER_MAGIC) + return fs.NewDirent(newProcInode(iops, inode.MountSource, fs.RegularFile, nil), n.Symlink.Target), nil } func newNamespaceDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - d := &ramfs.Dir{} - d.InitDir(t, map[string]*fs.Inode{ - "net": newNamespaceFile(t, msrc, "net"), - "pid": newNamespaceFile(t, msrc, "pid"), - "user": newNamespaceFile(t, msrc, "user"), - }, fs.RootOwner, fs.FilePermsFromMode(0511)) - return newFile(d, msrc, fs.SpecialDirectory, t) + contents := map[string]*fs.Inode{ + "net": newNamespaceSymlink(t, msrc, "net"), + "pid": newNamespaceSymlink(t, msrc, "pid"), + "user": newNamespaceSymlink(t, msrc, "user"), + } + d := ramfs.NewDir(t, contents, fs.RootOwner, fs.FilePermsFromMode(0511)) + return newProcInode(d, msrc, fs.SpecialDirectory, t) } // mapsData implements seqfile.SeqSource for /proc/[pid]/maps. @@ -290,7 +336,7 @@ type mapsData struct { } func newMaps(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - return newFile(seqfile.NewSeqFile(t, &mapsData{t}), msrc, fs.SpecialFile, t) + return newProcInode(seqfile.NewSeqFile(t, &mapsData{t}), msrc, fs.SpecialFile, t) } func (md *mapsData) mm() *mm.MemoryManager { @@ -330,7 +376,7 @@ type smapsData struct { } func newSmaps(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - return newFile(seqfile.NewSeqFile(t, &smapsData{t}), msrc, fs.SpecialFile, t) + return newProcInode(seqfile.NewSeqFile(t, &smapsData{t}), msrc, fs.SpecialFile, t) } func (sd *smapsData) mm() *mm.MemoryManager { @@ -376,7 +422,7 @@ type taskStatData struct { } func newTaskStat(t *kernel.Task, msrc *fs.MountSource, showSubtasks bool, pidns *kernel.PIDNamespace) *fs.Inode { - return newFile(seqfile.NewSeqFile(t, &taskStatData{t, showSubtasks /* tgstats */, pidns}), msrc, fs.SpecialFile, t) + return newProcInode(seqfile.NewSeqFile(t, &taskStatData{t, showSubtasks /* tgstats */, pidns}), msrc, fs.SpecialFile, t) } // NeedsUpdate returns whether the generation is old or not. @@ -450,7 +496,7 @@ type statmData struct { } func newStatm(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - return newFile(seqfile.NewSeqFile(t, &statmData{t}), msrc, fs.SpecialFile, t) + return newProcInode(seqfile.NewSeqFile(t, &statmData{t}), msrc, fs.SpecialFile, t) } // NeedsUpdate implements seqfile.SeqSource.NeedsUpdate. @@ -487,7 +533,7 @@ type statusData struct { } func newStatus(t *kernel.Task, msrc *fs.MountSource, pidns *kernel.PIDNamespace) *fs.Inode { - return newFile(seqfile.NewSeqFile(t, &statusData{t, pidns}), msrc, fs.SpecialFile, t) + return newProcInode(seqfile.NewSeqFile(t, &statusData{t, pidns}), msrc, fs.SpecialFile, t) } // NeedsUpdate implements seqfile.SeqSource.NeedsUpdate. @@ -552,7 +598,7 @@ type ioData struct { } func newIO(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - return newFile(seqfile.NewSeqFile(t, &ioData{t.ThreadGroup()}), msrc, fs.SpecialFile, t) + return newProcInode(seqfile.NewSeqFile(t, &ioData{t.ThreadGroup()}), msrc, fs.SpecialFile, t) } // NeedsUpdate returns whether the generation is old or not. @@ -590,25 +636,49 @@ func (i *ioData) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se // // +stateify savable type comm struct { - ramfs.Entry + fsutil.SimpleFileInode t *kernel.Task } // newComm returns a new comm file. func newComm(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - c := &comm{t: t} - c.InitEntry(t, fs.RootOwner, fs.FilePermsFromMode(0444)) - return newFile(c, msrc, fs.SpecialFile, t) + c := &comm{ + SimpleFileInode: *fsutil.NewSimpleFileInode(t, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + t: t, + } + return newProcInode(c, msrc, fs.SpecialFile, t) +} + +// GetFile implements fs.InodeOperations.GetFile. +func (c *comm) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &commFile{t: c.t}), nil +} + +// +stateify savable +type commFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` + + t *kernel.Task } -// DeprecatedPreadv reads the current command name. -func (c *comm) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { +var _ fs.FileOperations = (*commFile)(nil) + +// Read implements fs.FileOperations.Read. +func (f *commFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { if offset < 0 { return 0, syserror.EINVAL } - buf := []byte(c.t.Name() + "\n") + buf := []byte(f.t.Name() + "\n") if offset >= int64(len(buf)) { return 0, io.EOF } @@ -621,25 +691,47 @@ func (c *comm) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, off // // +stateify savable type auxvec struct { - ramfs.Entry + fsutil.SimpleFileInode t *kernel.Task } // newAuxvec returns a new auxvec file. func newAuxvec(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { - a := &auxvec{t: t} - a.InitEntry(t, fs.RootOwner, fs.FilePermsFromMode(0400)) - return newFile(a, msrc, fs.SpecialFile, t) + a := &auxvec{ + SimpleFileInode: *fsutil.NewSimpleFileInode(t, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + t: t, + } + return newProcInode(a, msrc, fs.SpecialFile, t) +} + +// GetFile implements fs.InodeOperations.GetFile. +func (a *auxvec) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &auxvecFile{t: a.t}), nil +} + +// +stateify savable +type auxvecFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` + + t *kernel.Task } -// DeprecatedPreadv reads the current auxiliary vector. -func (a *auxvec) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { +// Read implements fs.FileOperations.Read. +func (f *auxvecFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { if offset < 0 { return 0, syserror.EINVAL } - m, err := getTaskMM(a.t) + m, err := getTaskMM(f.t) if err != nil { return 0, err } diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index f70399686..815c40b7f 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -90,12 +90,13 @@ func newGIDMap(t *kernel.Task, msrc *fs.MountSource) *fs.Inode { } func newIDMap(t *kernel.Task, msrc *fs.MountSource, gids bool) *fs.Inode { - imsf := &idMapSeqFile{seqfile.SeqFile{SeqSource: &idMapSeqSource{ - t: t, - gids: gids, - }}} - imsf.InitEntry(t, fs.RootOwner, fs.FilePermsFromMode(0644)) - return newFile(imsf, msrc, fs.SpecialFile, t) + imsf := &idMapSeqFile{ + *seqfile.NewSeqFile(t, &idMapSeqSource{ + t: t, + gids: gids, + }), + } + return newProcInode(imsf, msrc, fs.SpecialFile, t) } func (imsf *idMapSeqFile) source() *idMapSeqSource { @@ -106,8 +107,8 @@ func (imsf *idMapSeqFile) source() *idMapSeqSource { // Linux 3.18, the limit is five lines." - user_namespaces(7) const maxIDMapLines = 5 -// DeprecatedPwritev implements fs.InodeOperations.DeprecatedPwritev. -func (imsf *idMapSeqFile) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { +// Write implements fs.FileOperations.Write. +func (imsf *idMapSeqFile) Write(ctx context.Context, _ *fs.File, src usermem.IOSequence, offset int64) (int64, error) { // "In addition, the number of bytes written to the file must be less than // the system page size, and the write must be performed at the start of // the file ..." - user_namespaces(7) diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index 80c7ce0b4..40d0fd1fd 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -18,42 +18,64 @@ import ( "fmt" "io" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // uptime is a file containing the system uptime. // // +stateify savable type uptime struct { - ramfs.Entry + fsutil.SimpleFileInode // The "start time" of the sandbox. startTime ktime.Time } // newUptime returns a new uptime file. -func (p *proc) newUptime(ctx context.Context, msrc *fs.MountSource) *fs.Inode { +func newUptime(ctx context.Context, msrc *fs.MountSource) *fs.Inode { u := &uptime{ - startTime: ktime.NowFromContext(ctx), + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.PROC_SUPER_MAGIC), + startTime: ktime.NowFromContext(ctx), } - u.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0444)) - return newFile(u, msrc, fs.SpecialFile, nil) + return newProcInode(u, msrc, fs.SpecialFile, nil) } -// DeprecatedPreadv reads the current uptime. -func (u *uptime) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { +// GetFile implements fs.InodeOperations.GetFile. +func (u *uptime) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &uptimeFile{startTime: u.startTime}), nil +} + +// +stateify savable +type uptimeFile struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` + + startTime ktime.Time +} + +// Read implements fs.FileOperations.Read. +func (f *uptimeFile) Read(ctx context.Context, _ *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { if offset < 0 { return 0, syserror.EINVAL } now := ktime.NowFromContext(ctx) // Pretend that we've spent zero time sleeping (second number). - s := []byte(fmt.Sprintf("%.2f 0.00\n", now.Sub(u.startTime).Seconds())) + s := []byte(fmt.Sprintf("%.2f 0.00\n", now.Sub(f.startTime).Seconds())) if offset >= int64(len(s)) { return 0, io.EOF } diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index a93ad6240..a476c9cce 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -6,8 +6,6 @@ go_library( name = "ramfs", srcs = [ "dir.go", - "file.go", - "ramfs.go", "socket.go", "symlink.go", "tree.go", @@ -15,14 +13,12 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs", visibility = ["//pkg/sentry:internal"], deps = [ - "//pkg/secio", + "//pkg/abi/linux", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/time", - "//pkg/sentry/memmap", - "//pkg/sentry/safemem", "//pkg/sentry/socket/unix/transport", "//pkg/sentry/usermem", "//pkg/syserror", diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index 0a911b155..729f37694 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -18,10 +18,12 @@ import ( "sync" "syscall" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" ) @@ -47,7 +49,17 @@ type CreateOps struct { // // +stateify savable type Dir struct { - Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeIsDirTruncate `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes + fsutil.InodeSimpleExtendedAttributes // CreateOps may be provided. // @@ -64,17 +76,23 @@ type Dir struct { children map[string]*fs.Inode // dentryMap is a sortedDentryMap containing entries for all children. - // Its entries ar kept up-to-date with d.children. + // Its entries are kept up-to-date with d.children. dentryMap *fs.SortedDentryMap } -// InitDir initializes a directory. -func (d *Dir) InitDir(ctx context.Context, contents map[string]*fs.Inode, owner fs.FileOwner, perms fs.FilePermissions) { - d.InitEntry(ctx, owner, perms) +var _ fs.InodeOperations = (*Dir)(nil) + +// NewDir returns a new Dir with the given contents and attributes. +func NewDir(ctx context.Context, contents map[string]*fs.Inode, owner fs.FileOwner, perms fs.FilePermissions) *Dir { + d := &Dir{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, perms, linux.RAMFS_MAGIC), + } + if contents == nil { contents = make(map[string]*fs.Inode) } d.children = contents + // Build the entries map ourselves, rather than calling addChildLocked, // because it will be faster. entries := make(map[string]fs.DentAttr, len(contents)) @@ -88,6 +106,8 @@ func (d *Dir) InitDir(ctx context.Context, contents map[string]*fs.Inode, owner // Directories have an extra link, corresponding to '.'. d.AddLink() + + return d } // addChildLocked add the child inode, inheriting its reference. @@ -124,17 +144,24 @@ func (d *Dir) FindChild(name string) (*fs.Inode, bool) { return child, ok } +// Children returns the names and DentAttrs of all children. It can be used to +// implement Readdir for types that embed ramfs.Dir. +func (d *Dir) Children() ([]string, map[string]fs.DentAttr) { + d.mu.Lock() + defer d.mu.Unlock() + return d.dentryMap.GetAll() +} + // removeChildLocked attempts to remove an entry from this directory. -// This Entry's mutex must be held. It returns the removed Inode. func (d *Dir) removeChildLocked(ctx context.Context, name string) (*fs.Inode, error) { inode, ok := d.children[name] if !ok { - return nil, ErrNotFound + return nil, syserror.EACCES } delete(d.children, name) d.dentryMap.Remove(name) - d.Entry.NotifyModification(ctx) + d.NotifyModification(ctx) // If the child was a subdirectory, then we must decrement this dir's // link count which was the child's ".." directory entry. @@ -143,7 +170,7 @@ func (d *Dir) removeChildLocked(ctx context.Context, name string) (*fs.Inode, er } // Update ctime. - inode.NotifyStatusChange(ctx) + inode.InodeOperations.NotifyStatusChange(ctx) // Given we're now removing this inode to the directory we must also // decrease its link count. Similarly it is increased in addChildLocked. @@ -152,8 +179,8 @@ func (d *Dir) removeChildLocked(ctx context.Context, name string) (*fs.Inode, er return inode, nil } -// RemoveEntry attempts to remove an entry from this directory. -func (d *Dir) RemoveEntry(ctx context.Context, name string) error { +// Remove removes the named non-directory. +func (d *Dir) Remove(ctx context.Context, _ *fs.Inode, name string) error { d.mu.Lock() defer d.mu.Unlock() inode, err := d.removeChildLocked(ctx, name) @@ -166,27 +193,23 @@ func (d *Dir) RemoveEntry(ctx context.Context, name string) error { return nil } -// Remove removes the named non-directory. -func (d *Dir) Remove(ctx context.Context, dir *fs.Inode, name string) error { - return d.RemoveEntry(ctx, name) -} - // RemoveDirectory removes the named directory. -func (d *Dir) RemoveDirectory(ctx context.Context, dir *fs.Inode, name string) error { +func (d *Dir) RemoveDirectory(ctx context.Context, _ *fs.Inode, name string) error { d.mu.Lock() defer d.mu.Unlock() - n, err := d.walkLocked(ctx, name) + // Get the child and make sure it is not empty. + childInode, err := d.walkLocked(ctx, name) if err != nil { return err } - dirCtx := &fs.DirCtx{} - if _, err := n.HandleOps().DeprecatedReaddir(ctx, dirCtx, 0); err != nil { + if ok, err := hasChildren(ctx, childInode); err != nil { return err + } else if ok { + return syserror.ENOTEMPTY } - if len(dirCtx.DentAttrs()) > 0 { - return ErrNotEmpty - } + + // Child was empty. Proceed with removal. inode, err := d.removeChildLocked(ctx, name) if err != nil { return err @@ -195,11 +218,11 @@ func (d *Dir) RemoveDirectory(ctx context.Context, dir *fs.Inode, name string) e // Remove our reference on the inode. inode.DecRef() - return err + return nil } // Lookup loads an inode at p into a Dirent. -func (d *Dir) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, error) { +func (d *Dir) Lookup(ctx context.Context, _ *fs.Inode, p string) (*fs.Dirent, error) { d.mu.Lock() defer d.mu.Unlock() @@ -214,9 +237,9 @@ func (d *Dir) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, return fs.NewDirent(inode, p), nil } -// walkLocked must be called with this Entry's mutex held. +// walkLocked must be called with d.mu held. func (d *Dir) walkLocked(ctx context.Context, p string) (*fs.Inode, error) { - d.Entry.NotifyAccess(ctx) + d.NotifyAccess(ctx) // Lookup a child node. if inode, ok := d.children[p]; ok { @@ -244,7 +267,7 @@ func (d *Dir) createInodeOperationsCommon(ctx context.Context, name string, make } d.addChildLocked(name, inode) - d.Entry.NotifyModification(ctx) + d.NotifyModification(ctx) return inode, nil } @@ -252,7 +275,7 @@ func (d *Dir) createInodeOperationsCommon(ctx context.Context, name string, make // Create creates a new Inode with the given name and returns its File. func (d *Dir) Create(ctx context.Context, dir *fs.Inode, name string, flags fs.FileFlags, perms fs.FilePermissions) (*fs.File, error) { if d.CreateOps == nil || d.CreateOps.NewFile == nil { - return nil, ErrDenied + return nil, syserror.EACCES } inode, err := d.createInodeOperationsCommon(ctx, name, func() (*fs.Inode, error) { @@ -274,7 +297,7 @@ func (d *Dir) Create(ctx context.Context, dir *fs.Inode, name string, flags fs.F // CreateLink returns a new link. func (d *Dir) CreateLink(ctx context.Context, dir *fs.Inode, oldname, newname string) error { if d.CreateOps == nil || d.CreateOps.NewSymlink == nil { - return ErrDenied + return syserror.EACCES } _, err := d.createInodeOperationsCommon(ctx, newname, func() (*fs.Inode, error) { return d.NewSymlink(ctx, dir, oldname) @@ -292,10 +315,10 @@ func (d *Dir) CreateHardLink(ctx context.Context, dir *fs.Inode, target *fs.Inod // The link count will be incremented in addChildLocked. d.addChildLocked(name, target) - d.Entry.NotifyModification(ctx) + d.NotifyModification(ctx) // Update ctime. - target.NotifyStatusChange(ctx) + target.InodeOperations.NotifyStatusChange(ctx) return nil } @@ -303,7 +326,7 @@ func (d *Dir) CreateHardLink(ctx context.Context, dir *fs.Inode, target *fs.Inod // CreateDirectory returns a new subdirectory. func (d *Dir) CreateDirectory(ctx context.Context, dir *fs.Inode, name string, perms fs.FilePermissions) error { if d.CreateOps == nil || d.CreateOps.NewDir == nil { - return ErrDenied + return syserror.EACCES } _, err := d.createInodeOperationsCommon(ctx, name, func() (*fs.Inode, error) { return d.NewDir(ctx, dir, perms) @@ -316,7 +339,7 @@ func (d *Dir) CreateDirectory(ctx context.Context, dir *fs.Inode, name string, p // Bind implements fs.InodeOperations.Bind. func (d *Dir) Bind(ctx context.Context, dir *fs.Inode, name string, ep transport.BoundEndpoint, perms fs.FilePermissions) (*fs.Dirent, error) { if d.CreateOps == nil || d.CreateOps.NewBoundEndpoint == nil { - return nil, ErrDenied + return nil, syserror.EACCES } inode, err := d.createInodeOperationsCommon(ctx, name, func() (*fs.Inode, error) { return d.NewBoundEndpoint(ctx, dir, ep, perms) @@ -335,7 +358,7 @@ func (d *Dir) Bind(ctx context.Context, dir *fs.Inode, name string, ep transport // CreateFifo implements fs.InodeOperations.CreateFifo. func (d *Dir) CreateFifo(ctx context.Context, dir *fs.Inode, name string, perms fs.FilePermissions) error { if d.CreateOps == nil || d.CreateOps.NewFifo == nil { - return ErrDenied + return syserror.EACCES } _, err := d.createInodeOperationsCommon(ctx, name, func() (*fs.Inode, error) { return d.NewFifo(ctx, dir, perms) @@ -343,29 +366,125 @@ func (d *Dir) CreateFifo(ctx context.Context, dir *fs.Inode, name string, perms return err } -func (d *Dir) readdirLocked(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - // Serialize the entries in dentryMap. - n, err := fs.GenericReaddir(dirCtx, d.dentryMap) +// GetFile implements fs.InodeOperations.GetFile. +func (d *Dir) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + flags.Pread = true + return fs.NewFile(ctx, dirent, flags, &dirFileOperations{dir: d}), nil +} - // Touch the access time. - d.Entry.NotifyAccess(ctx) +// Rename implements fs.InodeOperations.Rename. +func (*Dir) Rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent *fs.Inode, newName string) error { + return Rename(ctx, oldParent.InodeOperations, oldName, newParent.InodeOperations, newName) +} +// dirFileOperations implements fs.FileOperations for a ramfs directory. +// +// +stateify savable +type dirFileOperations struct { + fsutil.DirFileOperations `state:"nosave"` + + // dirCursor contains the name of the last directory entry that was + // serialized. + dirCursor string + + // dir is the ramfs dir that this file corresponds to. + dir *Dir +} + +var _ fs.FileOperations = (*dirFileOperations)(nil) + +// Seek implements fs.FileOperations.Seek. +func (dfo *dirFileOperations) Seek(ctx context.Context, file *fs.File, whence fs.SeekWhence, offset int64) (int64, error) { + return fsutil.SeekWithDirCursor(ctx, file, whence, offset, &dfo.dirCursor) +} + +// IterateDir implements DirIterator.IterateDir. +func (dfo *dirFileOperations) IterateDir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { + dfo.dir.mu.Lock() + defer dfo.dir.mu.Unlock() + + n, err := fs.GenericReaddir(dirCtx, dfo.dir.dentryMap) return offset + n, err } -// DeprecatedReaddir emits the entries contained in this directory. -func (d *Dir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset int) (int, error) { - d.mu.Lock() - defer d.mu.Unlock() - return d.readdirLocked(ctx, dirCtx, offset) +// Readdir implements FileOperations.Readdir. +func (dfo *dirFileOperations) Readdir(ctx context.Context, file *fs.File, serializer fs.DentrySerializer) (int64, error) { + root := fs.RootFromContext(ctx) + defer root.DecRef() + dirCtx := &fs.DirCtx{ + Serializer: serializer, + DirCursor: &dfo.dirCursor, + } + dfo.dir.mu.Lock() + dfo.dir.InodeSimpleAttributes.Unstable.AccessTime = ktime.NowFromContext(ctx) + dfo.dir.mu.Unlock() + return fs.DirentReaddir(ctx, file.Dirent, dfo, root, dirCtx, file.Offset()) } -// DeprecatedPreadv always returns ErrIsDirectory -func (*Dir) DeprecatedPreadv(context.Context, usermem.IOSequence, int64) (int64, error) { - return 0, ErrIsDirectory +// hasChildren is a helper method that determines whether an arbitrary inode +// (not necessarily ramfs) has any children. +func hasChildren(ctx context.Context, inode *fs.Inode) (bool, error) { + // Take an extra ref on inode which will be given to the dirent and + // dropped when that dirent is destroyed. + inode.IncRef() + d := fs.NewTransientDirent(inode) + defer d.DecRef() + + file, err := inode.GetFile(ctx, d, fs.FileFlags{Read: true}) + if err != nil { + return false, err + } + defer file.DecRef() + + ser := &fs.CollectEntriesSerializer{} + if err := file.Readdir(ctx, ser); err != nil { + return false, err + } + // We will always write "." and "..", so ignore those two. + if ser.Written() > 2 { + return true, nil + } + return false, nil } -// DeprecatedPwritev always returns ErrIsDirectory -func (*Dir) DeprecatedPwritev(context.Context, usermem.IOSequence, int64) (int64, error) { - return 0, ErrIsDirectory +// Rename renames from a *ramfs.Dir to another *ramfs.Dir. +func Rename(ctx context.Context, oldParent fs.InodeOperations, oldName string, newParent fs.InodeOperations, newName string) error { + op, ok := oldParent.(*Dir) + if !ok { + return syserror.EXDEV + } + np, ok := newParent.(*Dir) + if !ok { + return syserror.EXDEV + } + + np.mu.Lock() + defer np.mu.Unlock() + + // Check whether the ramfs entry to be replaced is a non-empty directory. + if replaced, ok := np.children[newName]; ok { + if fs.IsDir(replaced.StableAttr) { + if ok, err := hasChildren(ctx, replaced); err != nil { + return err + } else if ok { + return syserror.ENOTEMPTY + } + } + } + + // Be careful, we may have already grabbed this mutex above. + if op != np { + op.mu.Lock() + defer op.mu.Unlock() + } + + // Do the swap. + n := op.children[oldName] + op.removeChildLocked(ctx, oldName) + np.addChildLocked(newName, n) + + // Update ctime. + n.InodeOperations.NotifyStatusChange(ctx) + + return nil } diff --git a/pkg/sentry/fs/ramfs/file.go b/pkg/sentry/fs/ramfs/file.go deleted file mode 100644 index b7fc98ffc..000000000 --- a/pkg/sentry/fs/ramfs/file.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 ramfs - -import ( - "io" - "sync" - - "gvisor.googlesource.com/gvisor/pkg/secio" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" -) - -// File represents a unique file. It uses a simple byte slice as storage, and -// thus should only be used for small files. -// -// A File is not mappable. -// -// +stateify savable -type File struct { - Entry - - // mu protects the fields below. - mu sync.Mutex `state:"nosave"` - - // data tracks backing data for the file. - data []byte -} - -// InitFile initializes a file. -func (f *File) InitFile(ctx context.Context, owner fs.FileOwner, perms fs.FilePermissions) { - f.InitEntry(ctx, owner, perms) -} - -// UnstableAttr returns unstable attributes of this ramfs file. -func (f *File) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - f.mu.Lock() - defer f.mu.Unlock() - - uattr, _ := f.Entry.UnstableAttr(ctx, inode) - uattr.Size = int64(len(f.data)) - uattr.Usage = f.usageLocked() - - return uattr, nil -} - -// usageLocked returns the disk usage. Caller must hold f.mu. -func (f *File) usageLocked() int64 { - return int64(len(f.data)) -} - -// Append appends the given data. This is for internal use. -func (f *File) Append(data []byte) { - f.mu.Lock() - defer f.mu.Unlock() - f.data = append(f.data, data...) -} - -// Truncate truncates this node. -func (f *File) Truncate(ctx context.Context, inode *fs.Inode, l int64) error { - f.mu.Lock() - defer f.mu.Unlock() - if l < int64(len(f.data)) { - // Remove excess bytes. - f.data = f.data[:l] - return nil - } else if l > int64(len(f.data)) { - // Create a new slice with size l, and copy f.data into it. - d := make([]byte, l) - copy(d, f.data) - f.data = d - } - f.Entry.NotifyModification(ctx) - return nil -} - -// ReadAt implements io.ReaderAt. -func (f *File) ReadAt(data []byte, offset int64) (int, error) { - if offset < 0 { - return 0, ErrInvalidOp - } - if offset >= int64(len(f.data)) { - return 0, io.EOF - } - n := copy(data, f.data[offset:]) - // Did we read past the end? - if offset+int64(len(data)) >= int64(len(f.data)) { - return n, io.EOF - } - return n, nil -} - -// DeprecatedPreadv reads into a collection of slices from a given offset. -func (f *File) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - f.mu.Lock() - defer f.mu.Unlock() - if offset >= int64(len(f.data)) { - return 0, io.EOF - } - n, err := dst.CopyOut(ctx, f.data[offset:]) - if n > 0 { - f.Entry.NotifyAccess(ctx) - } - return int64(n), err -} - -// WriteAt implements io.WriterAt. -func (f *File) WriteAt(data []byte, offset int64) (int, error) { - if offset < 0 { - return 0, ErrInvalidOp - } - newLen := offset + int64(len(data)) - if newLen < 0 { - // Overflow. - return 0, syserror.EINVAL - } - if newLen > int64(len(f.data)) { - // Copy f.data into new slice with expanded length. - d := make([]byte, newLen) - copy(d, f.data) - f.data = d - } - return copy(f.data[offset:], data), nil -} - -// DeprecatedPwritev writes from a collection of slices at a given offset. -func (f *File) DeprecatedPwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { - f.mu.Lock() - defer f.mu.Unlock() - n, err := src.CopyInTo(ctx, safemem.FromIOWriter{secio.NewOffsetWriter(f, offset)}) - if n > 0 { - f.Entry.NotifyModification(ctx) - } - return n, err -} diff --git a/pkg/sentry/fs/ramfs/ramfs.go b/pkg/sentry/fs/ramfs/ramfs.go deleted file mode 100644 index d77688a34..000000000 --- a/pkg/sentry/fs/ramfs/ramfs.go +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 ramfs implements an in-memory file system that can be associated with -// any device. -package ramfs - -import ( - "errors" - "sync" - "syscall" - - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" - ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" - "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" - "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" - "gvisor.googlesource.com/gvisor/pkg/waiter" -) - -var ( - // ErrInvalidOp indicates the operation is not valid. - ErrInvalidOp = errors.New("invalid operation") - - // ErrDenied indicates the operation was denied. - ErrDenied = errors.New("operation denied") - - // ErrNotFound indicates that a node was not found on a walk. - ErrNotFound = errors.New("node not found") - - // ErrCrossDevice indicates a cross-device link or rename. - ErrCrossDevice = errors.New("can't link across filesystems") - - // ErrIsDirectory indicates that the operation failed because - // the node is a directory. - ErrIsDirectory = errors.New("is a directory") - - // ErrNotDirectory indicates that the operation failed because - // the node is a not directory. - ErrNotDirectory = errors.New("not a directory") - - // ErrNotEmpty indicates that the operation failed because the - // directory is not empty. - ErrNotEmpty = errors.New("directory not empty") -) - -// Entry represents common internal state for file and directory nodes. -// This may be used by other packages to easily create ramfs files. -// -// +stateify savable -type Entry struct { - waiter.AlwaysReady `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` - - // mu protects the fields below. - mu sync.Mutex `state:"nosave"` - - // unstable is unstable attributes. - unstable fs.UnstableAttr - - // xattrs are the extended attributes of the Entry. - xattrs map[string][]byte -} - -// InitEntry initializes an entry. -func (e *Entry) InitEntry(ctx context.Context, owner fs.FileOwner, p fs.FilePermissions) { - e.InitEntryWithAttr(ctx, fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: owner, - Perms: p, - // Always start unlinked. - Links: 0, - })) -} - -// InitEntryWithAttr initializes an entry with a complete set of attributes. -func (e *Entry) InitEntryWithAttr(ctx context.Context, uattr fs.UnstableAttr) { - e.unstable = uattr - e.xattrs = make(map[string][]byte) -} - -// UnstableAttr implements fs.InodeOperations.UnstableAttr. -func (e *Entry) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - e.mu.Lock() - attr := e.unstable - e.mu.Unlock() - return attr, nil -} - -// Check implements fs.InodeOperations.Check. -func (*Entry) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - -// Getxattr implements fs.InodeOperations.Getxattr. -func (e *Entry) Getxattr(inode *fs.Inode, name string) ([]byte, error) { - // Hot path. Avoid defers. - e.mu.Lock() - value, ok := e.xattrs[name] - e.mu.Unlock() - if ok { - return value, nil - } - return nil, syserror.ENOATTR -} - -// Setxattr implements fs.InodeOperations.Setxattr. -func (e *Entry) Setxattr(inode *fs.Inode, name string, value []byte) error { - e.mu.Lock() - e.xattrs[name] = value - e.mu.Unlock() - return nil -} - -// Listxattr implements fs.InodeOperations.Listxattr. -func (e *Entry) Listxattr(inode *fs.Inode) (map[string]struct{}, error) { - e.mu.Lock() - names := make(map[string]struct{}, len(e.xattrs)) - for name := range e.xattrs { - names[name] = struct{}{} - } - e.mu.Unlock() - return names, nil -} - -// GetFile returns a fs.File backed by the dirent argument and flags. -func (*Entry) GetFile(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { - return fsutil.NewHandle(ctx, d, flags, d.Inode.HandleOps()), nil -} - -// SetPermissions always sets the permissions. -func (e *Entry) SetPermissions(ctx context.Context, inode *fs.Inode, p fs.FilePermissions) bool { - e.mu.Lock() - e.unstable.Perms = p - e.unstable.StatusChangeTime = ktime.NowFromContext(ctx) - e.mu.Unlock() - return true -} - -// SetOwner always sets ownership. -func (e *Entry) SetOwner(ctx context.Context, inode *fs.Inode, owner fs.FileOwner) error { - e.mu.Lock() - if owner.UID.Ok() { - e.unstable.Owner.UID = owner.UID - } - if owner.GID.Ok() { - e.unstable.Owner.GID = owner.GID - } - e.mu.Unlock() - return nil -} - -// SetTimestamps sets the timestamps. -func (e *Entry) SetTimestamps(ctx context.Context, inode *fs.Inode, ts fs.TimeSpec) error { - if ts.ATimeOmit && ts.MTimeOmit { - return nil - } - - e.mu.Lock() - now := ktime.NowFromContext(ctx) - if !ts.ATimeOmit { - if ts.ATimeSetSystemTime { - e.unstable.AccessTime = now - } else { - e.unstable.AccessTime = ts.ATime - } - } - if !ts.MTimeOmit { - if ts.MTimeSetSystemTime { - e.unstable.ModificationTime = now - } else { - e.unstable.ModificationTime = ts.MTime - } - } - e.unstable.StatusChangeTime = now - e.mu.Unlock() - return nil -} - -// NotifyStatusChange updates the status change time (ctime). -func (e *Entry) NotifyStatusChange(ctx context.Context) { - e.mu.Lock() - e.unstable.StatusChangeTime = ktime.NowFromContext(ctx) - e.mu.Unlock() -} - -// StatusChangeTime returns the last status change time for this node. -func (e *Entry) StatusChangeTime() ktime.Time { - e.mu.Lock() - t := e.unstable.StatusChangeTime - e.mu.Unlock() - return t -} - -// NotifyModification updates the modification time and the status change time. -func (e *Entry) NotifyModification(ctx context.Context) { - e.mu.Lock() - now := ktime.NowFromContext(ctx) - e.unstable.ModificationTime = now - e.unstable.StatusChangeTime = now - e.mu.Unlock() -} - -// ModificationTime returns the last modification time for this node. -func (e *Entry) ModificationTime() ktime.Time { - e.mu.Lock() - t := e.unstable.ModificationTime - e.mu.Unlock() - return t -} - -// NotifyAccess updates the access time. -func (e *Entry) NotifyAccess(ctx context.Context) { - e.mu.Lock() - now := ktime.NowFromContext(ctx) - e.unstable.AccessTime = now - e.mu.Unlock() -} - -// AccessTime returns the last access time for this node. -func (e *Entry) AccessTime() ktime.Time { - e.mu.Lock() - t := e.unstable.AccessTime - e.mu.Unlock() - return t -} - -// Permissions returns permissions on this entry. -func (e *Entry) Permissions() fs.FilePermissions { - e.mu.Lock() - p := e.unstable.Perms - e.mu.Unlock() - return p -} - -// Lookup is not supported by default. -func (*Entry) Lookup(context.Context, *fs.Inode, string) (*fs.Dirent, error) { - return nil, ErrInvalidOp -} - -// Create is not supported by default. -func (*Entry) Create(context.Context, *fs.Inode, string, fs.FileFlags, fs.FilePermissions) (*fs.File, error) { - return nil, ErrInvalidOp -} - -// CreateLink is not supported by default. -func (*Entry) CreateLink(context.Context, *fs.Inode, string, string) error { - return ErrInvalidOp -} - -// CreateHardLink is not supported by default. -func (*Entry) CreateHardLink(context.Context, *fs.Inode, *fs.Inode, string) error { - return ErrInvalidOp -} - -// IsVirtual returns true. -func (*Entry) IsVirtual() bool { - return true -} - -// CreateDirectory is not supported by default. -func (*Entry) CreateDirectory(context.Context, *fs.Inode, string, fs.FilePermissions) error { - return ErrInvalidOp -} - -// Bind is not supported by default. -func (*Entry) Bind(context.Context, *fs.Inode, string, transport.BoundEndpoint, fs.FilePermissions) (*fs.Dirent, error) { - return nil, ErrInvalidOp -} - -// CreateFifo implements fs.InodeOperations.CreateFifo. CreateFifo is not supported by -// default. -func (*Entry) CreateFifo(context.Context, *fs.Inode, string, fs.FilePermissions) error { - return ErrInvalidOp -} - -// Remove is not supported by default. -func (*Entry) Remove(context.Context, *fs.Inode, string) error { - return ErrInvalidOp -} - -// RemoveDirectory is not supported by default. -func (*Entry) RemoveDirectory(context.Context, *fs.Inode, string) error { - return ErrInvalidOp -} - -// StatFS always returns ENOSYS. -func (*Entry) StatFS(context.Context) (fs.Info, error) { - return fs.Info{}, syscall.ENOSYS -} - -// Rename implements fs.InodeOperations.Rename. -func (e *Entry) Rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent *fs.Inode, newName string) error { - return Rename(ctx, oldParent.InodeOperations, oldName, newParent.InodeOperations, newName) -} - -// Rename renames from a *ramfs.Dir to another *ramfs.Dir. -func Rename(ctx context.Context, oldParent fs.InodeOperations, oldName string, newParent fs.InodeOperations, newName string) error { - op, ok := oldParent.(*Dir) - if !ok { - return ErrCrossDevice - } - np, ok := newParent.(*Dir) - if !ok { - return ErrCrossDevice - } - - np.mu.Lock() - defer np.mu.Unlock() - - // Check whether the ramfs entry to be replaced is a non-empty directory. - if replaced, ok := np.children[newName]; ok { - if fs.IsDir(replaced.StableAttr) { - // FIXME: simplify by pinning children of ramfs-backed directories - // in the Dirent tree: this allows us to generalize ramfs operations without - // relying on an implementation of Readdir (which may do anything, like require - // that the file be open ... which would be reasonable). - dirCtx := &fs.DirCtx{} - _, err := replaced.HandleOps().DeprecatedReaddir(ctx, dirCtx, 0) - if err != nil { - return err - } - attrs := dirCtx.DentAttrs() - - // ramfs-backed directories should not contain "." and "..", but we do this - // just in case. - delete(attrs, ".") - delete(attrs, "..") - - // If the directory to be replaced is not empty, reject the rename. - if len(attrs) != 0 { - return ErrNotEmpty - } - } - } - - // Be careful, we may have already grabbed this mutex above. - if op != np { - op.mu.Lock() - defer op.mu.Unlock() - } - - // Do the swap. - n := op.children[oldName] - op.removeChildLocked(ctx, oldName) - np.addChildLocked(newName, n) - - // Update ctime. - n.NotifyStatusChange(ctx) - - return nil -} - -// Truncate is not supported by default. -func (*Entry) Truncate(context.Context, *fs.Inode, int64) error { - return ErrInvalidOp -} - -// Readlink always returns ENOLINK. -func (*Entry) Readlink(context.Context, *fs.Inode) (string, error) { - return "", syscall.ENOLINK -} - -// Getlink always returns ENOLINK. -func (*Entry) Getlink(context.Context, *fs.Inode) (*fs.Dirent, error) { - return nil, syscall.ENOLINK -} - -// Release is a no-op. -func (e *Entry) Release(context.Context) {} - -// AddLink implements InodeOperationss.AddLink. -func (e *Entry) AddLink() { - e.mu.Lock() - e.unstable.Links++ - e.mu.Unlock() -} - -// DropLink implements InodeOperationss.DropLink. -func (e *Entry) DropLink() { - e.mu.Lock() - e.unstable.Links-- - e.mu.Unlock() -} - -// DeprecatedReaddir is not supported by default. -func (*Entry) DeprecatedReaddir(context.Context, *fs.DirCtx, int) (int, error) { - return 0, ErrNotDirectory -} - -// DeprecatedPreadv always returns ErrInvalidOp. -func (*Entry) DeprecatedPreadv(context.Context, usermem.IOSequence, int64) (int64, error) { - return 0, ErrInvalidOp -} - -// DeprecatedPwritev always returns ErrInvalidOp. -func (*Entry) DeprecatedPwritev(context.Context, usermem.IOSequence, int64) (int64, error) { - return 0, ErrInvalidOp -} - -// DeprecatedFsync is a noop. -func (*Entry) DeprecatedFsync() error { - // Ignore, this is in memory. - return nil -} - -// DeprecatedFlush always returns nil. -func (*Entry) DeprecatedFlush() error { - return nil -} - -// DeprecatedMappable implements fs.InodeOperations.DeprecatedMappable. -func (*Entry) DeprecatedMappable(context.Context, *fs.Inode) (memmap.Mappable, bool) { - return nil, false -} - -func init() { - // Register ramfs errors. - syserror.AddErrorTranslation(ErrInvalidOp, syscall.EINVAL) - syserror.AddErrorTranslation(ErrDenied, syscall.EACCES) - syserror.AddErrorTranslation(ErrNotFound, syscall.ENOENT) - syserror.AddErrorTranslation(ErrCrossDevice, syscall.EXDEV) - syserror.AddErrorTranslation(ErrIsDirectory, syscall.EISDIR) - syserror.AddErrorTranslation(ErrNotDirectory, syscall.ENOTDIR) - syserror.AddErrorTranslation(ErrNotEmpty, syscall.ENOTEMPTY) -} diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 8c81478c8..2c1295897 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -15,25 +15,42 @@ package ramfs import ( + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // Socket represents a socket. // // +stateify savable type Socket struct { - Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes + fsutil.InodeSimpleExtendedAttributes // ep is the bound endpoint. ep transport.BoundEndpoint } -// InitSocket initializes a socket. -func (s *Socket) InitSocket(ctx context.Context, ep transport.BoundEndpoint, owner fs.FileOwner, perms fs.FilePermissions) { - s.InitEntry(ctx, owner, perms) - s.ep = ep +var _ fs.InodeOperations = (*Socket)(nil) + +// NewSocket returns a new Socket. +func NewSocket(ctx context.Context, ep transport.BoundEndpoint, owner fs.FileOwner, perms fs.FilePermissions) *Socket { + return &Socket{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, perms, linux.SOCKFS_MAGIC), + ep: ep, + } } // BoundEndpoint returns the socket data. @@ -42,3 +59,24 @@ func (s *Socket) BoundEndpoint(*fs.Inode, string) transport.BoundEndpoint { // care about the path argument. return s.ep } + +// GetFile implements fs.FileOperations.GetFile. +func (s *Socket) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &socketFileOperations{}), nil +} + +// +stateify savable +type socketFileOperations struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoRead `state:"nosave"` + fsutil.FileNoSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` +} + +var _ fs.FileOperations = (*socketFileOperations)(nil) diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index a21fac2c7..47dae380b 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -15,44 +15,55 @@ package ramfs import ( - "sync" - + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" + "gvisor.googlesource.com/gvisor/pkg/waiter" ) // Symlink represents a symlink. // // +stateify savable type Symlink struct { - Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` - mu sync.Mutex `state:"nosave"` + fsutil.InodeSimpleAttributes + fsutil.InodeSimpleExtendedAttributes // Target is the symlink target. Target string } -// InitSymlink initializes a symlink, pointing to the given target. -// A symlink is assumed to always have permissions 0777. -func (s *Symlink) InitSymlink(ctx context.Context, owner fs.FileOwner, target string) { - s.InitEntry(ctx, owner, fs.FilePermsFromMode(0777)) - s.Target = target +var _ fs.InodeOperations = (*Symlink)(nil) + +// NewSymlink returns a new Symlink. +func NewSymlink(ctx context.Context, owner fs.FileOwner, target string) *Symlink { + // A symlink is assumed to always have permissions 0777. + return &Symlink{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, owner, fs.FilePermsFromMode(0777), linux.RAMFS_MAGIC), + Target: target, + } } // UnstableAttr returns all attributes of this ramfs symlink. func (s *Symlink) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - uattr, _ := s.Entry.UnstableAttr(ctx, inode) + uattr, err := s.InodeSimpleAttributes.UnstableAttr(ctx, inode) + if err != nil { + return fs.UnstableAttr{}, err + } uattr.Size = int64(len(s.Target)) uattr.Usage = uattr.Size return uattr, nil } -// Check implements InodeOperations.Check. -func (s *Symlink) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - // SetPermissions on a symlink is always rejected. func (s *Symlink) SetPermissions(context.Context, *fs.Inode, fs.FilePermissions) bool { return false @@ -60,10 +71,7 @@ func (s *Symlink) SetPermissions(context.Context, *fs.Inode, fs.FilePermissions) // Readlink reads the symlink value. func (s *Symlink) Readlink(ctx context.Context, _ *fs.Inode) (string, error) { - s.mu.Lock() - defer s.mu.Unlock() - - s.Entry.NotifyAccess(ctx) + s.NotifyAccess(ctx) return s.Target, nil } @@ -72,3 +80,24 @@ func (s *Symlink) Readlink(ctx context.Context, _ *fs.Inode) (string, error) { func (*Symlink) Getlink(context.Context, *fs.Inode) (*fs.Dirent, error) { return nil, fs.ErrResolveViaReadlink } + +// GetFile implements fs.FileOperations.GetFile. +func (s *Symlink) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return fs.NewFile(ctx, dirent, flags, &symlinkFileOperations{}), nil +} + +// +stateify savable +type symlinkFileOperations struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoRead `state:"nosave"` + fsutil.FileNoSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` +} + +var _ fs.FileOperations = (*symlinkFileOperations)(nil) diff --git a/pkg/sentry/fs/ramfs/test/BUILD b/pkg/sentry/fs/ramfs/test/BUILD deleted file mode 100644 index 187eac49d..000000000 --- a/pkg/sentry/fs/ramfs/test/BUILD +++ /dev/null @@ -1,16 +0,0 @@ -package(licenses = ["notice"]) # Apache 2.0 - -load("//tools/go_stateify:defs.bzl", "go_library") - -go_library( - name = "test", - testonly = 1, - srcs = ["test.go"], - importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs/test", - visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/sentry/context", - "//pkg/sentry/fs", - "//pkg/sentry/fs/ramfs", - ], -) diff --git a/pkg/sentry/fs/ramfs/test/test.go b/pkg/sentry/fs/ramfs/test/test.go deleted file mode 100644 index 11bff7729..000000000 --- a/pkg/sentry/fs/ramfs/test/test.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 test provides a simple ramfs-based filesystem for use in testing. -package test - -import ( - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" -) - -// Dir is a simple ramfs.Dir that supports save/restore as-is. -type Dir struct { - ramfs.Dir -} - -// NewDir returns a simple ramfs directory with the passed contents. -func NewDir(ctx context.Context, contents map[string]*fs.Inode, perms fs.FilePermissions) *Dir { - d := &Dir{} - d.InitDir(ctx, contents, fs.RootOwner, perms) - return d -} - -// File is a simple ramfs.File that supports save/restore as-is. -type File struct { - ramfs.File -} - -// NewFile returns a simple ramfs File. -func NewFile(ctx context.Context, perms fs.FilePermissions) *File { - f := &File{} - f.InitFile(ctx, fs.RootOwner, perms) - return f -} diff --git a/pkg/sentry/fs/ramfs/tree.go b/pkg/sentry/fs/ramfs/tree.go index 29a70f698..f6d5ffdec 100644 --- a/pkg/sentry/fs/ramfs/tree.go +++ b/pkg/sentry/fs/ramfs/tree.go @@ -60,8 +60,7 @@ func makeSubdir(ctx context.Context, msrc *fs.MountSource, root *Dir, subdir str // emptyDir returns an empty *ramfs.Dir that is traversable but not writable. func emptyDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - dir := &Dir{} - dir.InitDir(ctx, make(map[string]*fs.Inode), fs.RootOwner, fs.FilePermsFromMode(0555)) + dir := NewDir(ctx, make(map[string]*fs.Inode), fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(dir, msrc, fs.StableAttr{ DeviceID: anon.PseudoDevice.DeviceID(), InodeID: anon.PseudoDevice.NextIno(), diff --git a/pkg/sentry/fs/ramfs/tree_test.go b/pkg/sentry/fs/ramfs/tree_test.go index 54df2143c..8bee9cfc1 100644 --- a/pkg/sentry/fs/ramfs/tree_test.go +++ b/pkg/sentry/fs/ramfs/tree_test.go @@ -22,7 +22,7 @@ import ( ) func TestMakeDirectoryTree(t *testing.T) { - mount := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) + mount := fs.NewPseudoMountSource() for _, test := range []struct { name string diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 5ba23d5da..7de928e16 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -13,12 +13,13 @@ go_library( importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/sys", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/abi/linux", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", + "//pkg/sentry/fs/fsutil", "//pkg/sentry/fs/ramfs", "//pkg/sentry/kernel", "//pkg/sentry/usermem", - "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go index e64aa0edc..8b728a4e4 100644 --- a/pkg/sentry/fs/sys/devices.go +++ b/pkg/sentry/fs/sys/devices.go @@ -16,43 +16,50 @@ package sys import ( "fmt" - "io" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" ) // +stateify savable type cpunum struct { - ramfs.Entry + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNotVirtual `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` + + fsutil.InodeSimpleAttributes + fsutil.InodeStaticFileGetter + + // k is the system kernel. + k *kernel.Kernel } -func (c *cpunum) DeprecatedPreadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error) { - if offset < 0 { - return 0, syserror.EINVAL - } +var _ fs.InodeOperations = (*cpunum)(nil) +func newPossible(ctx context.Context, msrc *fs.MountSource) *fs.Inode { + var maxCore uint k := kernel.KernelFromContext(ctx) - if k == nil { - return 0, io.EOF + if k != nil { + maxCore = k.ApplicationCores() - 1 } + contents := []byte(fmt.Sprintf("0-%d\n", maxCore)) - str := []byte(fmt.Sprintf("0-%d\n", k.ApplicationCores()-1)) - if offset >= int64(len(str)) { - return 0, io.EOF + c := &cpunum{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.RootOwner, fs.FilePermsFromMode(0444), linux.SYSFS_MAGIC), + InodeStaticFileGetter: fsutil.InodeStaticFileGetter{ + Contents: contents, + }, } - - n, err := dst.CopyOut(ctx, str[offset:]) - return int64(n), err -} - -func newPossible(ctx context.Context, msrc *fs.MountSource) *fs.Inode { - c := &cpunum{} - c.InitEntry(ctx, fs.RootOwner, fs.FilePermsFromMode(0444)) return newFile(c, msrc) } diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index 5ce33f87f..301fef038 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -24,6 +24,8 @@ import ( // +stateify savable type filesystem struct{} +var _ fs.Filesystem = (*filesystem)(nil) + func init() { fs.RegisterFilesystem(&filesystem{}) } diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index 7cc1942c7..c5b56fe69 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -22,13 +22,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) -// sys is a root sys node. -// -// +stateify savable -type sys struct { - ramfs.Dir -} - func newFile(node fs.InodeOperations, msrc *fs.MountSource) *fs.Inode { sattr := fs.StableAttr{ DeviceID: sysfsDevice.DeviceID(), @@ -40,8 +33,7 @@ func newFile(node fs.InodeOperations, msrc *fs.MountSource) *fs.Inode { } func newDir(ctx context.Context, msrc *fs.MountSource, contents map[string]*fs.Inode) *fs.Inode { - d := &sys{} - d.InitDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) + d := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(d, msrc, fs.StableAttr{ DeviceID: sysfsDevice.DeviceID(), InodeID: sysfsDevice.NextIno(), diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index 7423e816c..b26466b9d 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -33,12 +33,12 @@ import ( // // +stateify savable type TimerOperations struct { - fsutil.ZeroSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` - fsutil.NoIoctl `state:"nosave"` + fsutil.FileZeroSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` events waiter.Queue `state:"zerovalue"` timer *ktime.Timer diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index 9065cdd5d..14c7a9e62 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -23,11 +23,13 @@ go_library( "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/pipe", + "//pkg/sentry/kernel/time", "//pkg/sentry/memmap", "//pkg/sentry/safemem", "//pkg/sentry/socket/unix/transport", "//pkg/sentry/usage", "//pkg/sentry/usermem", + "//pkg/syserror", "//pkg/waiter", ], ) diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 1f9d69909..2c1eb0fd2 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -28,13 +28,13 @@ import ( // // +stateify savable type regularFileOperations struct { - waiter.AlwaysReady `state:"nosave"` - fsutil.NoopRelease `state:"nosave"` - fsutil.GenericSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoopFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoIoctl `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` // iops is the InodeOperations of a regular tmpfs file. It is // guaranteed to be the same as file.Dirent.Inode.InodeOperations, diff --git a/pkg/sentry/fs/tmpfs/file_test.go b/pkg/sentry/fs/tmpfs/file_test.go index 02da9af82..e7bbdc404 100644 --- a/pkg/sentry/fs/tmpfs/file_test.go +++ b/pkg/sentry/fs/tmpfs/file_test.go @@ -52,19 +52,19 @@ func TestGrow(t *testing.T) { abuf := bytes.Repeat([]byte{'a'}, 68) n, err := f.Pwritev(ctx, usermem.BytesIOSequence(abuf), 0) if n != int64(len(abuf)) || err != nil { - t.Fatalf("DeprecatedPwritev got (%d, %v) want (%d, nil)", n, err, len(abuf)) + t.Fatalf("Pwritev got (%d, %v) want (%d, nil)", n, err, len(abuf)) } bbuf := bytes.Repeat([]byte{'b'}, 856) n, err = f.Pwritev(ctx, usermem.BytesIOSequence(bbuf), 68) if n != int64(len(bbuf)) || err != nil { - t.Fatalf("DeprecatedPwritev got (%d, %v) want (%d, nil)", n, err, len(bbuf)) + t.Fatalf("Pwritev got (%d, %v) want (%d, nil)", n, err, len(bbuf)) } rbuf := make([]byte, len(abuf)+len(bbuf)) n, err = f.Preadv(ctx, usermem.BytesIOSequence(rbuf), 0) if n != int64(len(rbuf)) || err != nil { - t.Fatalf("DeprecatedPreadv got (%d, %v) want (%d, nil)", n, err, len(rbuf)) + t.Fatalf("Preadv got (%d, %v) want (%d, nil)", n, err, len(rbuf)) } if want := append(abuf, bbuf...); !bytes.Equal(rbuf, want) { diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index 88f85b85a..caa3220ee 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -50,6 +50,8 @@ const ( // +stateify savable type Filesystem struct{} +var _ fs.Filesystem = (*Filesystem)(nil) + func init() { fs.RegisterFilesystem(&Filesystem{}) } diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index ca2b4aabb..42d4bc76f 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" "gvisor.googlesource.com/gvisor/pkg/sentry/usage" @@ -46,11 +47,13 @@ import ( // // +stateify savable type fileInodeOperations struct { - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.InodeNotDirectory `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` - fsutil.InodeNotSymlink `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + + fsutil.InodeSimpleExtendedAttributes // kernel is used to allocate platform memory that stores the file's contents. kernel *kernel.Kernel @@ -62,10 +65,10 @@ type fileInodeOperations struct { // attr contains the unstable metadata for the file. // - // attr is protected by attrMu. attr.Unstable.Size is protected by both - // attrMu and dataMu; reading it requires locking either mutex, while - // mutating it requires locking both. - attr fsutil.InMemoryAttributes + // attr is protected by attrMu. attr.Size is protected by both attrMu + // and dataMu; reading it requires locking either mutex, while mutating + // it requires locking both. + attr fs.UnstableAttr mapsMu sync.Mutex `state:"nosave"` @@ -83,12 +86,12 @@ type fileInodeOperations struct { data fsutil.FileRangeSet } +var _ fs.InodeOperations = (*fileInodeOperations)(nil) + // NewInMemoryFile returns a new file backed by p.Memory(). func NewInMemoryFile(ctx context.Context, usage usage.MemoryKind, uattr fs.UnstableAttr, k *kernel.Kernel) fs.InodeOperations { return &fileInodeOperations{ - attr: fsutil.InMemoryAttributes{ - Unstable: uattr, - }, + attr: uattr, kernel: k, memUsage: usage, } @@ -121,71 +124,56 @@ func (f *fileInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags f // UnstableAttr returns unstable attributes of this tmpfs file. func (f *fileInodeOperations) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { f.attrMu.Lock() - defer f.attrMu.Unlock() f.dataMu.RLock() - defer f.dataMu.RUnlock() - attr := f.attr.Unstable + attr := f.attr attr.Usage = int64(f.data.Span()) + f.dataMu.RUnlock() + f.attrMu.Unlock() return attr, nil } -// Getxattr implements fs.InodeOperations.Getxattr. -func (f *fileInodeOperations) Getxattr(inode *fs.Inode, name string) ([]byte, error) { - f.attrMu.Lock() - defer f.attrMu.Unlock() - return f.attr.Getxattr(name) -} - -// Setxattr implements fs.InodeOperations.Setxattr. -func (f *fileInodeOperations) Setxattr(inode *fs.Inode, name string, value []byte) error { - f.attrMu.Lock() - defer f.attrMu.Unlock() - return f.attr.Setxattr(name, value) -} - -// Listxattr implements fs.InodeOperations.Listxattr. -func (f *fileInodeOperations) Listxattr(inode *fs.Inode) (map[string]struct{}, error) { - f.attrMu.Lock() - defer f.attrMu.Unlock() - return f.attr.Listxattr() -} - // Check implements fs.InodeOperations.Check. func (f *fileInodeOperations) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { return fs.ContextCanAccessFile(ctx, inode, p) } // SetPermissions implements fs.InodeOperations.SetPermissions. -func (f *fileInodeOperations) SetPermissions(ctx context.Context, inode *fs.Inode, p fs.FilePermissions) bool { +func (f *fileInodeOperations) SetPermissions(ctx context.Context, _ *fs.Inode, p fs.FilePermissions) bool { f.attrMu.Lock() - defer f.attrMu.Unlock() - return f.attr.SetPermissions(ctx, p) + f.attr.SetPermissions(ctx, p) + f.attrMu.Unlock() + return true } // SetTimestamps implements fs.InodeOperations.SetTimestamps. -func (f *fileInodeOperations) SetTimestamps(ctx context.Context, inode *fs.Inode, ts fs.TimeSpec) error { +func (f *fileInodeOperations) SetTimestamps(ctx context.Context, _ *fs.Inode, ts fs.TimeSpec) error { f.attrMu.Lock() - defer f.attrMu.Unlock() - return f.attr.SetTimestamps(ctx, ts) + f.attr.SetTimestamps(ctx, ts) + f.attrMu.Unlock() + return nil } // SetOwner implements fs.InodeOperations.SetOwner. -func (f *fileInodeOperations) SetOwner(ctx context.Context, inode *fs.Inode, owner fs.FileOwner) error { +func (f *fileInodeOperations) SetOwner(ctx context.Context, _ *fs.Inode, owner fs.FileOwner) error { f.attrMu.Lock() - defer f.attrMu.Unlock() - return f.attr.SetOwner(ctx, owner) + f.attr.SetOwner(ctx, owner) + f.attrMu.Unlock() + return nil } // Truncate implements fs.InodeOperations.Truncate. -func (f *fileInodeOperations) Truncate(ctx context.Context, inode *fs.Inode, size int64) error { +func (f *fileInodeOperations) Truncate(ctx context.Context, _ *fs.Inode, size int64) error { f.attrMu.Lock() defer f.attrMu.Unlock() f.dataMu.Lock() - oldSize := f.attr.Unstable.Size + oldSize := f.attr.Size if oldSize != size { - f.attr.Unstable.Size = size - f.attr.TouchModificationTime(ctx) + f.attr.Size = size + // Update mtime and ctime. + now := ktime.NowFromContext(ctx) + f.attr.ModificationTime = now + f.attr.StatusChangeTime = now } f.dataMu.Unlock() @@ -220,21 +208,21 @@ func (f *fileInodeOperations) Truncate(ctx context.Context, inode *fs.Inode, siz // AddLink implements fs.InodeOperations.AddLink. func (f *fileInodeOperations) AddLink() { f.attrMu.Lock() - f.attr.Unstable.Links++ + f.attr.Links++ f.attrMu.Unlock() } // DropLink implements fs.InodeOperations.DropLink. func (f *fileInodeOperations) DropLink() { f.attrMu.Lock() - f.attr.Unstable.Links-- + f.attr.Links-- f.attrMu.Unlock() } // NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. func (f *fileInodeOperations) NotifyStatusChange(ctx context.Context) { f.attrMu.Lock() - f.attr.TouchStatusChangeTime(ctx) + f.attr.StatusChangeTime = ktime.NowFromContext(ctx) f.attrMu.Unlock() } @@ -264,7 +252,7 @@ func (f *fileInodeOperations) read(ctx context.Context, dst usermem.IOSequence, // TODO: Separate out f.attr.Size and use atomics instead of // f.dataMu. f.dataMu.RLock() - size := f.attr.Unstable.Size + size := f.attr.Size f.dataMu.RUnlock() if offset >= size { return 0, io.EOF @@ -273,7 +261,7 @@ func (f *fileInodeOperations) read(ctx context.Context, dst usermem.IOSequence, n, err := dst.CopyOutFrom(ctx, &fileReadWriter{f, offset}) // Compare Linux's mm/filemap.c:do_generic_file_read() => file_accessed(). f.attrMu.Lock() - f.attr.TouchAccessTime(ctx) + f.attr.AccessTime = ktime.NowFromContext(ctx) f.attrMu.Unlock() return n, err } @@ -287,7 +275,9 @@ func (f *fileInodeOperations) write(ctx context.Context, src usermem.IOSequence, f.attrMu.Lock() defer f.attrMu.Unlock() // Compare Linux's mm/filemap.c:__generic_file_write_iter() => file_update_time(). - f.attr.TouchModificationTime(ctx) + now := ktime.NowFromContext(ctx) + f.attr.ModificationTime = now + f.attr.StatusChangeTime = now return src.CopyInTo(ctx, &fileReadWriter{f, offset}) } @@ -302,10 +292,10 @@ func (rw *fileReadWriter) ReadToBlocks(dsts safemem.BlockSeq) (uint64, error) { defer rw.f.dataMu.RUnlock() // Compute the range to read. - if rw.offset >= rw.f.attr.Unstable.Size { + if rw.offset >= rw.f.attr.Size { return 0, io.EOF } - end := fs.ReadEndOffset(rw.offset, int64(dsts.NumBytes()), rw.f.attr.Unstable.Size) + end := fs.ReadEndOffset(rw.offset, int64(dsts.NumBytes()), rw.f.attr.Size) if end == rw.offset { // dsts.NumBytes() == 0? return 0, nil } @@ -371,8 +361,8 @@ func (rw *fileReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, error) defer func() { // If the write ends beyond the file's previous size, it causes the // file to grow. - if rw.offset > rw.f.attr.Unstable.Size { - rw.f.attr.Unstable.Size = rw.offset + if rw.offset > rw.f.attr.Size { + rw.f.attr.Size = rw.offset } }() @@ -450,9 +440,9 @@ func (f *fileInodeOperations) Translate(ctx context.Context, required, optional f.dataMu.Lock() defer f.dataMu.Unlock() - // Constrain translations to f.attr.Unstable.Size (rounded up) to prevent + // Constrain translations to f.attr.Size (rounded up) to prevent // translation to pages that may be concurrently truncated. - pgend := fs.OffsetPageEnd(f.attr.Unstable.Size) + pgend := fs.OffsetPageEnd(f.attr.Size) var beyondEOF bool if required.End > pgend { if required.Start >= pgend { diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 40a8c4b1e..a0277a132 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -19,12 +19,14 @@ import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/pipe" "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" "gvisor.googlesource.com/gvisor/pkg/sentry/usage" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" ) var fsInfo = fs.Info{ @@ -39,32 +41,54 @@ var fsInfo = fs.Info{ func rename(ctx context.Context, oldParent *fs.Inode, oldName string, newParent *fs.Inode, newName string) error { op, ok := oldParent.InodeOperations.(*Dir) if !ok { - return ramfs.ErrCrossDevice + return syserror.EXDEV } np, ok := newParent.InodeOperations.(*Dir) if !ok { - return ramfs.ErrCrossDevice + return syserror.EXDEV } - return ramfs.Rename(ctx, &op.Dir, oldName, &np.Dir, newName) + return ramfs.Rename(ctx, op.ramfsDir, oldName, np.ramfsDir, newName) } // Dir is a directory. // // +stateify savable type Dir struct { - ramfs.Dir + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeIsDirTruncate `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + // Ideally this would be embedded, so that we "inherit" all of the + // InodeOperations implemented by ramfs.Dir for free. + // + // However, ramfs.dirFileOperations stores a pointer to a ramfs.Dir, + // and our save/restore package does not allow saving a pointer to an + // embedded field elsewhere. + // + // Thus, we must make the ramfs.Dir is a field, and we delegate all the + // InodeOperation methods to it. + ramfsDir *ramfs.Dir // kernel is used to allocate platform memory as storage for tmpfs Files. kernel *kernel.Kernel } +var _ fs.InodeOperations = (*Dir)(nil) + // NewDir returns a new directory. func NewDir(ctx context.Context, contents map[string]*fs.Inode, owner fs.FileOwner, perms fs.FilePermissions, msrc *fs.MountSource, kernel *kernel.Kernel) *fs.Inode { - d := &Dir{kernel: kernel} - d.InitDir(ctx, contents, owner, perms) + d := &Dir{ + ramfsDir: ramfs.NewDir(ctx, contents, owner, perms), + kernel: kernel, + } // Manually set the CreateOps. - d.CreateOps = d.newCreateOps() + d.ramfsDir.CreateOps = d.newCreateOps() return fs.NewInode(d, msrc, fs.StableAttr{ DeviceID: tmpfsDevice.DeviceID(), @@ -77,7 +101,107 @@ func NewDir(ctx context.Context, contents map[string]*fs.Inode, owner fs.FileOwn // afterLoad is invoked by stateify. func (d *Dir) afterLoad() { // Per NewDir, manually set the CreateOps. - d.Dir.CreateOps = d.newCreateOps() + d.ramfsDir.CreateOps = d.newCreateOps() +} + +// GetFile implements fs.InodeOperations.GetFile. +func (d *Dir) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { + return d.ramfsDir.GetFile(ctx, dirent, flags) +} + +// AddLink implements fs.InodeOperations.AddLink. +func (d *Dir) AddLink() { + d.ramfsDir.AddLink() +} + +// DropLink implements fs.InodeOperations.DropLink. +func (d *Dir) DropLink() { + d.ramfsDir.DropLink() +} + +// Bind implements fs.InodeOperations.Bind. +func (d *Dir) Bind(ctx context.Context, dir *fs.Inode, name string, ep transport.BoundEndpoint, perms fs.FilePermissions) (*fs.Dirent, error) { + return d.ramfsDir.Bind(ctx, dir, name, ep, perms) +} + +// Create implements fs.InodeOperations.Create. +func (d *Dir) Create(ctx context.Context, dir *fs.Inode, name string, flags fs.FileFlags, perms fs.FilePermissions) (*fs.File, error) { + return d.ramfsDir.Create(ctx, dir, name, flags, perms) +} + +// CreateLink implements fs.InodeOperations.CreateLink. +func (d *Dir) CreateLink(ctx context.Context, dir *fs.Inode, oldname, newname string) error { + return d.ramfsDir.CreateLink(ctx, dir, oldname, newname) +} + +// CreateHardLink implements fs.InodeOperations.CreateHardLink. +func (d *Dir) CreateHardLink(ctx context.Context, dir *fs.Inode, target *fs.Inode, name string) error { + return d.ramfsDir.CreateHardLink(ctx, dir, target, name) +} + +// CreateDirectory implements fs.InodeOperations.CreateDirectory. +func (d *Dir) CreateDirectory(ctx context.Context, dir *fs.Inode, name string, perms fs.FilePermissions) error { + return d.ramfsDir.CreateDirectory(ctx, dir, name, perms) +} + +// CreateFifo implements fs.InodeOperations.CreateFifo. +func (d *Dir) CreateFifo(ctx context.Context, dir *fs.Inode, name string, perms fs.FilePermissions) error { + return d.ramfsDir.CreateFifo(ctx, dir, name, perms) +} + +// Getxattr implements fs.InodeOperations.Getxattr. +func (d *Dir) Getxattr(i *fs.Inode, name string) ([]byte, error) { + return d.ramfsDir.Getxattr(i, name) +} + +// Setxattr implements fs.InodeOperations.Setxattr. +func (d *Dir) Setxattr(i *fs.Inode, name string, value []byte) error { + return d.ramfsDir.Setxattr(i, name, value) +} + +// Listxattr implements fs.InodeOperations.Listxattr. +func (d *Dir) Listxattr(i *fs.Inode) (map[string]struct{}, error) { + return d.ramfsDir.Listxattr(i) +} + +// Lookup implements fs.InodeOperations.Lookup. +func (d *Dir) Lookup(ctx context.Context, i *fs.Inode, p string) (*fs.Dirent, error) { + return d.ramfsDir.Lookup(ctx, i, p) +} + +// NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. +func (d *Dir) NotifyStatusChange(ctx context.Context) { + d.ramfsDir.NotifyStatusChange(ctx) +} + +// Remove implements fs.InodeOperations.Remove. +func (d *Dir) Remove(ctx context.Context, i *fs.Inode, name string) error { + return d.ramfsDir.Remove(ctx, i, name) +} + +// RemoveDirectory implements fs.InodeOperations.RemoveDirectory. +func (d *Dir) RemoveDirectory(ctx context.Context, i *fs.Inode, name string) error { + return d.ramfsDir.RemoveDirectory(ctx, i, name) +} + +// UnstableAttr implements fs.InodeOperations.UnstableAttr. +func (d *Dir) UnstableAttr(ctx context.Context, i *fs.Inode) (fs.UnstableAttr, error) { + return d.ramfsDir.UnstableAttr(ctx, i) +} + +// SetPermissions implements fs.InodeOperations.SetPermissions. +func (d *Dir) SetPermissions(ctx context.Context, i *fs.Inode, p fs.FilePermissions) bool { + return d.ramfsDir.SetPermissions(ctx, i, p) +} + +// SetOwner implements fs.InodeOperations.SetOwner. +func (d *Dir) SetOwner(ctx context.Context, i *fs.Inode, owner fs.FileOwner) error { + return d.ramfsDir.SetOwner(ctx, i, owner) +} + +// SetTimestamps implements fs.InodeOperations.SetTimestamps. +func (d *Dir) SetTimestamps(ctx context.Context, i *fs.Inode, ts fs.TimeSpec) error { + return d.ramfsDir.SetTimestamps(ctx, i, ts) } // newCreateOps builds the custom CreateOps for this Dir. @@ -132,8 +256,7 @@ type Symlink struct { // NewSymlink returns a new symlink with the provided permissions. func NewSymlink(ctx context.Context, target string, owner fs.FileOwner, msrc *fs.MountSource) *fs.Inode { - s := &Symlink{} - s.InitSymlink(ctx, owner, target) + s := &Symlink{Symlink: *ramfs.NewSymlink(ctx, owner, target)} return fs.NewInode(s, msrc, fs.StableAttr{ DeviceID: tmpfsDevice.DeviceID(), InodeID: tmpfsDevice.NextIno(), @@ -157,12 +280,12 @@ func (s *Symlink) StatFS(context.Context) (fs.Info, error) { // +stateify savable type Socket struct { ramfs.Socket + fsutil.InodeNotTruncatable `state:"nosave"` } // NewSocket returns a new socket with the provided permissions. func NewSocket(ctx context.Context, socket transport.BoundEndpoint, owner fs.FileOwner, perms fs.FilePermissions, msrc *fs.MountSource) *fs.Inode { - s := &Socket{} - s.InitSocket(ctx, socket, owner, perms) + s := &Socket{Socket: *ramfs.NewSocket(ctx, socket, owner, perms)} return fs.NewInode(s, msrc, fs.StableAttr{ DeviceID: tmpfsDevice.DeviceID(), InodeID: tmpfsDevice.NextIno(), @@ -185,15 +308,22 @@ func (s *Socket) StatFS(context.Context) (fs.Info, error) { // // +stateify savable type Fifo struct { - ramfs.Entry + fs.InodeOperations } // NewFifo creates a new named pipe. func NewFifo(ctx context.Context, owner fs.FileOwner, perms fs.FilePermissions, msrc *fs.MountSource) *fs.Inode { - f := &Fifo{} - f.InitEntry(ctx, owner, perms) - iops := pipe.NewInodeOperations(f, pipe.NewPipe(ctx, true /* isNamed */, pipe.DefaultPipeSize, usermem.PageSize)) - return fs.NewInode(iops, msrc, fs.StableAttr{ + // First create a pipe. + p := pipe.NewPipe(ctx, true /* isNamed */, pipe.DefaultPipeSize, usermem.PageSize) + + // Build pipe InodeOperations. + iops := pipe.NewInodeOperations(ctx, perms, p) + + // Wrap the iops with our Fifo. + fifoIops := &Fifo{iops} + + // Build a new Inode. + return fs.NewInode(fifoIops, msrc, fs.StableAttr{ DeviceID: tmpfsDevice.DeviceID(), InodeID: tmpfsDevice.NextIno(), BlockSize: usermem.PageSize, diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index 2b45069a6..011cb6955 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -7,7 +7,6 @@ go_library( srcs = [ "dir.go", "fs.go", - "inode.go", "line_discipline.go", "master.go", "queue.go", @@ -25,7 +24,6 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/auth", - "//pkg/sentry/kernel/time", "//pkg/sentry/socket/unix/transport", "//pkg/sentry/unimpl", "//pkg/sentry/usermem", diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index e32b05c1d..485cdb456 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -52,13 +52,17 @@ import ( // // +stateify savable type dirInodeOperations struct { - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotRenameable `state:"nosave"` fsutil.InodeNotSymlink `state:"nosave"` - fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes // msrc is the super block this directory is on. // @@ -68,9 +72,6 @@ type dirInodeOperations struct { // mu protects the fields below. mu sync.Mutex `state:"nosave"` - // attr contains the UnstableAttrs. - attr fsutil.InMemoryAttributes - // master is the master PTY inode. master *fs.Inode @@ -97,15 +98,10 @@ var _ fs.InodeOperations = (*dirInodeOperations)(nil) // newDir creates a new dir with a ptmx file and no terminals. func newDir(ctx context.Context, m *fs.MountSource) *fs.Inode { d := &dirInodeOperations{ - attr: fsutil.InMemoryAttributes{ - Unstable: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: fs.RootOwner, - Perms: fs.FilePermsFromMode(0555), - }), - }, - msrc: m, - slaves: make(map[uint32]*fs.Inode), - dentryMap: fs.NewSortedDentryMap(nil), + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.RootOwner, fs.FilePermsFromMode(0555), linux.DEVPTS_SUPER_MAGIC), + msrc: m, + slaves: make(map[uint32]*fs.Inode), + dentryMap: fs.NewSortedDentryMap(nil), } // Linux devpts uses a default mode of 0000 for ptmx which can be // changed with the ptmxmode mount option. However, that default is not @@ -224,70 +220,6 @@ func (d *dirInodeOperations) GetFile(ctx context.Context, dirent *fs.Dirent, fla return fs.NewFile(ctx, dirent, flags, &dirFileOperations{di: d}), nil } -// UnstableAttr implements fs.InodeOperations.UnstableAttr. -func (d *dirInodeOperations) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - d.mu.Lock() - defer d.mu.Unlock() - return d.attr.Unstable, nil -} - -// Check implements fs.InodeOperations.Check. -func (d *dirInodeOperations) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - -// SetPermissions implements fs.InodeOperations.SetPermissions. -func (d *dirInodeOperations) SetPermissions(ctx context.Context, inode *fs.Inode, p fs.FilePermissions) bool { - d.mu.Lock() - defer d.mu.Unlock() - return d.attr.SetPermissions(ctx, p) -} - -// SetOwner implements fs.InodeOperations.SetOwner. -func (d *dirInodeOperations) SetOwner(ctx context.Context, inode *fs.Inode, owner fs.FileOwner) error { - d.mu.Lock() - defer d.mu.Unlock() - return d.attr.SetOwner(ctx, owner) -} - -// SetTimestamps implements fs.InodeOperations.SetTimestamps. -func (d *dirInodeOperations) SetTimestamps(ctx context.Context, inode *fs.Inode, ts fs.TimeSpec) error { - d.mu.Lock() - defer d.mu.Unlock() - return d.attr.SetTimestamps(ctx, ts) -} - -// Truncate implements fs.InodeOperations.Truncate. -func (d *dirInodeOperations) Truncate(ctx context.Context, inode *fs.Inode, size int64) error { - return syserror.EINVAL -} - -// AddLink implements fs.InodeOperations.AddLink. -func (d *dirInodeOperations) AddLink() {} - -// DropLink implements fs.InodeOperations.DropLink. -func (d *dirInodeOperations) DropLink() {} - -// NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. -func (d *dirInodeOperations) NotifyStatusChange(ctx context.Context) { - d.mu.Lock() - defer d.mu.Unlock() - - d.attr.TouchStatusChangeTime(ctx) -} - -// IsVirtual implements fs.InodeOperations.IsVirtual. -func (d *dirInodeOperations) IsVirtual() bool { - return true -} - -// StatFS implements fs.InodeOperations.StatFS. -func (d *dirInodeOperations) StatFS(ctx context.Context) (fs.Info, error) { - return fs.Info{ - Type: linux.DEVPTS_SUPER_MAGIC, - }, nil -} - // allocateTerminal creates a new Terminal and installs a pts node for it. // // The caller must call DecRef when done with the returned Terminal. @@ -353,13 +285,13 @@ func (d *dirInodeOperations) masterClose(t *Terminal) { // // +stateify savable type dirFileOperations struct { - waiter.AlwaysReady `state:"nosave"` - fsutil.NoopRelease `state:"nosave"` - fsutil.GenericSeek `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` - fsutil.NoIoctl `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` // di is the inode operations. di *dirInodeOperations diff --git a/pkg/sentry/fs/tty/inode.go b/pkg/sentry/fs/tty/inode.go deleted file mode 100644 index d5d1caafc..000000000 --- a/pkg/sentry/fs/tty/inode.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2018 Google LLC -// -// 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 tty - -import ( - "sync" - - "gvisor.googlesource.com/gvisor/pkg/abi/linux" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" - ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" - "gvisor.googlesource.com/gvisor/pkg/syserror" -) - -// inodeOperations are the base fs.InodeOperations for master and slave Inodes. -// -// inodeOperations does not implement: -// -// * fs.InodeOperations.Release -// * fs.InodeOperations.GetFile -// -// +stateify savable -type inodeOperations struct { - fsutil.DeprecatedFileOperations `state:"nosave"` - fsutil.InodeNoExtendedAttributes `state:"nosave"` - fsutil.InodeNotDirectory `state:"nosave"` - fsutil.InodeNotRenameable `state:"nosave"` - fsutil.InodeNotSocket `state:"nosave"` - fsutil.InodeNotSymlink `state:"nosave"` - fsutil.NoMappable `state:"nosave"` - fsutil.NoopWriteOut `state:"nosave"` - - // mu protects the fields below. - mu sync.Mutex `state:"nosave"` - - // uattr is the inode's UnstableAttr. - uattr fs.UnstableAttr -} - -// UnstableAttr implements fs.InodeOperations.UnstableAttr. -func (i *inodeOperations) UnstableAttr(ctx context.Context, inode *fs.Inode) (fs.UnstableAttr, error) { - i.mu.Lock() - defer i.mu.Unlock() - return i.uattr, nil -} - -// Check implements fs.InodeOperations.Check. -func (i *inodeOperations) Check(ctx context.Context, inode *fs.Inode, p fs.PermMask) bool { - return fs.ContextCanAccessFile(ctx, inode, p) -} - -// SetPermissions implements fs.InodeOperations.SetPermissions -func (i *inodeOperations) SetPermissions(ctx context.Context, inode *fs.Inode, p fs.FilePermissions) bool { - i.mu.Lock() - defer i.mu.Unlock() - i.uattr.Perms = p - i.uattr.StatusChangeTime = ktime.NowFromContext(ctx) - return true -} - -// SetOwner implements fs.InodeOperations.SetOwner. -func (i *inodeOperations) SetOwner(ctx context.Context, inode *fs.Inode, owner fs.FileOwner) error { - i.mu.Lock() - defer i.mu.Unlock() - if owner.UID.Ok() { - i.uattr.Owner.UID = owner.UID - } - if owner.GID.Ok() { - i.uattr.Owner.GID = owner.GID - } - return nil -} - -// SetTimestamps implements fs.InodeOperations.SetTimestamps. -func (i *inodeOperations) SetTimestamps(ctx context.Context, inode *fs.Inode, ts fs.TimeSpec) error { - if ts.ATimeOmit && ts.MTimeOmit { - return nil - } - - i.mu.Lock() - defer i.mu.Unlock() - - now := ktime.NowFromContext(ctx) - if !ts.ATimeOmit { - if ts.ATime.IsZero() { - i.uattr.AccessTime = now - } else { - i.uattr.AccessTime = ts.ATime - } - } - if !ts.MTimeOmit { - if ts.MTime.IsZero() { - i.uattr.ModificationTime = now - } else { - i.uattr.ModificationTime = ts.MTime - } - } - i.uattr.StatusChangeTime = now - return nil -} - -// Truncate implements fs.InodeOperations.Truncate. -func (i *inodeOperations) Truncate(ctx context.Context, inode *fs.Inode, size int64) error { - return syserror.EINVAL -} - -// AddLink implements fs.InodeOperations.AddLink. -func (i *inodeOperations) AddLink() { -} - -// DropLink implements fs.InodeOperations.DropLink. -func (i *inodeOperations) DropLink() { -} - -// NotifyStatusChange implements fs.InodeOperations.NotifyStatusChange. -func (i *inodeOperations) NotifyStatusChange(ctx context.Context) { - i.mu.Lock() - defer i.mu.Unlock() - i.uattr.StatusChangeTime = ktime.NowFromContext(ctx) -} - -// IsVirtual implements fs.InodeOperations.IsVirtual. -func (i *inodeOperations) IsVirtual() bool { - return true -} - -// StatFS implements fs.InodeOperations.StatFS. -func (i *inodeOperations) StatFS(ctx context.Context) (fs.Info, error) { - return fs.Info{ - Type: linux.DEVPTS_SUPER_MAGIC, - }, nil -} diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index 00bec4c2c..b5e13ab36 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -31,7 +31,7 @@ import ( // // +stateify savable type masterInodeOperations struct { - inodeOperations + fsutil.SimpleFileInode // d is the containing dir. d *dirInodeOperations @@ -42,15 +42,8 @@ var _ fs.InodeOperations = (*masterInodeOperations)(nil) // newMasterInode creates an Inode for the master end of a terminal. func newMasterInode(ctx context.Context, d *dirInodeOperations, owner fs.FileOwner, p fs.FilePermissions) *fs.Inode { iops := &masterInodeOperations{ - inodeOperations: inodeOperations{ - uattr: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: owner, - Perms: p, - Links: 1, - // Size and Blocks are always 0. - }), - }, - d: d, + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, owner, p, linux.DEVPTS_SUPER_MAGIC), + d: d, } return fs.NewInode(iops, d.msrc, fs.StableAttr{ @@ -102,11 +95,11 @@ func (mi *masterInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flag // // +stateify savable type masterFileOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` // d is the containing dir. d *dirInodeOperations diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index a696fbb51..6dbce90b4 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -30,7 +30,7 @@ import ( // // +stateify savable type slaveInodeOperations struct { - inodeOperations + fsutil.SimpleFileInode // d is the containing dir. d *dirInodeOperations @@ -46,16 +46,9 @@ var _ fs.InodeOperations = (*slaveInodeOperations)(nil) // newSlaveInode takes ownership of t. func newSlaveInode(ctx context.Context, d *dirInodeOperations, t *Terminal, owner fs.FileOwner, p fs.FilePermissions) *fs.Inode { iops := &slaveInodeOperations{ - inodeOperations: inodeOperations{ - uattr: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: owner, - Perms: p, - Links: 1, - // Size and Blocks are always 0. - }), - }, - d: d, - t: t, + SimpleFileInode: *fsutil.NewSimpleFileInode(ctx, owner, p, linux.DEVPTS_SUPER_MAGIC), + d: d, + t: t, } return fs.NewInode(iops, d.msrc, fs.StableAttr{ @@ -91,11 +84,11 @@ func (si *slaveInodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags // // +stateify savable type slaveFileOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` // si is the inode operations. si *slaveInodeOperations diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index 9c13ecfcc..502395f18 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -99,12 +99,12 @@ func (p *pollEntry) WeakRefGone() { // // +stateify savable type EventPoll struct { - fsutil.PipeSeek `state:"zerovalue"` - fsutil.NotDirReaddir `state:"zerovalue"` - fsutil.NoFsync `state:"zerovalue"` - fsutil.NoopFlush `state:"zerovalue"` - fsutil.NoMMap `state:"zerovalue"` - fsutil.NoIoctl `state:"zerovalue"` + fsutil.FilePipeSeek `state:"zerovalue"` + fsutil.FileNotDirReaddir `state:"zerovalue"` + fsutil.FileNoFsync `state:"zerovalue"` + fsutil.FileNoopFlush `state:"zerovalue"` + fsutil.FileNoMMap `state:"zerovalue"` + fsutil.FileNoIoctl `state:"zerovalue"` // Wait queue is used to notify interested parties when the event poll // object itself becomes readable or writable. diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index 063a1d5f5..2d43c986d 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -38,13 +38,13 @@ import ( // // +stateify savable type EventOperations struct { - fsutil.NoopRelease `state:"nosave"` - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` - fsutil.NoIoctl `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` // Mutex that protects accesses to the fields of this event. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 4b0e00b85..1336b6293 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -17,17 +17,30 @@ package pipe import ( "sync" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/amutex" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/syserror" ) -// inodeOperations wraps fs.InodeOperations operations with common pipe opening semantics. +// inodeOperations implements fs.InodeOperations for pipes. // // +stateify savable type inodeOperations struct { - fs.InodeOperations + fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopRelease `state:"nosave"` + fsutil.InodeNoopTruncate `state:"nosave"` + fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotDirectory `state:"nosave"` + fsutil.InodeNotMappable `state:"nosave"` + fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` + fsutil.InodeNotVirtual `state:"nosave"` + + fsutil.InodeSimpleAttributes // mu protects the fields below. mu sync.Mutex `state:"nosave"` @@ -46,12 +59,15 @@ type inodeOperations struct { wWakeup chan struct{} `state:"nosave"` } -// NewInodeOperations creates a new pipe fs.InodeOperations. -func NewInodeOperations(base fs.InodeOperations, p *Pipe) fs.InodeOperations { +var _ fs.InodeOperations = (*inodeOperations)(nil) + +// NewInodeOperations returns a new fs.InodeOperations for a given pipe. +func NewInodeOperations(ctx context.Context, perms fs.FilePermissions, p *Pipe) *inodeOperations { return &inodeOperations{ - InodeOperations: base, - p: p, + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.FileOwnerFromContext(ctx), perms, linux.PIPEFS_MAGIC), + p: p, } + } // GetFile implements fs.InodeOperations.GetFile. Named pipes have special blocking @@ -164,18 +180,6 @@ func (i *inodeOperations) waitFor(wakeupChan *chan struct{}, sleeper amutex.Slee } } -// Truncate implements fs.InodeOperations.Truncate -// -// This method is required to override the default i.InodeOperations.Truncate -// which may return ErrInvalidOperation, this allows open related -// syscalls to set the O_TRUNC flag without returning an error by -// calling Truncate directly during openat. The ftruncate and truncate -// system calls will check that the file is an actual file and return -// EINVAL because it's a PIPE, making this behavior consistent with linux. -func (i *inodeOperations) Truncate(context.Context, *fs.Inode, int64) error { - return nil -} - // newHandleLocked signals a new pipe reader or writer depending on where // 'wakeupChan' points. This unblocks any corresponding reader or writer // waiting for the other end of the channel to be opened, see Fifo.waitFor. diff --git a/pkg/sentry/kernel/pipe/node_test.go b/pkg/sentry/kernel/pipe/node_test.go index eda551594..ad103b195 100644 --- a/pkg/sentry/kernel/pipe/node_test.go +++ b/pkg/sentry/kernel/pipe/node_test.go @@ -53,6 +53,10 @@ type openResult struct { error } +var perms fs.FilePermissions = fs.FilePermissions{ + User: fs.PermMask{Read: true, Write: true}, +} + func testOpenOrDie(ctx context.Context, t *testing.T, n fs.InodeOperations, flags fs.FileFlags, doneChan chan<- struct{}) (*fs.File, error) { file, err := n.GetFile(ctx, nil, flags) if err != nil { @@ -93,8 +97,8 @@ func assertRecvBlocks(t *testing.T, c <-chan struct{}, blockDuration time.Durati } func TestReadOpenBlocksForWriteOpen(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) rDone := make(chan struct{}) go testOpenOrDie(ctx, t, f, fs.FileFlags{Read: true}, rDone) @@ -111,8 +115,8 @@ func TestReadOpenBlocksForWriteOpen(t *testing.T) { } func TestWriteOpenBlocksForReadOpen(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) wDone := make(chan struct{}) go testOpenOrDie(ctx, t, f, fs.FileFlags{Write: true}, wDone) @@ -129,8 +133,8 @@ func TestWriteOpenBlocksForReadOpen(t *testing.T) { } func TestMultipleWriteOpenDoesntCountAsReadOpen(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) rDone1 := make(chan struct{}) rDone2 := make(chan struct{}) @@ -151,8 +155,8 @@ func TestMultipleWriteOpenDoesntCountAsReadOpen(t *testing.T) { } func TestClosedReaderBlocksWriteOpen(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) rFile, _ := testOpenOrDie(ctx, t, f, fs.FileFlags{Read: true, NonBlocking: true}, nil) rFile.DecRef() @@ -172,8 +176,8 @@ func TestClosedReaderBlocksWriteOpen(t *testing.T) { } func TestReadWriteOpenNeverBlocks(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) rwDone := make(chan struct{}) // Open for read-write never wait for a reader or writer, even if the @@ -183,8 +187,8 @@ func TestReadWriteOpenNeverBlocks(t *testing.T) { } func TestReadWriteOpenUnblocksReadOpen(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) rDone := make(chan struct{}) go testOpenOrDie(ctx, t, f, fs.FileFlags{Read: true}, rDone) @@ -197,8 +201,8 @@ func TestReadWriteOpenUnblocksReadOpen(t *testing.T) { } func TestReadWriteOpenUnblocksWriteOpen(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) wDone := make(chan struct{}) go testOpenOrDie(ctx, t, f, fs.FileFlags{Write: true}, wDone) @@ -211,8 +215,8 @@ func TestReadWriteOpenUnblocksWriteOpen(t *testing.T) { } func TestBlockedOpenIsCancellable(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) done := make(chan openResult) go testOpen(ctx, t, f, fs.FileFlags{Read: true}, done) @@ -233,18 +237,18 @@ func TestBlockedOpenIsCancellable(t *testing.T) { } } -func TestNonblockingReadOpenNoWriters(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) +func TestNonblockingReadOpenFileNoWriters(t *testing.T) { ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) if _, err := testOpen(ctx, t, f, fs.FileFlags{Read: true, NonBlocking: true}, nil); err != nil { t.Fatalf("Nonblocking open for read failed with error %v.", err) } } -func TestNonblockingWriteOpenNoReaders(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) +func TestNonblockingWriteOpenFileNoReaders(t *testing.T) { ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) if _, err := testOpen(ctx, t, f, fs.FileFlags{Write: true, NonBlocking: true}, nil); err != syserror.ENXIO { t.Fatalf("Nonblocking open for write failed unexpected error %v.", err) @@ -252,8 +256,8 @@ func TestNonblockingWriteOpenNoReaders(t *testing.T) { } func TestNonBlockingReadOpenWithWriter(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) wDone := make(chan struct{}) go testOpenOrDie(ctx, t, f, fs.FileFlags{Write: true}, wDone) @@ -271,8 +275,8 @@ func TestNonBlockingReadOpenWithWriter(t *testing.T) { } func TestNonBlockingWriteOpenWithReader(t *testing.T) { - f := NewInodeOperations(nil, newNamedPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newNamedPipe(t)) rDone := make(chan struct{}) go testOpenOrDie(ctx, t, f, fs.FileFlags{Read: true}, rDone) @@ -290,8 +294,8 @@ func TestNonBlockingWriteOpenWithReader(t *testing.T) { } func TestAnonReadOpen(t *testing.T) { - f := NewInodeOperations(nil, newAnonPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newAnonPipe(t)) if _, err := testOpen(ctx, t, f, fs.FileFlags{Read: true}, nil); err != nil { t.Fatalf("open anon pipe for read failed: %v", err) @@ -299,8 +303,8 @@ func TestAnonReadOpen(t *testing.T) { } func TestAnonWriteOpen(t *testing.T) { - f := NewInodeOperations(nil, newAnonPipe(t)) ctx := newSleeperContext(t) + f := NewInodeOperations(ctx, perms, newAnonPipe(t)) if _, err := testOpen(ctx, t, f, fs.FileFlags{Write: true}, nil); err != nil { t.Fatalf("open anon pipe for write failed: %v", err) diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index 126054826..fad077d2d 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -25,11 +25,9 @@ import ( "sync/atomic" "syscall" - "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/ilist" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" "gvisor.googlesource.com/gvisor/pkg/syserror" "gvisor.googlesource.com/gvisor/pkg/waiter" @@ -50,7 +48,7 @@ type Pipe struct { isNamed bool // The dirent backing this pipe. Shared by all readers and writers. - dirent *fs.Dirent + Dirent *fs.Dirent // The buffered byte queue. data ilist.List @@ -97,28 +95,19 @@ func NewPipe(ctx context.Context, isNamed bool, sizeBytes, atomicIOBytes int) *P // Build the fs.Dirent of this pipe, shared by all fs.Files associated // with this pipe. + perms := fs.FilePermissions{ + User: fs.PermMask{Read: true, Write: true}, + } + iops := NewInodeOperations(ctx, perms, p) ino := pipeDevice.NextIno() - base := fsutil.NewSimpleInodeOperations(fsutil.InodeSimpleAttributes{ - FSType: linux.PIPEFS_MAGIC, - UAttr: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: fs.FileOwnerFromContext(ctx), - Perms: fs.FilePermissions{ - User: fs.PermMask{Read: true, Write: true}, - }, - Links: 1, - }), - }) sattr := fs.StableAttr{ Type: fs.Pipe, DeviceID: pipeDevice.DeviceID(), InodeID: ino, BlockSize: int64(atomicIOBytes), } - // There is no real filesystem backing this pipe, so we pass in a nil - // Filesystem. - sb := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) - p.dirent = fs.NewDirent(fs.NewInode(NewInodeOperations(base, p), sb, sattr), fmt.Sprintf("pipe:[%d]", ino)) - + ms := fs.NewPseudoMountSource() + p.Dirent = fs.NewDirent(fs.NewInode(iops, ms, sattr), fmt.Sprintf("pipe:[%d]", ino)) return p } @@ -135,7 +124,7 @@ func NewConnectedPipe(ctx context.Context, sizeBytes int, atomicIOBytes int) (*f // ROpen opens the pipe for reading. func (p *Pipe) ROpen(ctx context.Context) *fs.File { p.rOpen() - return fs.NewFile(ctx, p.dirent, fs.FileFlags{Read: true}, &Reader{ + return fs.NewFile(ctx, p.Dirent, fs.FileFlags{Read: true}, &Reader{ ReaderWriter: ReaderWriter{Pipe: p}, }) } @@ -143,7 +132,7 @@ func (p *Pipe) ROpen(ctx context.Context) *fs.File { // WOpen opens the pipe for writing. func (p *Pipe) WOpen(ctx context.Context) *fs.File { p.wOpen() - return fs.NewFile(ctx, p.dirent, fs.FileFlags{Write: true}, &Writer{ + return fs.NewFile(ctx, p.Dirent, fs.FileFlags{Write: true}, &Writer{ ReaderWriter: ReaderWriter{Pipe: p}, }) } @@ -152,7 +141,7 @@ func (p *Pipe) WOpen(ctx context.Context) *fs.File { func (p *Pipe) RWOpen(ctx context.Context) *fs.File { p.rOpen() p.wOpen() - return fs.NewFile(ctx, p.dirent, fs.FileFlags{Read: true, Write: true}, &ReaderWriter{ + return fs.NewFile(ctx, p.Dirent, fs.FileFlags{Read: true, Write: true}, &ReaderWriter{ Pipe: p, }) } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 36be1efc3..028175530 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -35,11 +35,11 @@ import ( // // +stateify savable type ReaderWriter struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` *Pipe } diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 437cc5da1..c070c7316 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -20,7 +20,6 @@ import ( "io" "gvisor.googlesource.com/gvisor/pkg/abi" - "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" @@ -38,20 +37,6 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// byteReaderFileOperations implements fs.FileOperations for reading -// from a []byte source. -type byteReader struct { - fsutil.NoopRelease - fsutil.PipeSeek - fsutil.NotDirReaddir - fsutil.NoFsync - fsutil.NoopFlush - fsutil.NoMMap - fsutil.NoIoctl - waiter.AlwaysReady - data []byte -} - type fileContext struct { context.Context } @@ -65,17 +50,34 @@ func (f *fileContext) Value(key interface{}) interface{} { } } +// byteReader implements fs.FileOperations for reading from a []byte source. +type byteReader struct { + waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + + data []byte +} + +var _ fs.FileOperations = (*byteReader)(nil) + // newByteReaderFile creates a fake file to read data from. func newByteReaderFile(data []byte) *fs.File { // Create a fake inode. - inode := fs.NewInode(fsutil.NewSimpleInodeOperations(fsutil.InodeSimpleAttributes{ - FSType: linux.ANON_INODE_FS_MAGIC, - }), fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{ - Type: fs.Anonymous, - DeviceID: anon.PseudoDevice.DeviceID(), - InodeID: anon.PseudoDevice.NextIno(), - BlockSize: usermem.PageSize, - }) + inode := fs.NewInode( + &fsutil.SimpleFileInode{}, + fs.NewPseudoMountSource(), + fs.StableAttr{ + Type: fs.Anonymous, + DeviceID: anon.PseudoDevice.DeviceID(), + InodeID: anon.PseudoDevice.NextIno(), + BlockSize: usermem.PageSize, + }) // Use the fake inode to create a fake dirent. dirent := fs.NewTransientDirent(inode) diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index d65b5f49e..ca865b111 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -138,11 +138,11 @@ type commonEndpoint interface { // // +stateify savable type SocketOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` socket.SendReceiveTimeout *waiter.Queue diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index f3ecb6dc3..2c54e8de2 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -46,11 +46,11 @@ const ( // socketOperations implements fs.FileOperations and socket.Socket for a socket // implemented using a host socket. type socketOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` socket.SendReceiveTimeout fd int // must be O_NONBLOCK diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 0a7d4772c..5b0c11c84 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -65,11 +65,11 @@ var netlinkSocketDevice = device.NewAnonDevice() // // +stateify savable type Socket struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` socket.SendReceiveTimeout // ports provides netlink port allocation. diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 8c8ebadb7..13681100e 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -45,11 +45,11 @@ import ( // socketOperations implements fs.FileOperations and socket.Socket for a socket // implemented using a host socket. type socketOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` socket.SendReceiveTimeout fd uint32 // must be O_NONBLOCK diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 9d4aaeb9d..e28d2c4fa 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -178,18 +178,12 @@ func Pair(t *kernel.Task, family int, stype transport.SockType, protocol int) (* // NewDirent returns a sockfs fs.Dirent that resides on device d. func NewDirent(ctx context.Context, d *device.Device) *fs.Dirent { ino := d.NextIno() - // There is no real filesystem backing this pipe, so we pass in a nil - // Filesystem. - inode := fs.NewInode(fsutil.NewSimpleInodeOperations(fsutil.InodeSimpleAttributes{ - FSType: linux.SOCKFS_MAGIC, - UAttr: fs.WithCurrentTime(ctx, fs.UnstableAttr{ - Owner: fs.FileOwnerFromContext(ctx), - Perms: fs.FilePermissions{ - User: fs.PermMask{Read: true, Write: true}, - }, - Links: 1, - }), - }), fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{ + iops := &fsutil.SimpleFileInode{ + InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.FileOwnerFromContext(ctx), fs.FilePermissions{ + User: fs.PermMask{Read: true, Write: true}, + }, linux.SOCKFS_MAGIC), + } + inode := fs.NewInode(iops, fs.NewPseudoMountSource(), fs.StableAttr{ Type: fs.Socket, DeviceID: d.DeviceID(), InodeID: ino, diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index da225eabb..19258e692 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -45,11 +45,11 @@ import ( // // +stateify savable type SocketOperations struct { - fsutil.PipeSeek `state:"nosave"` - fsutil.NotDirReaddir `state:"nosave"` - fsutil.NoFsync `state:"nosave"` - fsutil.NoopFlush `state:"nosave"` - fsutil.NoMMap `state:"nosave"` + fsutil.FilePipeSeek `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` refs.AtomicRefCount socket.SendReceiveTimeout diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 1e75b0efc..942315d6e 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -489,9 +489,7 @@ func mustFindFilesystem(name string) fs.Filesystem { // addSubmountOverlay overlays the inode over a ramfs tree containing the given // paths. func addSubmountOverlay(ctx context.Context, inode *fs.Inode, submounts []string) (*fs.Inode, error) { - // There is no real filesystem backing this ramfs tree, so we pass in - // "nil" here. - msrc := fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}) + msrc := fs.NewPseudoMountSource() mountTree, err := ramfs.MakeDirectoryTree(ctx, msrc, submounts) if err != nil { return nil, fmt.Errorf("error creating mount tree: %v", err) diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index e64df97b0..6ffe9aed6 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -334,6 +334,11 @@ int ReadlinkWhileExited(std::string const& basename, char* buf, size_t count) { return ret; } +TEST(ProcTest, NotFoundInRoot) { + struct stat s; + EXPECT_THAT(stat("/proc/foobar", &s), SyscallFailsWithErrno(ENOENT)); +} + TEST(ProcSelfTest, IsThreadGroupLeader) { ScopedThread([] { const pid_t tgid = getpid(); -- cgit v1.2.3 From 2a0c69b19f4b55c3f9777f0098a72af123ccff3c Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 31 Jan 2019 11:11:44 -0800 Subject: Remove license comments Nothing reads them and they can simply get stale. Generated with: $ sed -i "s/licenses(\(.*\)).*/licenses(\1)/" **/BUILD PiperOrigin-RevId: 231818945 Change-Id: Ibc3f9838546b7e94f13f217060d31f4ada9d4bf0 --- pkg/abi/BUILD | 2 +- pkg/abi/linux/BUILD | 2 +- pkg/amutex/BUILD | 2 +- pkg/atomicbitops/BUILD | 2 +- pkg/binary/BUILD | 2 +- pkg/bits/BUILD | 2 +- pkg/bpf/BUILD | 2 +- pkg/compressio/BUILD | 2 +- pkg/control/client/BUILD | 2 +- pkg/control/server/BUILD | 2 +- pkg/cpuid/BUILD | 2 +- pkg/dhcp/BUILD | 2 +- pkg/eventchannel/BUILD | 2 +- pkg/fd/BUILD | 2 +- pkg/fdnotifier/BUILD | 2 +- pkg/gate/BUILD | 2 +- pkg/ilist/BUILD | 2 +- pkg/linewriter/BUILD | 2 +- pkg/log/BUILD | 2 +- pkg/metric/BUILD | 2 +- pkg/p9/BUILD | 2 +- pkg/p9/local_server/BUILD | 2 +- pkg/p9/p9test/BUILD | 2 +- pkg/rand/BUILD | 2 +- pkg/refs/BUILD | 2 +- pkg/seccomp/BUILD | 2 +- pkg/secio/BUILD | 2 +- pkg/segment/BUILD | 2 +- pkg/segment/test/BUILD | 2 +- pkg/sentry/BUILD | 2 +- pkg/sentry/arch/BUILD | 2 +- pkg/sentry/context/BUILD | 2 +- pkg/sentry/context/contexttest/BUILD | 2 +- pkg/sentry/control/BUILD | 2 +- pkg/sentry/device/BUILD | 2 +- pkg/sentry/fs/BUILD | 2 +- pkg/sentry/fs/anon/BUILD | 2 +- pkg/sentry/fs/ashmem/BUILD | 2 +- pkg/sentry/fs/binder/BUILD | 2 +- pkg/sentry/fs/dev/BUILD | 2 +- pkg/sentry/fs/fdpipe/BUILD | 2 +- pkg/sentry/fs/filetest/BUILD | 2 +- pkg/sentry/fs/fsutil/BUILD | 2 +- pkg/sentry/fs/gofer/BUILD | 2 +- pkg/sentry/fs/host/BUILD | 2 +- pkg/sentry/fs/lock/BUILD | 2 +- pkg/sentry/fs/proc/BUILD | 2 +- pkg/sentry/fs/proc/device/BUILD | 2 +- pkg/sentry/fs/proc/seqfile/BUILD | 2 +- pkg/sentry/fs/ramfs/BUILD | 2 +- pkg/sentry/fs/sys/BUILD | 2 +- pkg/sentry/fs/timerfd/BUILD | 2 +- pkg/sentry/fs/tmpfs/BUILD | 2 +- pkg/sentry/fs/tty/BUILD | 2 +- pkg/sentry/hostcpu/BUILD | 2 +- pkg/sentry/inet/BUILD | 2 +- pkg/sentry/kernel/BUILD | 2 +- pkg/sentry/kernel/auth/BUILD | 2 +- pkg/sentry/kernel/contexttest/BUILD | 2 +- pkg/sentry/kernel/epoll/BUILD | 2 +- pkg/sentry/kernel/eventfd/BUILD | 2 +- pkg/sentry/kernel/fasync/BUILD | 2 +- pkg/sentry/kernel/futex/BUILD | 2 +- pkg/sentry/kernel/kdefs/BUILD | 2 +- pkg/sentry/kernel/memevent/BUILD | 2 +- pkg/sentry/kernel/pipe/BUILD | 2 +- pkg/sentry/kernel/sched/BUILD | 2 +- pkg/sentry/kernel/semaphore/BUILD | 2 +- pkg/sentry/kernel/shm/BUILD | 2 +- pkg/sentry/kernel/time/BUILD | 2 +- pkg/sentry/limits/BUILD | 2 +- pkg/sentry/loader/BUILD | 2 +- pkg/sentry/memmap/BUILD | 2 +- pkg/sentry/memutil/BUILD | 2 +- pkg/sentry/mm/BUILD | 2 +- pkg/sentry/platform/BUILD | 2 +- pkg/sentry/platform/filemem/BUILD | 2 +- pkg/sentry/platform/interrupt/BUILD | 2 +- pkg/sentry/platform/kvm/BUILD | 2 +- pkg/sentry/platform/kvm/testutil/BUILD | 2 +- pkg/sentry/platform/procid/BUILD | 2 +- pkg/sentry/platform/ptrace/BUILD | 2 +- pkg/sentry/platform/ring0/BUILD | 2 +- pkg/sentry/platform/ring0/gen_offsets/BUILD | 2 +- pkg/sentry/platform/ring0/pagetables/BUILD | 2 +- pkg/sentry/platform/safecopy/BUILD | 2 +- pkg/sentry/safemem/BUILD | 2 +- pkg/sentry/sighandling/BUILD | 2 +- pkg/sentry/socket/BUILD | 2 +- pkg/sentry/socket/control/BUILD | 2 +- pkg/sentry/socket/epsocket/BUILD | 2 +- pkg/sentry/socket/hostinet/BUILD | 2 +- pkg/sentry/socket/netlink/BUILD | 2 +- pkg/sentry/socket/netlink/port/BUILD | 2 +- pkg/sentry/socket/netlink/route/BUILD | 2 +- pkg/sentry/socket/rpcinet/BUILD | 2 +- pkg/sentry/socket/rpcinet/conn/BUILD | 2 +- pkg/sentry/socket/rpcinet/notifier/BUILD | 2 +- pkg/sentry/socket/unix/BUILD | 2 +- pkg/sentry/socket/unix/transport/BUILD | 2 +- pkg/sentry/state/BUILD | 2 +- pkg/sentry/strace/BUILD | 2 +- pkg/sentry/syscalls/BUILD | 2 +- pkg/sentry/syscalls/linux/BUILD | 2 +- pkg/sentry/time/BUILD | 2 +- pkg/sentry/unimpl/BUILD | 2 +- pkg/sentry/uniqueid/BUILD | 2 +- pkg/sentry/usage/BUILD | 2 +- pkg/sentry/usermem/BUILD | 2 +- pkg/sentry/watchdog/BUILD | 2 +- pkg/sleep/BUILD | 2 +- pkg/state/BUILD | 2 +- pkg/state/statefile/BUILD | 2 +- pkg/sync/BUILD | 2 +- pkg/sync/atomicptrtest/BUILD | 2 +- pkg/sync/seqatomictest/BUILD | 2 +- pkg/syserr/BUILD | 2 +- pkg/syserror/BUILD | 2 +- pkg/tcpip/BUILD | 2 +- pkg/tcpip/adapters/gonet/BUILD | 2 +- pkg/tcpip/buffer/BUILD | 2 +- pkg/tcpip/checker/BUILD | 2 +- pkg/tcpip/hash/jenkins/BUILD | 2 +- pkg/tcpip/header/BUILD | 2 +- pkg/tcpip/link/channel/BUILD | 2 +- pkg/tcpip/link/fdbased/BUILD | 2 +- pkg/tcpip/link/loopback/BUILD | 2 +- pkg/tcpip/link/rawfile/BUILD | 2 +- pkg/tcpip/link/sharedmem/BUILD | 2 +- pkg/tcpip/link/sharedmem/pipe/BUILD | 2 +- pkg/tcpip/link/sharedmem/queue/BUILD | 2 +- pkg/tcpip/link/sniffer/BUILD | 2 +- pkg/tcpip/link/tun/BUILD | 2 +- pkg/tcpip/link/waitable/BUILD | 2 +- pkg/tcpip/network/BUILD | 2 +- pkg/tcpip/network/arp/BUILD | 2 +- pkg/tcpip/network/fragmentation/BUILD | 2 +- pkg/tcpip/network/hash/BUILD | 2 +- pkg/tcpip/network/ipv4/BUILD | 2 +- pkg/tcpip/network/ipv6/BUILD | 2 +- pkg/tcpip/ports/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_connect/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_echo/BUILD | 2 +- pkg/tcpip/seqnum/BUILD | 2 +- pkg/tcpip/stack/BUILD | 2 +- pkg/tcpip/transport/ping/BUILD | 2 +- pkg/tcpip/transport/tcp/BUILD | 2 +- pkg/tcpip/transport/tcp/testing/context/BUILD | 2 +- pkg/tcpip/transport/tcpconntrack/BUILD | 2 +- pkg/tcpip/transport/udp/BUILD | 2 +- pkg/tmutex/BUILD | 2 +- pkg/unet/BUILD | 2 +- pkg/urpc/BUILD | 2 +- pkg/waiter/BUILD | 2 +- runsc/boot/BUILD | 2 +- runsc/boot/filter/BUILD | 2 +- runsc/cgroup/BUILD | 2 +- runsc/cmd/BUILD | 2 +- runsc/console/BUILD | 2 +- runsc/container/BUILD | 2 +- runsc/fsgofer/BUILD | 2 +- runsc/fsgofer/filter/BUILD | 2 +- runsc/sandbox/BUILD | 2 +- runsc/specutils/BUILD | 2 +- runsc/test/image/BUILD | 2 +- runsc/test/integration/BUILD | 2 +- runsc/test/root/BUILD | 2 +- runsc/test/root/testdata/BUILD | 2 +- runsc/test/testutil/BUILD | 2 +- runsc/tools/dockercfg/BUILD | 2 +- test/syscalls/BUILD | 2 +- test/syscalls/gtest/BUILD | 2 +- test/syscalls/linux/BUILD | 2 +- test/util/BUILD | 2 +- tools/go_generics/BUILD | 2 +- tools/go_generics/globals/BUILD | 2 +- tools/go_generics/go_merge/BUILD | 2 +- tools/go_generics/rules_tests/BUILD | 2 +- tools/go_stateify/BUILD | 2 +- vdso/BUILD | 2 +- 180 files changed, 180 insertions(+), 180 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/BUILD b/pkg/abi/BUILD index 1ba4f3a46..323263ebf 100644 --- a/pkg/abi/BUILD +++ b/pkg/abi/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index e6043abf4..7648c9469 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -2,7 +2,7 @@ # Linux kernel. It should be used instead of syscall or golang.org/x/sys/unix # when the host OS may not be Linux. -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/amutex/BUILD b/pkg/amutex/BUILD index 7cda07418..bdb6e8f2c 100644 --- a/pkg/amutex/BUILD +++ b/pkg/amutex/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "amutex", diff --git a/pkg/atomicbitops/BUILD b/pkg/atomicbitops/BUILD index 235188531..9555bf645 100644 --- a/pkg/atomicbitops/BUILD +++ b/pkg/atomicbitops/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "atomicbitops", diff --git a/pkg/binary/BUILD b/pkg/binary/BUILD index 571151f72..bd37376b0 100644 --- a/pkg/binary/BUILD +++ b/pkg/binary/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "binary", diff --git a/pkg/bits/BUILD b/pkg/bits/BUILD index 46794bdb8..5214b2c24 100644 --- a/pkg/bits/BUILD +++ b/pkg/bits/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/bpf/BUILD b/pkg/bpf/BUILD index 564df3af5..3c7ae3103 100644 --- a/pkg/bpf/BUILD +++ b/pkg/bpf/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/compressio/BUILD b/pkg/compressio/BUILD index 72952d735..3a0ac64e6 100644 --- a/pkg/compressio/BUILD +++ b/pkg/compressio/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "compressio", diff --git a/pkg/control/client/BUILD b/pkg/control/client/BUILD index 32853875d..22a4a4a5a 100644 --- a/pkg/control/client/BUILD +++ b/pkg/control/client/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "client", diff --git a/pkg/control/server/BUILD b/pkg/control/server/BUILD index ba2b1be9f..76b2e9787 100644 --- a/pkg/control/server/BUILD +++ b/pkg/control/server/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "server", diff --git a/pkg/cpuid/BUILD b/pkg/cpuid/BUILD index 46fc4703b..29cc38778 100644 --- a/pkg/cpuid/BUILD +++ b/pkg/cpuid/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/dhcp/BUILD b/pkg/dhcp/BUILD index c97dfc14b..003620b48 100644 --- a/pkg/dhcp/BUILD +++ b/pkg/dhcp/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "dhcp", diff --git a/pkg/eventchannel/BUILD b/pkg/eventchannel/BUILD index 18348ef54..5c2a44aa1 100644 --- a/pkg/eventchannel/BUILD +++ b/pkg/eventchannel/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "eventchannel", diff --git a/pkg/fd/BUILD b/pkg/fd/BUILD index 06cfd445e..ab1109157 100644 --- a/pkg/fd/BUILD +++ b/pkg/fd/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fd", diff --git a/pkg/fdnotifier/BUILD b/pkg/fdnotifier/BUILD index 27d378d5b..8c8d193cc 100644 --- a/pkg/fdnotifier/BUILD +++ b/pkg/fdnotifier/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fdnotifier", diff --git a/pkg/gate/BUILD b/pkg/gate/BUILD index 9a87a3a31..83679f2da 100644 --- a/pkg/gate/BUILD +++ b/pkg/gate/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "gate", diff --git a/pkg/ilist/BUILD b/pkg/ilist/BUILD index a67aa2cff..dbd65ab12 100644 --- a/pkg/ilist/BUILD +++ b/pkg/ilist/BUILD @@ -1,7 +1,7 @@ load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ilist", diff --git a/pkg/linewriter/BUILD b/pkg/linewriter/BUILD index 3f28ba867..d1aa2e7d6 100644 --- a/pkg/linewriter/BUILD +++ b/pkg/linewriter/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "linewriter", diff --git a/pkg/log/BUILD b/pkg/log/BUILD index 94ac66db3..b2d18eddb 100644 --- a/pkg/log/BUILD +++ b/pkg/log/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "log", diff --git a/pkg/metric/BUILD b/pkg/metric/BUILD index d96e5563b..4b2c7a00e 100644 --- a/pkg/metric/BUILD +++ b/pkg/metric/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "metric", diff --git a/pkg/p9/BUILD b/pkg/p9/BUILD index 2c224e65b..5d972309d 100644 --- a/pkg/p9/BUILD +++ b/pkg/p9/BUILD @@ -2,7 +2,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:public"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) go_library( diff --git a/pkg/p9/local_server/BUILD b/pkg/p9/local_server/BUILD index b17ebb79d..aa6db186c 100644 --- a/pkg/p9/local_server/BUILD +++ b/pkg/p9/local_server/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "local_server", diff --git a/pkg/p9/p9test/BUILD b/pkg/p9/p9test/BUILD index 7c4b875ce..cf22edde8 100644 --- a/pkg/p9/p9test/BUILD +++ b/pkg/p9/p9test/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) alias( name = "mockgen", diff --git a/pkg/rand/BUILD b/pkg/rand/BUILD index 0c9efc709..4eec3a4dd 100644 --- a/pkg/rand/BUILD +++ b/pkg/rand/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "rand", diff --git a/pkg/refs/BUILD b/pkg/refs/BUILD index 98150ba8f..fc562f821 100644 --- a/pkg/refs/BUILD +++ b/pkg/refs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/seccomp/BUILD b/pkg/seccomp/BUILD index 657f923ed..0e9c4692d 100644 --- a/pkg/seccomp/BUILD +++ b/pkg/seccomp/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_embed_data") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "victim", diff --git a/pkg/secio/BUILD b/pkg/secio/BUILD index 29f751725..2b4b87c61 100644 --- a/pkg/secio/BUILD +++ b/pkg/secio/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "secio", diff --git a/pkg/segment/BUILD b/pkg/segment/BUILD index 964d73af8..700385907 100644 --- a/pkg/segment/BUILD +++ b/pkg/segment/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) load("//tools/go_generics:defs.bzl", "go_template") diff --git a/pkg/segment/test/BUILD b/pkg/segment/test/BUILD index bdf53e24e..81e929b8c 100644 --- a/pkg/segment/test/BUILD +++ b/pkg/segment/test/BUILD @@ -2,7 +2,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//visibility:private"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/BUILD b/pkg/sentry/BUILD index d18cf3555..53989301f 100644 --- a/pkg/sentry/BUILD +++ b/pkg/sentry/BUILD @@ -1,7 +1,7 @@ # This BUILD file defines a package_group that allows for interdependencies for # sentry-internal packages. -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) package_group( name = "internal", diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD index 9bf04360a..0c044bc33 100644 --- a/pkg/sentry/arch/BUILD +++ b/pkg/sentry/arch/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/context/BUILD b/pkg/sentry/context/BUILD index 02d24defd..a3c8d0177 100644 --- a/pkg/sentry/context/BUILD +++ b/pkg/sentry/context/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "context", diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/context/contexttest/BUILD index 01bb40b04..bed156b70 100644 --- a/pkg/sentry/context/contexttest/BUILD +++ b/pkg/sentry/context/contexttest/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD index c3b682d6f..f54e01ee8 100644 --- a/pkg/sentry/control/BUILD +++ b/pkg/sentry/control/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "control", diff --git a/pkg/sentry/device/BUILD b/pkg/sentry/device/BUILD index bebdb2939..01de708d3 100644 --- a/pkg/sentry/device/BUILD +++ b/pkg/sentry/device/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "device", diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 6f368b0da..e58333da3 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/anon/BUILD b/pkg/sentry/fs/anon/BUILD index 4bd912e95..2111df2e8 100644 --- a/pkg/sentry/fs/anon/BUILD +++ b/pkg/sentry/fs/anon/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "anon", diff --git a/pkg/sentry/fs/ashmem/BUILD b/pkg/sentry/fs/ashmem/BUILD index e5bb661b5..dcf620dca 100644 --- a/pkg/sentry/fs/ashmem/BUILD +++ b/pkg/sentry/fs/ashmem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/fs/binder/BUILD b/pkg/sentry/fs/binder/BUILD index 27155819e..8a448175f 100644 --- a/pkg/sentry/fs/binder/BUILD +++ b/pkg/sentry/fs/binder/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD index 85371032a..e5b962c8c 100644 --- a/pkg/sentry/fs/dev/BUILD +++ b/pkg/sentry/fs/dev/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 8a0937cda..098463e97 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD index d137fee4c..05ca72aa0 100644 --- a/pkg/sentry/fs/filetest/BUILD +++ b/pkg/sentry/fs/filetest/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index d4767642b..7dff970ea 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index 35ffadd13..f2c79b475 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 6877eb161..ea2ca11bf 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index 3159ff1da..7164744b8 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index 74954f213..f6bc90634 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/proc/device/BUILD b/pkg/sentry/fs/proc/device/BUILD index ff7dacf07..64b0c5a3a 100644 --- a/pkg/sentry/fs/proc/device/BUILD +++ b/pkg/sentry/fs/proc/device/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "device", diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD index b4ba64e10..6b44c0075 100644 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ b/pkg/sentry/fs/proc/seqfile/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index 4a629e38e..f36e4a5e8 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD index 7de928e16..42e98230e 100644 --- a/pkg/sentry/fs/sys/BUILD +++ b/pkg/sentry/fs/sys/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD index ffdd7e0dc..0e06a5028 100644 --- a/pkg/sentry/fs/timerfd/BUILD +++ b/pkg/sentry/fs/timerfd/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD index c5ec85460..bf5b68869 100644 --- a/pkg/sentry/fs/tmpfs/BUILD +++ b/pkg/sentry/fs/tmpfs/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD index 011cb6955..bee2db3f3 100644 --- a/pkg/sentry/fs/tty/BUILD +++ b/pkg/sentry/fs/tty/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/hostcpu/BUILD b/pkg/sentry/hostcpu/BUILD index 33197cf14..b5067ae6d 100644 --- a/pkg/sentry/hostcpu/BUILD +++ b/pkg/sentry/hostcpu/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "hostcpu", diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD index 159c50efb..e288d34e9 100644 --- a/pkg/sentry/inet/BUILD +++ b/pkg/sentry/inet/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index 7d41626dc..b230aff98 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index a81085372..abd4f2dae 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/contexttest/BUILD b/pkg/sentry/kernel/contexttest/BUILD index 391986291..5769a3b28 100644 --- a/pkg/sentry/kernel/contexttest/BUILD +++ b/pkg/sentry/kernel/contexttest/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 5e8b36ed6..1567d5050 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index d96803fc9..f2f1a1223 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD index 17749c0de..5faf95909 100644 --- a/pkg/sentry/kernel/fasync/BUILD +++ b/pkg/sentry/kernel/fasync/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index afd35985f..da24c36c1 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/kdefs/BUILD b/pkg/sentry/kernel/kdefs/BUILD index 3f8fa206c..38aaca134 100644 --- a/pkg/sentry/kernel/kdefs/BUILD +++ b/pkg/sentry/kernel/kdefs/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "kdefs", diff --git a/pkg/sentry/kernel/memevent/BUILD b/pkg/sentry/kernel/memevent/BUILD index dfd8dd062..347a69062 100644 --- a/pkg/sentry/kernel/memevent/BUILD +++ b/pkg/sentry/kernel/memevent/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "memevent", diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 19b23c6d2..011a3f349 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/sched/BUILD b/pkg/sentry/kernel/sched/BUILD index 52e226a39..184e8a35b 100644 --- a/pkg/sentry/kernel/sched/BUILD +++ b/pkg/sentry/kernel/sched/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sched", diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index bdcf4ce5c..840943ca8 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 40e641355..f45770eef 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index 5d8db2273..584f7c7cc 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD index 90f4395d4..800166675 100644 --- a/pkg/sentry/limits/BUILD +++ b/pkg/sentry/limits/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 24e734b49..1ea260a4e 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_embed_data") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD index c9e0b95a0..9c2cbd18b 100644 --- a/pkg/sentry/memmap/BUILD +++ b/pkg/sentry/memmap/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/memutil/BUILD b/pkg/sentry/memutil/BUILD index 88738d65d..68b03d4cc 100644 --- a/pkg/sentry/memutil/BUILD +++ b/pkg/sentry/memutil/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "memutil", diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD index 0997ec0a7..f679262d0 100644 --- a/pkg/sentry/mm/BUILD +++ b/pkg/sentry/mm/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD index af9ba5394..ac8a6cb7f 100644 --- a/pkg/sentry/platform/BUILD +++ b/pkg/sentry/platform/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/platform/filemem/BUILD b/pkg/sentry/platform/filemem/BUILD index 2a5982763..1a61cfaa5 100644 --- a/pkg/sentry/platform/filemem/BUILD +++ b/pkg/sentry/platform/filemem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/platform/interrupt/BUILD b/pkg/sentry/platform/interrupt/BUILD index dbafa3204..eeccd4d0e 100644 --- a/pkg/sentry/platform/interrupt/BUILD +++ b/pkg/sentry/platform/interrupt/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "interrupt", diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD index 1b71e629f..6e40b3177 100644 --- a/pkg/sentry/platform/kvm/BUILD +++ b/pkg/sentry/platform/kvm/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/platform/kvm/testutil/BUILD b/pkg/sentry/platform/kvm/testutil/BUILD index 1dffe94a4..e10087e8e 100644 --- a/pkg/sentry/platform/kvm/testutil/BUILD +++ b/pkg/sentry/platform/kvm/testutil/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "testutil", diff --git a/pkg/sentry/platform/procid/BUILD b/pkg/sentry/platform/procid/BUILD index 20c8bc02c..277509624 100644 --- a/pkg/sentry/platform/procid/BUILD +++ b/pkg/sentry/platform/procid/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "procid", diff --git a/pkg/sentry/platform/ptrace/BUILD b/pkg/sentry/platform/ptrace/BUILD index 2eb354ad4..f86790942 100644 --- a/pkg/sentry/platform/ptrace/BUILD +++ b/pkg/sentry/platform/ptrace/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ptrace", diff --git a/pkg/sentry/platform/ring0/BUILD b/pkg/sentry/platform/ring0/BUILD index c35d49f2d..ecb3e9a9c 100644 --- a/pkg/sentry/platform/ring0/BUILD +++ b/pkg/sentry/platform/ring0/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/sentry/platform/ring0/gen_offsets/BUILD b/pkg/sentry/platform/ring0/gen_offsets/BUILD index b76d7974e..d7029d5a9 100644 --- a/pkg/sentry/platform/ring0/gen_offsets/BUILD +++ b/pkg/sentry/platform/ring0/gen_offsets/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/platform/ring0/pagetables/BUILD b/pkg/sentry/platform/ring0/pagetables/BUILD index de1b920af..fe93d3030 100644 --- a/pkg/sentry/platform/ring0/pagetables/BUILD +++ b/pkg/sentry/platform/ring0/pagetables/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/pkg/sentry/platform/safecopy/BUILD b/pkg/sentry/platform/safecopy/BUILD index cb8347dd8..05a6a61ae 100644 --- a/pkg/sentry/platform/safecopy/BUILD +++ b/pkg/sentry/platform/safecopy/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0, portions BSD, MIT +package(licenses = ["notice"]) go_library( name = "safecopy", diff --git a/pkg/sentry/safemem/BUILD b/pkg/sentry/safemem/BUILD index 87a9bff12..3ab453718 100644 --- a/pkg/sentry/safemem/BUILD +++ b/pkg/sentry/safemem/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "safemem", diff --git a/pkg/sentry/sighandling/BUILD b/pkg/sentry/sighandling/BUILD index 41313d334..cec3af92e 100644 --- a/pkg/sentry/sighandling/BUILD +++ b/pkg/sentry/sighandling/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sighandling", diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD index 3a8044b5f..076f953e7 100644 --- a/pkg/sentry/socket/BUILD +++ b/pkg/sentry/socket/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD index d3a63f15f..9f4763906 100644 --- a/pkg/sentry/socket/control/BUILD +++ b/pkg/sentry/socket/control/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/epsocket/BUILD b/pkg/sentry/socket/epsocket/BUILD index da4aaf510..45e418db3 100644 --- a/pkg/sentry/socket/epsocket/BUILD +++ b/pkg/sentry/socket/epsocket/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD index b8dceb102..a469af7ac 100644 --- a/pkg/sentry/socket/hostinet/BUILD +++ b/pkg/sentry/socket/hostinet/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD index cff922cb8..148306329 100644 --- a/pkg/sentry/socket/netlink/BUILD +++ b/pkg/sentry/socket/netlink/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD index 3a7dbc5ed..a7370a4ec 100644 --- a/pkg/sentry/socket/netlink/port/BUILD +++ b/pkg/sentry/socket/netlink/port/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD index e1bcfe252..be0419679 100644 --- a/pkg/sentry/socket/netlink/route/BUILD +++ b/pkg/sentry/socket/netlink/route/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/rpcinet/BUILD b/pkg/sentry/socket/rpcinet/BUILD index 06e121946..4da14a1e0 100644 --- a/pkg/sentry/socket/rpcinet/BUILD +++ b/pkg/sentry/socket/rpcinet/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "rpcinet", diff --git a/pkg/sentry/socket/rpcinet/conn/BUILD b/pkg/sentry/socket/rpcinet/conn/BUILD index a16977f29..4336ae9b4 100644 --- a/pkg/sentry/socket/rpcinet/conn/BUILD +++ b/pkg/sentry/socket/rpcinet/conn/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) go_library( name = "conn", diff --git a/pkg/sentry/socket/rpcinet/notifier/BUILD b/pkg/sentry/socket/rpcinet/notifier/BUILD index 2bab01774..b0b107ddb 100644 --- a/pkg/sentry/socket/rpcinet/notifier/BUILD +++ b/pkg/sentry/socket/rpcinet/notifier/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # BSD +package(licenses = ["notice"]) go_library( name = "notifier", diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD index a12fa93db..fe6871cc6 100644 --- a/pkg/sentry/socket/unix/BUILD +++ b/pkg/sentry/socket/unix/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/socket/unix/transport/BUILD b/pkg/sentry/socket/unix/transport/BUILD index 5a90837bc..5a2de0c4c 100644 --- a/pkg/sentry/socket/unix/transport/BUILD +++ b/pkg/sentry/socket/unix/transport/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD index f1f6fdb7d..42c459acc 100644 --- a/pkg/sentry/state/BUILD +++ b/pkg/sentry/state/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "state", diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD index 8517db1ac..552e79686 100644 --- a/pkg/sentry/strace/BUILD +++ b/pkg/sentry/strace/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "strace", diff --git a/pkg/sentry/syscalls/BUILD b/pkg/sentry/syscalls/BUILD index 35192ff49..6b5469e45 100644 --- a/pkg/sentry/syscalls/BUILD +++ b/pkg/sentry/syscalls/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "syscalls", diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 7621bfdbd..846601881 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/time/BUILD b/pkg/sentry/time/BUILD index 1191010e6..c4b6dcc63 100644 --- a/pkg/sentry/time/BUILD +++ b/pkg/sentry/time/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0, portions BSD +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sentry/unimpl/BUILD b/pkg/sentry/unimpl/BUILD index 42e24ace5..b608867a9 100644 --- a/pkg/sentry/unimpl/BUILD +++ b/pkg/sentry/unimpl/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) proto_library( name = "unimplemented_syscall_proto", diff --git a/pkg/sentry/uniqueid/BUILD b/pkg/sentry/uniqueid/BUILD index 0929497c3..ccc5a28d3 100644 --- a/pkg/sentry/uniqueid/BUILD +++ b/pkg/sentry/uniqueid/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "uniqueid", diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD index 868dfd400..09198496b 100644 --- a/pkg/sentry/usage/BUILD +++ b/pkg/sentry/usage/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD index dae41ed0e..1a560b6f3 100644 --- a/pkg/sentry/usermem/BUILD +++ b/pkg/sentry/usermem/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/sentry/watchdog/BUILD b/pkg/sentry/watchdog/BUILD index b2c687b20..0bbf3705c 100644 --- a/pkg/sentry/watchdog/BUILD +++ b/pkg/sentry/watchdog/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "watchdog", diff --git a/pkg/sleep/BUILD b/pkg/sleep/BUILD index 338fd9336..2b005bf66 100644 --- a/pkg/sleep/BUILD +++ b/pkg/sleep/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sleep", diff --git a/pkg/state/BUILD b/pkg/state/BUILD index dd0f250fa..0a975e162 100644 --- a/pkg/state/BUILD +++ b/pkg/state/BUILD @@ -1,7 +1,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/state/statefile/BUILD b/pkg/state/statefile/BUILD index 66c8f3807..5967781e8 100644 --- a/pkg/state/statefile/BUILD +++ b/pkg/state/statefile/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "statefile", diff --git a/pkg/sync/BUILD b/pkg/sync/BUILD index 6ddc6e812..1624e681c 100644 --- a/pkg/sync/BUILD +++ b/pkg/sync/BUILD @@ -2,7 +2,7 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0, portions BSD + licenses = ["notice"], ) load("//tools/go_generics:defs.bzl", "go_template") diff --git a/pkg/sync/atomicptrtest/BUILD b/pkg/sync/atomicptrtest/BUILD index 9cb7f66fe..198fbb895 100644 --- a/pkg/sync/atomicptrtest/BUILD +++ b/pkg/sync/atomicptrtest/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/sync/seqatomictest/BUILD b/pkg/sync/seqatomictest/BUILD index 54f8e59b1..23132650a 100644 --- a/pkg/sync/seqatomictest/BUILD +++ b/pkg/sync/seqatomictest/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") diff --git a/pkg/syserr/BUILD b/pkg/syserr/BUILD index 30ae20772..0d65115ef 100644 --- a/pkg/syserr/BUILD +++ b/pkg/syserr/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "syserr", diff --git a/pkg/syserror/BUILD b/pkg/syserror/BUILD index d4c6da97a..ac478d0ff 100644 --- a/pkg/syserror/BUILD +++ b/pkg/syserror/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "syserror", diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index daff9a0a0..83524cc8a 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/adapters/gonet/BUILD b/pkg/tcpip/adapters/gonet/BUILD index 723ad668f..ee2417238 100644 --- a/pkg/tcpip/adapters/gonet/BUILD +++ b/pkg/tcpip/adapters/gonet/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "gonet", diff --git a/pkg/tcpip/buffer/BUILD b/pkg/tcpip/buffer/BUILD index 11a725423..648d12cdf 100644 --- a/pkg/tcpip/buffer/BUILD +++ b/pkg/tcpip/buffer/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/checker/BUILD b/pkg/tcpip/checker/BUILD index a1de808b9..f597d0b24 100644 --- a/pkg/tcpip/checker/BUILD +++ b/pkg/tcpip/checker/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "checker", diff --git a/pkg/tcpip/hash/jenkins/BUILD b/pkg/tcpip/hash/jenkins/BUILD index bbb764db8..ce2194a4d 100644 --- a/pkg/tcpip/hash/jenkins/BUILD +++ b/pkg/tcpip/hash/jenkins/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "jenkins", diff --git a/pkg/tcpip/header/BUILD b/pkg/tcpip/header/BUILD index 8e455fe1e..a5c7290ee 100644 --- a/pkg/tcpip/header/BUILD +++ b/pkg/tcpip/header/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/link/channel/BUILD b/pkg/tcpip/link/channel/BUILD index 25f6c1457..ae285e495 100644 --- a/pkg/tcpip/link/channel/BUILD +++ b/pkg/tcpip/link/channel/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "channel", diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index a4aa3feec..0d78c9b15 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fdbased", diff --git a/pkg/tcpip/link/loopback/BUILD b/pkg/tcpip/link/loopback/BUILD index a46ba7f11..710a05ede 100644 --- a/pkg/tcpip/link/loopback/BUILD +++ b/pkg/tcpip/link/loopback/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "loopback", diff --git a/pkg/tcpip/link/rawfile/BUILD b/pkg/tcpip/link/rawfile/BUILD index 2746d4ced..f01bb2c07 100644 --- a/pkg/tcpip/link/rawfile/BUILD +++ b/pkg/tcpip/link/rawfile/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "rawfile", diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index d7f1e66ef..dc8f1543e 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sharedmem", diff --git a/pkg/tcpip/link/sharedmem/pipe/BUILD b/pkg/tcpip/link/sharedmem/pipe/BUILD index 12e813509..85deafa38 100644 --- a/pkg/tcpip/link/sharedmem/pipe/BUILD +++ b/pkg/tcpip/link/sharedmem/pipe/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "pipe", diff --git a/pkg/tcpip/link/sharedmem/queue/BUILD b/pkg/tcpip/link/sharedmem/queue/BUILD index 661037bb2..d7dc631eb 100644 --- a/pkg/tcpip/link/sharedmem/queue/BUILD +++ b/pkg/tcpip/link/sharedmem/queue/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "queue", diff --git a/pkg/tcpip/link/sniffer/BUILD b/pkg/tcpip/link/sniffer/BUILD index 52e237c25..7d0d1781e 100644 --- a/pkg/tcpip/link/sniffer/BUILD +++ b/pkg/tcpip/link/sniffer/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sniffer", diff --git a/pkg/tcpip/link/tun/BUILD b/pkg/tcpip/link/tun/BUILD index 5ec01cec9..e54852d3f 100644 --- a/pkg/tcpip/link/tun/BUILD +++ b/pkg/tcpip/link/tun/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "tun", diff --git a/pkg/tcpip/link/waitable/BUILD b/pkg/tcpip/link/waitable/BUILD index ba495c437..89a9eee23 100644 --- a/pkg/tcpip/link/waitable/BUILD +++ b/pkg/tcpip/link/waitable/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "waitable", diff --git a/pkg/tcpip/network/BUILD b/pkg/tcpip/network/BUILD index a2a07f533..f36f49453 100644 --- a/pkg/tcpip/network/BUILD +++ b/pkg/tcpip/network/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_test( name = "ip_test", diff --git a/pkg/tcpip/network/arp/BUILD b/pkg/tcpip/network/arp/BUILD index f6fb7daf7..ef18bb93d 100644 --- a/pkg/tcpip/network/arp/BUILD +++ b/pkg/tcpip/network/arp/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "arp", diff --git a/pkg/tcpip/network/fragmentation/BUILD b/pkg/tcpip/network/fragmentation/BUILD index aaabfcb9a..bf0a7b99c 100644 --- a/pkg/tcpip/network/fragmentation/BUILD +++ b/pkg/tcpip/network/fragmentation/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/network/hash/BUILD b/pkg/tcpip/network/hash/BUILD index 401dce646..ea520c6ed 100644 --- a/pkg/tcpip/network/hash/BUILD +++ b/pkg/tcpip/network/hash/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "hash", diff --git a/pkg/tcpip/network/ipv4/BUILD b/pkg/tcpip/network/ipv4/BUILD index e72317e9f..7a5341def 100644 --- a/pkg/tcpip/network/ipv4/BUILD +++ b/pkg/tcpip/network/ipv4/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ipv4", diff --git a/pkg/tcpip/network/ipv6/BUILD b/pkg/tcpip/network/ipv6/BUILD index 808c37df3..000e00dba 100644 --- a/pkg/tcpip/network/ipv6/BUILD +++ b/pkg/tcpip/network/ipv6/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ipv6", diff --git a/pkg/tcpip/ports/BUILD b/pkg/tcpip/ports/BUILD index a2fa9b84a..3ee80c62b 100644 --- a/pkg/tcpip/ports/BUILD +++ b/pkg/tcpip/ports/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "ports", diff --git a/pkg/tcpip/sample/tun_tcp_connect/BUILD b/pkg/tcpip/sample/tun_tcp_connect/BUILD index 32baf2115..996939581 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/BUILD +++ b/pkg/tcpip/sample/tun_tcp_connect/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "tun_tcp_connect", diff --git a/pkg/tcpip/sample/tun_tcp_echo/BUILD b/pkg/tcpip/sample/tun_tcp_echo/BUILD index 760445843..dad8ef399 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/BUILD +++ b/pkg/tcpip/sample/tun_tcp_echo/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "tun_tcp_echo", diff --git a/pkg/tcpip/seqnum/BUILD b/pkg/tcpip/seqnum/BUILD index c5c889239..a63665efc 100644 --- a/pkg/tcpip/seqnum/BUILD +++ b/pkg/tcpip/seqnum/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/tcpip/stack/BUILD b/pkg/tcpip/stack/BUILD index 8a598c57d..551c3c73e 100644 --- a/pkg/tcpip/stack/BUILD +++ b/pkg/tcpip/stack/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/transport/ping/BUILD b/pkg/tcpip/transport/ping/BUILD index 982b6795c..4d4241d4b 100644 --- a/pkg/tcpip/transport/ping/BUILD +++ b/pkg/tcpip/transport/ping/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library") diff --git a/pkg/tcpip/transport/tcp/BUILD b/pkg/tcpip/transport/tcp/BUILD index 726107739..e5c05f8c0 100644 --- a/pkg/tcpip/transport/tcp/BUILD +++ b/pkg/tcpip/transport/tcp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tcpip/transport/tcp/testing/context/BUILD b/pkg/tcpip/transport/tcp/testing/context/BUILD index 814e5c1ea..1584e4095 100644 --- a/pkg/tcpip/transport/tcp/testing/context/BUILD +++ b/pkg/tcpip/transport/tcp/testing/context/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "context", diff --git a/pkg/tcpip/transport/tcpconntrack/BUILD b/pkg/tcpip/transport/tcpconntrack/BUILD index ac1a94d4d..31a845dee 100644 --- a/pkg/tcpip/transport/tcpconntrack/BUILD +++ b/pkg/tcpip/transport/tcpconntrack/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "tcpconntrack", diff --git a/pkg/tcpip/transport/udp/BUILD b/pkg/tcpip/transport/udp/BUILD index 4225e28dc..8ccb79c48 100644 --- a/pkg/tcpip/transport/udp/BUILD +++ b/pkg/tcpip/transport/udp/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/pkg/tmutex/BUILD b/pkg/tmutex/BUILD index c20df7005..69035044d 100644 --- a/pkg/tmutex/BUILD +++ b/pkg/tmutex/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "tmutex", diff --git a/pkg/unet/BUILD b/pkg/unet/BUILD index f90e43c89..5e177e78e 100644 --- a/pkg/unet/BUILD +++ b/pkg/unet/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "unet", diff --git a/pkg/urpc/BUILD b/pkg/urpc/BUILD index 21008cf6c..36cae67e1 100644 --- a/pkg/urpc/BUILD +++ b/pkg/urpc/BUILD @@ -1,6 +1,6 @@ load("//tools/go_stateify:defs.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "urpc", diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index 5e611c54f..b748246da 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,4 +1,4 @@ -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_stateify:defs.bzl", "go_library", "go_test") diff --git a/runsc/boot/BUILD b/runsc/boot/BUILD index 15a7cdae1..540e99151 100644 --- a/runsc/boot/BUILD +++ b/runsc/boot/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "boot", diff --git a/runsc/boot/filter/BUILD b/runsc/boot/filter/BUILD index 004222242..3b6020cf3 100644 --- a/runsc/boot/filter/BUILD +++ b/runsc/boot/filter/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "filter", diff --git a/runsc/cgroup/BUILD b/runsc/cgroup/BUILD index 4f9a25a25..620d33a19 100644 --- a/runsc/cgroup/BUILD +++ b/runsc/cgroup/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "cgroup", diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD index a908172af..9e2be0d37 100644 --- a/runsc/cmd/BUILD +++ b/runsc/cmd/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "cmd", diff --git a/runsc/console/BUILD b/runsc/console/BUILD index ff4ccff69..3ff9eba27 100644 --- a/runsc/console/BUILD +++ b/runsc/console/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "console", diff --git a/runsc/container/BUILD b/runsc/container/BUILD index 354ce2661..3b25ff79a 100644 --- a/runsc/container/BUILD +++ b/runsc/container/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "container", diff --git a/runsc/fsgofer/BUILD b/runsc/fsgofer/BUILD index 756c20ad7..4adc9c1bc 100644 --- a/runsc/fsgofer/BUILD +++ b/runsc/fsgofer/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "fsgofer", diff --git a/runsc/fsgofer/filter/BUILD b/runsc/fsgofer/filter/BUILD index c7848d10c..78c5b526c 100644 --- a/runsc/fsgofer/filter/BUILD +++ b/runsc/fsgofer/filter/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "filter", diff --git a/runsc/sandbox/BUILD b/runsc/sandbox/BUILD index 899fd99de..2ed793333 100644 --- a/runsc/sandbox/BUILD +++ b/runsc/sandbox/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "sandbox", diff --git a/runsc/specutils/BUILD b/runsc/specutils/BUILD index 77a10e2b6..372799850 100644 --- a/runsc/specutils/BUILD +++ b/runsc/specutils/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "specutils", diff --git a/runsc/test/image/BUILD b/runsc/test/image/BUILD index 22b3ebd2a..e8b629c6a 100644 --- a/runsc/test/image/BUILD +++ b/runsc/test/image/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_test( name = "image_test", diff --git a/runsc/test/integration/BUILD b/runsc/test/integration/BUILD index e7204dc66..779d30ec9 100644 --- a/runsc/test/integration/BUILD +++ b/runsc/test/integration/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_test( name = "integration_test", diff --git a/runsc/test/root/BUILD b/runsc/test/root/BUILD index 77dcbd79e..75826a521 100644 --- a/runsc/test/root/BUILD +++ b/runsc/test/root/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "root", diff --git a/runsc/test/root/testdata/BUILD b/runsc/test/root/testdata/BUILD index 6c9fe0aea..7f272dcd3 100644 --- a/runsc/test/root/testdata/BUILD +++ b/runsc/test/root/testdata/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "testdata", diff --git a/runsc/test/testutil/BUILD b/runsc/test/testutil/BUILD index 8c3919320..ddec81444 100644 --- a/runsc/test/testutil/BUILD +++ b/runsc/test/testutil/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "testutil", diff --git a/runsc/tools/dockercfg/BUILD b/runsc/tools/dockercfg/BUILD index a80b3abab..fd406ab93 100644 --- a/runsc/tools/dockercfg/BUILD +++ b/runsc/tools/dockercfg/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "dockercfg", diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 8c391c8a6..148d9c366 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -1,7 +1,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") load("//test/syscalls:build_defs.bzl", "syscall_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) syscall_test(test = "//test/syscalls/linux:32bit_test") diff --git a/test/syscalls/gtest/BUILD b/test/syscalls/gtest/BUILD index d078fd3d5..22e061652 100644 --- a/test/syscalls/gtest/BUILD +++ b/test/syscalls/gtest/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "gtest", diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index e70742875..a311ca12c 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) cc_binary( diff --git a/test/util/BUILD b/test/util/BUILD index f2e563507..fac0730b4 100644 --- a/test/util/BUILD +++ b/test/util/BUILD @@ -1,6 +1,6 @@ package( default_visibility = ["//:sandbox"], - licenses = ["notice"], # Apache 2.0 + licenses = ["notice"], ) cc_library( diff --git a/tools/go_generics/BUILD b/tools/go_generics/BUILD index 2d97d99dc..39318b877 100644 --- a/tools/go_generics/BUILD +++ b/tools/go_generics/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "go_generics", diff --git a/tools/go_generics/globals/BUILD b/tools/go_generics/globals/BUILD index c26ac56d2..6628132f5 100644 --- a/tools/go_generics/globals/BUILD +++ b/tools/go_generics/globals/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_library( name = "globals", diff --git a/tools/go_generics/go_merge/BUILD b/tools/go_generics/go_merge/BUILD index a60437962..02b09120e 100644 --- a/tools/go_generics/go_merge/BUILD +++ b/tools/go_generics/go_merge/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "go_merge", diff --git a/tools/go_generics/rules_tests/BUILD b/tools/go_generics/rules_tests/BUILD index 23b2d656d..a6f8cdd3c 100644 --- a/tools/go_generics/rules_tests/BUILD +++ b/tools/go_generics/rules_tests/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_test") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance") diff --git a/tools/go_stateify/BUILD b/tools/go_stateify/BUILD index 68d37f5d7..bb53f8ae9 100644 --- a/tools/go_stateify/BUILD +++ b/tools/go_stateify/BUILD @@ -1,6 +1,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) go_binary( name = "stateify", diff --git a/vdso/BUILD b/vdso/BUILD index fd395511c..c43d24070 100644 --- a/vdso/BUILD +++ b/vdso/BUILD @@ -3,7 +3,7 @@ # normal system VDSO (time, gettimeofday, clock_gettimeofday) but which uses # timekeeping parameters managed by the sandbox kernel. -package(licenses = ["notice"]) # Apache 2.0 +package(licenses = ["notice"]) genrule( name = "vdso", -- cgit v1.2.3 From 2ba74f84be8b9d3d588fb834414d151607799fd3 Mon Sep 17 00:00:00 2001 From: Rahat Mahmood Date: Thu, 7 Feb 2019 14:43:18 -0800 Subject: Implement /proc/net/unix. PiperOrigin-RevId: 232948478 Change-Id: Ib830121e5e79afaf5d38d17aeef5a1ef97913d23 --- pkg/abi/linux/socket.go | 16 +++ pkg/sentry/fs/proc/BUILD | 3 + pkg/sentry/fs/proc/net.go | 126 +++++++++++++++++- pkg/sentry/fs/proc/proc.go | 2 +- pkg/sentry/kernel/kernel.go | 58 ++++++++- pkg/sentry/socket/socket.go | 10 +- pkg/sentry/socket/unix/unix.go | 2 + test/syscalls/BUILD | 7 + test/syscalls/linux/BUILD | 17 +++ test/syscalls/linux/proc_net_unix.cc | 246 +++++++++++++++++++++++++++++++++++ 10 files changed, 481 insertions(+), 6 deletions(-) create mode 100644 test/syscalls/linux/proc_net_unix.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 929814752..a5f78506a 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -191,6 +191,15 @@ const ( SO_TXTIME = 61 ) +// enum socket_state, from uapi/linux/net.h. +const ( + SS_FREE = 0 // Not allocated. + SS_UNCONNECTED = 1 // Unconnected to any socket. + SS_CONNECTING = 2 // In process of connecting. + SS_CONNECTED = 3 // Connected to socket. + SS_DISCONNECTING = 4 // In process of disconnecting. +) + // SockAddrMax is the maximum size of a struct sockaddr, from // uapi/linux/socket.h. const SockAddrMax = 128 @@ -343,3 +352,10 @@ const SizeOfControlMessageRight = 4 // SCM_MAX_FD is the maximum number of FDs accepted in a single sendmsg call. // From net/scm.h. const SCM_MAX_FD = 253 + +// SO_ACCEPTCON is defined as __SO_ACCEPTCON in +// include/uapi/linux/net.h, which represents a listening socket +// state. Note that this is distinct from SO_ACCEPTCONN, which is a +// socket option for querying whether a socket is in a listening +// state. +const SO_ACCEPTCON = 1 << 16 diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD index f6bc90634..666b0ab3a 100644 --- a/pkg/sentry/fs/proc/BUILD +++ b/pkg/sentry/fs/proc/BUILD @@ -30,6 +30,7 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/log", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", @@ -43,6 +44,8 @@ go_library( "//pkg/sentry/kernel/time", "//pkg/sentry/mm", "//pkg/sentry/socket/rpcinet", + "//pkg/sentry/socket/unix", + "//pkg/sentry/socket/unix/transport", "//pkg/sentry/usage", "//pkg/sentry/usermem", "//pkg/syserror", diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index 219eea7f8..55a958f9e 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -15,19 +15,24 @@ package proc import ( + "bytes" "fmt" "time" "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/proc/seqfile" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/ramfs" "gvisor.googlesource.com/gvisor/pkg/sentry/inet" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix" + "gvisor.googlesource.com/gvisor/pkg/sentry/socket/unix/transport" ) // newNet creates a new proc net entry. -func (p *proc) newNetDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { +func (p *proc) newNetDir(ctx context.Context, k *kernel.Kernel, msrc *fs.MountSource) *fs.Inode { var contents map[string]*fs.Inode if s := p.k.NetworkStack(); s != nil { contents = map[string]*fs.Inode{ @@ -52,6 +57,8 @@ func (p *proc) newNetDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode { "tcp": newStaticProcInode(ctx, msrc, []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode")), "udp": newStaticProcInode(ctx, msrc, []byte(" sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops")), + + "unix": seqfile.NewSeqFileInode(ctx, &netUnix{k: k}, msrc), } if s.SupportsIPv6() { @@ -182,3 +189,120 @@ func (n *netDev) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]se return data, 0 } + +// netUnix implements seqfile.SeqSource for /proc/net/unix. +// +// +stateify savable +type netUnix struct { + k *kernel.Kernel +} + +// NeedsUpdate implements seqfile.SeqSource.NeedsUpdate. +func (*netUnix) NeedsUpdate(generation int64) bool { + return true +} + +// ReadSeqFileData implements seqfile.SeqSource.ReadSeqFileData. +func (n *netUnix) ReadSeqFileData(ctx context.Context, h seqfile.SeqHandle) ([]seqfile.SeqData, int64) { + if h != nil { + return []seqfile.SeqData{}, 0 + } + + var buf bytes.Buffer + // Header + fmt.Fprintf(&buf, "Num RefCount Protocol Flags Type St Inode Path\n") + + // Entries + for _, sref := range n.k.ListSockets(linux.AF_UNIX) { + s := sref.Get() + if s == nil { + log.Debugf("Couldn't resolve weakref %v in socket table, racing with destruction?", sref) + continue + } + sfile := s.(*fs.File) + sops, ok := sfile.FileOperations.(*unix.SocketOperations) + if !ok { + panic(fmt.Sprintf("Found non-unix socket file in unix socket table: %+v", sfile)) + } + + addr, err := sops.Endpoint().GetLocalAddress() + if err != nil { + log.Warningf("Failed to retrieve socket name from %+v: %v", sfile, err) + addr.Addr = "" + } + + sockFlags := 0 + if ce, ok := sops.Endpoint().(transport.ConnectingEndpoint); ok { + if ce.Listening() { + // For unix domain sockets, linux reports a single flag + // value if the socket is listening, of __SO_ACCEPTCON. + sockFlags = linux.SO_ACCEPTCON + } + } + + var sockState int + switch sops.Endpoint().Type() { + case linux.SOCK_DGRAM: + sockState = linux.SS_CONNECTING + // Unlike Linux, we don't have unbound connection-less sockets, + // so no SS_DISCONNECTING. + + case linux.SOCK_SEQPACKET: + fallthrough + case linux.SOCK_STREAM: + // Connectioned. + if sops.Endpoint().(transport.ConnectingEndpoint).Connected() { + sockState = linux.SS_CONNECTED + } else { + sockState = linux.SS_UNCONNECTED + } + } + + // In the socket entry below, the value for the 'Num' field requires + // some consideration. Linux prints the address to the struct + // unix_sock representing a socket in the kernel, but may redact the + // value for unprivileged users depending on the kptr_restrict + // sysctl. + // + // One use for this field is to allow a privileged user to + // introspect into the kernel memory to determine information about + // a socket not available through procfs, such as the socket's peer. + // + // On gvisor, returning a pointer to our internal structures would + // be pointless, as it wouldn't match the memory layout for struct + // unix_sock, making introspection difficult. We could populate a + // struct unix_sock with the appropriate data, but even that + // requires consideration for which kernel version to emulate, as + // the definition of this struct changes over time. + // + // For now, we always redact this pointer. + fmt.Fprintf(&buf, "%#016p: %08X %08X %08X %04X %02X %5d", + (*unix.SocketOperations)(nil), // Num, pointer to kernel socket struct. + sfile.ReadRefs()-1, // RefCount, don't count our own ref. + 0, // Protocol, always 0 for UDS. + sockFlags, // Flags. + sops.Endpoint().Type(), // Type. + sockState, // State. + sfile.InodeID(), // Inode. + ) + + // Path + if len(addr.Addr) != 0 { + if addr.Addr[0] == 0 { + // Abstract path. + fmt.Fprintf(&buf, " @%s", string(addr.Addr[1:])) + } else { + fmt.Fprintf(&buf, " %s", string(addr.Addr)) + } + } + fmt.Fprintf(&buf, "\n") + + sfile.DecRef() + } + + data := []seqfile.SeqData{{ + Buf: buf.Bytes(), + Handle: (*netUnix)(nil), + }} + return data, 0 +} diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index be04f94af..88018e707 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -85,7 +85,7 @@ func New(ctx context.Context, msrc *fs.MountSource) (*fs.Inode, error) { if _, ok := p.k.NetworkStack().(*rpcinet.Stack); ok { p.AddChild(ctx, "net", newRPCInetProcNet(ctx, msrc)) } else { - p.AddChild(ctx, "net", p.newNetDir(ctx, msrc)) + p.AddChild(ctx, "net", p.newNetDir(ctx, k, msrc)) } return newProcInode(p, msrc, fs.SpecialDirectory, nil), nil diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 43e9823cb..e7e5ff777 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -43,6 +43,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/cpuid" "gvisor.googlesource.com/gvisor/pkg/eventchannel" "gvisor.googlesource.com/gvisor/pkg/log" + "gvisor.googlesource.com/gvisor/pkg/refs" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" @@ -164,7 +165,7 @@ type Kernel struct { // nextInotifyCookie is a monotonically increasing counter used for // generating unique inotify event cookies. // - // nextInotifyCookie is mutable, and is accesed using atomic memory + // nextInotifyCookie is mutable, and is accessed using atomic memory // operations. nextInotifyCookie uint32 @@ -177,6 +178,10 @@ type Kernel struct { // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` + + // socketTable is used to track all sockets on the system. Protected by + // extMu. + socketTable map[int]map[*refs.WeakRef]struct{} } // InitKernelArgs holds arguments to Init. @@ -266,6 +271,7 @@ func (k *Kernel) Init(args InitKernelArgs) error { k.monotonicClock = &timekeeperClock{tk: args.Timekeeper, c: sentrytime.Monotonic} k.futexes = futex.NewManager() k.netlinkPorts = port.New() + k.socketTable = make(map[int]map[*refs.WeakRef]struct{}) return nil } @@ -1051,6 +1057,56 @@ func (k *Kernel) EmitUnimplementedEvent(ctx context.Context) { }) } +// socketEntry represents a socket recorded in Kernel.socketTable. It implements +// refs.WeakRefUser for sockets stored in the socket table. +// +// +stateify savable +type socketEntry struct { + k *Kernel + sock *refs.WeakRef + family int +} + +// WeakRefGone implements refs.WeakRefUser.WeakRefGone. +func (s *socketEntry) WeakRefGone() { + s.k.extMu.Lock() + // k.socketTable is guaranteed to point to a valid socket table for s.family + // at this point, since we made sure of the fact when we created this + // socketEntry, and we never delete socket tables. + delete(s.k.socketTable[s.family], s.sock) + s.k.extMu.Unlock() +} + +// RecordSocket adds a socket to the system-wide socket table for tracking. +// +// Precondition: Caller must hold a reference to sock. +func (k *Kernel) RecordSocket(sock *fs.File, family int) { + k.extMu.Lock() + table, ok := k.socketTable[family] + if !ok { + table = make(map[*refs.WeakRef]struct{}) + k.socketTable[family] = table + } + se := socketEntry{k: k, family: family} + se.sock = refs.NewWeakRef(sock, &se) + table[se.sock] = struct{}{} + k.extMu.Unlock() +} + +// ListSockets returns a snapshot of all sockets of a given family. +func (k *Kernel) ListSockets(family int) []*refs.WeakRef { + k.extMu.Lock() + socks := []*refs.WeakRef{} + if table, ok := k.socketTable[family]; ok { + socks = make([]*refs.WeakRef, 0, len(table)) + for s, _ := range table { + socks = append(socks, s) + } + } + k.extMu.Unlock() + return socks +} + type supervisorContext struct { context.NoopSleeper log.Logger diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index e28d2c4fa..5ab423f3c 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -147,6 +147,7 @@ func New(t *kernel.Task, family int, stype transport.SockType, protocol int) (*f return nil, err } if s != nil { + t.Kernel().RecordSocket(s, family) return s, nil } } @@ -163,12 +164,15 @@ func Pair(t *kernel.Task, family int, stype transport.SockType, protocol int) (* } for _, p := range providers { - s, t, err := p.Pair(t, stype, protocol) + s1, s2, err := p.Pair(t, stype, protocol) if err != nil { return nil, nil, err } - if s != nil && t != nil { - return s, t, nil + if s1 != nil && s2 != nil { + k := t.Kernel() + k.RecordSocket(s1, family) + k.RecordSocket(s2, family) + return s1, s2, nil } } diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 19258e692..c857a0f33 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -219,6 +219,8 @@ func (s *SocketOperations) Accept(t *kernel.Task, peerRequested bool, flags int, return 0, nil, 0, syserr.FromError(e) } + t.Kernel().RecordSocket(ns, linux.AF_UNIX) + return fd, addr, addrLen, nil } diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 148d9c366..53da121ec 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -534,6 +534,13 @@ syscall_test( syscall_test(test = "//test/syscalls/linux:write_test") +syscall_test( + test = "//test/syscalls/linux:proc_net_unix_test", + # Unix domain socket creation isn't supported on all file systems. The + # sentry-internal tmpfs is known to support it. + use_tmpfs = True, +) + go_binary( name = "syscall_test_runner", srcs = ["syscall_test_runner.go"], diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index a311ca12c..590ee1659 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -3102,3 +3102,20 @@ cc_binary( "@com_google_googletest//:gtest", ], ) + +cc_binary( + name = "proc_net_unix_test", + testonly = 1, + srcs = ["proc_net_unix.cc"], + linkstatic = 1, + deps = [ + ":unix_domain_socket_test_util", + "//test/util:file_descriptor", + "//test/util:fs_util", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", + "@com_google_googletest//:gtest", + ], +) diff --git a/test/syscalls/linux/proc_net_unix.cc b/test/syscalls/linux/proc_net_unix.cc new file mode 100644 index 000000000..ea7c93012 --- /dev/null +++ b/test/syscalls/linux/proc_net_unix.cc @@ -0,0 +1,246 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_split.h" +#include "test/syscalls/linux/unix_domain_socket_test_util.h" +#include "test/util/file_descriptor.h" +#include "test/util/fs_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { +namespace { + +using absl::StrCat; +using absl::StreamFormat; +using absl::StrFormat; + +constexpr char kProcNetUnixHeader[] = + "Num RefCount Protocol Flags Type St Inode Path"; + +// UnixEntry represents a single entry from /proc/net/unix. +struct UnixEntry { + uintptr_t addr; + uint64_t refs; + uint64_t protocol; + uint64_t flags; + uint64_t type; + uint64_t state; + uint64_t inode; + std::string path; +}; + +std::string ExtractPath(const struct sockaddr* addr) { + const char* path = + reinterpret_cast(addr)->sun_path; + // Note: sockaddr_un.sun_path is an embedded character array of length + // UNIX_PATH_MAX, so we can always safely dereference the first 2 bytes below. + // + // The kernel also enforces that the path is always null terminated. + if (path[0] == 0) { + // Abstract socket paths are null padded to the end of the struct + // sockaddr. However, these null bytes may or may not show up in + // /proc/net/unix depending on the kernel version. Truncate after the first + // null byte (by treating path as a c-std::string). + return StrCat("@", &path[1]); + } + return std::string(path); +} + +// Returns a parsed representation of /proc/net/unix entries. +PosixErrorOr> ProcNetUnixEntries() { + std::string content; + RETURN_IF_ERRNO(GetContents("/proc/net/unix", &content)); + + bool skipped_header = false; + std::vector entries; + std::vector lines = absl::StrSplit(content, absl::ByAnyChar("\n")); + for (std::string line : lines) { + if (!skipped_header) { + EXPECT_EQ(line, kProcNetUnixHeader); + skipped_header = true; + continue; + } + if (line.empty()) { + continue; + } + + // Abstract socket paths can have trailing null bytes in them depending on + // the linux version. Strip off everything after a null byte, including the + // null byte. + std::size_t null_pos = line.find('\0'); + if (null_pos != std::string::npos) { + line.erase(null_pos); + } + + // Parse a single entry from /proc/net/unix. + // + // Sample file: + // + // clang-format off + // + // Num RefCount Protocol Flags Type St Inode Path" + // ffffa130e7041c00: 00000002 00000000 00010000 0001 01 1299413685 /tmp/control_server/13293772586877554487 + // ffffa14f547dc400: 00000002 00000000 00010000 0001 01 3793 @remote_coredump + // + // clang-format on + // + // Note that from the second entry, the inode number can be padded using + // spaces, so we need to handle it separately during parsing. See + // net/unix/af_unix.c:unix_seq_show() for how these entries are produced. In + // particular, only the inode field is padded with spaces. + UnixEntry entry; + + // Process the first 6 fields, up to but not including "Inode". + std::vector fields = absl::StrSplit(line, absl::MaxSplits(' ', 6)); + + if (fields.size() < 7) { + return PosixError(EINVAL, StrFormat("Invalid entry: '%s'\n", line)); + } + + // AtoiBase can't handle the ':' in the "Num" field, so strip it out. + std::vector addr = absl::StrSplit(fields[0], ':'); + ASSIGN_OR_RETURN_ERRNO(entry.addr, AtoiBase(addr[0], 16)); + + ASSIGN_OR_RETURN_ERRNO(entry.refs, AtoiBase(fields[1], 16)); + ASSIGN_OR_RETURN_ERRNO(entry.protocol, AtoiBase(fields[2], 16)); + ASSIGN_OR_RETURN_ERRNO(entry.flags, AtoiBase(fields[3], 16)); + ASSIGN_OR_RETURN_ERRNO(entry.type, AtoiBase(fields[4], 16)); + ASSIGN_OR_RETURN_ERRNO(entry.state, AtoiBase(fields[5], 16)); + + absl::string_view rest = absl::StripAsciiWhitespace(fields[6]); + fields = absl::StrSplit(rest, absl::MaxSplits(' ', 1)); + if (fields.empty()) { + return PosixError( + EINVAL, StrFormat("Invalid entry, missing 'Inode': '%s'\n", line)); + } + ASSIGN_OR_RETURN_ERRNO(entry.inode, AtoiBase(fields[0], 10)); + + entry.path = ""; + if (fields.size() > 1) { + entry.path = fields[1]; + } + + entries.push_back(entry); + } + + return entries; +} + +// Finds the first entry in 'entries' for which 'predicate' returns true. +// Returns true on match, and sets 'match' to point to the matching entry. +bool FindBy(std::vector entries, UnixEntry* match, + std::function predicate) { + for (int i = 0; i < entries.size(); ++i) { + if (predicate(entries[i])) { + *match = entries[i]; + return true; + } + } + return false; +} + +bool FindByPath(std::vector entries, UnixEntry* match, + const std::string& path) { + return FindBy(entries, match, [path](UnixEntry e) { return e.path == path; }); +} + +TEST(ProcNetUnix, Exists) { + const std::string content = + ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/net/unix")); + const std::string header_line = StrCat(kProcNetUnixHeader, "\n"); + if (IsRunningOnGvisor()) { + // Should be just the header since we don't have any unix domain sockets + // yet. + EXPECT_EQ(content, header_line); + } else { + // However, on a general linux machine, we could have abitrary sockets on + // the system, so just check the header. + EXPECT_THAT(content, ::testing::StartsWith(header_line)); + } +} + +TEST(ProcNetUnix, FilesystemBindAcceptConnect) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE( + FilesystemBoundUnixDomainSocketPair(SOCK_STREAM).Create()); + + std::string path1 = ExtractPath(sockets->first_addr()); + std::string path2 = ExtractPath(sockets->second_addr()); + std::cout << StreamFormat("Server socket address: %s\n", path1); + std::cout << StreamFormat("Client socket address: %s\n", path2); + + std::vector entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + if (IsRunningOnGvisor()) { + EXPECT_EQ(entries.size(), 2); + } + + // The server-side socket's path is listed in the socket entry... + UnixEntry s1; + EXPECT_TRUE(FindByPath(entries, &s1, path1)); + + // ... but the client-side socket's path is not. + UnixEntry s2; + EXPECT_FALSE(FindByPath(entries, &s2, path2)); +} + +TEST(ProcNetUnix, AbstractBindAcceptConnect) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE( + AbstractBoundUnixDomainSocketPair(SOCK_STREAM).Create()); + + std::string path1 = ExtractPath(sockets->first_addr()); + std::string path2 = ExtractPath(sockets->second_addr()); + std::cout << StreamFormat("Server socket address: '%s'\n", path1); + std::cout << StreamFormat("Client socket address: '%s'\n", path2); + + std::vector entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + if (IsRunningOnGvisor()) { + EXPECT_EQ(entries.size(), 2); + } + + // The server-side socket's path is listed in the socket entry... + UnixEntry s1; + EXPECT_TRUE(FindByPath(entries, &s1, path1)); + + // ... but the client-side socket's path is not. + UnixEntry s2; + EXPECT_FALSE(FindByPath(entries, &s2, path2)); +} + +TEST(ProcNetUnix, SocketPair) { + // Under gvisor, ensure a socketpair() syscall creates exactly 2 new + // entries. We have no way to verify this under Linux, as we have no control + // over socket creation on a general Linux machine. + SKIP_IF(!IsRunningOnGvisor()); + + std::vector entries = + ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + ASSERT_EQ(entries.size(), 0); + + auto sockets = + ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_STREAM).Create()); + + entries = ASSERT_NO_ERRNO_AND_VALUE(ProcNetUnixEntries()); + EXPECT_EQ(entries.size(), 2); +} + +} // namespace +} // namespace testing +} // namespace gvisor -- cgit v1.2.3 From 80f901b16b8bb8fe397cc44578035173f5155b24 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 7 Feb 2019 23:14:06 -0800 Subject: Plumb IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP to netstack. Also includes a few fixes for IPv4 multicast support. IPv6 support is coming in a followup CL. PiperOrigin-RevId: 233008638 Change-Id: If7dae6222fef43fda48033f0292af77832d95e82 --- pkg/abi/linux/socket.go | 21 +- pkg/sentry/socket/epsocket/epsocket.go | 46 ++- pkg/tcpip/stack/stack.go | 7 + pkg/tcpip/transport/udp/endpoint.go | 16 +- pkg/tcpip/transport/udp/endpoint_state.go | 6 + test/syscalls/BUILD | 2 + test/syscalls/linux/BUILD | 34 ++ test/syscalls/linux/ip_socket_test_util.cc | 33 +- test/syscalls/linux/ip_socket_test_util.h | 7 + test/syscalls/linux/socket_ip_udp_generic.cc | 14 + test/syscalls/linux/socket_ipv4_udp_unbound.cc | 424 +++++++++++++++++++++ test/syscalls/linux/socket_ipv4_udp_unbound.h | 29 ++ .../linux/socket_ipv4_udp_unbound_loopback.cc | 35 ++ test/syscalls/linux/socket_test_util.cc | 38 +- test/syscalls/linux/socket_test_util.h | 5 + 15 files changed, 694 insertions(+), 23 deletions(-) create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound.cc create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound.h create mode 100644 test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index a5f78506a..906776525 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -204,15 +204,30 @@ const ( // uapi/linux/socket.h. const SockAddrMax = 128 -// SockAddrInt is struct sockaddr_in, from uapi/linux/in.h. +// InetAddr is struct in_addr, from uapi/linux/in.h. +type InetAddr [4]byte + +// SockAddrInet is struct sockaddr_in, from uapi/linux/in.h. type SockAddrInet struct { Family uint16 Port uint16 - Addr [4]byte + Addr InetAddr Zero [8]uint8 // pad to sizeof(struct sockaddr). } -// SockAddrInt6 is struct sockaddr_in6, from uapi/linux/in6.h. +// InetMulticastRequest is struct ip_mreq, from uapi/linux/in.h. +type InetMulticastRequest struct { + MulticastAddr InetAddr + InterfaceAddr InetAddr +} + +// InetMulticastRequestWithNIC is struct ip_mreqn, from uapi/linux/in.h. +type InetMulticastRequestWithNIC struct { + InetMulticastRequest + InterfaceIndex int32 +} + +// SockAddrInet6 is struct sockaddr_in6, from uapi/linux/in6.h. type SockAddrInet6 struct { Family uint16 Port uint16 diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index ca865b111..16720456a 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -1078,6 +1078,25 @@ func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) return syserr.TranslateNetstackError(ep.SetSockOpt(struct{}{})) } +var ( + inetMulticastRequestSize = int(binary.Size(linux.InetMulticastRequest{})) + inetMulticastRequestWithNICSize = int(binary.Size(linux.InetMulticastRequestWithNIC{})) +) + +func copyInMulticastRequest(optVal []byte) (linux.InetMulticastRequestWithNIC, *syserr.Error) { + if len(optVal) < inetMulticastRequestSize { + return linux.InetMulticastRequestWithNIC{}, syserr.ErrInvalidArgument + } + + var req linux.InetMulticastRequestWithNIC + if len(optVal) >= inetMulticastRequestWithNICSize { + binary.Unmarshal(optVal[:inetMulticastRequestWithNICSize], usermem.ByteOrder, &req) + } else { + binary.Unmarshal(optVal[:inetMulticastRequestSize], usermem.ByteOrder, &req.InetMulticastRequest) + } + return req, nil +} + // setSockOptIP implements SetSockOpt when level is SOL_IP. func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error { switch name { @@ -1096,7 +1115,31 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s } return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.MulticastTTLOption(v))) - case linux.IP_ADD_MEMBERSHIP, linux.MCAST_JOIN_GROUP, linux.IP_MULTICAST_IF: + case linux.IP_ADD_MEMBERSHIP: + req, err := copyInMulticastRequest(optVal) + if err != nil { + return err + } + + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.AddMembershipOption{ + NIC: tcpip.NICID(req.InterfaceIndex), + InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), + MulticastAddr: tcpip.Address(req.MulticastAddr[:]), + })) + + case linux.IP_DROP_MEMBERSHIP: + req, err := copyInMulticastRequest(optVal) + if err != nil { + return err + } + + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.RemoveMembershipOption{ + NIC: tcpip.NICID(req.InterfaceIndex), + InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]), + MulticastAddr: tcpip.Address(req.MulticastAddr[:]), + })) + + case linux.MCAST_JOIN_GROUP, linux.IP_MULTICAST_IF: // FIXME: Disallow IP-level multicast group options by // default. These will need to be supported by appropriately plumbing // the level through to the network stack (if at all). However, we @@ -1108,7 +1151,6 @@ func setSockOptIP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *s linux.IP_BIND_ADDRESS_NO_PORT, linux.IP_BLOCK_SOURCE, linux.IP_CHECKSUM, - linux.IP_DROP_MEMBERSHIP, linux.IP_DROP_SOURCE_MEMBERSHIP, linux.IP_FREEBIND, linux.IP_HDRINCL, diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 7aa9dbd46..854ebe1bb 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -742,6 +742,9 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n return Route{}, tcpip.ErrNoRoute } + // TODO: Route multicast packets with no specified local + // address or NIC. + for i := range s.routeTable { if (id != 0 && id != s.routeTable[i].NIC) || (len(remoteAddr) != 0 && !s.routeTable[i].Match(remoteAddr)) { continue @@ -768,6 +771,10 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n return r, nil } + if isMulticast { + return Route{}, tcpip.ErrNetworkUnreachable + } + return Route{}, tcpip.ErrNoRoute } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index b2a27a7cb..d46bf0ade 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -99,6 +99,7 @@ type endpoint struct { effectiveNetProtos []tcpip.NetworkProtocolNumber } +// +stateify savable type multicastMembership struct { nicID tcpip.NICID multicastAddr tcpip.Address @@ -412,6 +413,8 @@ func (e *endpoint) SetSockOpt(opt interface{}) *tcpip.Error { nicID = e.stack.CheckLocalAddress(nicID, e.netProto, v.InterfaceAddr) } if nicID == 0 { + // TODO: Allow adding memberships without + // specifing an interface. return tcpip.ErrNoRoute } @@ -766,9 +769,11 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error } } + nicid := addr.NIC if len(addr.Addr) != 0 { // A local address was specified, verify that it's valid. - if e.stack.CheckLocalAddress(addr.NIC, netProto, addr.Addr) == 0 { + nicid = e.stack.CheckLocalAddress(addr.NIC, netProto, addr.Addr) + if nicid == 0 { return tcpip.ErrBadLocalAddress } } @@ -777,21 +782,21 @@ func (e *endpoint) bindLocked(addr tcpip.FullAddress, commit func() *tcpip.Error LocalPort: addr.Port, LocalAddress: addr.Addr, } - id, err = e.registerWithStack(addr.NIC, netProtos, id) + id, err = e.registerWithStack(nicid, netProtos, id) if err != nil { return err } if commit != nil { if err := commit(); err != nil { // Unregister, the commit failed. - e.stack.UnregisterTransportEndpoint(addr.NIC, netProtos, ProtocolNumber, id, e) + e.stack.UnregisterTransportEndpoint(nicid, netProtos, ProtocolNumber, id, e) e.stack.ReleasePort(netProtos, ProtocolNumber, id.LocalAddress, id.LocalPort) return err } } e.id = id - e.regNICID = addr.NIC + e.regNICID = nicid e.effectiveNetProtos = netProtos // Mark endpoint as bound. @@ -815,7 +820,8 @@ func (e *endpoint) Bind(addr tcpip.FullAddress, commit func() *tcpip.Error) *tcp return err } - e.bindNICID = addr.NIC + // Save the effective NICID generated by bindLocked. + e.bindNICID = e.regNICID return nil } diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index db1e281ad..4d8210294 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -103,4 +103,10 @@ func (e *endpoint) afterLoad() { if err != nil { panic(*err) } + + for _, m := range e.multicastMemberships { + if err := e.stack.JoinGroup(e.netProto, m.nicID, m.multicastAddr); err != nil { + panic(err) + } + } } diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 53da121ec..a5abf8013 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -361,6 +361,8 @@ syscall_test( test = "//test/syscalls/linux:socket_ip_udp_loopback_test", ) +syscall_test(test = "//test/syscalls/linux:socket_ipv4_udp_unbound_loopback_test") + syscall_test(test = "//test/syscalls/linux:socket_netdevice_test") syscall_test(test = "//test/syscalls/linux:socket_netlink_route_test") diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 590ee1659..75fa52a57 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1931,6 +1931,24 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "socket_ipv4_udp_unbound_test_cases", + testonly = 1, + srcs = [ + "socket_ipv4_udp_unbound.cc", + ], + hdrs = [ + "socket_ipv4_udp_unbound.h", + ], + deps = [ + ":ip_socket_test_util", + ":socket_test_util", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + cc_binary( name = "socket_abstract_test", testonly = 1, @@ -2124,6 +2142,22 @@ cc_binary( ], ) +cc_binary( + name = "socket_ipv4_udp_unbound_loopback_test", + testonly = 1, + srcs = [ + "socket_ipv4_udp_unbound_loopback.cc", + ], + linkstatic = 1, + deps = [ + ":ip_socket_test_util", + ":socket_ipv4_udp_unbound_test_cases", + ":socket_test_util", + "//test/util:test_main", + "//test/util:test_util", + ], +) + cc_binary( name = "socket_domain_test", testonly = 1, diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc index 1659d3d83..f8232fc24 100644 --- a/test/syscalls/linux/ip_socket_test_util.cc +++ b/test/syscalls/linux/ip_socket_test_util.cc @@ -12,11 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include + #include "test/syscalls/linux/ip_socket_test_util.h" namespace gvisor { namespace testing { +PosixErrorOr InterfaceIndex(std::string name) { + // TODO: Consider using netlink. + ifreq req = {}; + memcpy(req.ifr_name, name.c_str(), name.size()); + ASSIGN_OR_RETURN_ERRNO(auto sock, Socket(AF_INET, SOCK_DGRAM, 0)); + RETURN_ERROR_IF_SYSCALL_FAIL(ioctl(sock.get(), SIOCGIFINDEX, &req)); + return req.ifr_ifindex; +} + namespace { std::string DescribeSocketType(int type) { @@ -28,7 +41,7 @@ std::string DescribeSocketType(int type) { SocketPairKind IPv6TCPAcceptBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv6 TCP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv6 TCP socket"); return SocketPairKind{ description, TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM, 0, /* dual_stack = */ false)}; @@ -36,7 +49,7 @@ SocketPairKind IPv6TCPAcceptBindSocketPair(int type) { SocketPairKind IPv4TCPAcceptBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv4 TCP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv4 TCP socket"); return SocketPairKind{ description, TCPAcceptBindSocketPairCreator(AF_INET, type | SOCK_STREAM, 0, /* dual_stack = */ false)}; @@ -44,7 +57,7 @@ SocketPairKind IPv4TCPAcceptBindSocketPair(int type) { SocketPairKind DualStackTCPAcceptBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "dual stack TCP socket"); + absl::StrCat(DescribeSocketType(type), "connected dual stack TCP socket"); return SocketPairKind{ description, TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM, 0, /* dual_stack = */ true)}; @@ -52,7 +65,7 @@ SocketPairKind DualStackTCPAcceptBindSocketPair(int type) { SocketPairKind IPv6UDPBidirectionalBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv6 UDP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv6 UDP socket"); return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator( AF_INET6, type | SOCK_DGRAM, 0, /* dual_stack = */ false)}; @@ -60,7 +73,7 @@ SocketPairKind IPv6UDPBidirectionalBindSocketPair(int type) { SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket"); + absl::StrCat(DescribeSocketType(type), "connected IPv4 UDP socket"); return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator( AF_INET, type | SOCK_DGRAM, 0, /* dual_stack = */ false)}; @@ -68,11 +81,19 @@ SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type) { SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type) { std::string description = - absl::StrCat(DescribeSocketType(type), "dual stack UDP socket"); + absl::StrCat(DescribeSocketType(type), "connected dual stack UDP socket"); return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator( AF_INET6, type | SOCK_DGRAM, 0, /* dual_stack = */ true)}; } +SocketPairKind IPv4UDPUnboundSocketPair(int type) { + std::string description = + absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket"); + return SocketPairKind{ + description, UDPUnboundSocketPairCreator(AF_INET, type | SOCK_DGRAM, 0, + /* dual_stack = */ false)}; +} + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/ip_socket_test_util.h b/test/syscalls/linux/ip_socket_test_util.h index 1e1400ecd..a6721091a 100644 --- a/test/syscalls/linux/ip_socket_test_util.h +++ b/test/syscalls/linux/ip_socket_test_util.h @@ -21,6 +21,9 @@ namespace gvisor { namespace testing { +// InterfaceIndex returns the index of the named interface. +PosixErrorOr InterfaceIndex(std::string name); + // IPv6TCPAcceptBindSocketPair returns a SocketPairKind that represents // SocketPairs created with bind() and accept() syscalls with AF_INET6 and the // given type bound to the IPv6 loopback. @@ -51,6 +54,10 @@ SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type); // AF_INET6 and the given type bound to the IPv4 loopback. SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type); +// IPv4UDPUnboundSocketPair returns a SocketPairKind that represents +// SocketPairs created with AF_INET and the given type. +SocketPairKind IPv4UDPUnboundSocketPair(int type); + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ip_udp_generic.cc b/test/syscalls/linux/socket_ip_udp_generic.cc index 789154fb3..58d1c846d 100644 --- a/test/syscalls/linux/socket_ip_udp_generic.cc +++ b/test/syscalls/linux/socket_ip_udp_generic.cc @@ -117,5 +117,19 @@ TEST_P(UDPSocketPairTest, SetUDPMulticastTTLAboveMax) { SyscallFailsWithErrno(EINVAL)); } +TEST_P(UDPSocketPairTest, SetEmptyIPAddMembership) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + struct ip_mreqn req = {}; + int ret = setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, + sizeof(req)); + // FIXME: gVisor returns the incorrect errno. + if (IsRunningOnGvisor()) { + EXPECT_THAT(ret, SyscallFails()); + } else { + EXPECT_THAT(ret, SyscallFailsWithErrno(EINVAL)); + } +} + } // namespace testing } // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc new file mode 100644 index 000000000..1b47139e4 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -0,0 +1,424 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include "test/syscalls/linux/socket_ipv4_udp_unbound.h" + +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +// Check that packets are not received without a group memebership. Default send +// interface configured by bind. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNoGroup) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address. If multicast worked like unicast, + // this would ensure that we get the packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Send the multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that not setting a default send interface prevents multicast packets +// from being sent. Group membership interface configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddrNoDefaultSendIf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the second FD to the v4 any address to ensure that we can receive any + // unicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallFailsWithErrno(ENETUNREACH)); +} + +// Check that not setting a default send interface prevents multicast packets +// from being sent. Group membership interface configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNicNoDefaultSendIf) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the second FD to the v4 any address to ensure that we can receive any + // unicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallFailsWithErrno(ENETUNREACH)); +} + +// Check that multicast works when the default send interface is configured by +// bind and the group membership is configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackAddr) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that multicast works when the default send interface is confgured by +// bind and the group membership is configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastLoopbackNic) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we received the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + ASSERT_THAT( + RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), 0), + SyscallSucceedsWithValue(sizeof(recv_buf))); + + EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); +} + +// Check that dropping a group membership that does not exist fails. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastInvalidDrop) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Unregister from a membership that we didn't have. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallFailsWithErrno(EADDRNOTAVAIL)); +} + +// Check that dropping a group membership prevents multicast packets from being +// delivered. Default send address configured by bind and group membership +// interface configured by address. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastDropAddr) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register and unregister to receive multicast packets. + ip_mreq group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_interface.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +// Check that dropping a group membership prevents multicast packets from being +// delivered. Default send address configured by bind and group membership +// interface configured by NIC ID. +TEST_P(IPv4UDPUnboundSocketPairTest, IpMulticastDropNic) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Bind the first FD to the loopback. This is an alternative to + // IP_MULTICAST_IF for setting the default send interface. + sockaddr_in senderAddr = {}; + senderAddr.sin_family = AF_INET; + senderAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + EXPECT_THAT( + bind(sockets->first_fd(), reinterpret_cast(&senderAddr), + sizeof(senderAddr)), + SyscallSucceeds()); + + // Bind the second FD to the v4 any address to ensure that we can receive the + // multicast packet. + sockaddr_in receiverAddr = {}; + receiverAddr.sin_family = AF_INET; + receiverAddr.sin_addr.s_addr = htonl(INADDR_ANY); + EXPECT_THAT( + bind(sockets->second_fd(), reinterpret_cast(&receiverAddr), + sizeof(receiverAddr)), + SyscallSucceeds()); + socklen_t receiverAddrLen = sizeof(receiverAddr); + EXPECT_THAT( + getsockname(sockets->second_fd(), + reinterpret_cast(&receiverAddr), &receiverAddrLen), + SyscallSucceeds()); + EXPECT_EQ(receiverAddrLen, sizeof(receiverAddr)); + + // Register and unregister to receive multicast packets. + ip_mreqn group = {}; + group.imr_multiaddr.s_addr = inet_addr("224.0.2.1"); + group.imr_ifindex = ASSERT_NO_ERRNO_AND_VALUE(InterfaceIndex("lo")); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + EXPECT_THAT(setsockopt(sockets->second_fd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, + &group, sizeof(group)), + SyscallSucceeds()); + + // Send a multicast packet. + sockaddr_in sendAddr = {}; + sendAddr.sin_family = AF_INET; + sendAddr.sin_port = receiverAddr.sin_port; + sendAddr.sin_addr.s_addr = inet_addr("224.0.2.1"); + char send_buf[200]; + RandomizeBuffer(send_buf, sizeof(send_buf)); + EXPECT_THAT(RetryEINTR(sendto)( + sockets->first_fd(), send_buf, sizeof(send_buf), 0, + reinterpret_cast(&sendAddr), sizeof(sendAddr)), + SyscallSucceedsWithValue(sizeof(send_buf))); + + // Check that we did not receive the multicast packet. + char recv_buf[sizeof(send_buf)] = {}; + EXPECT_THAT(RetryEINTR(recv)(sockets->second_fd(), recv_buf, sizeof(recv_buf), + MSG_DONTWAIT), + SyscallFailsWithErrno(EAGAIN)); +} + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.h b/test/syscalls/linux/socket_ipv4_udp_unbound.h new file mode 100644 index 000000000..a780c0144 --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.h @@ -0,0 +1,29 @@ +// Copyright 2019 Google LLC +// +// 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. + +#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_H_ +#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_H_ + +#include "test/syscalls/linux/socket_test_util.h" + +namespace gvisor { +namespace testing { + +// Test fixture for tests that apply to pairs of IPv4 UDP sockets. +using IPv4UDPUnboundSocketPairTest = SocketPairTest; + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_H_ diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc new file mode 100644 index 000000000..b70faa33d --- /dev/null +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc @@ -0,0 +1,35 @@ +// Copyright 2018 Google LLC +// +// 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. + +#include + +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_ipv4_udp_unbound.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +std::vector GetSocketPairs() { + return ApplyVec( + IPv4UDPUnboundSocketPair, + AllBitwiseCombinations(List{0, SOCK_NONBLOCK})); +} + +INSTANTIATE_TEST_CASE_P(IPv4UDPSockets, IPv4UDPUnboundSocketPairTest, + ::testing::ValuesIn(GetSocketPairs())); + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index 80a59df7e..49b8c583f 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -388,24 +388,33 @@ Creator TCPAcceptBindSocketPairCreator(int domain, int type, }; } +template +PosixErrorOr> CreateUDPBoundSocketPair( + int sock1, int sock2, int type, bool dual_stack) { + ASSIGN_OR_RETURN_ERRNO(T addr1, BindIP(sock1, dual_stack)); + ASSIGN_OR_RETURN_ERRNO(T addr2, BindIP(sock2, dual_stack)); + + return absl::make_unique(sock1, sock2, addr1, addr2); +} + template PosixErrorOr> CreateUDPBidirectionalBindSocketPair(int sock1, int sock2, int type, bool dual_stack) { - ASSIGN_OR_RETURN_ERRNO(T addr1, BindIP(sock1, dual_stack)); - ASSIGN_OR_RETURN_ERRNO(T addr2, BindIP(sock2, dual_stack)); + ASSIGN_OR_RETURN_ERRNO( + auto socks, CreateUDPBoundSocketPair(sock1, sock2, type, dual_stack)); // Connect sock1 to sock2. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock1, reinterpret_cast(&addr2), sizeof(addr2))); + RETURN_ERROR_IF_SYSCALL_FAIL(connect(socks->first_fd(), socks->second_addr(), + socks->second_addr_size())); MaybeSave(); // Successful connection. // Connect sock2 to sock1. - RETURN_ERROR_IF_SYSCALL_FAIL(connect( - sock2, reinterpret_cast(&addr1), sizeof(addr1))); + RETURN_ERROR_IF_SYSCALL_FAIL(connect(socks->second_fd(), socks->first_addr(), + socks->first_addr_size())); MaybeSave(); // Successful connection. - return absl::make_unique(sock1, sock2, addr1, addr2); + return socks; } Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, @@ -429,6 +438,21 @@ Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, }; } +Creator UDPUnboundSocketPairCreator(int domain, int type, + int protocol, bool dual_stack) { + return [=]() -> PosixErrorOr> { + int sock1; + RETURN_ERROR_IF_SYSCALL_FAIL(sock1 = socket(domain, type, protocol)); + MaybeSave(); // Successful socket creation. + + int sock2; + RETURN_ERROR_IF_SYSCALL_FAIL(sock2 = socket(domain, type, protocol)); + MaybeSave(); // Successful socket creation. + + return absl::make_unique(sock1, sock2); + }; +} + SocketPairKind Reversed(SocketPairKind const& base) { auto const& creator = base.creator; return SocketPairKind{ diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h index 6d84b3fa8..826374dc6 100644 --- a/test/syscalls/linux/socket_test_util.h +++ b/test/syscalls/linux/socket_test_util.h @@ -273,6 +273,11 @@ Creator UDPBidirectionalBindSocketPairCreator(int domain, int type, int protocol, bool dual_stack); +// UDPUnboundSocketPairCreator returns a Creator that obtains file +// descriptors by creating UDP sockets. +Creator UDPUnboundSocketPairCreator(int domain, int type, + int protocol, bool dual_stack); + // A SocketPairKind couples a human-readable description of a socket pair with // a function that creates such a socket pair. struct SocketPairKind { -- cgit v1.2.3 From e884168e1ea5cd8be4d50c85a4ad4fbcdaca1e5c Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Fri, 8 Feb 2019 15:47:25 -0800 Subject: Encode stat to bytes manually, instead of calling CopyObjectOut. CopyObjectOut grows its destination byte slice incrementally, causing many small slice allocations on the heap. This leads to increased GC and noticeably slower stat calls. PiperOrigin-RevId: 233140904 Change-Id: Ieb90295dd8dd45b3e56506fef9d7f86c92e97d97 --- pkg/abi/linux/file.go | 4 +++ pkg/sentry/syscalls/linux/sys_stat.go | 61 ++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 15 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index ae33f4a4d..e5a51a9fd 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -19,6 +19,7 @@ import ( "strings" "gvisor.googlesource.com/gvisor/pkg/abi" + "gvisor.googlesource.com/gvisor/pkg/binary" ) // Constants for open(2). @@ -177,6 +178,9 @@ type Stat struct { X_unused [3]int64 } +// SizeOfStat is the size of a Stat struct. +var SizeOfStat = binary.Size(Stat{}) + // FileMode represents a mode_t. type FileMode uint diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go index 9c433c45d..95f161aac 100644 --- a/pkg/sentry/syscalls/linux/sys_stat.go +++ b/pkg/sentry/syscalls/linux/sys_stat.go @@ -16,6 +16,7 @@ package linux import ( "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/binary" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" @@ -124,21 +125,51 @@ func stat(t *kernel.Task, d *fs.Dirent, dirPath bool, statAddr usermem.Addr) err mode |= linux.ModeSocket } - _, err = t.CopyOut(statAddr, linux.Stat{ - Dev: uint64(d.Inode.StableAttr.DeviceID), - Rdev: uint64(linux.MakeDeviceID(d.Inode.StableAttr.DeviceFileMajor, d.Inode.StableAttr.DeviceFileMinor)), - Ino: uint64(d.Inode.StableAttr.InodeID), - Nlink: uattr.Links, - Mode: mode | uint32(uattr.Perms.LinuxMode()), - UID: uint32(uattr.Owner.UID.In(t.UserNamespace()).OrOverflow()), - GID: uint32(uattr.Owner.GID.In(t.UserNamespace()).OrOverflow()), - Size: uattr.Size, - Blksize: d.Inode.StableAttr.BlockSize, - Blocks: uattr.Usage / 512, - ATime: uattr.AccessTime.Timespec(), - MTime: uattr.ModificationTime.Timespec(), - CTime: uattr.StatusChangeTime.Timespec(), - }) + // We encode the stat struct to bytes manually, as stat() is a very + // common syscall for many applications, and t.CopyObjectOut has + // noticeable performance impact due to its many slice allocations and + // use of reflection. + b := make([]byte, 0, linux.SizeOfStat) + + // Dev (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(d.Inode.StableAttr.DeviceID)) + // Ino (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(d.Inode.StableAttr.InodeID)) + // Nlink (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uattr.Links) + // Mode (uint32) + b = binary.AppendUint32(b, usermem.ByteOrder, mode|uint32(uattr.Perms.LinuxMode())) + // UID (uint32) + b = binary.AppendUint32(b, usermem.ByteOrder, uint32(uattr.Owner.UID.In(t.UserNamespace()).OrOverflow())) + // GID (uint32) + b = binary.AppendUint32(b, usermem.ByteOrder, uint32(uattr.Owner.GID.In(t.UserNamespace()).OrOverflow())) + // Padding (uint32) + b = binary.AppendUint32(b, usermem.ByteOrder, 0) + // Rdev (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(linux.MakeDeviceID(d.Inode.StableAttr.DeviceFileMajor, d.Inode.StableAttr.DeviceFileMinor))) + // Size (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(uattr.Size)) + // Blksize (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(d.Inode.StableAttr.BlockSize)) + // Blocks (uint64) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(uattr.Usage/512)) + + // ATime + atime := uattr.AccessTime.Timespec() + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(atime.Sec)) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(atime.Nsec)) + + // MTime + mtime := uattr.ModificationTime.Timespec() + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(mtime.Sec)) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(mtime.Nsec)) + + // CTime + ctime := uattr.StatusChangeTime.Timespec() + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(ctime.Sec)) + b = binary.AppendUint64(b, usermem.ByteOrder, uint64(ctime.Nsec)) + + _, err = t.CopyOutBytes(statAddr, b) return err } -- cgit v1.2.3 From 3dbd4a16f8ae4da967f69fd93870462d1b3554f5 Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Fri, 1 Mar 2019 10:55:22 -0800 Subject: Add semctl(GETPID) syscall Also added unimplemented notification for semctl(2) commands. PiperOrigin-RevId: 236340672 Change-Id: I0795e3bd2e6d41d7936fabb731884df426a42478 --- pkg/abi/linux/sem.go | 5 ++-- pkg/sentry/kernel/semaphore/semaphore.go | 34 +++++++++++++++++---- pkg/sentry/kernel/semaphore/semaphore_test.go | 6 ++-- pkg/sentry/syscalls/linux/sys_sem.go | 43 +++++++++++++++++++++++++-- runsc/boot/compat.go | 4 +++ test/syscalls/linux/semaphore.cc | 29 ++++++++++++++++++ 6 files changed, 107 insertions(+), 14 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go index d1a0bdb32..b80c93daf 100644 --- a/pkg/abi/linux/sem.go +++ b/pkg/abi/linux/sem.go @@ -27,8 +27,9 @@ const ( // ipcs ctl cmds. Source: include/uapi/linux/sem.h const ( - SEM_STAT = 18 - SEM_INFO = 19 + SEM_STAT = 18 + SEM_INFO = 19 + SEM_STAT_ANY = 20 ) const SEM_UNDO = 0x1000 diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index c134931cd..29a2eb804 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -92,6 +92,7 @@ type Set struct { type sem struct { value int16 waiters waiterList `state:"zerovalue"` + pid int32 } // waiter represents a caller that is waiting for the semaphore value to @@ -283,7 +284,7 @@ func (s *Set) Change(ctx context.Context, creds *auth.Credentials, owner fs.File } // SetVal overrides a semaphore value, waking up waiters as needed. -func (s *Set) SetVal(ctx context.Context, num int32, val int16, creds *auth.Credentials) error { +func (s *Set) SetVal(ctx context.Context, num int32, val int16, creds *auth.Credentials, pid int32) error { if val < 0 || val > valueMax { return syserror.ERANGE } @@ -303,15 +304,17 @@ func (s *Set) SetVal(ctx context.Context, num int32, val int16, creds *auth.Cred // TODO: Clear undo entries in all processes sem.value = val + sem.pid = pid s.changeTime = ktime.NowFromContext(ctx) sem.wakeWaiters() return nil } -// SetValAll overrides all semaphores values, waking up waiters as needed. +// SetValAll overrides all semaphores values, waking up waiters as needed. It also +// sets semaphore's PID which was fixed in Linux 4.6. // // 'len(vals)' must be equal to 's.Size()'. -func (s *Set) SetValAll(ctx context.Context, vals []uint16, creds *auth.Credentials) error { +func (s *Set) SetValAll(ctx context.Context, vals []uint16, creds *auth.Credentials, pid int32) error { if len(vals) != s.Size() { panic(fmt.Sprintf("vals length (%d) different that Set.Size() (%d)", len(vals), s.Size())) } @@ -335,6 +338,7 @@ func (s *Set) SetValAll(ctx context.Context, vals []uint16, creds *auth.Credenti // TODO: Clear undo entries in all processes sem.value = int16(val) + sem.pid = pid sem.wakeWaiters() } s.changeTime = ktime.NowFromContext(ctx) @@ -375,12 +379,29 @@ func (s *Set) GetValAll(creds *auth.Credentials) ([]uint16, error) { return vals, nil } +// GetPID returns the PID set when performing operations in the semaphore. +func (s *Set) GetPID(num int32, creds *auth.Credentials) (int32, error) { + s.mu.Lock() + defer s.mu.Unlock() + + // "The calling process must have read permission on the semaphore set." + if !s.checkPerms(creds, fs.PermMask{Read: true}) { + return 0, syserror.EACCES + } + + sem := s.findSem(num) + if sem == nil { + return 0, syserror.ERANGE + } + return sem.pid, nil +} + // ExecuteOps attempts to execute a list of operations to the set. It only // succeeds when all operations can be applied. No changes are made if it fails. // // On failure, it may return an error (retries are hopeless) or it may return // a channel that can be waited on before attempting again. -func (s *Set) ExecuteOps(ctx context.Context, ops []linux.Sembuf, creds *auth.Credentials) (chan struct{}, int32, error) { +func (s *Set) ExecuteOps(ctx context.Context, ops []linux.Sembuf, creds *auth.Credentials, pid int32) (chan struct{}, int32, error) { s.mu.Lock() defer s.mu.Unlock() @@ -404,14 +425,14 @@ func (s *Set) ExecuteOps(ctx context.Context, ops []linux.Sembuf, creds *auth.Cr return nil, 0, syserror.EACCES } - ch, num, err := s.executeOps(ctx, ops) + ch, num, err := s.executeOps(ctx, ops, pid) if err != nil { return nil, 0, err } return ch, num, nil } -func (s *Set) executeOps(ctx context.Context, ops []linux.Sembuf) (chan struct{}, int32, error) { +func (s *Set) executeOps(ctx context.Context, ops []linux.Sembuf, pid int32) (chan struct{}, int32, error) { // Changes to semaphores go to this slice temporarily until they all succeed. tmpVals := make([]int16, len(s.sems)) for i := range s.sems { @@ -464,6 +485,7 @@ func (s *Set) executeOps(ctx context.Context, ops []linux.Sembuf) (chan struct{} for i, v := range tmpVals { s.sems[i].value = v s.sems[i].wakeWaiters() + s.sems[i].pid = pid } s.opTime = ktime.NowFromContext(ctx) return nil, 0, nil diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go index 5f886bf31..2e51e6ee5 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_test.go +++ b/pkg/sentry/kernel/semaphore/semaphore_test.go @@ -25,7 +25,7 @@ import ( ) func executeOps(ctx context.Context, t *testing.T, set *Set, ops []linux.Sembuf, block bool) chan struct{} { - ch, _, err := set.executeOps(ctx, ops) + ch, _, err := set.executeOps(ctx, ops, 123) if err != nil { t.Fatalf("ExecuteOps(ops) failed, err: %v, ops: %+v", err, ops) } @@ -123,13 +123,13 @@ func TestNoWait(t *testing.T) { ops[0].SemOp = -2 ops[0].SemFlg = linux.IPC_NOWAIT - if _, _, err := set.executeOps(ctx, ops); err != syserror.ErrWouldBlock { + if _, _, err := set.executeOps(ctx, ops, 123); err != syserror.ErrWouldBlock { t.Fatalf("ExecuteOps(ops) wrong result, got: %v, expected: %v", err, syserror.ErrWouldBlock) } ops[0].SemOp = 0 ops[0].SemFlg = linux.IPC_NOWAIT - if _, _, err := set.executeOps(ctx, ops); err != syserror.ErrWouldBlock { + if _, _, err := set.executeOps(ctx, ops, 123); err != syserror.ErrWouldBlock { t.Fatalf("ExecuteOps(ops) wrong result, got: %v, expected: %v", err, syserror.ErrWouldBlock) } } diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go index 6775725ca..86f850ef1 100644 --- a/pkg/sentry/syscalls/linux/sys_sem.go +++ b/pkg/sentry/syscalls/linux/sys_sem.go @@ -71,8 +71,9 @@ func Semop(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall } creds := auth.CredentialsFromContext(t) + pid := t.Kernel().GlobalInit().PIDNamespace().IDOfThreadGroup(t.ThreadGroup()) for { - ch, num, err := set.ExecuteOps(t, ops, creds) + ch, num, err := set.ExecuteOps(t, ops, creds, int32(pid)) if ch == nil || err != nil { // We're done (either on success or a failure). return 0, nil, err @@ -123,6 +124,21 @@ func Semctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal perms := fs.FilePermsFromMode(linux.FileMode(s.SemPerm.Mode & 0777)) return 0, nil, ipcSet(t, id, auth.UID(s.SemPerm.UID), auth.GID(s.SemPerm.GID), perms) + case linux.GETPID: + v, err := getPID(t, id, num) + return uintptr(v), nil, err + + case linux.IPC_INFO, + linux.SEM_INFO, + linux.IPC_STAT, + linux.SEM_STAT, + linux.SEM_STAT_ANY, + linux.GETNCNT, + linux.GETZCNT: + + t.Kernel().EmitUnimplementedEvent(t) + fallthrough + default: return 0, nil, syserror.EINVAL } @@ -161,7 +177,8 @@ func setVal(t *kernel.Task, id int32, num int32, val int16) error { return syserror.EINVAL } creds := auth.CredentialsFromContext(t) - return set.SetVal(t, num, val, creds) + pid := t.Kernel().GlobalInit().PIDNamespace().IDOfThreadGroup(t.ThreadGroup()) + return set.SetVal(t, num, val, creds, int32(pid)) } func setValAll(t *kernel.Task, id int32, array usermem.Addr) error { @@ -175,7 +192,8 @@ func setValAll(t *kernel.Task, id int32, array usermem.Addr) error { return err } creds := auth.CredentialsFromContext(t) - return set.SetValAll(t, vals, creds) + pid := t.Kernel().GlobalInit().PIDNamespace().IDOfThreadGroup(t.ThreadGroup()) + return set.SetValAll(t, vals, creds, int32(pid)) } func getVal(t *kernel.Task, id int32, num int32) (int16, error) { @@ -202,3 +220,22 @@ func getValAll(t *kernel.Task, id int32, array usermem.Addr) error { _, err = t.CopyOut(array, vals) return err } + +func getPID(t *kernel.Task, id int32, num int32) (int32, error) { + r := t.IPCNamespace().SemaphoreRegistry() + set := r.FindByID(id) + if set == nil { + return 0, syserror.EINVAL + } + creds := auth.CredentialsFromContext(t) + gpid, err := set.GetPID(num, creds) + if err != nil { + return 0, err + } + // Convert pid from init namespace to the caller's namespace. + tg := t.PIDNamespace().ThreadGroupWithID(kernel.ThreadID(gpid)) + if tg == nil { + return 0, nil + } + return int32(tg.ID()), nil +} diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index c2a77ebf5..572b5b472 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -100,6 +100,10 @@ func (c *compatEmitter) Emit(msg proto.Message) (hangup bool, err error) { // args: fd, level, name, ... tr = newArgsTracker(1, 2) + case syscall.SYS_SEMCTL: + // args: semid, semnum, cmd, ... + tr = newArgsTracker(2) + default: tr = &onceTracker{} } diff --git a/test/syscalls/linux/semaphore.cc b/test/syscalls/linux/semaphore.cc index da3d2c6fe..1c47b6851 100644 --- a/test/syscalls/linux/semaphore.cc +++ b/test/syscalls/linux/semaphore.cc @@ -431,6 +431,35 @@ TEST(SemaphoreTest, SemCtlValAll) { SyscallFailsWithErrno(EFAULT)); } +TEST(SemaphoreTest, SemCtlGetPid) { + AutoSem sem(semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)); + ASSERT_THAT(sem.get(), SyscallSucceeds()); + + ASSERT_THAT(semctl(sem.get(), 0, SETVAL, 1), SyscallSucceeds()); + EXPECT_THAT(semctl(sem.get(), 0, GETPID), SyscallSucceedsWithValue(getpid())); +} + +TEST(SemaphoreTest, SemCtlGetPidFork) { + AutoSem sem(semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT)); + ASSERT_THAT(sem.get(), SyscallSucceeds()); + + const pid_t child_pid = fork(); + if (child_pid == 0) { + ASSERT_THAT(semctl(sem.get(), 0, SETVAL, 1), SyscallSucceeds()); + ASSERT_THAT(semctl(sem.get(), 0, GETPID), + SyscallSucceedsWithValue(getpid())); + + _exit(0); + } + ASSERT_THAT(child_pid, SyscallSucceeds()); + + int status; + ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), + SyscallSucceedsWithValue(child_pid)); + EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0) + << " status " << status; +} + TEST(SemaphoreTest, SemIpcSet) { // Drop CAP_IPC_OWNER which allows us to bypass semaphore permissions. ASSERT_NO_ERRNO(SetCapability(CAP_IPC_OWNER, false)); -- cgit v1.2.3 From 0b76887147820a809beaa497ede8dc4f7b7b120a Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Tue, 5 Mar 2019 23:39:14 -0800 Subject: Priority-inheritance futex implementation It is Implemented without the priority inheritance part given that gVisor defers scheduling decisions to Go runtime and doesn't have control over it. PiperOrigin-RevId: 236989545 Change-Id: I714c8ca0798743ecf3167b14ffeb5cd834302560 --- pkg/abi/linux/futex.go | 6 + pkg/sentry/kernel/futex/BUILD | 2 + pkg/sentry/kernel/futex/futex.go | 215 +++++++++++++++++++++--- pkg/sentry/kernel/futex/futex_test.go | 4 + pkg/sentry/kernel/task_futex.go | 7 + pkg/sentry/mm/io.go | 45 +++++ pkg/sentry/platform/platform.go | 10 ++ pkg/sentry/platform/safecopy/BUILD | 4 +- pkg/sentry/platform/safecopy/atomic_amd64.s | 28 +++ pkg/sentry/platform/safecopy/atomic_arm64.s | 28 +++ pkg/sentry/platform/safecopy/safecopy.go | 4 + pkg/sentry/platform/safecopy/safecopy_unsafe.go | 20 +++ pkg/sentry/platform/safecopy/sighandler_amd64.s | 9 + pkg/sentry/platform/safecopy/sighandler_arm64.s | 11 ++ pkg/sentry/safemem/block_unsafe.go | 10 ++ pkg/sentry/syscalls/linux/sys_futex.go | 68 +++++++- pkg/sentry/usermem/bytes_io_unsafe.go | 8 + pkg/sentry/usermem/usermem.go | 7 + pkg/syserror/syserror.go | 1 + runsc/boot/compat.go | 4 +- test/syscalls/linux/BUILD | 1 + test/syscalls/linux/futex.cc | 115 ++++++++++++- 22 files changed, 578 insertions(+), 29 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go index 5dff01fba..afdf4123b 100644 --- a/pkg/abi/linux/futex.go +++ b/pkg/abi/linux/futex.go @@ -54,3 +54,9 @@ const ( // FUTEX_TID_MASK is the TID portion of a PI futex word. const FUTEX_TID_MASK = 0x3fffffff + +// Constants used for priority-inheritance futexes. +const ( + FUTEX_WAITERS = 0x80000000 + FUTEX_OWNER_DIED = 0x40000000 +) diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index 91feeb5ed..b6af5b20b 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -37,6 +37,8 @@ go_library( visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", + "//pkg/log", + "//pkg/sentry/context", "//pkg/sentry/memmap", "//pkg/sentry/usermem", "//pkg/syserror", diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index b3e628fd4..cd7d51621 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -95,12 +95,15 @@ func (k *Key) matches(k2 *Key) bool { // Target abstracts memory accesses and keys. type Target interface { - // SwapUint32 gives access to usermem.SwapUint32. + // SwapUint32 gives access to usermem.IO.SwapUint32. SwapUint32(addr usermem.Addr, new uint32) (uint32, error) - // CompareAndSwap gives access to usermem.CompareAndSwapUint32. + // CompareAndSwap gives access to usermem.IO.CompareAndSwapUint32. CompareAndSwapUint32(addr usermem.Addr, old, new uint32) (uint32, error) + // LoadUint32 gives access to usermem.IO.LoadUint32. + LoadUint32(addr usermem.Addr) (uint32, error) + // GetSharedKey returns a Key with kind KindSharedPrivate or // KindSharedMappable corresponding to the memory mapped at address addr. // @@ -112,11 +115,11 @@ type Target interface { // check performs a basic equality check on the given address. func check(t Target, addr usermem.Addr, val uint32) error { - prev, err := t.CompareAndSwapUint32(addr, val, val) + cur, err := t.LoadUint32(addr) if err != nil { return err } - if prev != val { + if cur != val { return syserror.EAGAIN } return nil @@ -140,11 +143,14 @@ func atomicOp(t Target, addr usermem.Addr, opIn uint32) (bool, error) { ) if opType == linux.FUTEX_OP_SET { oldVal, err = t.SwapUint32(addr, opArg) + if err != nil { + return false, err + } } else { for { - oldVal, err = t.CompareAndSwapUint32(addr, 0, 0) + oldVal, err = t.LoadUint32(addr) if err != nil { - break + return false, err } var newVal uint32 switch opType { @@ -161,7 +167,7 @@ func atomicOp(t Target, addr usermem.Addr, opIn uint32) (bool, error) { } prev, err := t.CompareAndSwapUint32(addr, oldVal, newVal) if err != nil { - break + return false, err } if prev == oldVal { break // Success. @@ -222,6 +228,9 @@ type Waiter struct { // The bitmask we're waiting on. // This is used the case of a FUTEX_WAKE_BITSET. bitmask uint32 + + // tid is the thread ID for the waiter in case this is a PI mutex. + tid uint32 } // NewWaiter returns a new unqueued Waiter. @@ -262,23 +271,28 @@ func (b *bucket) wakeLocked(key *Key, bitmask uint32, n int) int { // Remove from the bucket and wake the waiter. woke := w w = w.Next() // Next iteration. - b.waiters.Remove(woke) - woke.C <- struct{}{} - - // NOTE: The above channel write establishes a write barrier according - // to the memory model, so nothing may be ordered around it. Since - // we've dequeued woke and will never touch it again, we can safely - // store nil to woke.bucket here and allow the WaitComplete() to - // short-circuit grabbing the bucket lock. If they somehow miss the - // store, we are still holding the lock, so we can know that they won't - // dequeue woke, assume it's free and have the below operation - // afterwards. - woke.bucket.Store(nil) + b.wakeWaiterLocked(woke) done++ } return done } +func (b *bucket) wakeWaiterLocked(w *Waiter) { + // Remove from the bucket and wake the waiter. + b.waiters.Remove(w) + w.C <- struct{}{} + + // NOTE: The above channel write establishes a write barrier according + // to the memory model, so nothing may be ordered around it. Since + // we've dequeued w and will never touch it again, we can safely + // store nil to w.bucket here and allow the WaitComplete() to + // short-circuit grabbing the bucket lock. If they somehow miss the + // store, we are still holding the lock, so we can know that they won't + // dequeue w, assume it's free and have the below operation + // afterwards. + w.bucket.Store(nil) +} + // requeueLocked takes n waiters from the bucket and moves them to naddr on the // bucket "to". // @@ -596,7 +610,7 @@ func (m *Manager) WaitComplete(w *Waiter) { continue } - // Remove w from b. + // Remove waiter from bucket. b.waiters.Remove(w) w.bucket.Store(nil) b.mu.Unlock() @@ -606,3 +620,164 @@ func (m *Manager) WaitComplete(w *Waiter) { // Release references held by the waiter. w.key.release() } + +// LockPI attempts to lock the futex following the Priority-inheritance futex +// rules. The lock is acquired only when 'addr' points to 0. The TID of the +// calling task is set to 'addr' to indicate the futex is owned. It returns true +// if the futex was successfully acquired. +// +// FUTEX_OWNER_DIED is only set by the Linux when robust lists are in use (see +// exit_robust_list()). Given we don't support robust lists, although handled +// below, it's never set. +func (m *Manager) LockPI(w *Waiter, t Target, addr usermem.Addr, tid uint32, private, try bool) (bool, error) { + k, err := getKey(t, addr, private) + if err != nil { + return false, err + } + // Ownership of k is transferred to w below. + + // Prepare the Waiter before taking the bucket lock. + select { + case <-w.C: + default: + } + w.key = k + w.tid = tid + + b := m.lockBucket(&k) + // Hot function: avoid defers. + + success, err := m.lockPILocked(w, t, addr, tid, b, try) + if err != nil { + w.key.release() + b.mu.Unlock() + return false, err + } + if success || try { + // Release waiter if it's not going to be a wait. + w.key.release() + } + b.mu.Unlock() + return success, nil +} + +func (m *Manager) lockPILocked(w *Waiter, t Target, addr usermem.Addr, tid uint32, b *bucket, try bool) (bool, error) { + for { + cur, err := t.LoadUint32(addr) + if err != nil { + return false, err + } + if (cur & linux.FUTEX_TID_MASK) == tid { + return false, syserror.EDEADLK + } + + if (cur & linux.FUTEX_TID_MASK) == 0 { + // No owner and no waiters, try to acquire the futex. + + // Set TID and preserve owner died status. + val := tid + val |= cur & linux.FUTEX_OWNER_DIED + prev, err := t.CompareAndSwapUint32(addr, cur, val) + if err != nil { + return false, err + } + if prev != cur { + // CAS failed, retry... + // Linux reacquires the bucket lock on retries, which will re-lookup the + // mapping at the futex address. However, retrying while holding the + // lock is more efficient and reduces the chance of another conflict. + continue + } + // Futex acquired. + return true, nil + } + + // Futex is already owned, prepare to wait. + + if try { + // Caller doesn't want to wait. + return false, nil + } + + // Set waiters bit if not set yet. + if cur&linux.FUTEX_WAITERS == 0 { + prev, err := t.CompareAndSwapUint32(addr, cur, cur|linux.FUTEX_WAITERS) + if err != nil { + return false, err + } + if prev != cur { + // CAS failed, retry... + continue + } + } + + // Add the waiter to the bucket. + b.waiters.PushBack(w) + w.bucket.Store(b) + return false, nil + } +} + +// UnlockPI unlock the futex following the Priority-inheritance futex +// rules. The address provided must contain the caller's TID. If there are +// waiters, TID of the next waiter (FIFO) is set to the given address, and the +// waiter woken up. If there are no waiters, 0 is set to the address. +func (m *Manager) UnlockPI(t Target, addr usermem.Addr, tid uint32, private bool) error { + k, err := getKey(t, addr, private) + if err != nil { + return err + } + b := m.lockBucket(&k) + + err = m.unlockPILocked(t, addr, tid, b) + + k.release() + b.mu.Unlock() + return err +} + +func (m *Manager) unlockPILocked(t Target, addr usermem.Addr, tid uint32, b *bucket) error { + cur, err := t.LoadUint32(addr) + if err != nil { + return err + } + + if (cur & linux.FUTEX_TID_MASK) != tid { + return syserror.EPERM + } + + if b.waiters.Empty() { + // It's safe to set 0 because there are no waiters, no new owner, and the + // executing task is the current owner (no owner died bit). + prev, err := t.CompareAndSwapUint32(addr, cur, 0) + if err != nil { + return err + } + if prev != cur { + // Let user mode handle CAS races. This is different than lock, which + // retries when CAS fails. + return syserror.EAGAIN + } + return nil + } + + next := b.waiters.Front() + + // Set next owner's TID, waiters if there are any. Resets owner died bit, if + // set, because the executing task takes over as the owner. + val := next.tid + if next.Next() != nil { + val |= linux.FUTEX_WAITERS + } + + prev, err := t.CompareAndSwapUint32(addr, cur, val) + if err != nil { + return err + } + if prev != cur { + return syserror.EINVAL + } + + b.wakeWaiterLocked(next) + return nil +} diff --git a/pkg/sentry/kernel/futex/futex_test.go b/pkg/sentry/kernel/futex/futex_test.go index a7ab9f229..9d44ee8e5 100644 --- a/pkg/sentry/kernel/futex/futex_test.go +++ b/pkg/sentry/kernel/futex/futex_test.go @@ -49,6 +49,10 @@ func (t testData) CompareAndSwapUint32(addr usermem.Addr, old, new uint32) (uint return atomic.LoadUint32((*uint32)(unsafe.Pointer(&t[addr]))), nil } +func (t testData) LoadUint32(addr usermem.Addr) (uint32, error) { + return atomic.LoadUint32((*uint32)(unsafe.Pointer(&t[addr]))), nil +} + func (t testData) GetSharedKey(addr usermem.Addr) (Key, error) { return Key{ Kind: KindSharedMappable, diff --git a/pkg/sentry/kernel/task_futex.go b/pkg/sentry/kernel/task_futex.go index 921f7bdbc..351cf47d7 100644 --- a/pkg/sentry/kernel/task_futex.go +++ b/pkg/sentry/kernel/task_futex.go @@ -41,6 +41,13 @@ func (t *Task) CompareAndSwapUint32(addr usermem.Addr, old, new uint32) (uint32, }) } +// LoadUint32 implemets futex.Target.LoadUint32. +func (t *Task) LoadUint32(addr usermem.Addr) (uint32, error) { + return t.MemoryManager().LoadUint32(t, addr, usermem.IOOpts{ + AddressSpaceActive: true, + }) +} + // GetSharedKey implements futex.Target.GetSharedKey. func (t *Task) GetSharedKey(addr usermem.Addr) (futex.Key, error) { return t.MemoryManager().GetSharedFutexKey(t, addr) diff --git a/pkg/sentry/mm/io.go b/pkg/sentry/mm/io.go index 6600ddd78..e0cebef84 100644 --- a/pkg/sentry/mm/io.go +++ b/pkg/sentry/mm/io.go @@ -346,6 +346,7 @@ func (mm *MemoryManager) SwapUint32(ctx context.Context, addr usermem.Addr, new if err != nil { return 0, translateIOError(ctx, err) } + // Return the number of bytes read. return 4, nil }) return old, err @@ -388,11 +389,55 @@ func (mm *MemoryManager) CompareAndSwapUint32(ctx context.Context, addr usermem. if err != nil { return 0, translateIOError(ctx, err) } + // Return the number of bytes read. return 4, nil }) return prev, err } +// LoadUint32 implements usermem.IO.LoadUint32. +func (mm *MemoryManager) LoadUint32(ctx context.Context, addr usermem.Addr, opts usermem.IOOpts) (uint32, error) { + ar, ok := mm.CheckIORange(addr, 4) + if !ok { + return 0, syserror.EFAULT + } + + // Do AddressSpace IO if applicable. + if mm.haveASIO && opts.AddressSpaceActive && !opts.IgnorePermissions { + for { + val, err := mm.as.LoadUint32(addr) + if err == nil { + return val, nil + } + if f, ok := err.(platform.SegmentationFault); ok { + if err := mm.handleASIOFault(ctx, f.Addr, ar, usermem.Read); err != nil { + return 0, err + } + continue + } + return 0, translateIOError(ctx, err) + } + } + + // Go through internal mappings. + var val uint32 + _, err := mm.withInternalMappings(ctx, ar, usermem.Read, opts.IgnorePermissions, func(ims safemem.BlockSeq) (uint64, error) { + if ims.NumBlocks() != 1 || ims.NumBytes() != 4 { + // Atomicity is unachievable across mappings. + return 0, syserror.EFAULT + } + im := ims.Head() + var err error + val, err = safemem.LoadUint32(im) + if err != nil { + return 0, translateIOError(ctx, err) + } + // Return the number of bytes read. + return 4, nil + }) + return val, err +} + // handleASIOFault handles a page fault at address addr for an AddressSpaceIO // operation spanning ioar. // diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index f16588e6e..a9e76bd45 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -254,6 +254,11 @@ type AddressSpaceIO interface { // // Preconditions: addr must be aligned to a 4-byte boundary. CompareAndSwapUint32(addr usermem.Addr, old, new uint32) (uint32, error) + + // LoadUint32 atomically loads the uint32 value at addr and returns it. + // + // Preconditions: addr must be aligned to a 4-byte boundary. + LoadUint32(addr usermem.Addr) (uint32, error) } // NoAddressSpaceIO implements AddressSpaceIO methods by panicing. @@ -284,6 +289,11 @@ func (NoAddressSpaceIO) CompareAndSwapUint32(addr usermem.Addr, old, new uint32) panic("This platform does not support AddressSpaceIO") } +// LoadUint32 implements AddressSpaceIO.LoadUint32. +func (NoAddressSpaceIO) LoadUint32(addr usermem.Addr) (uint32, error) { + panic("This platform does not support AddressSpaceIO") +} + // SegmentationFault is an error returned by AddressSpaceIO methods when IO // fails due to access of an unmapped page, or a mapped page with insufficient // permissions. diff --git a/pkg/sentry/platform/safecopy/BUILD b/pkg/sentry/platform/safecopy/BUILD index 05a6a61ae..d97a40297 100644 --- a/pkg/sentry/platform/safecopy/BUILD +++ b/pkg/sentry/platform/safecopy/BUILD @@ -18,9 +18,7 @@ go_library( ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/platform/safecopy", visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/syserror", - ], + deps = ["//pkg/syserror"], ) go_test( diff --git a/pkg/sentry/platform/safecopy/atomic_amd64.s b/pkg/sentry/platform/safecopy/atomic_amd64.s index 873ffa046..f90b4bfd1 100644 --- a/pkg/sentry/platform/safecopy/atomic_amd64.s +++ b/pkg/sentry/platform/safecopy/atomic_amd64.s @@ -106,3 +106,31 @@ TEXT ·compareAndSwapUint32(SB), NOSPLIT, $0-24 CMPXCHGL DX, 0(DI) MOVL AX, prev+16(FP) RET + +// handleLoadUint32Fault returns the value stored in DI. Control is transferred +// to it when LoadUint32 below receives SIGSEGV or SIGBUS, with the signal +// number stored in DI. +// +// It must have the same frame configuration as loadUint32 so that it can undo +// any potential call frame set up by the assembler. +TEXT handleLoadUint32Fault(SB), NOSPLIT, $0-16 + MOVL DI, sig+12(FP) + RET + +// loadUint32 atomically loads *addr and returns it. If a SIGSEGV or SIGBUS +// signal is received, the value returned is unspecified, and sig is the number +// of the signal that was received. +// +// Preconditions: addr must be aligned to a 4-byte boundary. +// +//func loadUint32(ptr unsafe.Pointer) (val uint32, sig int32) +TEXT ·loadUint32(SB), NOSPLIT, $0-16 + // Store 0 as the returned signal number. If we run to completion, + // this is the value the caller will see; if a signal is received, + // handleLoadUint32Fault will store a different value in this address. + MOVL $0, sig+12(FP) + + MOVQ addr+0(FP), AX + MOVL (AX), BX + MOVL BX, val+8(FP) + RET diff --git a/pkg/sentry/platform/safecopy/atomic_arm64.s b/pkg/sentry/platform/safecopy/atomic_arm64.s index 554a5c1e1..d58ed71f7 100644 --- a/pkg/sentry/platform/safecopy/atomic_arm64.s +++ b/pkg/sentry/platform/safecopy/atomic_arm64.s @@ -96,3 +96,31 @@ again: done: MOVW R3, prev+16(FP) RET + +// handleLoadUint32Fault returns the value stored in DI. Control is transferred +// to it when LoadUint32 below receives SIGSEGV or SIGBUS, with the signal +// number stored in DI. +// +// It must have the same frame configuration as loadUint32 so that it can undo +// any potential call frame set up by the assembler. +TEXT handleLoadUint32Fault(SB), NOSPLIT, $0-16 + MOVW R1, sig+12(FP) + RET + +// loadUint32 atomically loads *addr and returns it. If a SIGSEGV or SIGBUS +// signal is received, the value returned is unspecified, and sig is the number +// of the signal that was received. +// +// Preconditions: addr must be aligned to a 4-byte boundary. +// +//func loadUint32(ptr unsafe.Pointer) (val uint32, sig int32) +TEXT ·loadUint32(SB), NOSPLIT, $0-16 + // Store 0 as the returned signal number. If we run to completion, + // this is the value the caller will see; if a signal is received, + // handleLoadUint32Fault will store a different value in this address. + MOVW $0, sig+12(FP) + + MOVD addr+0(FP), R0 + LDARW (R0), R1 + MOVW R1, val+8(FP) + RET diff --git a/pkg/sentry/platform/safecopy/safecopy.go b/pkg/sentry/platform/safecopy/safecopy.go index c60f73103..69c66a3b7 100644 --- a/pkg/sentry/platform/safecopy/safecopy.go +++ b/pkg/sentry/platform/safecopy/safecopy.go @@ -75,6 +75,8 @@ var ( swapUint64End uintptr compareAndSwapUint32Begin uintptr compareAndSwapUint32End uintptr + loadUint32Begin uintptr + loadUint32End uintptr // savedSigSegVHandler is a pointer to the SIGSEGV handler that was // configured before we replaced it with our own. We still call into it @@ -119,6 +121,8 @@ func initializeAddresses() { swapUint64End = FindEndAddress(swapUint64Begin) compareAndSwapUint32Begin = reflect.ValueOf(compareAndSwapUint32).Pointer() compareAndSwapUint32End = FindEndAddress(compareAndSwapUint32Begin) + loadUint32Begin = reflect.ValueOf(loadUint32).Pointer() + loadUint32End = FindEndAddress(loadUint32Begin) } func init() { diff --git a/pkg/sentry/platform/safecopy/safecopy_unsafe.go b/pkg/sentry/platform/safecopy/safecopy_unsafe.go index e78a6714e..f84527484 100644 --- a/pkg/sentry/platform/safecopy/safecopy_unsafe.go +++ b/pkg/sentry/platform/safecopy/safecopy_unsafe.go @@ -79,6 +79,14 @@ func swapUint64(ptr unsafe.Pointer, new uint64) (old uint64, sig int32) //go:noescape func compareAndSwapUint32(ptr unsafe.Pointer, old, new uint32) (prev uint32, sig int32) +// LoadUint32 is like sync/atomic.LoadUint32, but operates with user memory. It +// may fail with SIGSEGV or SIGBUS if it is received while reading from ptr. +// +// Preconditions: ptr must be aligned to a 4-byte boundary. +// +//go:noescape +func loadUint32(ptr unsafe.Pointer) (val uint32, sig int32) + // CopyIn copies len(dst) bytes from src to dst. It returns the number of bytes // copied and an error if SIGSEGV or SIGBUS is received while reading from src. func CopyIn(dst []byte, src unsafe.Pointer) (int, error) { @@ -260,6 +268,18 @@ func CompareAndSwapUint32(ptr unsafe.Pointer, old, new uint32) (uint32, error) { return prev, errorFromFaultSignal(ptr, sig) } +// LoadUint32 is like sync/atomic.LoadUint32, but operates with user memory. It +// may fail with SIGSEGV or SIGBUS if it is received while reading from ptr. +// +// Preconditions: ptr must be aligned to a 4-byte boundary. +func LoadUint32(ptr unsafe.Pointer) (uint32, error) { + if addr := uintptr(ptr); addr&3 != 0 { + return 0, AlignmentError{addr, 4} + } + val, sig := loadUint32(ptr) + return val, errorFromFaultSignal(ptr, sig) +} + func errorFromFaultSignal(addr unsafe.Pointer, sig int32) error { switch sig { case 0: diff --git a/pkg/sentry/platform/safecopy/sighandler_amd64.s b/pkg/sentry/platform/safecopy/sighandler_amd64.s index 06614f1b4..db7701a29 100644 --- a/pkg/sentry/platform/safecopy/sighandler_amd64.s +++ b/pkg/sentry/platform/safecopy/sighandler_amd64.s @@ -101,6 +101,15 @@ not_swapuint64: JMP handle_fault not_casuint32: + CMPQ CX, ·loadUint32Begin(SB) + JB not_loaduint32 + CMPQ CX, ·loadUint32End(SB) + JAE not_loaduint32 + + LEAQ handleLoadUint32Fault(SB), CX + JMP handle_fault + +not_loaduint32: original_handler: // Jump to the previous signal handler, which is likely the golang one. XORQ CX, CX diff --git a/pkg/sentry/platform/safecopy/sighandler_arm64.s b/pkg/sentry/platform/safecopy/sighandler_arm64.s index 5e8e193e7..cdfca8207 100644 --- a/pkg/sentry/platform/safecopy/sighandler_arm64.s +++ b/pkg/sentry/platform/safecopy/sighandler_arm64.s @@ -110,6 +110,17 @@ not_swapuint64: B handle_fault not_casuint32: + MOVD ·loadUint32Begin(SB), R8 + CMP R8, R7 + BLO not_loaduint32 + MOVD ·loadUint32End(SB), R8 + CMP R8, R7 + BHS not_loaduint32 + + MOVD $handleLoadUint32Fault(SB), R7 + B handle_fault + +not_loaduint32: original_handler: // Jump to the previous signal handler, which is likely the golang one. MOVD ·savedSigBusHandler(SB), R7 diff --git a/pkg/sentry/safemem/block_unsafe.go b/pkg/sentry/safemem/block_unsafe.go index e91ff66ae..c3a9780d2 100644 --- a/pkg/sentry/safemem/block_unsafe.go +++ b/pkg/sentry/safemem/block_unsafe.go @@ -267,3 +267,13 @@ func CompareAndSwapUint32(b Block, old, new uint32) (uint32, error) { } return safecopy.CompareAndSwapUint32(b.start, old, new) } + +// LoadUint32 invokes safecopy.LoadUint32 on the first 4 bytes of b. +// +// Preconditions: b.Len() >= 4. +func LoadUint32(b Block) (uint32, error) { + if b.length < 4 { + panic(fmt.Sprintf("insufficient length: %d", b.length)) + } + return safecopy.LoadUint32(b.start) +} diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index 7a1d396ec..f0c89cba4 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -124,6 +124,46 @@ func futexWaitDuration(t *kernel.Task, duration time.Duration, forever bool, add return 0, kernel.ERESTART_RESTARTBLOCK } +func futexLockPI(t *kernel.Task, ts linux.Timespec, forever bool, addr usermem.Addr, private bool) error { + w := t.FutexWaiter() + locked, err := t.Futex().LockPI(w, t, addr, uint32(t.ThreadID()), private, false) + if err != nil { + return err + } + if locked { + // Futex acquired, we're done! + return nil + } + + if forever { + err = t.Block(w.C) + } else { + notifier, tchan := ktime.NewChannelNotifier() + timer := ktime.NewTimer(t.Kernel().RealtimeClock(), notifier) + timer.Swap(ktime.Setting{ + Enabled: true, + Next: ktime.FromTimespec(ts), + }) + err = t.BlockWithTimer(w.C, tchan) + timer.Destroy() + } + + t.Futex().WaitComplete(w) + return syserror.ConvertIntr(err, kernel.ERESTARTSYS) +} + +func tryLockPI(t *kernel.Task, addr usermem.Addr, private bool) error { + w := t.FutexWaiter() + locked, err := t.Futex().LockPI(w, t, addr, uint32(t.ThreadID()), private, true) + if err != nil { + return err + } + if !locked { + return syserror.EWOULDBLOCK + } + return nil +} + // Futex implements linux syscall futex(2). // It provides a method for a program to wait for a value at a given address to // change, and a method to wake up anyone waiting on a particular address. @@ -144,7 +184,7 @@ func Futex(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall switch cmd { case linux.FUTEX_WAIT, linux.FUTEX_WAIT_BITSET: // WAIT{_BITSET} wait forever if the timeout isn't passed. - forever := timeout == 0 + forever := (timeout == 0) var timespec linux.Timespec if !forever { @@ -205,8 +245,30 @@ func Futex(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall n, err := t.Futex().WakeOp(t, addr, naddr, private, val, nreq, op) return uintptr(n), nil, err - case linux.FUTEX_LOCK_PI, linux.FUTEX_UNLOCK_PI, linux.FUTEX_TRYLOCK_PI, linux.FUTEX_WAIT_REQUEUE_PI, linux.FUTEX_CMP_REQUEUE_PI: - // We don't support any priority inversion futexes. + case linux.FUTEX_LOCK_PI: + forever := (timeout == 0) + + var timespec linux.Timespec + if !forever { + var err error + timespec, err = copyTimespecIn(t, timeout) + if err != nil { + return 0, nil, err + } + } + err := futexLockPI(t, timespec, forever, addr, private) + return 0, nil, err + + case linux.FUTEX_TRYLOCK_PI: + err := tryLockPI(t, addr, private) + return 0, nil, err + + case linux.FUTEX_UNLOCK_PI: + err := t.Futex().UnlockPI(t, addr, uint32(t.ThreadID()), private) + return 0, nil, err + + case linux.FUTEX_WAIT_REQUEUE_PI, linux.FUTEX_CMP_REQUEUE_PI: + t.Kernel().EmitUnimplementedEvent(t) return 0, nil, syserror.ENOSYS default: diff --git a/pkg/sentry/usermem/bytes_io_unsafe.go b/pkg/sentry/usermem/bytes_io_unsafe.go index 8bdf3a508..7add8bc82 100644 --- a/pkg/sentry/usermem/bytes_io_unsafe.go +++ b/pkg/sentry/usermem/bytes_io_unsafe.go @@ -37,3 +37,11 @@ func (b *BytesIO) CompareAndSwapUint32(ctx context.Context, addr Addr, old, new } return atomicbitops.CompareAndSwapUint32((*uint32)(unsafe.Pointer(&b.Bytes[int(addr)])), old, new), nil } + +// LoadUint32 implements IO.LoadUint32. +func (b *BytesIO) LoadUint32(ctx context.Context, addr Addr, opts IOOpts) (uint32, error) { + if _, err := b.rangeCheck(addr, 4); err != nil { + return 0, err + } + return atomic.LoadUint32((*uint32)(unsafe.Pointer(&b.Bytes[int(addr)]))), nil +} diff --git a/pkg/sentry/usermem/usermem.go b/pkg/sentry/usermem/usermem.go index 75ac4d22d..c3c9c153b 100644 --- a/pkg/sentry/usermem/usermem.go +++ b/pkg/sentry/usermem/usermem.go @@ -103,6 +103,13 @@ type IO interface { // any following locks in the lock order. addr must be aligned to a 4-byte // boundary. CompareAndSwapUint32(ctx context.Context, addr Addr, old, new uint32, opts IOOpts) (uint32, error) + + // LoadUint32 atomically loads the uint32 value at addr and returns it. + // + // Preconditions: The caller must not hold mm.MemoryManager.mappingMu or + // any following locks in the lock order. addr must be aligned to a 4-byte + // boundary. + LoadUint32(ctx context.Context, addr Addr, opts IOOpts) (uint32, error) } // IOOpts contains options applicable to all IO methods. diff --git a/pkg/syserror/syserror.go b/pkg/syserror/syserror.go index 4228707f4..5558cccff 100644 --- a/pkg/syserror/syserror.go +++ b/pkg/syserror/syserror.go @@ -33,6 +33,7 @@ var ( ECHILD = error(syscall.ECHILD) ECONNREFUSED = error(syscall.ECONNREFUSED) ECONNRESET = error(syscall.ECONNRESET) + EDEADLK = error(syscall.EDEADLK) EEXIST = error(syscall.EEXIST) EFAULT = error(syscall.EFAULT) EFBIG = error(syscall.EFBIG) diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index 37d0c31fd..b3499bcde 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -99,8 +99,8 @@ func (c *compatEmitter) emitUnimplementedSyscall(us *spb.UnimplementedSyscall) { // args: cmd, ... tr = newArgsTracker(0) - case syscall.SYS_IOCTL, syscall.SYS_EPOLL_CTL, syscall.SYS_SHMCTL: - // args: fd, cmd, ... + case syscall.SYS_IOCTL, syscall.SYS_EPOLL_CTL, syscall.SYS_SHMCTL, syscall.SYS_FUTEX: + // args: fd/addr, cmd, ... tr = newArgsTracker(1) case syscall.SYS_GETSOCKOPT, syscall.SYS_SETSOCKOPT: diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 4c818238b..2c214925e 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -808,6 +808,7 @@ cc_binary( "//test/util:cleanup", "//test/util:file_descriptor", "//test/util:memory_util", + "//test/util:save_util", "//test/util:temp_path", "//test/util:test_main", "//test/util:test_util", diff --git a/test/syscalls/linux/futex.cc b/test/syscalls/linux/futex.cc index 6fa284013..35933b660 100644 --- a/test/syscalls/linux/futex.cc +++ b/test/syscalls/linux/futex.cc @@ -32,6 +32,7 @@ #include "test/util/cleanup.h" #include "test/util/file_descriptor.h" #include "test/util/memory_util.h" +#include "test/util/save_util.h" #include "test/util/temp_path.h" #include "test/util/test_util.h" #include "test/util/thread_util.h" @@ -118,6 +119,30 @@ int futex_wake_op(bool priv, std::atomic* uaddr1, std::atomic* uaddr2, return syscall(SYS_futex, uaddr1, op, nwake1, nwake2, uaddr2, sub_op); } +int futex_lock_pi(bool priv, std::atomic* uaddr) { + int op = FUTEX_LOCK_PI; + if (priv) { + op |= FUTEX_PRIVATE_FLAG; + } + return RetryEINTR(syscall)(SYS_futex, uaddr, op, nullptr, nullptr); +} + +int futex_trylock_pi(bool priv, std::atomic* uaddr) { + int op = FUTEX_TRYLOCK_PI; + if (priv) { + op |= FUTEX_PRIVATE_FLAG; + } + return RetryEINTR(syscall)(SYS_futex, uaddr, op, nullptr, nullptr); +} + +int futex_unlock_pi(bool priv, std::atomic* uaddr) { + int op = FUTEX_UNLOCK_PI; + if (priv) { + op |= FUTEX_PRIVATE_FLAG; + } + return RetryEINTR(syscall)(SYS_futex, uaddr, op, nullptr, nullptr); +} + // Fixture for futex tests parameterized by whether to use private or shared // futexes. class PrivateAndSharedFutexTest : public ::testing::TestWithParam { @@ -589,7 +614,95 @@ TEST(SharedFutexTest, WakeInterprocessFile_NoRandomSave) { << " status " << status; } -} // namespace +TEST_P(PrivateAndSharedFutexTest, PIBasic) { + std::atomic a = ATOMIC_VAR_INIT(0); + + ASSERT_THAT(futex_lock_pi(IsPrivate(), &a), SyscallSucceeds()); + EXPECT_EQ(a.load(), gettid()); + EXPECT_THAT(futex_lock_pi(IsPrivate(), &a), SyscallFailsWithErrno(EDEADLK)); + ASSERT_THAT(futex_unlock_pi(IsPrivate(), &a), SyscallSucceeds()); + EXPECT_EQ(a.load(), 0); + EXPECT_THAT(futex_unlock_pi(IsPrivate(), &a), SyscallFailsWithErrno(EPERM)); +} + +TEST_P(PrivateAndSharedFutexTest, PIConcurrency_NoRandomSave) { + DisableSave ds; // Too many syscalls. + + std::atomic a = ATOMIC_VAR_INIT(0); + const bool is_priv = IsPrivate(); + + std::unique_ptr threads[100]; + for (size_t i = 0; i < ABSL_ARRAYSIZE(threads); ++i) { + threads[i] = absl::make_unique([is_priv, &a] { + for (size_t j = 0; j < 10; ++j) { + ASSERT_THAT(futex_lock_pi(is_priv, &a), SyscallSucceeds()); + EXPECT_EQ(a.load() & FUTEX_TID_MASK, gettid()); + SleepSafe(absl::Milliseconds(5)); + ASSERT_THAT(futex_unlock_pi(is_priv, &a), SyscallSucceeds()); + } + }); + } +} + +TEST_P(PrivateAndSharedFutexTest, PIWaiters) { + std::atomic a = ATOMIC_VAR_INIT(0); + const bool is_priv = IsPrivate(); + + ASSERT_THAT(futex_lock_pi(is_priv, &a), SyscallSucceeds()); + EXPECT_EQ(a.load(), gettid()); + + ScopedThread th([is_priv, &a] { + ASSERT_THAT(futex_lock_pi(is_priv, &a), SyscallSucceeds()); + ASSERT_THAT(futex_unlock_pi(is_priv, &a), SyscallSucceeds()); + }); + + // Wait until the thread blocks on the futex, setting the waiters bit. + auto start = absl::Now(); + while (a.load() != (FUTEX_WAITERS | gettid())) { + ASSERT_LT(absl::Now() - start, absl::Seconds(5)); + absl::SleepFor(absl::Milliseconds(100)); + } + ASSERT_THAT(futex_unlock_pi(is_priv, &a), SyscallSucceeds()); +} + +TEST_P(PrivateAndSharedFutexTest, PITryLock) { + std::atomic a = ATOMIC_VAR_INIT(0); + const bool is_priv = IsPrivate(); + + ASSERT_THAT(futex_trylock_pi(IsPrivate(), &a), SyscallSucceeds()); + EXPECT_EQ(a.load(), gettid()); + + EXPECT_THAT(futex_trylock_pi(is_priv, &a), SyscallFailsWithErrno(EDEADLK)); + ScopedThread th([is_priv, &a] { + EXPECT_THAT(futex_trylock_pi(is_priv, &a), SyscallFailsWithErrno(EAGAIN)); + }); + th.Join(); + + ASSERT_THAT(futex_unlock_pi(IsPrivate(), &a), SyscallSucceeds()); +} + +TEST_P(PrivateAndSharedFutexTest, PITryLockConcurrency_NoRandomSave) { + DisableSave ds; // Too many syscalls. + + std::atomic a = ATOMIC_VAR_INIT(0); + const bool is_priv = IsPrivate(); + + std::unique_ptr threads[100]; + for (size_t i = 0; i < ABSL_ARRAYSIZE(threads); ++i) { + threads[i] = absl::make_unique([is_priv, &a] { + for (size_t j = 0; j < 10;) { + if (futex_trylock_pi(is_priv, &a) >= 0) { + ++j; + EXPECT_EQ(a.load() & FUTEX_TID_MASK, gettid()); + SleepSafe(absl::Milliseconds(5)); + ASSERT_THAT(futex_unlock_pi(is_priv, &a), SyscallSucceeds()); + } + } + }); + } +} + +} // namespace } // namespace testing } // namespace gvisor -- cgit v1.2.3 From 06ec97a3f823f1f5d928fc9c2beb3a11c2c88487 Mon Sep 17 00:00:00 2001 From: Rahat Mahmood Date: Tue, 26 Mar 2019 16:15:55 -0700 Subject: Implement memfd_create. Memfds are simply anonymous tmpfs files with no associated mounts. Also implementing file seals, which Linux only implements for memfds at the moment. PiperOrigin-RevId: 240450031 Change-Id: I31de78b950101ae8d7a13d0e93fe52d98ea06f2f --- pkg/abi/linux/file.go | 18 ++ pkg/sentry/fs/tmpfs/inode_file.go | 151 ++++++++++ pkg/sentry/syscalls/linux/BUILD | 1 + pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 59 ++++ test/syscalls/linux/BUILD | 17 ++ test/syscalls/linux/memfd.cc | 546 ++++++++++++++++++++++++++++++++++ 7 files changed, 793 insertions(+), 1 deletion(-) create mode 100644 test/syscalls/linux/memfd.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index e5a51a9fd..46b10ca97 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -236,3 +236,21 @@ var fileType = abi.ValueSet{ ModeCharacterDevice: "S_IFCHR", ModeNamedPipe: "S_IFIFO", } + +// Constants for memfd_create(2). Source: include/uapi/linux/memfd.h +const ( + MFD_CLOEXEC = 0x0001 + MFD_ALLOW_SEALING = 0x0002 +) + +// Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h +const ( + F_LINUX_SPECIFIC_BASE = 1024 + F_ADD_SEALS = F_LINUX_SPECIFIC_BASE + 9 + F_GET_SEALS = F_LINUX_SPECIFIC_BASE + 10 + + F_SEAL_SEAL = 0x0001 // Prevent further seals from being set. + F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking. + F_SEAL_GROW = 0x0004 // Prevent file from growing. + F_SEAL_WRITE = 0x0008 // Prevent writes. +) diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 25bf2b9dd..7c80d711b 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -15,10 +15,12 @@ package tmpfs import ( + "fmt" "io" "sync" "time" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/metric" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" @@ -29,6 +31,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" "gvisor.googlesource.com/gvisor/pkg/sentry/usage" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" ) var ( @@ -42,6 +45,8 @@ var ( // These files are backed by pages allocated from a platform.Memory, and may be // directly mapped. // +// Lock order: attrMu -> mapsMu -> dataMu. +// // +stateify savable type fileInodeOperations struct { fsutil.InodeGenericChecker `state:"nosave"` @@ -74,6 +79,17 @@ type fileInodeOperations struct { // mappings is protected by mapsMu. mappings memmap.MappingSet + // writableMappingPages tracks how many pages of virtual memory are mapped + // as potentially writable from this file. If a page has multiple mappings, + // each mapping is counted separately. + // + // This counter is susceptible to overflow as we can potentially count + // mappings from many VMAs. We count pages rather than bytes to slightly + // mitigate this. + // + // Protected by mapsMu. + writableMappingPages uint64 + dataMu sync.RWMutex `state:"nosave"` // data maps offsets into the file to offsets into platform.Memory() that @@ -81,6 +97,11 @@ type fileInodeOperations struct { // // data is protected by dataMu. data fsutil.FileRangeSet + + // seals represents file seals on this inode. + // + // Protected by dataMu. + seals uint32 } var _ fs.InodeOperations = (*fileInodeOperations)(nil) @@ -91,9 +112,30 @@ func NewInMemoryFile(ctx context.Context, usage usage.MemoryKind, uattr fs.Unsta attr: uattr, kernel: kernel.KernelFromContext(ctx), memUsage: usage, + seals: linux.F_SEAL_SEAL, } } +// NewMemfdInode creates a new inode backing a memfd. Memory used by the memfd +// is backed by platform memory. +func NewMemfdInode(ctx context.Context, allowSeals bool) *fs.Inode { + // Per Linux, mm/shmem.c:__shmem_file_setup(), memfd inodes are set up with + // S_IRWXUGO. + perms := fs.PermMask{Read: true, Write: true, Execute: true} + iops := NewInMemoryFile(ctx, usage.Tmpfs, fs.UnstableAttr{ + Owner: fs.FileOwnerFromContext(ctx), + Perms: fs.FilePermissions{User: perms, Group: perms, Other: perms}}).(*fileInodeOperations) + if allowSeals { + iops.seals = 0 + } + return fs.NewInode(iops, fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{ + Type: fs.RegularFile, + DeviceID: tmpfsDevice.DeviceID(), + InodeID: tmpfsDevice.NextIno(), + BlockSize: usermem.PageSize, + }) +} + // Release implements fs.InodeOperations.Release. func (f *fileInodeOperations) Release(context.Context) { f.dataMu.Lock() @@ -170,6 +212,16 @@ func (f *fileInodeOperations) Truncate(ctx context.Context, _ *fs.Inode, size in f.dataMu.Lock() oldSize := f.attr.Size + + // Check if current seals allow truncation. + switch { + case size > oldSize && f.seals&linux.F_SEAL_GROW != 0: // Grow sealed + fallthrough + case oldSize > size && f.seals&linux.F_SEAL_SHRINK != 0: // Shrink sealed + f.dataMu.Unlock() + return syserror.EPERM + } + if oldSize != size { f.attr.Size = size // Update mtime and ctime. @@ -370,6 +422,34 @@ func (rw *fileReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, error) return 0, nil } + // Check if seals prevent either file growth or all writes. + switch { + case rw.f.seals&linux.F_SEAL_WRITE != 0: // Write sealed + return 0, syserror.EPERM + case end > rw.f.attr.Size && rw.f.seals&linux.F_SEAL_GROW != 0: // Grow sealed + // When growth is sealed, Linux effectively allows writes which would + // normally grow the file to partially succeed up to the current EOF, + // rounded down to the page boundary before the EOF. + // + // This happens because writes (and thus the growth check) for tmpfs + // files proceed page-by-page on Linux, and the final write to the page + // containing EOF fails, resulting in a partial write up to the start of + // that page. + // + // To emulate this behaviour, artifically truncate the write to the + // start of the page containing the current EOF. + // + // See Linux, mm/filemap.c:generic_perform_write() and + // mm/shmem.c:shmem_write_begin(). + if pgstart := int64(usermem.Addr(rw.f.attr.Size).RoundDown()); end > pgstart { + end = pgstart + } + if end <= rw.offset { + // Truncation would result in no data being written. + return 0, syserror.EPERM + } + } + defer func() { // If the write ends beyond the file's previous size, it causes the // file to grow. @@ -431,7 +511,27 @@ func (rw *fileReadWriter) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, error) func (f *fileInodeOperations) AddMapping(ctx context.Context, ms memmap.MappingSpace, ar usermem.AddrRange, offset uint64, writable bool) error { f.mapsMu.Lock() defer f.mapsMu.Unlock() + + f.dataMu.RLock() + defer f.dataMu.RUnlock() + + // Reject writable mapping if F_SEAL_WRITE is set. + if f.seals&linux.F_SEAL_WRITE != 0 && writable { + return syserror.EPERM + } + f.mappings.AddMapping(ms, ar, offset, writable) + if writable { + pagesBefore := f.writableMappingPages + + // ar is guaranteed to be page aligned per memmap.Mappable. + f.writableMappingPages += uint64(ar.Length() / usermem.PageSize) + + if f.writableMappingPages < pagesBefore { + panic(fmt.Sprintf("Overflow while mapping potentially writable pages pointing to a tmpfs file. Before %v, after %v", pagesBefore, f.writableMappingPages)) + } + } + return nil } @@ -439,7 +539,19 @@ func (f *fileInodeOperations) AddMapping(ctx context.Context, ms memmap.MappingS func (f *fileInodeOperations) RemoveMapping(ctx context.Context, ms memmap.MappingSpace, ar usermem.AddrRange, offset uint64, writable bool) { f.mapsMu.Lock() defer f.mapsMu.Unlock() + f.mappings.RemoveMapping(ms, ar, offset, writable) + + if writable { + pagesBefore := f.writableMappingPages + + // ar is guaranteed to be page aligned per memmap.Mappable. + f.writableMappingPages -= uint64(ar.Length() / usermem.PageSize) + + if f.writableMappingPages > pagesBefore { + panic(fmt.Sprintf("Underflow while unmapping potentially writable pages pointing to a tmpfs file. Before %v, after %v", pagesBefore, f.writableMappingPages)) + } + } } // CopyMapping implements memmap.Mappable.CopyMapping. @@ -501,3 +613,42 @@ func (f *fileInodeOperations) Translate(ctx context.Context, required, optional func (f *fileInodeOperations) InvalidateUnsavable(ctx context.Context) error { return nil } + +// GetSeals returns the current set of seals on a memfd inode. +func GetSeals(inode *fs.Inode) (uint32, error) { + if f, ok := inode.InodeOperations.(*fileInodeOperations); ok { + f.dataMu.RLock() + defer f.dataMu.RUnlock() + return f.seals, nil + } + // Not a memfd inode. + return 0, syserror.EINVAL +} + +// AddSeals adds new file seals to a memfd inode. +func AddSeals(inode *fs.Inode, val uint32) error { + if f, ok := inode.InodeOperations.(*fileInodeOperations); ok { + f.mapsMu.Lock() + defer f.mapsMu.Unlock() + f.dataMu.Lock() + defer f.dataMu.Unlock() + + if f.seals&linux.F_SEAL_SEAL != 0 { + // Seal applied which prevents addition of any new seals. + return syserror.EPERM + } + + // F_SEAL_WRITE can only be added if there are no active writable maps. + if f.seals&linux.F_SEAL_WRITE == 0 && val&linux.F_SEAL_WRITE != 0 { + if f.writableMappingPages > 0 { + return syserror.EBUSY + } + } + + // Seals can only be added, never removed. + f.seals |= val + return nil + } + // Not a memfd inode. + return syserror.EINVAL +} diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 846601881..6e2843b36 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -63,6 +63,7 @@ go_library( "//pkg/sentry/fs/anon", "//pkg/sentry/fs/lock", "//pkg/sentry/fs/timerfd", + "//pkg/sentry/fs/tmpfs", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/epoll", diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index e855590e6..888b5aa9f 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -367,7 +367,7 @@ var AMD64 = &kernel.SyscallTable{ // 316: Renameat2, TODO 317: Seccomp, 318: GetRandom, - // 319: MemfdCreate, TODO + 319: MemfdCreate, 320: syscalls.CapError(linux.CAP_SYS_BOOT), // KexecFileLoad, infeasible to support 321: syscalls.CapError(linux.CAP_SYS_ADMIN), // Bpf, requires cap_sys_admin for all commands // 322: Execveat, TODO diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index cf6fdc190..3193718b5 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -23,6 +23,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/lock" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/tmpfs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/fasync" @@ -933,6 +934,15 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall case linux.F_SETOWN: fSetOwn(t, file, args[2].Int()) return 0, nil, nil + case linux.F_GET_SEALS: + val, err := tmpfs.GetSeals(file.Dirent.Inode) + return uintptr(val), nil, err + case linux.F_ADD_SEALS: + if !file.Flags().Write { + return 0, nil, syserror.EPERM + } + err := tmpfs.AddSeals(file.Dirent.Inode, args[2].Uint()) + return 0, nil, err default: // Everything else is not yet supported. return 0, nil, syserror.EINVAL @@ -2066,3 +2076,52 @@ func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc // arbitrarily. return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "sendfile", inFile) } + +const ( + memfdPrefix = "/memfd:" + memfdAllFlags = uint32(linux.MFD_CLOEXEC | linux.MFD_ALLOW_SEALING) + memfdMaxNameLen = linux.NAME_MAX - len(memfdPrefix) + 1 +) + +// MemfdCreate implements the linux syscall memfd_create(2). +func MemfdCreate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + addr := args[0].Pointer() + flags := args[1].Uint() + + if flags&^memfdAllFlags != 0 { + // Unknown bits in flags. + return 0, nil, syserror.EINVAL + } + + allowSeals := flags&linux.MFD_ALLOW_SEALING != 0 + cloExec := flags&linux.MFD_CLOEXEC != 0 + + name, err := t.CopyInString(addr, syscall.PathMax-len(memfdPrefix)) + if err != nil { + return 0, nil, err + } + if len(name) > memfdMaxNameLen { + return 0, nil, syserror.EINVAL + } + name = memfdPrefix + name + + inode := tmpfs.NewMemfdInode(t, allowSeals) + dirent := fs.NewDirent(inode, name) + // Per Linux, mm/shmem.c:__shmem_file_setup(), memfd files are set up with + // FMODE_READ | FMODE_WRITE. + file, err := inode.GetFile(t, dirent, fs.FileFlags{Read: true, Write: true}) + if err != nil { + return 0, nil, err + } + + defer dirent.DecRef() + defer file.DecRef() + + fdFlags := kernel.FDFlags{CloseOnExec: cloExec} + newFD, err := t.FDMap().NewFDFrom(0, file, fdFlags, t.ThreadGroup().Limits()) + if err != nil { + return 0, nil, err + } + + return uintptr(newFD), nil, nil +} diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 2c214925e..7dd63dd0a 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -3261,3 +3261,20 @@ cc_binary( "@com_google_googletest//:gtest", ], ) + +cc_binary( + name = "memfd_test", + testonly = 1, + srcs = ["memfd.cc"], + linkstatic = 1, + deps = [ + "//test/util:file_descriptor", + "//test/util:fs_util", + "//test/util:memory_util", + "//test/util:multiprocess_util", + "//test/util:temp_path", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], +) diff --git a/test/syscalls/linux/memfd.cc b/test/syscalls/linux/memfd.cc new file mode 100644 index 000000000..ccdddd4e5 --- /dev/null +++ b/test/syscalls/linux/memfd.cc @@ -0,0 +1,546 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gtest/gtest.h" +#include "test/util/file_descriptor.h" +#include "test/util/fs_util.h" +#include "test/util/memory_util.h" +#include "test/util/multiprocess_util.h" +#include "test/util/temp_path.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { +namespace { + +// The header sys/memfd.h isn't available on all systems, so redefining some of +// the constants here. +#define F_LINUX_SPECIFIC_BASE 1024 +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) +#define F_SEAL_SEAL 0x0001 +#define F_SEAL_SHRINK 0x0002 +#define F_SEAL_GROW 0x0004 +#define F_SEAL_WRITE 0x0008 + +using ::testing::StartsWith; + +const std::string kMemfdName = "some-memfd"; + +int memfd_create(const std::string& name, unsigned int flags) { + return syscall(__NR_memfd_create, name.c_str(), flags); +} + +PosixErrorOr MemfdCreate(const std::string& name, uint32_t flags) { + int fd = memfd_create(name, flags); + if (fd < 0) { + return PosixError( + errno, absl::StrFormat("memfd_create(\"%s\", %#x)", name, flags)); + } + MaybeSave(); + return FileDescriptor(fd); +} + +// Procfs entries for memfds display the appropriate name. +TEST(MemfdTest, Name) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, 0)); + const std::string proc_name = ASSERT_NO_ERRNO_AND_VALUE( + ReadLink(absl::StrFormat("/proc/self/fd/%d", memfd.get()))); + EXPECT_THAT(proc_name, StartsWith("/memfd:" + kMemfdName)); +} + +// Memfds support read/write syscalls. +TEST(MemfdTest, WriteRead) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, 0)); + + // Write a random page of data to the memfd via write(2). + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Read back the same data and verify. + std::vector buf2(kPageSize); + ASSERT_THAT(lseek(memfd.get(), 0, SEEK_SET), SyscallSucceeds()); + EXPECT_THAT(read(memfd.get(), buf2.data(), buf2.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(buf, buf2); +} + +// Memfds can be mapped and used as usual. +TEST(MemfdTest, Mmap) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, 0)); + const Mapping m1 = ASSERT_NO_ERRNO_AND_VALUE(Mmap( + nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, memfd.get(), 0)); + + // Write a random page of data to the memfd via mmap m1. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + memcpy(m1.ptr(), buf.data(), buf.size()); + + // Read the data back via a read syscall on the memfd. + std::vector buf2(kPageSize); + EXPECT_THAT(read(memfd.get(), buf2.data(), buf2.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(buf, buf2); + + // The same data should be accessible via a new mapping m2. + const Mapping m2 = ASSERT_NO_ERRNO_AND_VALUE(Mmap( + nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, memfd.get(), 0)); + EXPECT_EQ(0, memcmp(m1.ptr(), m2.ptr(), kPageSize)); +} + +TEST(MemfdTest, DuplicateFDsShareContent) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, 0)); + const Mapping m1 = ASSERT_NO_ERRNO_AND_VALUE(Mmap( + nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, memfd.get(), 0)); + const FileDescriptor memfd2 = ASSERT_NO_ERRNO_AND_VALUE(memfd.Dup()); + + // Write a random page of data to the memfd via mmap m1. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + memcpy(m1.ptr(), buf.data(), buf.size()); + + // Read the data back via a read syscall on a duplicate fd. + std::vector buf2(kPageSize); + EXPECT_THAT(read(memfd2.get(), buf2.data(), buf2.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(buf, buf2); +} + +// File seals are disabled by default on memfds. +TEST(MemfdTest, SealingDisabledByDefault) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, 0)); + EXPECT_THAT(fcntl(memfd.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_SEAL)); + // Attempting to set any seal should fail. + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), + SyscallFailsWithErrno(EPERM)); +} + +// Seals can be retrieved and updated for memfds. +TEST(MemfdTest, SealsGetSet) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + int seals; + ASSERT_THAT(seals = fcntl(memfd.get(), F_GET_SEALS), SyscallSucceeds()); + // No seals are set yet. + EXPECT_EQ(0, seals); + + // Set a seal and check that we can get it back. + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), SyscallSucceeds()); + EXPECT_THAT(fcntl(memfd.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_WRITE)); + + // Set some more seals and verify. + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK), + SyscallSucceeds()); + EXPECT_THAT( + fcntl(memfd.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_WRITE | F_SEAL_GROW | F_SEAL_SHRINK)); + + // Attempting to set a seal that is already set is a no-op. + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), SyscallSucceeds()); + EXPECT_THAT( + fcntl(memfd.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_WRITE | F_SEAL_GROW | F_SEAL_SHRINK)); + + // Add remaining seals and verify. + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_SEAL), SyscallSucceeds()); + EXPECT_THAT(fcntl(memfd.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_WRITE | F_SEAL_GROW | + F_SEAL_SHRINK | F_SEAL_SEAL)); +} + +// F_SEAL_GROW prevents a memfd from being grown using ftruncate. +TEST(MemfdTest, SealGrowWithTruncate) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_GROW), SyscallSucceeds()); + + // Try grow the memfd by 1 page. + ASSERT_THAT(ftruncate(memfd.get(), kPageSize * 2), + SyscallFailsWithErrno(EPERM)); + + // Ftruncate calls that don't actually grow the memfd are allowed. + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize / 2), SyscallSucceeds()); + + // After shrinking, growing back is not allowed. + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallFailsWithErrno(EPERM)); +} + +// F_SEAL_GROW prevents a memfd from being grown using the write syscall. +TEST(MemfdTest, SealGrowWithWrite) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + + // Initially, writing to the memfd succeeds. + const std::vector buf(kPageSize); + EXPECT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Apply F_SEAL_GROW, subsequent writes which extend the memfd should fail. + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_GROW), SyscallSucceeds()); + EXPECT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallFailsWithErrno(EPERM)); + + // However, zero-length writes are ok since they don't grow the memfd. + EXPECT_THAT(write(memfd.get(), buf.data(), 0), SyscallSucceeds()); + + // Writing to existing parts of the memfd is also ok. + ASSERT_THAT(lseek(memfd.get(), 0, SEEK_SET), SyscallSucceeds()); + EXPECT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Returning the end of the file and writing still not allowed. + EXPECT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallFailsWithErrno(EPERM)); +} + +// F_SEAL_GROW causes writes which partially extend off the current EOF to +// partially succeed, up to the page containing the EOF. +TEST(MemfdTest, SealGrowPartialWriteTruncated) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_GROW), SyscallSucceeds()); + + // FD offset: 1 page, EOF: 1 page. + + ASSERT_THAT(lseek(memfd.get(), kPageSize * 3 / 4, SEEK_SET), + SyscallSucceeds()); + + // FD offset: 3/4 page. Writing a full page now should only write 1/4 page + // worth of data. This partially succeeds because the first page is entirely + // within the file and requires no growth, but attempting to write the final + // 3/4 page would require growing the file. + const std::vector buf(kPageSize); + EXPECT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize / 4)); +} + +// F_SEAL_GROW causes writes which partially extend off the current EOF to fail +// in its entirety if the only data written would be to the page containing the +// EOF. +TEST(MemfdTest, SealGrowPartialWriteTruncatedSamePage) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize * 3 / 4), SyscallSucceeds()); + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_GROW), SyscallSucceeds()); + + // EOF: 3/4 page, writing 1/2 page starting at 1/2 page would cause the file + // to grow. Since this would require only the page containing the EOF to be + // modified, the write is rejected entirely. + const std::vector buf(kPageSize / 2); + EXPECT_THAT(pwrite(memfd.get(), buf.data(), buf.size(), kPageSize / 2), + SyscallFailsWithErrno(EPERM)); + + // However, writing up to EOF is fine. + EXPECT_THAT(pwrite(memfd.get(), buf.data(), buf.size() / 2, kPageSize / 2), + SyscallSucceedsWithValue(kPageSize / 4)); +} + +// F_SEAL_SHRINK prevents a memfd from being shrunk using ftruncate. +TEST(MemfdTest, SealShrink) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_SHRINK), + SyscallSucceeds()); + + // Shrink by half a page. + ASSERT_THAT(ftruncate(memfd.get(), kPageSize / 2), + SyscallFailsWithErrno(EPERM)); + + // Ftruncate calls that don't actually shrink the file are allowed. + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallSucceeds()); + ASSERT_THAT(ftruncate(memfd.get(), kPageSize * 2), SyscallSucceeds()); + + // After growing, shrinking is still not allowed. + ASSERT_THAT(ftruncate(memfd.get(), kPageSize), SyscallFailsWithErrno(EPERM)); +} + +// F_SEAL_WRITE prevents a memfd from being written to through a write +// syscall. +TEST(MemfdTest, SealWriteWithWrite) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + const std::vector buf(kPageSize); + ASSERT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), SyscallSucceeds()); + + // Attemping to write at the end of the file fails. + EXPECT_THAT(write(memfd.get(), buf.data(), 1), SyscallFailsWithErrno(EPERM)); + + // Attemping to overwrite an existing part of the memfd fails. + EXPECT_THAT(pwrite(memfd.get(), buf.data(), 1, 0), + SyscallFailsWithErrno(EPERM)); + EXPECT_THAT(pwrite(memfd.get(), buf.data(), buf.size() / 2, kPageSize / 2), + SyscallFailsWithErrno(EPERM)); + EXPECT_THAT(pwrite(memfd.get(), buf.data(), buf.size(), kPageSize / 2), + SyscallFailsWithErrno(EPERM)); + + // Zero-length writes however do not fail. + EXPECT_THAT(write(memfd.get(), buf.data(), 0), SyscallSucceeds()); +} + +// F_SEAL_WRITE prevents a memfd from being written to through an mmap. +TEST(MemfdTest, SealWriteWithMmap) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + const std::vector buf(kPageSize); + ASSERT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), SyscallSucceeds()); + + // Can't create a shared mapping with writes sealed. + void* ret = mmap(nullptr, kPageSize, PROT_WRITE, MAP_SHARED, memfd.get(), 0); + EXPECT_EQ(ret, MAP_FAILED); + EXPECT_EQ(errno, EPERM); + ret = mmap(nullptr, kPageSize, PROT_READ, MAP_SHARED, memfd.get(), 0); + EXPECT_EQ(ret, MAP_FAILED); + EXPECT_EQ(errno, EPERM); + + // However, private mappings are ok. + EXPECT_NO_ERRNO(Mmap(nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, + memfd.get(), 0)); +} + +// Adding F_SEAL_WRITE fails when there are outstanding writable mappings to a +// memfd. +TEST(MemfdTest, SealWriteWithOutstandingWritbleMapping) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + const std::vector buf(kPageSize); + ASSERT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Attempting to add F_SEAL_WRITE with active shared mapping with any set of + // permissions fails. + + // Read-only shared mapping. + { + const Mapping m = ASSERT_NO_ERRNO_AND_VALUE( + Mmap(nullptr, kPageSize, PROT_READ, MAP_SHARED, memfd.get(), 0)); + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), + SyscallFailsWithErrno(EBUSY)); + } + + // Write-only shared mapping. + { + const Mapping m = ASSERT_NO_ERRNO_AND_VALUE( + Mmap(nullptr, kPageSize, PROT_WRITE, MAP_SHARED, memfd.get(), 0)); + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), + SyscallFailsWithErrno(EBUSY)); + } + + // Read-write shared mapping. + { + const Mapping m = ASSERT_NO_ERRNO_AND_VALUE( + Mmap(nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, + memfd.get(), 0)); + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), + SyscallFailsWithErrno(EBUSY)); + } + + // F_SEAL_WRITE can be set with private mappings with any permissions. + { + const Mapping m = ASSERT_NO_ERRNO_AND_VALUE( + Mmap(nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, + memfd.get(), 0)); + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), + SyscallSucceeds()); + } +} + +// When applying F_SEAL_WRITE fails due to outstanding writable mappings, any +// additional seals passed to the same add seal call are also rejected. +TEST(MemfdTest, NoPartialSealApplicationWhenWriteSealRejected) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + const Mapping m = ASSERT_NO_ERRNO_AND_VALUE(Mmap( + nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, memfd.get(), 0)); + + // Try add some seals along with F_SEAL_WRITE. The seal application should + // fail since there exists an active shared mapping. + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE | F_SEAL_GROW), + SyscallFailsWithErrno(EBUSY)); + + // None of the seals should be applied. + EXPECT_THAT(fcntl(memfd.get(), F_GET_SEALS), SyscallSucceedsWithValue(0)); +} + +// Seals are inode level properties, and apply to all file descriptors referring +// to a memfd. +TEST(MemfdTest, SealsAreInodeLevelProperties) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + const FileDescriptor memfd2 = ASSERT_NO_ERRNO_AND_VALUE(memfd.Dup()); + + // Add seal through the original memfd, and verify that it appears on the + // dupped fd. + ASSERT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), SyscallSucceeds()); + EXPECT_THAT(fcntl(memfd2.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_WRITE)); + + // Verify the seal actually applies to both fds. + std::vector buf(kPageSize); + EXPECT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallFailsWithErrno(EPERM)); + EXPECT_THAT(write(memfd2.get(), buf.data(), buf.size()), + SyscallFailsWithErrno(EPERM)); + + // Seals are enforced on new FDs that are dupped after the seal is already + // applied. + const FileDescriptor memfd3 = ASSERT_NO_ERRNO_AND_VALUE(memfd2.Dup()); + EXPECT_THAT(write(memfd3.get(), buf.data(), buf.size()), + SyscallFailsWithErrno(EPERM)); + + // Try a new seal applied to one of the dupped fds. + ASSERT_THAT(fcntl(memfd3.get(), F_ADD_SEALS, F_SEAL_GROW), SyscallSucceeds()); + EXPECT_THAT(ftruncate(memfd.get(), kPageSize), SyscallFailsWithErrno(EPERM)); + EXPECT_THAT(ftruncate(memfd2.get(), kPageSize), SyscallFailsWithErrno(EPERM)); + EXPECT_THAT(ftruncate(memfd3.get(), kPageSize), SyscallFailsWithErrno(EPERM)); +} + +PosixErrorOr IsTmpfs(const std::string& path) { + struct statfs stat; + if (statfs(path.c_str(), &stat)) { + if (errno == ENOENT) { + // Nothing at path, don't raise this as an error. Instead, just report no + // tmpfs at path. + return false; + } + return PosixError(errno, + absl::StrFormat("statfs(\"%s\", %#p)", path, &stat)); + } + return stat.f_type == TMPFS_MAGIC; +} + +// Tmpfs files also support seals, but are created with F_SEAL_SEAL. +TEST(MemfdTest, TmpfsFilesHaveSealSeal) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(IsTmpfs("/tmp"))); + const TempPath tmpfs_file = + ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileIn("/tmp")); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(tmpfs_file.path(), O_RDWR, 0644)); + EXPECT_THAT(fcntl(fd.get(), F_GET_SEALS), + SyscallSucceedsWithValue(F_SEAL_SEAL)); +} + +// Can open a memfd from procfs and use as normal. +TEST(MemfdTest, CanOpenFromProcfs) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + + // Write a random page of data to the memfd via write(2). + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Read back the same data from the fd obtained from procfs and verify. + const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE( + Open(absl::StrFormat("/proc/self/fd/%d", memfd.get()), O_RDWR)); + std::vector buf2(kPageSize); + EXPECT_THAT(pread(fd.get(), buf2.data(), buf2.size(), 0), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(buf, buf2); +} + +// Test that memfd permissions are set up correctly to allow another process to +// open it from procfs. +TEST(MemfdTest, OtherProcessCanOpenFromProcfs) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + pid_t pid = getpid(); + const auto rest = [&] { + ASSERT_NO_ERRNO( + Open(absl::StrFormat("/proc/self/%d/%d", pid, memfd.get()), O_RDWR)); + }; + EXPECT_THAT(InForkedProcess(rest), IsPosixErrorOkAndHolds(0)); +} + +// Test that only files opened as writable can have seals applied to them. +// Normally there's no way to specify file permissions on memfds, but we can +// obtain a read-only memfd by opening the corresponding procfs fd entry as +// read-only. +TEST(MemfdTest, MemfdMustBeWritableToModifySeals) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, MFD_ALLOW_SEALING)); + + // Initially adding a seal works. + EXPECT_THAT(fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_WRITE), SyscallSucceeds()); + + // Re-open the memfd as read-only from procfs. + const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE( + Open(absl::StrFormat("/proc/self/fd/%d", memfd.get()), O_RDONLY)); + + // Can't add seals through an unwritable fd. + EXPECT_THAT(fcntl(fd.get(), F_ADD_SEALS, F_SEAL_GROW), + SyscallFailsWithErrno(EPERM)); +} + +// Test that the memfd implementation internally tracks potentially writable +// maps correctly. +TEST(MemfdTest, MultipleWritableAndNonWritableRefsToSameFileRegion) { + const FileDescriptor memfd = + ASSERT_NO_ERRNO_AND_VALUE(MemfdCreate(kMemfdName, 0)); + + // Populate with a random page of data. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(memfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Read-only map to the page. This should cause an initial mapping to be + // created. + Mapping m1 = ASSERT_NO_ERRNO_AND_VALUE( + Mmap(nullptr, kPageSize, PROT_READ, MAP_PRIVATE, memfd.get(), 0)); + + // Create a shared writable map to the page. This should cause the internal + // mapping to become potentially writable. + Mapping m2 = ASSERT_NO_ERRNO_AND_VALUE(Mmap( + nullptr, kPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, memfd.get(), 0)); + + // Drop the read-only mapping first. If writable-ness isn't tracked correctly, + // this can cause some misaccounting, which can trigger asserts internally. + m1.reset(); + m2.reset(); +} + +} // namespace +} // namespace testing +} // namespace gvisor -- cgit v1.2.3 From 82529becaee6f5050cb3ebb4aaa7a798357c1cf1 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Wed, 3 Apr 2019 12:59:27 -0700 Subject: Fix index out of bounds in tty implementation. The previous implementation revolved around runes instead of bytes, which caused weird behavior when converting between the two. For example, peekRune would read the byte 0xff from a buffer, convert it to a rune, then return it. As rune is an alias of int32, 0xff was 0-padded to int32(255), which is the hex code point for ?. However, peekRune also returned the length of the byte (1). When calling utf8.EncodeRune, we only allocated 1 byte, but tried the write the 2-byte character ?. tl;dr: I apparently didn't understand runes when I wrote this. PiperOrigin-RevId: 241789081 Change-Id: I14c788af4d9754973137801500ef6af7ab8a8727 --- pkg/abi/linux/tty.go | 20 +++++++------ pkg/sentry/fs/tty/line_discipline.go | 55 ++++++++++++++++-------------------- test/syscalls/linux/pty.cc | 6 ++++ 3 files changed, 42 insertions(+), 39 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index e6f7c5b2a..bff882d89 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -14,10 +14,6 @@ package linux -import ( - "unicode/utf8" -) - const ( // NumControlCharacters is the number of control characters in Termios. NumControlCharacters = 19 @@ -104,11 +100,19 @@ func (t *KernelTermios) FromTermios(term Termios) { } // IsTerminating returns whether c is a line terminating character. -func (t *KernelTermios) IsTerminating(c rune) bool { +func (t *KernelTermios) IsTerminating(cBytes []byte) bool { + // All terminating characters are 1 byte. + if len(cBytes) != 1 { + return false + } + c := cBytes[0] + + // Is this the user-set EOF character? if t.IsEOF(c) { return true } - switch byte(c) { + + switch c { case disabledChar: return false case '\n', t.ControlCharacters[VEOL]: @@ -120,8 +124,8 @@ func (t *KernelTermios) IsTerminating(c rune) bool { } // IsEOF returns whether c is the EOF character. -func (t *KernelTermios) IsEOF(c rune) bool { - return utf8.RuneLen(c) == 1 && byte(c) == t.ControlCharacters[VEOF] && t.ControlCharacters[VEOF] != disabledChar +func (t *KernelTermios) IsEOF(c byte) bool { + return c == t.ControlCharacters[VEOF] && t.ControlCharacters[VEOF] != disabledChar } // Input flags. diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index 31b6344f2..c4a364edb 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -280,10 +280,12 @@ func (*outputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte var ret int for len(buf) > 0 { - c, size := l.peekRune(buf) + size := l.peek(buf) + cBytes := append([]byte{}, buf[:size]...) ret += size buf = buf[size:] - switch c { + // We're guaranteed that cBytes has at least one element. + switch cBytes[0] { case '\n': if l.termios.OEnabled(linux.ONLRET) { l.column = 0 @@ -297,7 +299,7 @@ func (*outputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte continue } if l.termios.OEnabled(linux.OCRNL) { - c = '\n' + cBytes[0] = '\n' if l.termios.OEnabled(linux.ONLRET) { l.column = 0 } @@ -319,10 +321,7 @@ func (*outputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte default: l.column++ } - // The compiler optimizes this by growing readBuf without - // creating the intermediate slice. - q.readBuf = append(q.readBuf, make([]byte, size)...) - utf8.EncodeRune(q.readBuf[len(q.readBuf)-size:], c) + q.readBuf = append(q.readBuf, cBytes...) } if len(q.readBuf) > 0 { q.readable = true @@ -358,8 +357,10 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) var ret int for len(buf) > 0 && len(q.readBuf) < canonMaxBytes { - c, size := l.peekRune(buf) - switch c { + size := l.peek(buf) + cBytes := append([]byte{}, buf[:size]...) + // We're guaranteed that cBytes has at least one element. + switch cBytes[0] { case '\r': if l.termios.IEnabled(linux.IGNCR) { buf = buf[size:] @@ -367,17 +368,17 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) continue } if l.termios.IEnabled(linux.ICRNL) { - c = '\n' + cBytes[0] = '\n' } case '\n': if l.termios.IEnabled(linux.INLCR) { - c = '\r' + cBytes[0] = '\r' } } // In canonical mode, we discard non-terminating characters // after the first 4095. - if l.shouldDiscard(q, c) { + if l.shouldDiscard(q, cBytes) { buf = buf[size:] ret += size continue @@ -387,20 +388,16 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) if len(q.readBuf)+size > maxBytes { break } - cBytes := buf[:size] buf = buf[size:] ret += size // If we get EOF, make the buffer available for reading. - if l.termios.LEnabled(linux.ICANON) && l.termios.IsEOF(c) { + if l.termios.LEnabled(linux.ICANON) && l.termios.IsEOF(cBytes[0]) { q.readable = true break } - // The compiler optimizes this by growing readBuf without - // creating the intermediate slice. - q.readBuf = append(q.readBuf, make([]byte, size)...) - utf8.EncodeRune(q.readBuf[len(q.readBuf)-size:], c) + q.readBuf = append(q.readBuf, cBytes...) // Anything written to the readBuf will have to be echoed. if l.termios.LEnabled(linux.ECHO) { @@ -409,7 +406,7 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) } // If we finish a line, make it available for reading. - if l.termios.LEnabled(linux.ICANON) && l.termios.IsTerminating(c) { + if l.termios.LEnabled(linux.ICANON) && l.termios.IsTerminating(cBytes) { q.readable = true break } @@ -430,21 +427,17 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) // Precondition: // * l.termiosMu must be held for reading. // * q.mu must be held. -func (l *lineDiscipline) shouldDiscard(q *queue, c rune) bool { - return l.termios.LEnabled(linux.ICANON) && len(q.readBuf)+utf8.RuneLen(c) >= canonMaxBytes && !l.termios.IsTerminating(c) +func (l *lineDiscipline) shouldDiscard(q *queue, cBytes []byte) bool { + return l.termios.LEnabled(linux.ICANON) && len(q.readBuf)+len(cBytes) >= canonMaxBytes && !l.termios.IsTerminating(cBytes) } -// peekRune returns the first rune from the byte array depending on whether -// UTF8 is enabled. -func (l *lineDiscipline) peekRune(b []byte) (rune, int) { - var c rune - var size int +// peek returns the size in bytes of the next character to process. As long as +// b isn't empty, peek returns a value of at least 1. +func (l *lineDiscipline) peek(b []byte) int { + size := 1 // If UTF-8 support is enabled, runes might be multiple bytes. if l.termios.IEnabled(linux.IUTF8) { - c, size = utf8.DecodeRune(b) - } else { - c = rune(b[0]) - size = 1 + _, size = utf8.DecodeRune(b) } - return c, size + return size } diff --git a/test/syscalls/linux/pty.cc b/test/syscalls/linux/pty.cc index 253aa26ba..5b2dc9ccb 100644 --- a/test/syscalls/linux/pty.cc +++ b/test/syscalls/linux/pty.cc @@ -568,6 +568,12 @@ TEST_F(PtyTest, WriteSlaveToMaster) { EXPECT_EQ(memcmp(buf, kExpected, sizeof(kExpected)), 0); } +TEST_F(PtyTest, WriteInvalidUTF8) { + char c = 0xff; + ASSERT_THAT(syscall(__NR_write, master_.get(), &c, sizeof(c)), + SyscallSucceedsWithValue(sizeof(c))); +} + // Both the master and slave report the standard default termios settings. // // Note that TCGETS on the master actually redirects to the slave (see comment -- cgit v1.2.3 From 133700007a8495c7d8df53801b1d34345d6c5cf8 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 18 Apr 2019 11:50:26 -0700 Subject: Only emit unimplemented syscall events for unsupported values. Only emit unimplemented syscall events for setting SO_OOBINLINE and SO_LINGER when attempting to set unsupported values. PiperOrigin-RevId: 244229675 Change-Id: Icc4562af8f733dd75a90404621711f01a32a9fc1 --- pkg/abi/linux/socket.go | 13 +++++++++++-- pkg/sentry/socket/epsocket/epsocket.go | 31 +++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 906776525..6fa4e7c3e 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -247,6 +247,15 @@ type SockAddrUnix struct { Path [UnixPathMax]int8 } +// Linger is struct linger, from include/linux/socket.h. +type Linger struct { + OnOff int32 + Linger int32 +} + +// SizeOfLinger is the binary size of a Linger struct. +const SizeOfLinger = 8 + // TCPInfo is a collection of TCP statistics. // // From uapi/linux/tcp.h. @@ -322,8 +331,8 @@ type TCPInfo struct { SndBufLimited uint64 } -// SizeOfTCPInfo is the binary size of a TCPInfo struct (104 bytes). -var SizeOfTCPInfo = binary.Size(TCPInfo{}) +// SizeOfTCPInfo is the binary size of a TCPInfo struct. +const SizeOfTCPInfo = 104 // Control message types, from linux/socket.h. const ( diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 78f43178f..f370b803b 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -783,10 +783,10 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family return int32(v), nil case linux.SO_LINGER: - if outLen < syscall.SizeofLinger { + if outLen < linux.SizeOfLinger { return nil, syserr.ErrInvalidArgument } - return syscall.Linger{}, nil + return linux.Linger{}, nil case linux.SO_SNDTIMEO: // TODO: Linux allows shorter lengths for partial results. @@ -1126,6 +1126,33 @@ func setSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, name i s.SetRecvTimeout(v.ToNsecCapped()) return nil + case linux.SO_OOBINLINE: + if len(optVal) < sizeOfInt32 { + return syserr.ErrInvalidArgument + } + + v := usermem.ByteOrder.Uint32(optVal) + + if v == 0 { + socket.SetSockOptEmitUnimplementedEvent(t, name) + } + + return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.OutOfBandInlineOption(v))) + + case linux.SO_LINGER: + if len(optVal) < linux.SizeOfLinger { + return syserr.ErrInvalidArgument + } + + var v linux.Linger + binary.Unmarshal(optVal[:linux.SizeOfLinger], usermem.ByteOrder, &v) + + if v != (linux.Linger{}) { + socket.SetSockOptEmitUnimplementedEvent(t, name) + } + + return nil + default: socket.SetSockOptEmitUnimplementedEvent(t, name) } -- cgit v1.2.3 From 4d52a5520101a88424fb63dd99412a1db33fbd06 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 29 Apr 2019 14:25:05 -0700 Subject: Change copyright notice to "The gVisor Authors" Based on the guidelines at https://opensource.google.com/docs/releasing/authors/. 1. $ rg -l "Google LLC" | xargs sed -i 's/Google LLC.*/The gVisor Authors./' 2. Manual fixup of "Google Inc" references. 3. Add AUTHORS file. Authors may request to be added to this file. 4. Point netstack AUTHORS to gVisor AUTHORS. Drop CONTRIBUTORS. Fixes #209 PiperOrigin-RevId: 245823212 Change-Id: I64530b24ad021a7d683137459cafc510f5ee1de9 --- AUTHORS | 8 ++++++++ kokoro/run_build.sh | 2 +- kokoro/run_tests.sh | 2 +- pkg/abi/abi.go | 2 +- pkg/abi/abi_linux.go | 2 +- pkg/abi/flag.go | 2 +- pkg/abi/linux/aio.go | 2 +- pkg/abi/linux/ashmem.go | 2 +- pkg/abi/linux/audit.go | 2 +- pkg/abi/linux/binder.go | 2 +- pkg/abi/linux/bpf.go | 2 +- pkg/abi/linux/capability.go | 2 +- pkg/abi/linux/dev.go | 2 +- pkg/abi/linux/elf.go | 2 +- pkg/abi/linux/errors.go | 2 +- pkg/abi/linux/eventfd.go | 2 +- pkg/abi/linux/exec.go | 2 +- pkg/abi/linux/fcntl.go | 2 +- pkg/abi/linux/file.go | 2 +- pkg/abi/linux/fs.go | 2 +- pkg/abi/linux/futex.go | 2 +- pkg/abi/linux/inotify.go | 2 +- pkg/abi/linux/ioctl.go | 2 +- pkg/abi/linux/ip.go | 2 +- pkg/abi/linux/ipc.go | 2 +- pkg/abi/linux/limits.go | 2 +- pkg/abi/linux/linux.go | 2 +- pkg/abi/linux/mm.go | 2 +- pkg/abi/linux/netdevice.go | 2 +- pkg/abi/linux/netlink.go | 2 +- pkg/abi/linux/netlink_route.go | 2 +- pkg/abi/linux/poll.go | 2 +- pkg/abi/linux/prctl.go | 2 +- pkg/abi/linux/ptrace.go | 2 +- pkg/abi/linux/rusage.go | 2 +- pkg/abi/linux/sched.go | 2 +- pkg/abi/linux/seccomp.go | 2 +- pkg/abi/linux/sem.go | 2 +- pkg/abi/linux/shm.go | 2 +- pkg/abi/linux/signal.go | 2 +- pkg/abi/linux/socket.go | 2 +- pkg/abi/linux/tcp.go | 2 +- pkg/abi/linux/time.go | 2 +- pkg/abi/linux/timer.go | 2 +- pkg/abi/linux/tty.go | 2 +- pkg/abi/linux/uio.go | 2 +- pkg/abi/linux/utsname.go | 2 +- pkg/amutex/amutex.go | 2 +- pkg/amutex/amutex_test.go | 2 +- pkg/atomicbitops/atomic_bitops.go | 2 +- pkg/atomicbitops/atomic_bitops_amd64.s | 2 +- pkg/atomicbitops/atomic_bitops_common.go | 2 +- pkg/atomicbitops/atomic_bitops_test.go | 2 +- pkg/binary/binary.go | 2 +- pkg/binary/binary_test.go | 2 +- pkg/bits/bits.go | 2 +- pkg/bits/bits_template.go | 2 +- pkg/bits/uint64_arch_amd64.go | 2 +- pkg/bits/uint64_arch_amd64_asm.s | 2 +- pkg/bits/uint64_arch_generic.go | 2 +- pkg/bits/uint64_test.go | 2 +- pkg/bpf/bpf.go | 2 +- pkg/bpf/decoder.go | 2 +- pkg/bpf/decoder_test.go | 2 +- pkg/bpf/input_bytes.go | 2 +- pkg/bpf/interpreter.go | 2 +- pkg/bpf/interpreter_test.go | 2 +- pkg/bpf/program_builder.go | 2 +- pkg/bpf/program_builder_test.go | 2 +- pkg/compressio/compressio.go | 2 +- pkg/compressio/compressio_test.go | 2 +- pkg/control/client/client.go | 2 +- pkg/control/server/server.go | 2 +- pkg/cpuid/cpu_amd64.s | 2 +- pkg/cpuid/cpuid.go | 2 +- pkg/cpuid/cpuid_parse_test.go | 2 +- pkg/cpuid/cpuid_test.go | 2 +- pkg/dhcp/client.go | 2 +- pkg/dhcp/dhcp.go | 2 +- pkg/dhcp/dhcp_string.go | 2 +- pkg/dhcp/dhcp_test.go | 2 +- pkg/dhcp/server.go | 2 +- pkg/eventchannel/event.go | 2 +- pkg/eventchannel/event.proto | 2 +- pkg/fd/fd.go | 2 +- pkg/fd/fd_test.go | 2 +- pkg/fdnotifier/fdnotifier.go | 2 +- pkg/fdnotifier/poll_unsafe.go | 2 +- pkg/gate/gate.go | 2 +- pkg/gate/gate_test.go | 2 +- pkg/ilist/list.go | 2 +- pkg/ilist/list_test.go | 2 +- pkg/linewriter/linewriter.go | 2 +- pkg/linewriter/linewriter_test.go | 2 +- pkg/log/glog.go | 2 +- pkg/log/glog_unsafe.go | 2 +- pkg/log/json.go | 2 +- pkg/log/json_k8s.go | 2 +- pkg/log/json_test.go | 2 +- pkg/log/log.go | 2 +- pkg/log/log_test.go | 2 +- pkg/metric/metric.go | 2 +- pkg/metric/metric.proto | 2 +- pkg/metric/metric_test.go | 2 +- pkg/p9/buffer.go | 2 +- pkg/p9/buffer_test.go | 2 +- pkg/p9/client.go | 2 +- pkg/p9/client_file.go | 2 +- pkg/p9/client_test.go | 2 +- pkg/p9/file.go | 2 +- pkg/p9/handlers.go | 2 +- pkg/p9/local_server/local_server.go | 2 +- pkg/p9/messages.go | 2 +- pkg/p9/messages_test.go | 2 +- pkg/p9/p9.go | 2 +- pkg/p9/p9_test.go | 2 +- pkg/p9/p9test/client_test.go | 2 +- pkg/p9/p9test/p9test.go | 2 +- pkg/p9/path_tree.go | 2 +- pkg/p9/pool.go | 2 +- pkg/p9/pool_test.go | 2 +- pkg/p9/server.go | 2 +- pkg/p9/transport.go | 2 +- pkg/p9/transport_test.go | 2 +- pkg/p9/version.go | 2 +- pkg/p9/version_test.go | 2 +- pkg/rand/rand.go | 2 +- pkg/rand/rand_linux.go | 2 +- pkg/refs/refcounter.go | 2 +- pkg/refs/refcounter_state.go | 2 +- pkg/refs/refcounter_test.go | 2 +- pkg/seccomp/seccomp.go | 2 +- pkg/seccomp/seccomp_rules.go | 2 +- pkg/seccomp/seccomp_test.go | 2 +- pkg/seccomp/seccomp_test_victim.go | 2 +- pkg/seccomp/seccomp_unsafe.go | 2 +- pkg/secio/full_reader.go | 2 +- pkg/secio/secio.go | 2 +- pkg/secio/secio_test.go | 2 +- pkg/segment/range.go | 2 +- pkg/segment/set.go | 2 +- pkg/segment/set_state.go | 2 +- pkg/segment/test/segment_test.go | 2 +- pkg/segment/test/set_functions.go | 2 +- pkg/sentry/arch/aligned.go | 2 +- pkg/sentry/arch/arch.go | 2 +- pkg/sentry/arch/arch_amd64.go | 2 +- pkg/sentry/arch/arch_amd64.s | 2 +- pkg/sentry/arch/arch_state_x86.go | 2 +- pkg/sentry/arch/arch_x86.go | 2 +- pkg/sentry/arch/auxv.go | 2 +- pkg/sentry/arch/registers.proto | 2 +- pkg/sentry/arch/signal_act.go | 2 +- pkg/sentry/arch/signal_amd64.go | 2 +- pkg/sentry/arch/signal_info.go | 2 +- pkg/sentry/arch/signal_stack.go | 2 +- pkg/sentry/arch/stack.go | 2 +- pkg/sentry/arch/syscalls_amd64.go | 2 +- pkg/sentry/context/context.go | 2 +- pkg/sentry/context/contexttest/contexttest.go | 2 +- pkg/sentry/control/control.go | 2 +- pkg/sentry/control/pprof.go | 2 +- pkg/sentry/control/proc.go | 2 +- pkg/sentry/control/proc_test.go | 2 +- pkg/sentry/control/state.go | 2 +- pkg/sentry/device/device.go | 2 +- pkg/sentry/device/device_test.go | 2 +- pkg/sentry/fs/anon/anon.go | 2 +- pkg/sentry/fs/anon/device.go | 2 +- pkg/sentry/fs/ashmem/area.go | 2 +- pkg/sentry/fs/ashmem/device.go | 2 +- pkg/sentry/fs/ashmem/pin_board.go | 2 +- pkg/sentry/fs/ashmem/pin_board_test.go | 2 +- pkg/sentry/fs/attr.go | 2 +- pkg/sentry/fs/binder/binder.go | 2 +- pkg/sentry/fs/context.go | 2 +- pkg/sentry/fs/copy_up.go | 2 +- pkg/sentry/fs/copy_up_test.go | 2 +- pkg/sentry/fs/dentry.go | 2 +- pkg/sentry/fs/dev/dev.go | 2 +- pkg/sentry/fs/dev/device.go | 2 +- pkg/sentry/fs/dev/fs.go | 2 +- pkg/sentry/fs/dev/full.go | 2 +- pkg/sentry/fs/dev/null.go | 2 +- pkg/sentry/fs/dev/random.go | 2 +- pkg/sentry/fs/dirent.go | 2 +- pkg/sentry/fs/dirent_cache.go | 2 +- pkg/sentry/fs/dirent_cache_limiter.go | 2 +- pkg/sentry/fs/dirent_cache_test.go | 2 +- pkg/sentry/fs/dirent_refs_test.go | 2 +- pkg/sentry/fs/dirent_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener.go | 2 +- pkg/sentry/fs/fdpipe/pipe_opener_test.go | 2 +- pkg/sentry/fs/fdpipe/pipe_state.go | 2 +- pkg/sentry/fs/fdpipe/pipe_test.go | 2 +- pkg/sentry/fs/file.go | 2 +- pkg/sentry/fs/file_operations.go | 2 +- pkg/sentry/fs/file_overlay.go | 2 +- pkg/sentry/fs/file_overlay_test.go | 2 +- pkg/sentry/fs/file_state.go | 2 +- pkg/sentry/fs/file_test.go | 2 +- pkg/sentry/fs/filesystems.go | 2 +- pkg/sentry/fs/filetest/filetest.go | 2 +- pkg/sentry/fs/flags.go | 2 +- pkg/sentry/fs/fs.go | 2 +- pkg/sentry/fs/fsutil/dirty_set.go | 2 +- pkg/sentry/fs/fsutil/dirty_set_test.go | 2 +- pkg/sentry/fs/fsutil/file.go | 2 +- pkg/sentry/fs/fsutil/file_range_set.go | 2 +- pkg/sentry/fs/fsutil/frame_ref_set.go | 2 +- pkg/sentry/fs/fsutil/fsutil.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_state.go | 2 +- pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go | 2 +- pkg/sentry/fs/fsutil/host_mappable.go | 2 +- pkg/sentry/fs/fsutil/inode.go | 2 +- pkg/sentry/fs/fsutil/inode_cached.go | 2 +- pkg/sentry/fs/fsutil/inode_cached_test.go | 2 +- pkg/sentry/fs/gofer/attr.go | 2 +- pkg/sentry/fs/gofer/cache_policy.go | 2 +- pkg/sentry/fs/gofer/context_file.go | 2 +- pkg/sentry/fs/gofer/device.go | 2 +- pkg/sentry/fs/gofer/file.go | 2 +- pkg/sentry/fs/gofer/file_state.go | 2 +- pkg/sentry/fs/gofer/fs.go | 2 +- pkg/sentry/fs/gofer/gofer_test.go | 2 +- pkg/sentry/fs/gofer/handles.go | 2 +- pkg/sentry/fs/gofer/inode.go | 2 +- pkg/sentry/fs/gofer/inode_state.go | 2 +- pkg/sentry/fs/gofer/path.go | 2 +- pkg/sentry/fs/gofer/session.go | 2 +- pkg/sentry/fs/gofer/session_state.go | 2 +- pkg/sentry/fs/gofer/socket.go | 2 +- pkg/sentry/fs/gofer/util.go | 2 +- pkg/sentry/fs/host/control.go | 2 +- pkg/sentry/fs/host/descriptor.go | 2 +- pkg/sentry/fs/host/descriptor_state.go | 2 +- pkg/sentry/fs/host/descriptor_test.go | 2 +- pkg/sentry/fs/host/device.go | 2 +- pkg/sentry/fs/host/file.go | 2 +- pkg/sentry/fs/host/fs.go | 2 +- pkg/sentry/fs/host/fs_test.go | 2 +- pkg/sentry/fs/host/inode.go | 2 +- pkg/sentry/fs/host/inode_state.go | 2 +- pkg/sentry/fs/host/inode_test.go | 2 +- pkg/sentry/fs/host/ioctl_unsafe.go | 2 +- pkg/sentry/fs/host/socket.go | 2 +- pkg/sentry/fs/host/socket_iovec.go | 2 +- pkg/sentry/fs/host/socket_state.go | 2 +- pkg/sentry/fs/host/socket_test.go | 2 +- pkg/sentry/fs/host/socket_unsafe.go | 2 +- pkg/sentry/fs/host/tty.go | 2 +- pkg/sentry/fs/host/util.go | 2 +- pkg/sentry/fs/host/util_unsafe.go | 2 +- pkg/sentry/fs/host/wait_test.go | 2 +- pkg/sentry/fs/inode.go | 2 +- pkg/sentry/fs/inode_inotify.go | 2 +- pkg/sentry/fs/inode_operations.go | 2 +- pkg/sentry/fs/inode_overlay.go | 2 +- pkg/sentry/fs/inode_overlay_test.go | 2 +- pkg/sentry/fs/inotify.go | 2 +- pkg/sentry/fs/inotify_event.go | 2 +- pkg/sentry/fs/inotify_watch.go | 2 +- pkg/sentry/fs/lock/lock.go | 2 +- pkg/sentry/fs/lock/lock_range_test.go | 2 +- pkg/sentry/fs/lock/lock_set_functions.go | 2 +- pkg/sentry/fs/lock/lock_test.go | 2 +- pkg/sentry/fs/mock.go | 2 +- pkg/sentry/fs/mount.go | 2 +- pkg/sentry/fs/mount_overlay.go | 2 +- pkg/sentry/fs/mount_test.go | 2 +- pkg/sentry/fs/mounts.go | 2 +- pkg/sentry/fs/mounts_test.go | 2 +- pkg/sentry/fs/offset.go | 2 +- pkg/sentry/fs/overlay.go | 2 +- pkg/sentry/fs/path.go | 2 +- pkg/sentry/fs/path_test.go | 2 +- pkg/sentry/fs/proc/cpuinfo.go | 2 +- pkg/sentry/fs/proc/device/device.go | 2 +- pkg/sentry/fs/proc/exec_args.go | 2 +- pkg/sentry/fs/proc/fds.go | 2 +- pkg/sentry/fs/proc/filesystems.go | 2 +- pkg/sentry/fs/proc/fs.go | 2 +- pkg/sentry/fs/proc/inode.go | 2 +- pkg/sentry/fs/proc/loadavg.go | 2 +- pkg/sentry/fs/proc/meminfo.go | 2 +- pkg/sentry/fs/proc/mounts.go | 2 +- pkg/sentry/fs/proc/net.go | 2 +- pkg/sentry/fs/proc/net_test.go | 2 +- pkg/sentry/fs/proc/proc.go | 2 +- pkg/sentry/fs/proc/rpcinet_proc.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile.go | 2 +- pkg/sentry/fs/proc/seqfile/seqfile_test.go | 2 +- pkg/sentry/fs/proc/stat.go | 2 +- pkg/sentry/fs/proc/sys.go | 2 +- pkg/sentry/fs/proc/sys_net.go | 2 +- pkg/sentry/fs/proc/sys_net_state.go | 2 +- pkg/sentry/fs/proc/sys_net_test.go | 2 +- pkg/sentry/fs/proc/task.go | 2 +- pkg/sentry/fs/proc/uid_gid_map.go | 2 +- pkg/sentry/fs/proc/uptime.go | 2 +- pkg/sentry/fs/proc/version.go | 2 +- pkg/sentry/fs/ramfs/dir.go | 2 +- pkg/sentry/fs/ramfs/socket.go | 2 +- pkg/sentry/fs/ramfs/symlink.go | 2 +- pkg/sentry/fs/ramfs/tree.go | 2 +- pkg/sentry/fs/ramfs/tree_test.go | 2 +- pkg/sentry/fs/restore.go | 2 +- pkg/sentry/fs/save.go | 2 +- pkg/sentry/fs/seek.go | 2 +- pkg/sentry/fs/sync.go | 2 +- pkg/sentry/fs/sys/device.go | 2 +- pkg/sentry/fs/sys/devices.go | 2 +- pkg/sentry/fs/sys/fs.go | 2 +- pkg/sentry/fs/sys/sys.go | 2 +- pkg/sentry/fs/timerfd/timerfd.go | 2 +- pkg/sentry/fs/tmpfs/device.go | 2 +- pkg/sentry/fs/tmpfs/file_regular.go | 2 +- pkg/sentry/fs/tmpfs/file_test.go | 2 +- pkg/sentry/fs/tmpfs/fs.go | 2 +- pkg/sentry/fs/tmpfs/inode_file.go | 2 +- pkg/sentry/fs/tmpfs/tmpfs.go | 2 +- pkg/sentry/fs/tty/dir.go | 2 +- pkg/sentry/fs/tty/fs.go | 2 +- pkg/sentry/fs/tty/line_discipline.go | 2 +- pkg/sentry/fs/tty/master.go | 2 +- pkg/sentry/fs/tty/queue.go | 2 +- pkg/sentry/fs/tty/slave.go | 2 +- pkg/sentry/fs/tty/terminal.go | 2 +- pkg/sentry/fs/tty/tty_test.go | 2 +- pkg/sentry/hostcpu/getcpu_amd64.s | 2 +- pkg/sentry/hostcpu/hostcpu.go | 2 +- pkg/sentry/hostcpu/hostcpu_test.go | 2 +- pkg/sentry/inet/context.go | 2 +- pkg/sentry/inet/inet.go | 2 +- pkg/sentry/inet/test_stack.go | 2 +- pkg/sentry/kernel/abstract_socket_namespace.go | 2 +- pkg/sentry/kernel/auth/auth.go | 2 +- pkg/sentry/kernel/auth/capability_set.go | 2 +- pkg/sentry/kernel/auth/context.go | 2 +- pkg/sentry/kernel/auth/credentials.go | 2 +- pkg/sentry/kernel/auth/id.go | 2 +- pkg/sentry/kernel/auth/id_map.go | 2 +- pkg/sentry/kernel/auth/id_map_functions.go | 2 +- pkg/sentry/kernel/auth/user_namespace.go | 2 +- pkg/sentry/kernel/context.go | 2 +- pkg/sentry/kernel/contexttest/contexttest.go | 2 +- pkg/sentry/kernel/epoll/epoll.go | 2 +- pkg/sentry/kernel/epoll/epoll_state.go | 2 +- pkg/sentry/kernel/epoll/epoll_test.go | 2 +- pkg/sentry/kernel/eventfd/eventfd.go | 2 +- pkg/sentry/kernel/eventfd/eventfd_test.go | 2 +- pkg/sentry/kernel/fasync/fasync.go | 2 +- pkg/sentry/kernel/fd_map.go | 2 +- pkg/sentry/kernel/fd_map_test.go | 2 +- pkg/sentry/kernel/fs_context.go | 2 +- pkg/sentry/kernel/futex/futex.go | 2 +- pkg/sentry/kernel/futex/futex_test.go | 2 +- pkg/sentry/kernel/ipc_namespace.go | 2 +- pkg/sentry/kernel/kdefs/kdefs.go | 2 +- pkg/sentry/kernel/kernel.go | 2 +- pkg/sentry/kernel/kernel_state.go | 2 +- pkg/sentry/kernel/memevent/memory_events.go | 2 +- pkg/sentry/kernel/memevent/memory_events.proto | 2 +- pkg/sentry/kernel/pending_signals.go | 2 +- pkg/sentry/kernel/pending_signals_state.go | 2 +- pkg/sentry/kernel/pipe/buffers.go | 2 +- pkg/sentry/kernel/pipe/device.go | 2 +- pkg/sentry/kernel/pipe/node.go | 2 +- pkg/sentry/kernel/pipe/node_test.go | 2 +- pkg/sentry/kernel/pipe/pipe.go | 2 +- pkg/sentry/kernel/pipe/pipe_test.go | 2 +- pkg/sentry/kernel/pipe/reader.go | 2 +- pkg/sentry/kernel/pipe/reader_writer.go | 2 +- pkg/sentry/kernel/pipe/writer.go | 2 +- pkg/sentry/kernel/posixtimer.go | 2 +- pkg/sentry/kernel/ptrace.go | 2 +- pkg/sentry/kernel/ptrace_amd64.go | 2 +- pkg/sentry/kernel/ptrace_arm64.go | 2 +- pkg/sentry/kernel/rseq.go | 2 +- pkg/sentry/kernel/sched/cpuset.go | 2 +- pkg/sentry/kernel/sched/cpuset_test.go | 2 +- pkg/sentry/kernel/sched/sched.go | 2 +- pkg/sentry/kernel/seccomp.go | 2 +- pkg/sentry/kernel/semaphore/semaphore.go | 2 +- pkg/sentry/kernel/semaphore/semaphore_test.go | 2 +- pkg/sentry/kernel/sessions.go | 2 +- pkg/sentry/kernel/shm/device.go | 2 +- pkg/sentry/kernel/shm/shm.go | 2 +- pkg/sentry/kernel/signal.go | 2 +- pkg/sentry/kernel/signal_handlers.go | 2 +- pkg/sentry/kernel/syscalls.go | 2 +- pkg/sentry/kernel/syscalls_state.go | 2 +- pkg/sentry/kernel/syslog.go | 2 +- pkg/sentry/kernel/table_test.go | 2 +- pkg/sentry/kernel/task.go | 2 +- pkg/sentry/kernel/task_acct.go | 2 +- pkg/sentry/kernel/task_block.go | 2 +- pkg/sentry/kernel/task_clone.go | 2 +- pkg/sentry/kernel/task_context.go | 2 +- pkg/sentry/kernel/task_exec.go | 2 +- pkg/sentry/kernel/task_exit.go | 2 +- pkg/sentry/kernel/task_futex.go | 2 +- pkg/sentry/kernel/task_identity.go | 2 +- pkg/sentry/kernel/task_log.go | 2 +- pkg/sentry/kernel/task_net.go | 2 +- pkg/sentry/kernel/task_run.go | 2 +- pkg/sentry/kernel/task_sched.go | 2 +- pkg/sentry/kernel/task_signals.go | 2 +- pkg/sentry/kernel/task_start.go | 2 +- pkg/sentry/kernel/task_stop.go | 2 +- pkg/sentry/kernel/task_syscall.go | 2 +- pkg/sentry/kernel/task_test.go | 2 +- pkg/sentry/kernel/task_usermem.go | 2 +- pkg/sentry/kernel/thread_group.go | 2 +- pkg/sentry/kernel/threads.go | 2 +- pkg/sentry/kernel/time/context.go | 2 +- pkg/sentry/kernel/time/time.go | 2 +- pkg/sentry/kernel/timekeeper.go | 2 +- pkg/sentry/kernel/timekeeper_state.go | 2 +- pkg/sentry/kernel/timekeeper_test.go | 2 +- pkg/sentry/kernel/uncaught_signal.proto | 2 +- pkg/sentry/kernel/uts_namespace.go | 2 +- pkg/sentry/kernel/vdso.go | 2 +- pkg/sentry/kernel/version.go | 2 +- pkg/sentry/limits/context.go | 2 +- pkg/sentry/limits/limits.go | 2 +- pkg/sentry/limits/limits_test.go | 2 +- pkg/sentry/limits/linux.go | 2 +- pkg/sentry/loader/elf.go | 2 +- pkg/sentry/loader/interpreter.go | 2 +- pkg/sentry/loader/loader.go | 2 +- pkg/sentry/loader/vdso.go | 2 +- pkg/sentry/loader/vdso_state.go | 2 +- pkg/sentry/memmap/mapping_set.go | 2 +- pkg/sentry/memmap/mapping_set_test.go | 2 +- pkg/sentry/memmap/memmap.go | 2 +- pkg/sentry/memutil/memutil.go | 2 +- pkg/sentry/memutil/memutil_unsafe.go | 2 +- pkg/sentry/mm/address_space.go | 2 +- pkg/sentry/mm/aio_context.go | 2 +- pkg/sentry/mm/aio_context_state.go | 2 +- pkg/sentry/mm/debug.go | 2 +- pkg/sentry/mm/io.go | 2 +- pkg/sentry/mm/lifecycle.go | 2 +- pkg/sentry/mm/metadata.go | 2 +- pkg/sentry/mm/mm.go | 2 +- pkg/sentry/mm/mm_test.go | 2 +- pkg/sentry/mm/pma.go | 2 +- pkg/sentry/mm/procfs.go | 2 +- pkg/sentry/mm/save_restore.go | 2 +- pkg/sentry/mm/shm.go | 2 +- pkg/sentry/mm/special_mappable.go | 2 +- pkg/sentry/mm/syscalls.go | 2 +- pkg/sentry/mm/vma.go | 2 +- pkg/sentry/pgalloc/context.go | 2 +- pkg/sentry/pgalloc/pgalloc.go | 2 +- pkg/sentry/pgalloc/pgalloc_test.go | 2 +- pkg/sentry/pgalloc/pgalloc_unsafe.go | 2 +- pkg/sentry/pgalloc/save_restore.go | 2 +- pkg/sentry/platform/context.go | 2 +- pkg/sentry/platform/interrupt/interrupt.go | 2 +- pkg/sentry/platform/interrupt/interrupt_test.go | 2 +- pkg/sentry/platform/kvm/address_space.go | 2 +- pkg/sentry/platform/kvm/allocator.go | 2 +- pkg/sentry/platform/kvm/bluepill.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.go | 2 +- pkg/sentry/platform/kvm/bluepill_amd64.s | 2 +- pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/bluepill_fault.go | 2 +- pkg/sentry/platform/kvm/bluepill_unsafe.go | 2 +- pkg/sentry/platform/kvm/context.go | 2 +- pkg/sentry/platform/kvm/kvm.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64.go | 2 +- pkg/sentry/platform/kvm/kvm_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/kvm_const.go | 2 +- pkg/sentry/platform/kvm/kvm_test.go | 2 +- pkg/sentry/platform/kvm/machine.go | 2 +- pkg/sentry/platform/kvm/machine_amd64.go | 2 +- pkg/sentry/platform/kvm/machine_amd64_unsafe.go | 2 +- pkg/sentry/platform/kvm/machine_unsafe.go | 2 +- pkg/sentry/platform/kvm/physical_map.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.go | 2 +- pkg/sentry/platform/kvm/testutil/testutil_amd64.s | 2 +- pkg/sentry/platform/kvm/virtual_map.go | 2 +- pkg/sentry/platform/kvm/virtual_map_test.go | 2 +- pkg/sentry/platform/mmap_min_addr.go | 2 +- pkg/sentry/platform/platform.go | 2 +- pkg/sentry/platform/procid/procid.go | 2 +- pkg/sentry/platform/procid/procid_amd64.s | 2 +- pkg/sentry/platform/procid/procid_arm64.s | 2 +- pkg/sentry/platform/procid/procid_net_test.go | 2 +- pkg/sentry/platform/procid/procid_test.go | 2 +- pkg/sentry/platform/ptrace/ptrace.go | 2 +- pkg/sentry/platform/ptrace/ptrace_unsafe.go | 2 +- pkg/sentry/platform/ptrace/stub_amd64.s | 2 +- pkg/sentry/platform/ptrace/stub_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess.go | 2 +- pkg/sentry/platform/ptrace/subprocess_amd64.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux.go | 2 +- pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go | 2 +- pkg/sentry/platform/ptrace/subprocess_unsafe.go | 2 +- pkg/sentry/platform/ring0/defs.go | 2 +- pkg/sentry/platform/ring0/defs_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.go | 2 +- pkg/sentry/platform/ring0/entry_amd64.s | 2 +- pkg/sentry/platform/ring0/gen_offsets/main.go | 2 +- pkg/sentry/platform/ring0/kernel.go | 2 +- pkg/sentry/platform/ring0/kernel_amd64.go | 2 +- pkg/sentry/platform/ring0/kernel_unsafe.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.go | 2 +- pkg/sentry/platform/ring0/lib_amd64.s | 2 +- pkg/sentry/platform/ring0/offsets_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator.go | 2 +- pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_test.go | 2 +- pkg/sentry/platform/ring0/pagetables/pagetables_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/pcids_x86.go | 2 +- pkg/sentry/platform/ring0/pagetables/walker_amd64.go | 2 +- pkg/sentry/platform/ring0/ring0.go | 2 +- pkg/sentry/platform/ring0/x86.go | 2 +- pkg/sentry/platform/safecopy/atomic_amd64.s | 2 +- pkg/sentry/platform/safecopy/safecopy.go | 2 +- pkg/sentry/platform/safecopy/safecopy_test.go | 2 +- pkg/sentry/platform/safecopy/safecopy_unsafe.go | 2 +- pkg/sentry/platform/safecopy/sighandler_amd64.s | 2 +- pkg/sentry/platform/safecopy/sighandler_arm64.s | 2 +- pkg/sentry/safemem/block_unsafe.go | 2 +- pkg/sentry/safemem/io.go | 2 +- pkg/sentry/safemem/io_test.go | 2 +- pkg/sentry/safemem/safemem.go | 2 +- pkg/sentry/safemem/seq_test.go | 2 +- pkg/sentry/safemem/seq_unsafe.go | 2 +- pkg/sentry/sighandling/sighandling.go | 2 +- pkg/sentry/sighandling/sighandling_unsafe.go | 2 +- pkg/sentry/socket/control/control.go | 2 +- pkg/sentry/socket/epsocket/device.go | 2 +- pkg/sentry/socket/epsocket/epsocket.go | 2 +- pkg/sentry/socket/epsocket/provider.go | 2 +- pkg/sentry/socket/epsocket/save_restore.go | 2 +- pkg/sentry/socket/epsocket/stack.go | 2 +- pkg/sentry/socket/hostinet/device.go | 2 +- pkg/sentry/socket/hostinet/hostinet.go | 2 +- pkg/sentry/socket/hostinet/save_restore.go | 2 +- pkg/sentry/socket/hostinet/socket.go | 2 +- pkg/sentry/socket/hostinet/socket_unsafe.go | 2 +- pkg/sentry/socket/hostinet/stack.go | 2 +- pkg/sentry/socket/netlink/message.go | 2 +- pkg/sentry/socket/netlink/port/port.go | 2 +- pkg/sentry/socket/netlink/port/port_test.go | 2 +- pkg/sentry/socket/netlink/provider.go | 2 +- pkg/sentry/socket/netlink/route/protocol.go | 2 +- pkg/sentry/socket/netlink/socket.go | 2 +- pkg/sentry/socket/rpcinet/conn/conn.go | 2 +- pkg/sentry/socket/rpcinet/device.go | 2 +- pkg/sentry/socket/rpcinet/notifier/notifier.go | 2 +- pkg/sentry/socket/rpcinet/rpcinet.go | 2 +- pkg/sentry/socket/rpcinet/socket.go | 2 +- pkg/sentry/socket/rpcinet/stack.go | 2 +- pkg/sentry/socket/rpcinet/stack_unsafe.go | 2 +- pkg/sentry/socket/socket.go | 2 +- pkg/sentry/socket/unix/device.go | 2 +- pkg/sentry/socket/unix/io.go | 2 +- pkg/sentry/socket/unix/transport/connectioned.go | 2 +- pkg/sentry/socket/unix/transport/connectioned_state.go | 2 +- pkg/sentry/socket/unix/transport/connectionless.go | 2 +- pkg/sentry/socket/unix/transport/queue.go | 2 +- pkg/sentry/socket/unix/transport/unix.go | 2 +- pkg/sentry/socket/unix/unix.go | 2 +- pkg/sentry/state/state.go | 2 +- pkg/sentry/state/state_metadata.go | 2 +- pkg/sentry/state/state_unsafe.go | 2 +- pkg/sentry/strace/capability.go | 2 +- pkg/sentry/strace/clone.go | 2 +- pkg/sentry/strace/futex.go | 2 +- pkg/sentry/strace/linux64.go | 2 +- pkg/sentry/strace/open.go | 2 +- pkg/sentry/strace/poll.go | 2 +- pkg/sentry/strace/ptrace.go | 2 +- pkg/sentry/strace/signal.go | 2 +- pkg/sentry/strace/socket.go | 2 +- pkg/sentry/strace/strace.go | 2 +- pkg/sentry/strace/strace.proto | 2 +- pkg/sentry/strace/syscalls.go | 2 +- pkg/sentry/syscalls/epoll.go | 2 +- pkg/sentry/syscalls/linux/error.go | 2 +- pkg/sentry/syscalls/linux/flags.go | 2 +- pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sigset.go | 2 +- pkg/sentry/syscalls/linux/sys_aio.go | 2 +- pkg/sentry/syscalls/linux/sys_capability.go | 2 +- pkg/sentry/syscalls/linux/sys_epoll.go | 2 +- pkg/sentry/syscalls/linux/sys_eventfd.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 2 +- pkg/sentry/syscalls/linux/sys_futex.go | 2 +- pkg/sentry/syscalls/linux/sys_getdents.go | 2 +- pkg/sentry/syscalls/linux/sys_identity.go | 2 +- pkg/sentry/syscalls/linux/sys_inotify.go | 2 +- pkg/sentry/syscalls/linux/sys_lseek.go | 2 +- pkg/sentry/syscalls/linux/sys_mmap.go | 2 +- pkg/sentry/syscalls/linux/sys_mount.go | 2 +- pkg/sentry/syscalls/linux/sys_pipe.go | 2 +- pkg/sentry/syscalls/linux/sys_poll.go | 2 +- pkg/sentry/syscalls/linux/sys_prctl.go | 2 +- pkg/sentry/syscalls/linux/sys_random.go | 2 +- pkg/sentry/syscalls/linux/sys_read.go | 2 +- pkg/sentry/syscalls/linux/sys_rlimit.go | 2 +- pkg/sentry/syscalls/linux/sys_rusage.go | 2 +- pkg/sentry/syscalls/linux/sys_sched.go | 2 +- pkg/sentry/syscalls/linux/sys_seccomp.go | 2 +- pkg/sentry/syscalls/linux/sys_sem.go | 2 +- pkg/sentry/syscalls/linux/sys_shm.go | 2 +- pkg/sentry/syscalls/linux/sys_signal.go | 2 +- pkg/sentry/syscalls/linux/sys_socket.go | 2 +- pkg/sentry/syscalls/linux/sys_stat.go | 2 +- pkg/sentry/syscalls/linux/sys_sync.go | 2 +- pkg/sentry/syscalls/linux/sys_sysinfo.go | 2 +- pkg/sentry/syscalls/linux/sys_syslog.go | 2 +- pkg/sentry/syscalls/linux/sys_thread.go | 2 +- pkg/sentry/syscalls/linux/sys_time.go | 2 +- pkg/sentry/syscalls/linux/sys_timer.go | 2 +- pkg/sentry/syscalls/linux/sys_timerfd.go | 2 +- pkg/sentry/syscalls/linux/sys_tls.go | 2 +- pkg/sentry/syscalls/linux/sys_utsname.go | 2 +- pkg/sentry/syscalls/linux/sys_write.go | 2 +- pkg/sentry/syscalls/linux/timespec.go | 2 +- pkg/sentry/syscalls/syscalls.go | 2 +- pkg/sentry/time/calibrated_clock.go | 2 +- pkg/sentry/time/calibrated_clock_test.go | 2 +- pkg/sentry/time/clock_id.go | 2 +- pkg/sentry/time/clocks.go | 2 +- pkg/sentry/time/muldiv_amd64.s | 2 +- pkg/sentry/time/muldiv_arm64.s | 2 +- pkg/sentry/time/parameters.go | 2 +- pkg/sentry/time/parameters_test.go | 2 +- pkg/sentry/time/sampler.go | 2 +- pkg/sentry/time/sampler_test.go | 2 +- pkg/sentry/time/sampler_unsafe.go | 2 +- pkg/sentry/time/tsc_amd64.s | 2 +- pkg/sentry/time/tsc_arm64.s | 2 +- pkg/sentry/unimpl/events.go | 2 +- pkg/sentry/unimpl/unimplemented_syscall.proto | 2 +- pkg/sentry/uniqueid/context.go | 2 +- pkg/sentry/usage/cpu.go | 2 +- pkg/sentry/usage/io.go | 2 +- pkg/sentry/usage/memory.go | 2 +- pkg/sentry/usage/memory_unsafe.go | 2 +- pkg/sentry/usage/usage.go | 2 +- pkg/sentry/usermem/access_type.go | 2 +- pkg/sentry/usermem/addr.go | 2 +- pkg/sentry/usermem/addr_range_seq_test.go | 2 +- pkg/sentry/usermem/addr_range_seq_unsafe.go | 2 +- pkg/sentry/usermem/bytes_io.go | 2 +- pkg/sentry/usermem/bytes_io_unsafe.go | 2 +- pkg/sentry/usermem/usermem.go | 2 +- pkg/sentry/usermem/usermem_arm64.go | 2 +- pkg/sentry/usermem/usermem_test.go | 2 +- pkg/sentry/usermem/usermem_unsafe.go | 2 +- pkg/sentry/usermem/usermem_x86.go | 2 +- pkg/sentry/watchdog/watchdog.go | 2 +- pkg/sleep/commit_amd64.s | 2 +- pkg/sleep/commit_asm.go | 2 +- pkg/sleep/commit_noasm.go | 2 +- pkg/sleep/empty.s | 2 +- pkg/sleep/sleep_test.go | 2 +- pkg/sleep/sleep_unsafe.go | 2 +- pkg/state/decode.go | 2 +- pkg/state/encode.go | 2 +- pkg/state/encode_unsafe.go | 2 +- pkg/state/map.go | 2 +- pkg/state/object.proto | 2 +- pkg/state/printer.go | 2 +- pkg/state/state.go | 2 +- pkg/state/state_test.go | 2 +- pkg/state/statefile/statefile.go | 2 +- pkg/state/statefile/statefile_test.go | 2 +- pkg/state/stats.go | 2 +- pkg/syserr/host_linux.go | 2 +- pkg/syserr/netstack.go | 2 +- pkg/syserr/syserr.go | 2 +- pkg/syserror/syserror.go | 2 +- pkg/syserror/syserror_test.go | 2 +- pkg/tcpip/adapters/gonet/gonet.go | 2 +- pkg/tcpip/adapters/gonet/gonet_test.go | 2 +- pkg/tcpip/buffer/prependable.go | 2 +- pkg/tcpip/buffer/view.go | 2 +- pkg/tcpip/buffer/view_test.go | 2 +- pkg/tcpip/checker/checker.go | 2 +- pkg/tcpip/hash/jenkins/jenkins.go | 2 +- pkg/tcpip/hash/jenkins/jenkins_test.go | 2 +- pkg/tcpip/header/arp.go | 2 +- pkg/tcpip/header/checksum.go | 2 +- pkg/tcpip/header/eth.go | 2 +- pkg/tcpip/header/gue.go | 2 +- pkg/tcpip/header/icmpv4.go | 2 +- pkg/tcpip/header/icmpv6.go | 2 +- pkg/tcpip/header/interfaces.go | 2 +- pkg/tcpip/header/ipv4.go | 2 +- pkg/tcpip/header/ipv6.go | 2 +- pkg/tcpip/header/ipv6_fragment.go | 2 +- pkg/tcpip/header/ipversion_test.go | 2 +- pkg/tcpip/header/tcp.go | 2 +- pkg/tcpip/header/tcp_test.go | 2 +- pkg/tcpip/header/udp.go | 2 +- pkg/tcpip/link/channel/channel.go | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 2 +- pkg/tcpip/link/fdbased/endpoint_test.go | 2 +- pkg/tcpip/link/fdbased/endpoint_unsafe.go | 2 +- pkg/tcpip/link/fdbased/mmap.go | 2 +- pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go | 2 +- pkg/tcpip/link/loopback/loopback.go | 2 +- pkg/tcpip/link/muxed/injectable.go | 2 +- pkg/tcpip/link/muxed/injectable_test.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64.s | 2 +- pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go | 2 +- pkg/tcpip/link/rawfile/blockingpoll_unsafe.go | 2 +- pkg/tcpip/link/rawfile/errors.go | 2 +- pkg/tcpip/link/rawfile/rawfile_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_test.go | 2 +- pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/pipe/rx.go | 2 +- pkg/tcpip/link/sharedmem/pipe/tx.go | 2 +- pkg/tcpip/link/sharedmem/queue/queue_test.go | 2 +- pkg/tcpip/link/sharedmem/queue/rx.go | 2 +- pkg/tcpip/link/sharedmem/queue/tx.go | 2 +- pkg/tcpip/link/sharedmem/rx.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_test.go | 2 +- pkg/tcpip/link/sharedmem/sharedmem_unsafe.go | 2 +- pkg/tcpip/link/sharedmem/tx.go | 2 +- pkg/tcpip/link/sniffer/pcap.go | 2 +- pkg/tcpip/link/sniffer/sniffer.go | 2 +- pkg/tcpip/link/tun/tun_unsafe.go | 2 +- pkg/tcpip/link/waitable/waitable.go | 2 +- pkg/tcpip/link/waitable/waitable_test.go | 2 +- pkg/tcpip/network/arp/arp.go | 2 +- pkg/tcpip/network/arp/arp_test.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap.go | 2 +- pkg/tcpip/network/fragmentation/frag_heap_test.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation.go | 2 +- pkg/tcpip/network/fragmentation/fragmentation_test.go | 2 +- pkg/tcpip/network/fragmentation/reassembler.go | 2 +- pkg/tcpip/network/fragmentation/reassembler_test.go | 2 +- pkg/tcpip/network/hash/hash.go | 2 +- pkg/tcpip/network/ip_test.go | 2 +- pkg/tcpip/network/ipv4/icmp.go | 2 +- pkg/tcpip/network/ipv4/ipv4.go | 2 +- pkg/tcpip/network/ipv4/ipv4_test.go | 2 +- pkg/tcpip/network/ipv6/icmp.go | 2 +- pkg/tcpip/network/ipv6/icmp_test.go | 2 +- pkg/tcpip/network/ipv6/ipv6.go | 2 +- pkg/tcpip/ports/ports.go | 2 +- pkg/tcpip/ports/ports_test.go | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- pkg/tcpip/seqnum/seqnum.go | 2 +- pkg/tcpip/stack/linkaddrcache.go | 2 +- pkg/tcpip/stack/linkaddrcache_test.go | 2 +- pkg/tcpip/stack/nic.go | 2 +- pkg/tcpip/stack/registration.go | 2 +- pkg/tcpip/stack/route.go | 2 +- pkg/tcpip/stack/stack.go | 2 +- pkg/tcpip/stack/stack_global_state.go | 2 +- pkg/tcpip/stack/stack_test.go | 2 +- pkg/tcpip/stack/transport_demuxer.go | 2 +- pkg/tcpip/stack/transport_test.go | 2 +- pkg/tcpip/tcpip.go | 2 +- pkg/tcpip/tcpip_test.go | 2 +- pkg/tcpip/time.s | 2 +- pkg/tcpip/time_unsafe.go | 2 +- pkg/tcpip/transport/icmp/endpoint.go | 2 +- pkg/tcpip/transport/icmp/endpoint_state.go | 2 +- pkg/tcpip/transport/icmp/protocol.go | 2 +- pkg/tcpip/transport/raw/raw.go | 2 +- pkg/tcpip/transport/raw/state.go | 2 +- pkg/tcpip/transport/tcp/accept.go | 2 +- pkg/tcpip/transport/tcp/connect.go | 2 +- pkg/tcpip/transport/tcp/cubic.go | 2 +- pkg/tcpip/transport/tcp/dual_stack_test.go | 2 +- pkg/tcpip/transport/tcp/endpoint.go | 2 +- pkg/tcpip/transport/tcp/endpoint_state.go | 2 +- pkg/tcpip/transport/tcp/forwarder.go | 2 +- pkg/tcpip/transport/tcp/protocol.go | 2 +- pkg/tcpip/transport/tcp/rcv.go | 2 +- pkg/tcpip/transport/tcp/reno.go | 2 +- pkg/tcpip/transport/tcp/sack.go | 2 +- pkg/tcpip/transport/tcp/sack_scoreboard.go | 2 +- pkg/tcpip/transport/tcp/sack_scoreboard_test.go | 2 +- pkg/tcpip/transport/tcp/segment.go | 2 +- pkg/tcpip/transport/tcp/segment_heap.go | 2 +- pkg/tcpip/transport/tcp/segment_queue.go | 2 +- pkg/tcpip/transport/tcp/segment_state.go | 2 +- pkg/tcpip/transport/tcp/snd.go | 2 +- pkg/tcpip/transport/tcp/snd_state.go | 2 +- pkg/tcpip/transport/tcp/tcp_sack_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_test.go | 2 +- pkg/tcpip/transport/tcp/tcp_timestamp_test.go | 2 +- pkg/tcpip/transport/tcp/testing/context/context.go | 2 +- pkg/tcpip/transport/tcp/timer.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go | 2 +- pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go | 2 +- pkg/tcpip/transport/udp/endpoint.go | 2 +- pkg/tcpip/transport/udp/endpoint_state.go | 2 +- pkg/tcpip/transport/udp/forwarder.go | 2 +- pkg/tcpip/transport/udp/protocol.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 2 +- pkg/tmutex/tmutex.go | 2 +- pkg/tmutex/tmutex_test.go | 2 +- pkg/unet/unet.go | 2 +- pkg/unet/unet_test.go | 2 +- pkg/unet/unet_unsafe.go | 2 +- pkg/urpc/urpc.go | 2 +- pkg/urpc/urpc_test.go | 2 +- pkg/waiter/waiter.go | 2 +- pkg/waiter/waiter_test.go | 2 +- runsc/boot/compat.go | 2 +- runsc/boot/compat_amd64.go | 2 +- runsc/boot/compat_test.go | 2 +- runsc/boot/config.go | 2 +- runsc/boot/controller.go | 2 +- runsc/boot/debug.go | 2 +- runsc/boot/events.go | 2 +- runsc/boot/fds.go | 2 +- runsc/boot/filter/config.go | 2 +- runsc/boot/filter/extra_filters.go | 2 +- runsc/boot/filter/extra_filters_msan.go | 2 +- runsc/boot/filter/extra_filters_race.go | 2 +- runsc/boot/filter/filter.go | 2 +- runsc/boot/fs.go | 2 +- runsc/boot/limits.go | 2 +- runsc/boot/loader.go | 2 +- runsc/boot/loader_test.go | 2 +- runsc/boot/network.go | 2 +- runsc/boot/strace.go | 2 +- runsc/cgroup/cgroup.go | 2 +- runsc/cgroup/cgroup_test.go | 2 +- runsc/cmd/boot.go | 2 +- runsc/cmd/capability.go | 2 +- runsc/cmd/capability_test.go | 2 +- runsc/cmd/checkpoint.go | 2 +- runsc/cmd/chroot.go | 2 +- runsc/cmd/cmd.go | 2 +- runsc/cmd/create.go | 2 +- runsc/cmd/debug.go | 2 +- runsc/cmd/delete.go | 2 +- runsc/cmd/delete_test.go | 2 +- runsc/cmd/do.go | 2 +- runsc/cmd/events.go | 2 +- runsc/cmd/exec.go | 2 +- runsc/cmd/exec_test.go | 2 +- runsc/cmd/gofer.go | 2 +- runsc/cmd/gofer_test.go | 2 +- runsc/cmd/kill.go | 2 +- runsc/cmd/list.go | 2 +- runsc/cmd/path.go | 2 +- runsc/cmd/pause.go | 2 +- runsc/cmd/ps.go | 2 +- runsc/cmd/restore.go | 2 +- runsc/cmd/resume.go | 2 +- runsc/cmd/run.go | 2 +- runsc/cmd/spec.go | 2 +- runsc/cmd/start.go | 2 +- runsc/cmd/state.go | 2 +- runsc/cmd/wait.go | 2 +- runsc/console/console.go | 2 +- runsc/container/console_test.go | 2 +- runsc/container/container.go | 2 +- runsc/container/container_test.go | 2 +- runsc/container/hook.go | 2 +- runsc/container/multi_container_test.go | 2 +- runsc/container/shared_volume_test.go | 2 +- runsc/container/status.go | 2 +- runsc/container/test_app.go | 2 +- runsc/fsgofer/filter/config.go | 2 +- runsc/fsgofer/filter/extra_filters.go | 2 +- runsc/fsgofer/filter/extra_filters_msan.go | 2 +- runsc/fsgofer/filter/extra_filters_race.go | 2 +- runsc/fsgofer/filter/filter.go | 2 +- runsc/fsgofer/fsgofer.go | 2 +- runsc/fsgofer/fsgofer_test.go | 2 +- runsc/fsgofer/fsgofer_unsafe.go | 2 +- runsc/main.go | 2 +- runsc/sandbox/network.go | 2 +- runsc/sandbox/network_unsafe.go | 2 +- runsc/sandbox/sandbox.go | 2 +- runsc/specutils/fs.go | 2 +- runsc/specutils/namespace.go | 2 +- runsc/specutils/specutils.go | 2 +- runsc/specutils/specutils_test.go | 2 +- runsc/test/image/image.go | 2 +- runsc/test/image/image_test.go | 2 +- runsc/test/image/mysql.sql | 2 +- runsc/test/image/ruby.rb | 2 +- runsc/test/image/ruby.sh | 2 +- runsc/test/install.sh | 2 +- runsc/test/integration/exec_test.go | 2 +- runsc/test/integration/integration.go | 2 +- runsc/test/integration/integration_test.go | 2 +- runsc/test/root/cgroup_test.go | 2 +- runsc/test/root/chroot_test.go | 2 +- runsc/test/root/crictl_test.go | 2 +- runsc/test/root/root.go | 2 +- runsc/test/root/testdata/busybox.go | 2 +- runsc/test/root/testdata/containerd_config.go | 2 +- runsc/test/root/testdata/httpd.go | 2 +- runsc/test/root/testdata/httpd_mount_paths.go | 2 +- runsc/test/root/testdata/sandbox.go | 2 +- runsc/test/testutil/crictl.go | 2 +- runsc/test/testutil/docker.go | 2 +- runsc/test/testutil/testutil.go | 2 +- runsc/test/testutil/testutil_race.go | 2 +- runsc/tools/dockercfg/dockercfg.go | 2 +- runsc/version.go | 2 +- test/syscalls/gtest/gtest.go | 2 +- test/syscalls/linux/32bit.cc | 2 +- test/syscalls/linux/accept_bind.cc | 2 +- test/syscalls/linux/accept_bind_stream.cc | 2 +- test/syscalls/linux/access.cc | 2 +- test/syscalls/linux/affinity.cc | 2 +- test/syscalls/linux/aio.cc | 2 +- test/syscalls/linux/alarm.cc | 2 +- test/syscalls/linux/arch_prctl.cc | 2 +- test/syscalls/linux/bad.cc | 2 +- test/syscalls/linux/base_poll_test.cc | 2 +- test/syscalls/linux/base_poll_test.h | 2 +- test/syscalls/linux/bind.cc | 2 +- test/syscalls/linux/brk.cc | 2 +- test/syscalls/linux/chdir.cc | 2 +- test/syscalls/linux/chmod.cc | 2 +- test/syscalls/linux/chown.cc | 2 +- test/syscalls/linux/chroot.cc | 2 +- test/syscalls/linux/clock_getres.cc | 2 +- test/syscalls/linux/clock_gettime.cc | 2 +- test/syscalls/linux/clock_nanosleep.cc | 2 +- test/syscalls/linux/concurrency.cc | 2 +- test/syscalls/linux/creat.cc | 2 +- test/syscalls/linux/dev.cc | 2 +- test/syscalls/linux/dup.cc | 2 +- test/syscalls/linux/epoll.cc | 2 +- test/syscalls/linux/eventfd.cc | 2 +- test/syscalls/linux/exceptions.cc | 2 +- test/syscalls/linux/exec.cc | 2 +- test/syscalls/linux/exec.h | 2 +- test/syscalls/linux/exec_assert_closed_workload.cc | 2 +- test/syscalls/linux/exec_basic_workload.cc | 2 +- test/syscalls/linux/exec_binary.cc | 2 +- test/syscalls/linux/exec_proc_exe_workload.cc | 2 +- test/syscalls/linux/exec_state_workload.cc | 2 +- test/syscalls/linux/exit.cc | 2 +- test/syscalls/linux/exit_script.sh | 2 +- test/syscalls/linux/fadvise64.cc | 2 +- test/syscalls/linux/fallocate.cc | 2 +- test/syscalls/linux/fault.cc | 2 +- test/syscalls/linux/fchdir.cc | 2 +- test/syscalls/linux/fcntl.cc | 2 +- test/syscalls/linux/file_base.h | 2 +- test/syscalls/linux/flock.cc | 2 +- test/syscalls/linux/fork.cc | 2 +- test/syscalls/linux/fpsig_fork.cc | 2 +- test/syscalls/linux/fpsig_nested.cc | 2 +- test/syscalls/linux/fsync.cc | 2 +- test/syscalls/linux/futex.cc | 2 +- test/syscalls/linux/getcpu.cc | 2 +- test/syscalls/linux/getdents.cc | 2 +- test/syscalls/linux/getrandom.cc | 2 +- test/syscalls/linux/getrusage.cc | 2 +- test/syscalls/linux/inotify.cc | 2 +- test/syscalls/linux/ioctl.cc | 2 +- test/syscalls/linux/ip_socket_test_util.cc | 2 +- test/syscalls/linux/ip_socket_test_util.h | 2 +- test/syscalls/linux/itimer.cc | 2 +- test/syscalls/linux/kill.cc | 2 +- test/syscalls/linux/link.cc | 2 +- test/syscalls/linux/lseek.cc | 2 +- test/syscalls/linux/madvise.cc | 2 +- test/syscalls/linux/memfd.cc | 2 +- test/syscalls/linux/memory_accounting.cc | 2 +- test/syscalls/linux/mempolicy.cc | 2 +- test/syscalls/linux/mincore.cc | 2 +- test/syscalls/linux/mkdir.cc | 2 +- test/syscalls/linux/mknod.cc | 2 +- test/syscalls/linux/mlock.cc | 2 +- test/syscalls/linux/mmap.cc | 2 +- test/syscalls/linux/mount.cc | 2 +- test/syscalls/linux/mremap.cc | 2 +- test/syscalls/linux/msync.cc | 2 +- test/syscalls/linux/munmap.cc | 2 +- test/syscalls/linux/open.cc | 2 +- test/syscalls/linux/open_create.cc | 2 +- test/syscalls/linux/partial_bad_buffer.cc | 2 +- test/syscalls/linux/pause.cc | 2 +- test/syscalls/linux/pipe.cc | 2 +- test/syscalls/linux/poll.cc | 2 +- test/syscalls/linux/ppoll.cc | 2 +- test/syscalls/linux/prctl.cc | 2 +- test/syscalls/linux/prctl_setuid.cc | 2 +- test/syscalls/linux/pread64.cc | 2 +- test/syscalls/linux/preadv.cc | 2 +- test/syscalls/linux/preadv2.cc | 2 +- test/syscalls/linux/priority.cc | 2 +- test/syscalls/linux/priority_execve.cc | 2 +- test/syscalls/linux/proc.cc | 2 +- test/syscalls/linux/proc_net.cc | 2 +- test/syscalls/linux/proc_net_unix.cc | 2 +- test/syscalls/linux/proc_pid_smaps.cc | 2 +- test/syscalls/linux/proc_pid_uid_gid_map.cc | 2 +- test/syscalls/linux/pselect.cc | 2 +- test/syscalls/linux/ptrace.cc | 2 +- test/syscalls/linux/pty.cc | 2 +- test/syscalls/linux/pwrite64.cc | 2 +- test/syscalls/linux/pwritev2.cc | 2 +- test/syscalls/linux/raw_socket_ipv4.cc | 2 +- test/syscalls/linux/read.cc | 2 +- test/syscalls/linux/readv.cc | 2 +- test/syscalls/linux/readv_common.cc | 2 +- test/syscalls/linux/readv_common.h | 2 +- test/syscalls/linux/readv_socket.cc | 2 +- test/syscalls/linux/rename.cc | 2 +- test/syscalls/linux/rlimits.cc | 2 +- test/syscalls/linux/rtsignal.cc | 2 +- test/syscalls/linux/sched.cc | 2 +- test/syscalls/linux/sched_yield.cc | 2 +- test/syscalls/linux/seccomp.cc | 2 +- test/syscalls/linux/select.cc | 2 +- test/syscalls/linux/semaphore.cc | 2 +- test/syscalls/linux/sendfile.cc | 2 +- test/syscalls/linux/sendfile_socket.cc | 2 +- test/syscalls/linux/shm.cc | 2 +- test/syscalls/linux/sigaction.cc | 2 +- test/syscalls/linux/sigaltstack.cc | 2 +- test/syscalls/linux/sigaltstack_check.cc | 2 +- test/syscalls/linux/sigiret.cc | 2 +- test/syscalls/linux/sigprocmask.cc | 2 +- test/syscalls/linux/sigstop.cc | 2 +- test/syscalls/linux/sigtimedwait.cc | 2 +- test/syscalls/linux/socket_abstract.cc | 2 +- test/syscalls/linux/socket_blocking.cc | 2 +- test/syscalls/linux/socket_blocking.h | 2 +- test/syscalls/linux/socket_filesystem.cc | 2 +- test/syscalls/linux/socket_generic.cc | 2 +- test/syscalls/linux/socket_generic.h | 2 +- test/syscalls/linux/socket_inet_loopback.cc | 2 +- test/syscalls/linux/socket_ip_loopback_blocking.cc | 2 +- test/syscalls/linux/socket_ip_tcp_generic.cc | 2 +- test/syscalls/linux/socket_ip_tcp_generic.h | 2 +- test/syscalls/linux/socket_ip_tcp_generic_loopback.cc | 2 +- test/syscalls/linux/socket_ip_tcp_loopback.cc | 2 +- test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc | 2 +- test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc | 2 +- test/syscalls/linux/socket_ip_tcp_udp_generic.cc | 2 +- test/syscalls/linux/socket_ip_udp_generic.cc | 2 +- test/syscalls/linux/socket_ip_udp_generic.h | 2 +- test/syscalls/linux/socket_ip_udp_loopback.cc | 2 +- test/syscalls/linux/socket_ip_udp_loopback_blocking.cc | 2 +- test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc | 2 +- .../syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc | 2 +- test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h | 2 +- .../linux/socket_ipv4_tcp_unbound_external_networking_test.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound.h | 2 +- .../syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h | 2 +- .../linux/socket_ipv4_udp_unbound_external_networking_test.cc | 2 +- test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc | 2 +- test/syscalls/linux/socket_netdevice.cc | 2 +- test/syscalls/linux/socket_netlink_route.cc | 2 +- test/syscalls/linux/socket_netlink_util.cc | 2 +- test/syscalls/linux/socket_netlink_util.h | 2 +- test/syscalls/linux/socket_non_blocking.cc | 2 +- test/syscalls/linux/socket_non_blocking.h | 2 +- test/syscalls/linux/socket_non_stream.cc | 2 +- test/syscalls/linux/socket_non_stream.h | 2 +- test/syscalls/linux/socket_non_stream_blocking.cc | 2 +- test/syscalls/linux/socket_non_stream_blocking.h | 2 +- test/syscalls/linux/socket_stream.cc | 2 +- test/syscalls/linux/socket_stream.h | 2 +- test/syscalls/linux/socket_stream_blocking.cc | 2 +- test/syscalls/linux/socket_stream_blocking.h | 2 +- test/syscalls/linux/socket_stream_nonblock.cc | 2 +- test/syscalls/linux/socket_stream_nonblock.h | 2 +- test/syscalls/linux/socket_test_util.cc | 2 +- test/syscalls/linux/socket_test_util.h | 2 +- test/syscalls/linux/socket_unix.cc | 2 +- test/syscalls/linux/socket_unix.h | 2 +- test/syscalls/linux/socket_unix_abstract.cc | 2 +- test/syscalls/linux/socket_unix_abstract_nonblock.cc | 2 +- test/syscalls/linux/socket_unix_blocking_local.cc | 2 +- test/syscalls/linux/socket_unix_dgram.cc | 2 +- test/syscalls/linux/socket_unix_dgram.h | 2 +- test/syscalls/linux/socket_unix_dgram_local.cc | 2 +- test/syscalls/linux/socket_unix_dgram_non_blocking.cc | 2 +- test/syscalls/linux/socket_unix_domain.cc | 2 +- test/syscalls/linux/socket_unix_filesystem.cc | 2 +- test/syscalls/linux/socket_unix_filesystem_nonblock.cc | 2 +- test/syscalls/linux/socket_unix_non_stream.cc | 2 +- test/syscalls/linux/socket_unix_non_stream.h | 2 +- test/syscalls/linux/socket_unix_non_stream_blocking_local.cc | 2 +- test/syscalls/linux/socket_unix_pair.cc | 2 +- test/syscalls/linux/socket_unix_pair_nonblock.cc | 2 +- test/syscalls/linux/socket_unix_seqpacket.cc | 2 +- test/syscalls/linux/socket_unix_seqpacket.h | 2 +- test/syscalls/linux/socket_unix_seqpacket_local.cc | 2 +- test/syscalls/linux/socket_unix_stream.cc | 2 +- test/syscalls/linux/socket_unix_stream_blocking_local.cc | 2 +- test/syscalls/linux/socket_unix_stream_local.cc | 2 +- test/syscalls/linux/socket_unix_stream_nonblock_local.cc | 2 +- test/syscalls/linux/socket_unix_unbound_abstract.cc | 2 +- test/syscalls/linux/socket_unix_unbound_dgram.cc | 2 +- test/syscalls/linux/socket_unix_unbound_filesystem.cc | 2 +- test/syscalls/linux/socket_unix_unbound_seqpacket.cc | 2 +- test/syscalls/linux/socket_unix_unbound_stream.cc | 2 +- test/syscalls/linux/stat.cc | 2 +- test/syscalls/linux/stat_times.cc | 2 +- test/syscalls/linux/statfs.cc | 2 +- test/syscalls/linux/sticky.cc | 2 +- test/syscalls/linux/symlink.cc | 2 +- test/syscalls/linux/sync.cc | 2 +- test/syscalls/linux/sync_file_range.cc | 2 +- test/syscalls/linux/sysinfo.cc | 2 +- test/syscalls/linux/syslog.cc | 2 +- test/syscalls/linux/sysret.cc | 2 +- test/syscalls/linux/tcp_socket.cc | 2 +- test/syscalls/linux/temp_umask.h | 2 +- test/syscalls/linux/tgkill.cc | 2 +- test/syscalls/linux/time.cc | 2 +- test/syscalls/linux/timerfd.cc | 2 +- test/syscalls/linux/timers.cc | 2 +- test/syscalls/linux/tkill.cc | 2 +- test/syscalls/linux/truncate.cc | 2 +- test/syscalls/linux/udp_bind.cc | 2 +- test/syscalls/linux/udp_socket.cc | 2 +- test/syscalls/linux/uidgid.cc | 2 +- test/syscalls/linux/uname.cc | 2 +- test/syscalls/linux/unix_domain_socket_test_util.cc | 2 +- test/syscalls/linux/unix_domain_socket_test_util.h | 2 +- test/syscalls/linux/unlink.cc | 2 +- test/syscalls/linux/unshare.cc | 2 +- test/syscalls/linux/utimes.cc | 2 +- test/syscalls/linux/vdso.cc | 2 +- test/syscalls/linux/vdso_clock_gettime.cc | 2 +- test/syscalls/linux/vfork.cc | 2 +- test/syscalls/linux/vsyscall.cc | 2 +- test/syscalls/linux/wait.cc | 2 +- test/syscalls/linux/write.cc | 2 +- test/syscalls/syscall_test_runner.go | 2 +- test/syscalls/syscall_test_runner.sh | 2 +- test/util/capability_util.cc | 2 +- test/util/capability_util.h | 2 +- test/util/cleanup.h | 2 +- test/util/epoll_util.cc | 2 +- test/util/epoll_util.h | 2 +- test/util/eventfd_util.h | 2 +- test/util/file_descriptor.h | 2 +- test/util/fs_util.cc | 2 +- test/util/fs_util.h | 2 +- test/util/fs_util_test.cc | 2 +- test/util/logging.cc | 2 +- test/util/logging.h | 2 +- test/util/memory_util.h | 2 +- test/util/mount_util.h | 2 +- test/util/multiprocess_util.cc | 2 +- test/util/multiprocess_util.h | 2 +- test/util/posix_error.cc | 2 +- test/util/posix_error.h | 2 +- test/util/posix_error_test.cc | 2 +- test/util/proc_util.cc | 2 +- test/util/proc_util.h | 2 +- test/util/proc_util_test.cc | 2 +- test/util/rlimit_util.cc | 2 +- test/util/rlimit_util.h | 2 +- test/util/save_util.cc | 2 +- test/util/save_util.h | 2 +- test/util/signal_util.cc | 2 +- test/util/signal_util.h | 2 +- test/util/temp_path.cc | 2 +- test/util/temp_path.h | 2 +- test/util/test_main.cc | 2 +- test/util/test_util.cc | 2 +- test/util/test_util.h | 2 +- test/util/test_util_test.cc | 2 +- test/util/thread_util.h | 2 +- test/util/timer_util.cc | 2 +- test/util/timer_util.h | 2 +- third_party/gvsync/atomicptr_unsafe.go | 2 +- third_party/gvsync/atomicptrtest/atomicptr_test.go | 2 +- third_party/gvsync/downgradable_rwmutex_test.go | 2 +- third_party/gvsync/downgradable_rwmutex_unsafe.go | 2 +- third_party/gvsync/gvsync.go | 2 +- third_party/gvsync/memmove_unsafe.go | 2 +- third_party/gvsync/norace_unsafe.go | 2 +- third_party/gvsync/race_unsafe.go | 2 +- third_party/gvsync/seqatomic_unsafe.go | 2 +- third_party/gvsync/seqatomictest/seqatomic_test.go | 2 +- third_party/gvsync/seqcount.go | 2 +- third_party/gvsync/seqcount_test.go | 2 +- tools/go_generics/generics.go | 2 +- tools/go_generics/generics_tests/all_stmts/input.go | 2 +- tools/go_generics/generics_tests/all_stmts/output/output.go | 2 +- tools/go_generics/generics_tests/all_types/input.go | 2 +- tools/go_generics/generics_tests/all_types/lib/lib.go | 2 +- tools/go_generics/generics_tests/all_types/output/output.go | 2 +- tools/go_generics/generics_tests/consts/input.go | 2 +- tools/go_generics/generics_tests/consts/output/output.go | 2 +- tools/go_generics/generics_tests/imports/input.go | 2 +- tools/go_generics/generics_tests/imports/output/output.go | 2 +- tools/go_generics/generics_tests/remove_typedef/input.go | 2 +- tools/go_generics/generics_tests/remove_typedef/output/output.go | 2 +- tools/go_generics/generics_tests/simple/input.go | 2 +- tools/go_generics/generics_tests/simple/output/output.go | 2 +- tools/go_generics/globals/globals_visitor.go | 2 +- tools/go_generics/globals/scope.go | 2 +- tools/go_generics/go_generics_unittest.sh | 2 +- tools/go_generics/go_merge/main.go | 2 +- tools/go_generics/imports.go | 2 +- tools/go_generics/remove.go | 2 +- tools/go_generics/rules_tests/template.go | 2 +- tools/go_generics/rules_tests/template_test.go | 2 +- tools/go_stateify/main.go | 2 +- tools/tag_release.sh | 2 +- tools/workspace_status.sh | 2 +- vdso/barrier.h | 2 +- vdso/check_vdso.py | 2 +- vdso/compiler.h | 2 +- vdso/cycle_clock.h | 2 +- vdso/seqlock.h | 2 +- vdso/syscalls.h | 2 +- vdso/vdso.cc | 2 +- vdso/vdso_time.cc | 2 +- vdso/vdso_time.h | 2 +- 1235 files changed, 1242 insertions(+), 1234 deletions(-) create mode 100644 AUTHORS (limited to 'pkg/abi') diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..01ba46567 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +# This is the list of gVisor authors for copyright purposes. +# +# This does not necessarily list everyone who has contributed code, since in +# some cases, their employer may be the copyright holder. To see the full list +# of contributors, see the revision history in source control. +# +# Please send a patch if you would like to be included in this list. +Google LLC diff --git a/kokoro/run_build.sh b/kokoro/run_build.sh index 89e24b037..63fffda48 100755 --- a/kokoro/run_build.sh +++ b/kokoro/run_build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/kokoro/run_tests.sh b/kokoro/run_tests.sh index 8a3ce7402..08f678e39 100755 --- a/kokoro/run_tests.sh +++ b/kokoro/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/pkg/abi/abi.go b/pkg/abi/abi.go index 7770f0405..d56c481c9 100644 --- a/pkg/abi/abi.go +++ b/pkg/abi/abi.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/abi_linux.go b/pkg/abi/abi_linux.go index 9d9f361a4..3059479bd 100644 --- a/pkg/abi/abi_linux.go +++ b/pkg/abi/abi_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/flag.go b/pkg/abi/flag.go index b48757da8..dcdd66d4e 100644 --- a/pkg/abi/flag.go +++ b/pkg/abi/flag.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/aio.go b/pkg/abi/linux/aio.go index 1b7ca714a..3c6e0079d 100644 --- a/pkg/abi/linux/aio.go +++ b/pkg/abi/linux/aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ashmem.go b/pkg/abi/linux/ashmem.go index ced1e44d4..2a722abe0 100644 --- a/pkg/abi/linux/ashmem.go +++ b/pkg/abi/linux/ashmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/audit.go b/pkg/abi/linux/audit.go index b39ba4515..6cca69af9 100644 --- a/pkg/abi/linux/audit.go +++ b/pkg/abi/linux/audit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/binder.go b/pkg/abi/linux/binder.go index 522dc6f53..63b08324a 100644 --- a/pkg/abi/linux/binder.go +++ b/pkg/abi/linux/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/bpf.go b/pkg/abi/linux/bpf.go index d9cd09948..aa3d3ce70 100644 --- a/pkg/abi/linux/bpf.go +++ b/pkg/abi/linux/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/capability.go b/pkg/abi/linux/capability.go index 7d96f013e..c120cac64 100644 --- a/pkg/abi/linux/capability.go +++ b/pkg/abi/linux/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/dev.go b/pkg/abi/linux/dev.go index 5b1199aac..421e11256 100644 --- a/pkg/abi/linux/dev.go +++ b/pkg/abi/linux/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/elf.go b/pkg/abi/linux/elf.go index 928067c04..fb1c679d2 100644 --- a/pkg/abi/linux/elf.go +++ b/pkg/abi/linux/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errors.go index e5f6f3f07..93f85a864 100644 --- a/pkg/abi/linux/errors.go +++ b/pkg/abi/linux/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/eventfd.go b/pkg/abi/linux/eventfd.go index 5614f5cf1..9c479fc8f 100644 --- a/pkg/abi/linux/eventfd.go +++ b/pkg/abi/linux/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/exec.go b/pkg/abi/linux/exec.go index a07c29243..579d46c41 100644 --- a/pkg/abi/linux/exec.go +++ b/pkg/abi/linux/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index c8558933a..cc8f2702d 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 46b10ca97..753fec3ed 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/fs.go b/pkg/abi/linux/fs.go index a9f2ba132..c82ab9b5b 100644 --- a/pkg/abi/linux/fs.go +++ b/pkg/abi/linux/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/futex.go b/pkg/abi/linux/futex.go index afdf4123b..08bfde3b5 100644 --- a/pkg/abi/linux/futex.go +++ b/pkg/abi/linux/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/inotify.go b/pkg/abi/linux/inotify.go index 79c5d3593..2d08194ba 100644 --- a/pkg/abi/linux/inotify.go +++ b/pkg/abi/linux/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ioctl.go b/pkg/abi/linux/ioctl.go index 191b26e4d..04bb767dc 100644 --- a/pkg/abi/linux/ioctl.go +++ b/pkg/abi/linux/ioctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ip.go b/pkg/abi/linux/ip.go index 77ac1062c..31e56ffa6 100644 --- a/pkg/abi/linux/ip.go +++ b/pkg/abi/linux/ip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ipc.go b/pkg/abi/linux/ipc.go index 10681768b..2ef8d6cbb 100644 --- a/pkg/abi/linux/ipc.go +++ b/pkg/abi/linux/ipc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/limits.go b/pkg/abi/linux/limits.go index e0aa5b31d..c74dfcd53 100644 --- a/pkg/abi/linux/limits.go +++ b/pkg/abi/linux/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/linux.go b/pkg/abi/linux/linux.go index d365f693d..8a8f831cd 100644 --- a/pkg/abi/linux/linux.go +++ b/pkg/abi/linux/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/mm.go b/pkg/abi/linux/mm.go index eda8d9788..0b02f938a 100644 --- a/pkg/abi/linux/mm.go +++ b/pkg/abi/linux/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/netdevice.go b/pkg/abi/linux/netdevice.go index e3b6b1e40..aef1acf75 100644 --- a/pkg/abi/linux/netdevice.go +++ b/pkg/abi/linux/netdevice.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/netlink.go b/pkg/abi/linux/netlink.go index 25c5e17fd..5e718c363 100644 --- a/pkg/abi/linux/netlink.go +++ b/pkg/abi/linux/netlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/netlink_route.go b/pkg/abi/linux/netlink_route.go index 4200b6506..630dc339a 100644 --- a/pkg/abi/linux/netlink_route.go +++ b/pkg/abi/linux/netlink_route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/poll.go b/pkg/abi/linux/poll.go index 9f0b15d1c..c04d26e4c 100644 --- a/pkg/abi/linux/poll.go +++ b/pkg/abi/linux/poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index db3206f36..dae2de290 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/ptrace.go b/pkg/abi/linux/ptrace.go index 7db4f5464..23e605ab2 100644 --- a/pkg/abi/linux/ptrace.go +++ b/pkg/abi/linux/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/rusage.go b/pkg/abi/linux/rusage.go index 7fea4b589..d8302dc85 100644 --- a/pkg/abi/linux/rusage.go +++ b/pkg/abi/linux/rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/sched.go b/pkg/abi/linux/sched.go index ef96a3801..193d9a242 100644 --- a/pkg/abi/linux/sched.go +++ b/pkg/abi/linux/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/seccomp.go b/pkg/abi/linux/seccomp.go index 8673a27bf..4eeb5cd7a 100644 --- a/pkg/abi/linux/seccomp.go +++ b/pkg/abi/linux/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/sem.go b/pkg/abi/linux/sem.go index b80c93daf..de422c519 100644 --- a/pkg/abi/linux/sem.go +++ b/pkg/abi/linux/sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/shm.go b/pkg/abi/linux/shm.go index 82a80e609..e45aadb10 100644 --- a/pkg/abi/linux/shm.go +++ b/pkg/abi/linux/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/signal.go b/pkg/abi/linux/signal.go index 395f9f31e..9cbd77dda 100644 --- a/pkg/abi/linux/signal.go +++ b/pkg/abi/linux/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/socket.go b/pkg/abi/linux/socket.go index 6fa4e7c3e..417840731 100644 --- a/pkg/abi/linux/socket.go +++ b/pkg/abi/linux/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/tcp.go b/pkg/abi/linux/tcp.go index 67908deb9..174d470e2 100644 --- a/pkg/abi/linux/tcp.go +++ b/pkg/abi/linux/tcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/time.go b/pkg/abi/linux/time.go index bbd21e726..fa9ee27e1 100644 --- a/pkg/abi/linux/time.go +++ b/pkg/abi/linux/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/timer.go b/pkg/abi/linux/timer.go index a6f420bdb..e32d09e10 100644 --- a/pkg/abi/linux/timer.go +++ b/pkg/abi/linux/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/tty.go b/pkg/abi/linux/tty.go index bff882d89..8ac02aee8 100644 --- a/pkg/abi/linux/tty.go +++ b/pkg/abi/linux/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/uio.go b/pkg/abi/linux/uio.go index 7e00d9959..1fd1e9802 100644 --- a/pkg/abi/linux/uio.go +++ b/pkg/abi/linux/uio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/abi/linux/utsname.go b/pkg/abi/linux/utsname.go index f80ed7d4a..60f220a67 100644 --- a/pkg/abi/linux/utsname.go +++ b/pkg/abi/linux/utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/amutex/amutex.go b/pkg/amutex/amutex.go index 26b674435..85e819304 100644 --- a/pkg/amutex/amutex.go +++ b/pkg/amutex/amutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/amutex/amutex_test.go b/pkg/amutex/amutex_test.go index 104e0dab1..6a0af006e 100644 --- a/pkg/amutex/amutex_test.go +++ b/pkg/amutex/amutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops.go b/pkg/atomicbitops/atomic_bitops.go index 9a57f9599..63aa2b7f1 100644 --- a/pkg/atomicbitops/atomic_bitops.go +++ b/pkg/atomicbitops/atomic_bitops.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops_amd64.s b/pkg/atomicbitops/atomic_bitops_amd64.s index b37e3aad3..db0972001 100644 --- a/pkg/atomicbitops/atomic_bitops_amd64.s +++ b/pkg/atomicbitops/atomic_bitops_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops_common.go b/pkg/atomicbitops/atomic_bitops_common.go index b03242baa..b2a943dcb 100644 --- a/pkg/atomicbitops/atomic_bitops_common.go +++ b/pkg/atomicbitops/atomic_bitops_common.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/atomicbitops/atomic_bitops_test.go b/pkg/atomicbitops/atomic_bitops_test.go index ee6207cb3..965e9be79 100644 --- a/pkg/atomicbitops/atomic_bitops_test.go +++ b/pkg/atomicbitops/atomic_bitops_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/binary/binary.go b/pkg/binary/binary.go index 02f7e9fb8..631785f7b 100644 --- a/pkg/binary/binary.go +++ b/pkg/binary/binary.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/binary/binary_test.go b/pkg/binary/binary_test.go index 200961c70..4d609a438 100644 --- a/pkg/binary/binary_test.go +++ b/pkg/binary/binary_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/bits.go b/pkg/bits/bits.go index eb3c80f49..a26433ad6 100644 --- a/pkg/bits/bits.go +++ b/pkg/bits/bits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/bits_template.go b/pkg/bits/bits_template.go index 8c578cca2..93a435b80 100644 --- a/pkg/bits/bits_template.go +++ b/pkg/bits/bits_template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_arch_amd64.go b/pkg/bits/uint64_arch_amd64.go index 1fef89394..faccaa61a 100644 --- a/pkg/bits/uint64_arch_amd64.go +++ b/pkg/bits/uint64_arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_arch_amd64_asm.s b/pkg/bits/uint64_arch_amd64_asm.s index 8c7322f0f..8ff364181 100644 --- a/pkg/bits/uint64_arch_amd64_asm.s +++ b/pkg/bits/uint64_arch_amd64_asm.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_arch_generic.go b/pkg/bits/uint64_arch_generic.go index cfb47400b..7dd2d1480 100644 --- a/pkg/bits/uint64_arch_generic.go +++ b/pkg/bits/uint64_arch_generic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bits/uint64_test.go b/pkg/bits/uint64_test.go index d6dbaf602..1b018d808 100644 --- a/pkg/bits/uint64_test.go +++ b/pkg/bits/uint64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/bpf.go b/pkg/bpf/bpf.go index 98d44d911..eb546f48f 100644 --- a/pkg/bpf/bpf.go +++ b/pkg/bpf/bpf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/decoder.go b/pkg/bpf/decoder.go index ae6b8839a..45c192215 100644 --- a/pkg/bpf/decoder.go +++ b/pkg/bpf/decoder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/decoder_test.go b/pkg/bpf/decoder_test.go index f093e1e41..8c4bdad21 100644 --- a/pkg/bpf/decoder_test.go +++ b/pkg/bpf/decoder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/input_bytes.go b/pkg/bpf/input_bytes.go index 745c0749b..86b216cfc 100644 --- a/pkg/bpf/input_bytes.go +++ b/pkg/bpf/input_bytes.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/interpreter.go b/pkg/bpf/interpreter.go index 86c7add4d..86de523a2 100644 --- a/pkg/bpf/interpreter.go +++ b/pkg/bpf/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/interpreter_test.go b/pkg/bpf/interpreter_test.go index c46a43991..67b00ffe3 100644 --- a/pkg/bpf/interpreter_test.go +++ b/pkg/bpf/interpreter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/program_builder.go b/pkg/bpf/program_builder.go index b4ce228e1..fc9d27203 100644 --- a/pkg/bpf/program_builder.go +++ b/pkg/bpf/program_builder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/bpf/program_builder_test.go b/pkg/bpf/program_builder_test.go index 0e0b79d88..5b2ad67de 100644 --- a/pkg/bpf/program_builder_test.go +++ b/pkg/bpf/program_builder_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/compressio/compressio.go b/pkg/compressio/compressio.go index 4daaa82b6..8c14ccbfa 100644 --- a/pkg/compressio/compressio.go +++ b/pkg/compressio/compressio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/compressio/compressio_test.go b/pkg/compressio/compressio_test.go index 1bbabee79..86dc47e44 100644 --- a/pkg/compressio/compressio_test.go +++ b/pkg/compressio/compressio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/control/client/client.go b/pkg/control/client/client.go index 0d0c9f148..3fec27846 100644 --- a/pkg/control/client/client.go +++ b/pkg/control/client/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/control/server/server.go b/pkg/control/server/server.go index c46b5d70b..1a15da1a8 100644 --- a/pkg/control/server/server.go +++ b/pkg/control/server/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpu_amd64.s b/pkg/cpuid/cpu_amd64.s index 905c1d12e..ac80d3c8a 100644 --- a/pkg/cpuid/cpu_amd64.s +++ b/pkg/cpuid/cpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index 61441150e..3eb2bcd2b 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpuid_parse_test.go b/pkg/cpuid/cpuid_parse_test.go index e8f87a10e..dd9969db4 100644 --- a/pkg/cpuid/cpuid_parse_test.go +++ b/pkg/cpuid/cpuid_parse_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/cpuid/cpuid_test.go b/pkg/cpuid/cpuid_test.go index 64ade1cbe..6ae14d2da 100644 --- a/pkg/cpuid/cpuid_test.go +++ b/pkg/cpuid/cpuid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/client.go b/pkg/dhcp/client.go index 2ba79be32..b7cde3819 100644 --- a/pkg/dhcp/client.go +++ b/pkg/dhcp/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/dhcp.go b/pkg/dhcp/dhcp.go index 6945bcd35..f96ffd891 100644 --- a/pkg/dhcp/dhcp.go +++ b/pkg/dhcp/dhcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/dhcp_string.go b/pkg/dhcp/dhcp_string.go index 8533895bd..29ce98593 100644 --- a/pkg/dhcp/dhcp_string.go +++ b/pkg/dhcp/dhcp_string.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/dhcp_test.go b/pkg/dhcp/dhcp_test.go index e1d8ef603..751626bb0 100644 --- a/pkg/dhcp/dhcp_test.go +++ b/pkg/dhcp/dhcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/dhcp/server.go b/pkg/dhcp/server.go index 9549ff705..6a1972860 100644 --- a/pkg/dhcp/server.go +++ b/pkg/dhcp/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/eventchannel/event.go b/pkg/eventchannel/event.go index 41a7b5ed3..4c8ae573b 100644 --- a/pkg/eventchannel/event.go +++ b/pkg/eventchannel/event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/eventchannel/event.proto b/pkg/eventchannel/event.proto index c1679c7e7..34468f072 100644 --- a/pkg/eventchannel/event.proto +++ b/pkg/eventchannel/event.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fd/fd.go b/pkg/fd/fd.go index d40758c22..2785243a2 100644 --- a/pkg/fd/fd.go +++ b/pkg/fd/fd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fd/fd_test.go b/pkg/fd/fd_test.go index 42bb3ef6c..5fb0ad47d 100644 --- a/pkg/fd/fd_test.go +++ b/pkg/fd/fd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fdnotifier/fdnotifier.go b/pkg/fdnotifier/fdnotifier.go index aa4906ca0..f0b028b0b 100644 --- a/pkg/fdnotifier/fdnotifier.go +++ b/pkg/fdnotifier/fdnotifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/fdnotifier/poll_unsafe.go b/pkg/fdnotifier/poll_unsafe.go index 05be9aeb5..bc5e0ac44 100644 --- a/pkg/fdnotifier/poll_unsafe.go +++ b/pkg/fdnotifier/poll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 48122bf5a..bda6aae09 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/gate/gate_test.go b/pkg/gate/gate_test.go index 95620fa8e..7467e7d07 100644 --- a/pkg/gate/gate_test.go +++ b/pkg/gate/gate_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/ilist/list.go b/pkg/ilist/list.go index 51c9b6df3..019caadca 100644 --- a/pkg/ilist/list.go +++ b/pkg/ilist/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/ilist/list_test.go b/pkg/ilist/list_test.go index f37946dc2..3f9abfb56 100644 --- a/pkg/ilist/list_test.go +++ b/pkg/ilist/list_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/linewriter/linewriter.go b/pkg/linewriter/linewriter.go index 5fbd4e779..cd6e4e2ce 100644 --- a/pkg/linewriter/linewriter.go +++ b/pkg/linewriter/linewriter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/linewriter/linewriter_test.go b/pkg/linewriter/linewriter_test.go index 9140ee6af..96dc7e6e0 100644 --- a/pkg/linewriter/linewriter_test.go +++ b/pkg/linewriter/linewriter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/glog.go b/pkg/log/glog.go index 24d5390d7..5732785b4 100644 --- a/pkg/log/glog.go +++ b/pkg/log/glog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/glog_unsafe.go b/pkg/log/glog_unsafe.go index bb06aa7d3..ea17ae349 100644 --- a/pkg/log/glog_unsafe.go +++ b/pkg/log/glog_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/json.go b/pkg/log/json.go index 96bd13d87..a278c8fc8 100644 --- a/pkg/log/json.go +++ b/pkg/log/json.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/json_k8s.go b/pkg/log/json_k8s.go index 9c2f8d2b7..c2c019915 100644 --- a/pkg/log/json_k8s.go +++ b/pkg/log/json_k8s.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/json_test.go b/pkg/log/json_test.go index b8c7a795e..f25224fe1 100644 --- a/pkg/log/json_test.go +++ b/pkg/log/json_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/log.go b/pkg/log/log.go index b8d456aae..7d563241e 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go index a59d457dd..0634e7c1f 100644 --- a/pkg/log/log_test.go +++ b/pkg/log/log_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index e5eb95f89..803709cc4 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/metric/metric.proto b/pkg/metric/metric.proto index 917fda1ac..a2c2bd1ba 100644 --- a/pkg/metric/metric.proto +++ b/pkg/metric/metric.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/metric/metric_test.go b/pkg/metric/metric_test.go index 40034a589..b8b124c83 100644 --- a/pkg/metric/metric_test.go +++ b/pkg/metric/metric_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/buffer.go b/pkg/p9/buffer.go index b7bb14ef9..4c8c6555d 100644 --- a/pkg/p9/buffer.go +++ b/pkg/p9/buffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/buffer_test.go b/pkg/p9/buffer_test.go index 18d55e5c0..a9c75f86b 100644 --- a/pkg/p9/buffer_test.go +++ b/pkg/p9/buffer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/client.go b/pkg/p9/client.go index 67887874a..2f9c716d0 100644 --- a/pkg/p9/client.go +++ b/pkg/p9/client.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/client_file.go b/pkg/p9/client_file.go index 992d1daf7..63c65129a 100644 --- a/pkg/p9/client_file.go +++ b/pkg/p9/client_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/client_test.go b/pkg/p9/client_test.go index f7145452d..fc49729d8 100644 --- a/pkg/p9/client_test.go +++ b/pkg/p9/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/file.go b/pkg/p9/file.go index 55ceb52e1..a52a0f3e7 100644 --- a/pkg/p9/file.go +++ b/pkg/p9/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index c1d1ac1e8..6da2ce4e3 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/local_server/local_server.go b/pkg/p9/local_server/local_server.go index 69b90c6cd..f4077a9d4 100644 --- a/pkg/p9/local_server/local_server.go +++ b/pkg/p9/local_server/local_server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/messages.go b/pkg/p9/messages.go index 97decd3cc..833defbd6 100644 --- a/pkg/p9/messages.go +++ b/pkg/p9/messages.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/messages_test.go b/pkg/p9/messages_test.go index 68395a396..10a0587cf 100644 --- a/pkg/p9/messages_test.go +++ b/pkg/p9/messages_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9.go b/pkg/p9/p9.go index 4ea9f2f9a..78c7d3f86 100644 --- a/pkg/p9/p9.go +++ b/pkg/p9/p9.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9_test.go b/pkg/p9/p9_test.go index 02498346c..8dda6cc64 100644 --- a/pkg/p9/p9_test.go +++ b/pkg/p9/p9_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9test/client_test.go b/pkg/p9/p9test/client_test.go index 242d81b95..e00dd03ab 100644 --- a/pkg/p9/p9test/client_test.go +++ b/pkg/p9/p9test/client_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/p9test/p9test.go b/pkg/p9/p9test/p9test.go index f9bacbf84..1c8eff200 100644 --- a/pkg/p9/p9test/p9test.go +++ b/pkg/p9/p9test/p9test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/path_tree.go b/pkg/p9/path_tree.go index 60b20578e..f37ad4ab2 100644 --- a/pkg/p9/path_tree.go +++ b/pkg/p9/path_tree.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/pool.go b/pkg/p9/pool.go index 34ed898e8..52de889e1 100644 --- a/pkg/p9/pool.go +++ b/pkg/p9/pool.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/pool_test.go b/pkg/p9/pool_test.go index 71052d8c4..e4746b8da 100644 --- a/pkg/p9/pool_test.go +++ b/pkg/p9/pool_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/server.go b/pkg/p9/server.go index 3ef151595..b2a86d8fa 100644 --- a/pkg/p9/server.go +++ b/pkg/p9/server.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/transport.go b/pkg/p9/transport.go index bafb377de..ef59077ff 100644 --- a/pkg/p9/transport.go +++ b/pkg/p9/transport.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/transport_test.go b/pkg/p9/transport_test.go index b7b7825bd..c833d1c9c 100644 --- a/pkg/p9/transport_test.go +++ b/pkg/p9/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/version.go b/pkg/p9/version.go index ceb6fabbf..a36a499a1 100644 --- a/pkg/p9/version.go +++ b/pkg/p9/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/p9/version_test.go b/pkg/p9/version_test.go index c053614c9..291e8580e 100644 --- a/pkg/p9/version_test.go +++ b/pkg/p9/version_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/rand/rand.go b/pkg/rand/rand.go index 593a14380..a2714784d 100644 --- a/pkg/rand/rand.go +++ b/pkg/rand/rand.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/rand/rand_linux.go b/pkg/rand/rand_linux.go index 7ebe8f3b0..2b92db3e6 100644 --- a/pkg/rand/rand_linux.go +++ b/pkg/rand/rand_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/refs/refcounter.go b/pkg/refs/refcounter.go index 8f08c74c7..20f515391 100644 --- a/pkg/refs/refcounter.go +++ b/pkg/refs/refcounter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/refs/refcounter_state.go b/pkg/refs/refcounter_state.go index 136f06fbf..7c99fd2b5 100644 --- a/pkg/refs/refcounter_state.go +++ b/pkg/refs/refcounter_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/refs/refcounter_test.go b/pkg/refs/refcounter_test.go index abaa87453..ffd3d3f07 100644 --- a/pkg/refs/refcounter_test.go +++ b/pkg/refs/refcounter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index e113f3574..50c9409e4 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index a9278c64b..29eec8db1 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 11ed90eb4..47ecac6f7 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_test_victim.go b/pkg/seccomp/seccomp_test_victim.go index dd5ed0041..afc2f755f 100644 --- a/pkg/seccomp/seccomp_test_victim.go +++ b/pkg/seccomp/seccomp_test_victim.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/seccomp/seccomp_unsafe.go b/pkg/seccomp/seccomp_unsafe.go index a31c6471d..ccd40d9db 100644 --- a/pkg/seccomp/seccomp_unsafe.go +++ b/pkg/seccomp/seccomp_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/secio/full_reader.go b/pkg/secio/full_reader.go index 90b1772a7..aed2564bd 100644 --- a/pkg/secio/full_reader.go +++ b/pkg/secio/full_reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/secio/secio.go b/pkg/secio/secio.go index e5f74a497..b43226035 100644 --- a/pkg/secio/secio.go +++ b/pkg/secio/secio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/secio/secio_test.go b/pkg/secio/secio_test.go index 8304c4f74..d1d905187 100644 --- a/pkg/secio/secio_test.go +++ b/pkg/secio/secio_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/range.go b/pkg/segment/range.go index 057bcd7ff..4d4aeffef 100644 --- a/pkg/segment/range.go +++ b/pkg/segment/range.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/set.go b/pkg/segment/set.go index 74a916ea3..982eb3fdd 100644 --- a/pkg/segment/set.go +++ b/pkg/segment/set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/set_state.go b/pkg/segment/set_state.go index b86e1b75f..76de92591 100644 --- a/pkg/segment/set_state.go +++ b/pkg/segment/set_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/test/segment_test.go b/pkg/segment/test/segment_test.go index 0825105db..f19a005f3 100644 --- a/pkg/segment/test/segment_test.go +++ b/pkg/segment/test/segment_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/segment/test/set_functions.go b/pkg/segment/test/set_functions.go index 41f649011..bcddb39bb 100644 --- a/pkg/segment/test/set_functions.go +++ b/pkg/segment/test/set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/aligned.go b/pkg/sentry/arch/aligned.go index c88c034f6..df01a903d 100644 --- a/pkg/sentry/arch/aligned.go +++ b/pkg/sentry/arch/aligned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index 16d8eb2b2..53f0c9018 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go index 7ec2f2c84..135c2ee1f 100644 --- a/pkg/sentry/arch/arch_amd64.go +++ b/pkg/sentry/arch/arch_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_amd64.s b/pkg/sentry/arch/arch_amd64.s index fa9857df7..bd61402cf 100644 --- a/pkg/sentry/arch/arch_amd64.s +++ b/pkg/sentry/arch/arch_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go index 01949049d..bb52d8db0 100644 --- a/pkg/sentry/arch/arch_state_x86.go +++ b/pkg/sentry/arch/arch_state_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index 4305fe2cb..4d167ce98 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go index 5df65a691..80c923103 100644 --- a/pkg/sentry/arch/auxv.go +++ b/pkg/sentry/arch/auxv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/registers.proto b/pkg/sentry/arch/registers.proto index f4c2f7043..9dc83e241 100644 --- a/pkg/sentry/arch/registers.proto +++ b/pkg/sentry/arch/registers.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_act.go b/pkg/sentry/arch/signal_act.go index ad098c746..f9ca2e74e 100644 --- a/pkg/sentry/arch/signal_act.go +++ b/pkg/sentry/arch/signal_act.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go index 7f76eba27..aa030fd70 100644 --- a/pkg/sentry/arch/signal_amd64.go +++ b/pkg/sentry/arch/signal_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_info.go b/pkg/sentry/arch/signal_info.go index fa0ecbec5..f93ee8b46 100644 --- a/pkg/sentry/arch/signal_info.go +++ b/pkg/sentry/arch/signal_info.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/signal_stack.go b/pkg/sentry/arch/signal_stack.go index c02ae3b7c..a442f9fdc 100644 --- a/pkg/sentry/arch/signal_stack.go +++ b/pkg/sentry/arch/signal_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/stack.go b/pkg/sentry/arch/stack.go index 2e33ccdf5..7e6324e82 100644 --- a/pkg/sentry/arch/stack.go +++ b/pkg/sentry/arch/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/arch/syscalls_amd64.go b/pkg/sentry/arch/syscalls_amd64.go index 47c31d4b9..8b4f23007 100644 --- a/pkg/sentry/arch/syscalls_amd64.go +++ b/pkg/sentry/arch/syscalls_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go index eefc3e1b4..d70f3a5c3 100644 --- a/pkg/sentry/context/context.go +++ b/pkg/sentry/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/context/contexttest/contexttest.go b/pkg/sentry/context/contexttest/contexttest.go index a29087775..a42038711 100644 --- a/pkg/sentry/context/contexttest/contexttest.go +++ b/pkg/sentry/context/contexttest/contexttest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/control.go b/pkg/sentry/control/control.go index 32d30b6ea..6060b9b4f 100644 --- a/pkg/sentry/control/control.go +++ b/pkg/sentry/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/pprof.go b/pkg/sentry/control/pprof.go index 1af092af3..94ed149f2 100644 --- a/pkg/sentry/control/pprof.go +++ b/pkg/sentry/control/pprof.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index aca2267a7..f7f02a3e1 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/proc_test.go b/pkg/sentry/control/proc_test.go index 5d52cd829..b7895d03c 100644 --- a/pkg/sentry/control/proc_test.go +++ b/pkg/sentry/control/proc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/control/state.go b/pkg/sentry/control/state.go index b6bbf69fa..11efcaba1 100644 --- a/pkg/sentry/control/state.go +++ b/pkg/sentry/control/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/device/device.go b/pkg/sentry/device/device.go index ae4fa1d93..458d03b30 100644 --- a/pkg/sentry/device/device.go +++ b/pkg/sentry/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/device/device_test.go b/pkg/sentry/device/device_test.go index 5d8805c2f..e3f51ce4f 100644 --- a/pkg/sentry/device/device_test.go +++ b/pkg/sentry/device/device_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/anon/anon.go b/pkg/sentry/fs/anon/anon.go index a5e8c4f0d..a6ea8b9e7 100644 --- a/pkg/sentry/fs/anon/anon.go +++ b/pkg/sentry/fs/anon/anon.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/anon/device.go b/pkg/sentry/fs/anon/device.go index 2d1249299..5927bd11e 100644 --- a/pkg/sentry/fs/anon/device.go +++ b/pkg/sentry/fs/anon/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index 1f61c5711..b53746519 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index 5369d1b0d..5e005bc2e 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/pin_board.go b/pkg/sentry/fs/ashmem/pin_board.go index 7c997f533..bdf23b371 100644 --- a/pkg/sentry/fs/ashmem/pin_board.go +++ b/pkg/sentry/fs/ashmem/pin_board.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ashmem/pin_board_test.go b/pkg/sentry/fs/ashmem/pin_board_test.go index 736e628dc..24f5d86d6 100644 --- a/pkg/sentry/fs/ashmem/pin_board_test.go +++ b/pkg/sentry/fs/ashmem/pin_board_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index 3523b068a..591e35e6a 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index d9f1559de..acbbd5466 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/context.go b/pkg/sentry/fs/context.go index 4869428a8..c80ea0175 100644 --- a/pkg/sentry/fs/context.go +++ b/pkg/sentry/fs/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/copy_up.go b/pkg/sentry/fs/copy_up.go index ba69e718d..ee2d3d115 100644 --- a/pkg/sentry/fs/copy_up.go +++ b/pkg/sentry/fs/copy_up.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/copy_up_test.go b/pkg/sentry/fs/copy_up_test.go index 98a0b7638..54810afca 100644 --- a/pkg/sentry/fs/copy_up_test.go +++ b/pkg/sentry/fs/copy_up_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dentry.go b/pkg/sentry/fs/dentry.go index 29fb155a4..fe656cc24 100644 --- a/pkg/sentry/fs/dentry.go +++ b/pkg/sentry/fs/dentry.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index fbc750a71..34ac01173 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/device.go b/pkg/sentry/fs/dev/device.go index 3cecdf6e2..9f4e41fc9 100644 --- a/pkg/sentry/fs/dev/device.go +++ b/pkg/sentry/fs/dev/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go index cf4e7d00f..6096a40f8 100644 --- a/pkg/sentry/fs/dev/fs.go +++ b/pkg/sentry/fs/dev/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 82da9aae9..6b11afa44 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 5d306d352..069212b6d 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index ffd5cf6c3..de0f3e5e5 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 54fc11fe1..c0bc261a2 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_cache.go b/pkg/sentry/fs/dirent_cache.go index d26a06971..71f2d11de 100644 --- a/pkg/sentry/fs/dirent_cache.go +++ b/pkg/sentry/fs/dirent_cache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_cache_limiter.go b/pkg/sentry/fs/dirent_cache_limiter.go index 024c7b2d5..ebb80bd50 100644 --- a/pkg/sentry/fs/dirent_cache_limiter.go +++ b/pkg/sentry/fs/dirent_cache_limiter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_cache_test.go b/pkg/sentry/fs/dirent_cache_test.go index 93e8d415f..395c879f5 100644 --- a/pkg/sentry/fs/dirent_cache_test.go +++ b/pkg/sentry/fs/dirent_cache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go index 325404e27..db88d850e 100644 --- a/pkg/sentry/fs/dirent_refs_test.go +++ b/pkg/sentry/fs/dirent_refs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/dirent_state.go b/pkg/sentry/fs/dirent_state.go index 5cf151dab..18652b809 100644 --- a/pkg/sentry/fs/dirent_state.go +++ b/pkg/sentry/fs/dirent_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 98483ab68..95e66ea8d 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go index 92ab6ff0e..0cabe2e18 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go index 69516e048..8c8b1b40c 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_state.go b/pkg/sentry/fs/fdpipe/pipe_state.go index 4395666ad..8b347aa11 100644 --- a/pkg/sentry/fs/fdpipe/pipe_state.go +++ b/pkg/sentry/fs/fdpipe/pipe_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go index 7e3ee5257..b59a6aa0e 100644 --- a/pkg/sentry/fs/fdpipe/pipe_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 5d5026661..62b35dabc 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go index e0fa5135f..ab0acb6eb 100644 --- a/pkg/sentry/fs/file_operations.go +++ b/pkg/sentry/fs/file_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 6e680f0a4..948ce9c6f 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_overlay_test.go b/pkg/sentry/fs/file_overlay_test.go index a4ac58763..6a2b8007c 100644 --- a/pkg/sentry/fs/file_overlay_test.go +++ b/pkg/sentry/fs/file_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_state.go b/pkg/sentry/fs/file_state.go index 1c3bae3e8..523182d59 100644 --- a/pkg/sentry/fs/file_state.go +++ b/pkg/sentry/fs/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/file_test.go b/pkg/sentry/fs/file_test.go index f3ed9a70b..d867a0257 100644 --- a/pkg/sentry/fs/file_test.go +++ b/pkg/sentry/fs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go index a6b27c402..acd84dfcc 100644 --- a/pkg/sentry/fs/filesystems.go +++ b/pkg/sentry/fs/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go index 388a1ce36..f6b827800 100644 --- a/pkg/sentry/fs/filetest/filetest.go +++ b/pkg/sentry/fs/filetest/filetest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go index bf2a20b33..5c8cb773f 100644 --- a/pkg/sentry/fs/flags.go +++ b/pkg/sentry/fs/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go index 119689776..632055cce 100644 --- a/pkg/sentry/fs/fs.go +++ b/pkg/sentry/fs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go index 5add16ac4..9cd196d7d 100644 --- a/pkg/sentry/fs/fsutil/dirty_set.go +++ b/pkg/sentry/fs/fsutil/dirty_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/dirty_set_test.go b/pkg/sentry/fs/fsutil/dirty_set_test.go index f5c9d9215..d9c68baa3 100644 --- a/pkg/sentry/fs/fsutil/dirty_set_test.go +++ b/pkg/sentry/fs/fsutil/dirty_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index 42afdd11c..e355d8594 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/file_range_set.go b/pkg/sentry/fs/fsutil/file_range_set.go index 32ebf64ff..b5ac6c71c 100644 --- a/pkg/sentry/fs/fsutil/file_range_set.go +++ b/pkg/sentry/fs/fsutil/file_range_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/frame_ref_set.go b/pkg/sentry/fs/fsutil/frame_ref_set.go index b6e783614..6565c28c8 100644 --- a/pkg/sentry/fs/fsutil/frame_ref_set.go +++ b/pkg/sentry/fs/fsutil/frame_ref_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/fsutil.go b/pkg/sentry/fs/fsutil/fsutil.go index 319c4841b..c9587b1d9 100644 --- a/pkg/sentry/fs/fsutil/fsutil.go +++ b/pkg/sentry/fs/fsutil/fsutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index 9599665f0..2bdfc0db6 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_state.go b/pkg/sentry/fs/fsutil/host_file_mapper_state.go index bbd15b30b..576d2a3df 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_state.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go index 86df76822..7167be263 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/host_mappable.go b/pkg/sentry/fs/fsutil/host_mappable.go index 4a182baa1..28686f3b3 100644 --- a/pkg/sentry/fs/fsutil/host_mappable.go +++ b/pkg/sentry/fs/fsutil/host_mappable.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index 468171a9b..b6366d906 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index ba33b9912..919d2534c 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go index 2a8a1639c..661ec41f6 100644 --- a/pkg/sentry/fs/fsutil/inode_cached_test.go +++ b/pkg/sentry/fs/fsutil/inode_cached_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/attr.go b/pkg/sentry/fs/gofer/attr.go index 98700d014..c572f3396 100644 --- a/pkg/sentry/fs/gofer/attr.go +++ b/pkg/sentry/fs/gofer/attr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/cache_policy.go b/pkg/sentry/fs/gofer/cache_policy.go index 51c573aef..35cd0c1d6 100644 --- a/pkg/sentry/fs/gofer/cache_policy.go +++ b/pkg/sentry/fs/gofer/cache_policy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/context_file.go b/pkg/sentry/fs/gofer/context_file.go index 455953237..d512afefc 100644 --- a/pkg/sentry/fs/gofer/context_file.go +++ b/pkg/sentry/fs/gofer/context_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/device.go b/pkg/sentry/fs/gofer/device.go index 52c5acf48..1de6c247c 100644 --- a/pkg/sentry/fs/gofer/device.go +++ b/pkg/sentry/fs/gofer/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 35caa42cd..bc2be546e 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go index d0c64003c..31264e065 100644 --- a/pkg/sentry/fs/gofer/file_state.go +++ b/pkg/sentry/fs/gofer/file_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go index adff0abac..6ab89fcc2 100644 --- a/pkg/sentry/fs/gofer/fs.go +++ b/pkg/sentry/fs/gofer/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/gofer_test.go b/pkg/sentry/fs/gofer/gofer_test.go index 36201f017..29d34da7e 100644 --- a/pkg/sentry/fs/gofer/gofer_test.go +++ b/pkg/sentry/fs/gofer/gofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/handles.go b/pkg/sentry/fs/gofer/handles.go index 0b33e80c3..c7098cd36 100644 --- a/pkg/sentry/fs/gofer/handles.go +++ b/pkg/sentry/fs/gofer/handles.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index 1181a24cc..f6f20844d 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go index 44d76ba9f..ac22ee4b1 100644 --- a/pkg/sentry/fs/gofer/inode_state.go +++ b/pkg/sentry/fs/gofer/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/path.go b/pkg/sentry/fs/gofer/path.go index 8ae33d286..4cbf9e9d9 100644 --- a/pkg/sentry/fs/gofer/path.go +++ b/pkg/sentry/fs/gofer/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go index 4ed688ce5..4cb65e7c6 100644 --- a/pkg/sentry/fs/gofer/session.go +++ b/pkg/sentry/fs/gofer/session.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/session_state.go b/pkg/sentry/fs/gofer/session_state.go index b1f299be5..68fbf3417 100644 --- a/pkg/sentry/fs/gofer/session_state.go +++ b/pkg/sentry/fs/gofer/session_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/socket.go b/pkg/sentry/fs/gofer/socket.go index ce6d3d5c3..cbd5b9a84 100644 --- a/pkg/sentry/fs/gofer/socket.go +++ b/pkg/sentry/fs/gofer/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/gofer/util.go b/pkg/sentry/fs/gofer/util.go index 1a759370d..d0e1096ce 100644 --- a/pkg/sentry/fs/gofer/util.go +++ b/pkg/sentry/fs/gofer/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/control.go b/pkg/sentry/fs/host/control.go index 0753640a2..480f0c8f4 100644 --- a/pkg/sentry/fs/host/control.go +++ b/pkg/sentry/fs/host/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index 554e1693a..ffcd57a94 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/descriptor_state.go b/pkg/sentry/fs/host/descriptor_state.go index 530c0109f..8167390a9 100644 --- a/pkg/sentry/fs/host/descriptor_state.go +++ b/pkg/sentry/fs/host/descriptor_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/descriptor_test.go b/pkg/sentry/fs/host/descriptor_test.go index 5dec84ab2..ff08e43af 100644 --- a/pkg/sentry/fs/host/descriptor_test.go +++ b/pkg/sentry/fs/host/descriptor_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/device.go b/pkg/sentry/fs/host/device.go index b5adedf44..055024c44 100644 --- a/pkg/sentry/fs/host/device.go +++ b/pkg/sentry/fs/host/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index 2a8f285ff..82e2ae3b9 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go index de349a41a..b1b8dc0b6 100644 --- a/pkg/sentry/fs/host/fs.go +++ b/pkg/sentry/fs/host/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/fs_test.go b/pkg/sentry/fs/host/fs_test.go index c83b29a16..16c89ddf1 100644 --- a/pkg/sentry/fs/host/fs_test.go +++ b/pkg/sentry/fs/host/fs_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 69c648f67..20e077f77 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/inode_state.go b/pkg/sentry/fs/host/inode_state.go index b7c1a9581..26cc755bc 100644 --- a/pkg/sentry/fs/host/inode_state.go +++ b/pkg/sentry/fs/host/inode_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go index 9f1561bd5..ad1878b5a 100644 --- a/pkg/sentry/fs/host/inode_test.go +++ b/pkg/sentry/fs/host/inode_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/ioctl_unsafe.go b/pkg/sentry/fs/host/ioctl_unsafe.go index 175dca613..b5a85c4d9 100644 --- a/pkg/sentry/fs/host/ioctl_unsafe.go +++ b/pkg/sentry/fs/host/ioctl_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index be2c3581f..3034e9441 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_iovec.go b/pkg/sentry/fs/host/socket_iovec.go index d4ce4a8c1..5efbb3ae8 100644 --- a/pkg/sentry/fs/host/socket_iovec.go +++ b/pkg/sentry/fs/host/socket_iovec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_state.go b/pkg/sentry/fs/host/socket_state.go index 2932c1f16..5676c451a 100644 --- a/pkg/sentry/fs/host/socket_state.go +++ b/pkg/sentry/fs/host/socket_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go index 83e8e1b3c..cc760a7e1 100644 --- a/pkg/sentry/fs/host/socket_test.go +++ b/pkg/sentry/fs/host/socket_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/socket_unsafe.go b/pkg/sentry/fs/host/socket_unsafe.go index f35e2492d..8873705c0 100644 --- a/pkg/sentry/fs/host/socket_unsafe.go +++ b/pkg/sentry/fs/host/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go index c5cb75df7..e45b339f5 100644 --- a/pkg/sentry/fs/host/tty.go +++ b/pkg/sentry/fs/host/tty.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/util.go b/pkg/sentry/fs/host/util.go index 40c450660..94ff7708e 100644 --- a/pkg/sentry/fs/host/util.go +++ b/pkg/sentry/fs/host/util.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/util_unsafe.go b/pkg/sentry/fs/host/util_unsafe.go index a8721d197..b95a57c3f 100644 --- a/pkg/sentry/fs/host/util_unsafe.go +++ b/pkg/sentry/fs/host/util_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go index 9ca8c399f..afcb74724 100644 --- a/pkg/sentry/fs/host/wait_test.go +++ b/pkg/sentry/fs/host/wait_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index fe411a766..d764ef93d 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_inotify.go b/pkg/sentry/fs/inode_inotify.go index d2b653bc7..0f2a66a79 100644 --- a/pkg/sentry/fs/inode_inotify.go +++ b/pkg/sentry/fs/inode_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index ff8b75f31..ac287e1e4 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index bda3e1861..3d015328e 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go index fa8accf6c..66b3da2d0 100644 --- a/pkg/sentry/fs/inode_overlay_test.go +++ b/pkg/sentry/fs/inode_overlay_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 59fa662f3..2652582c3 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index f09928b68..d52f956e4 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/inotify_watch.go b/pkg/sentry/fs/inotify_watch.go index d33e7e498..a0b488467 100644 --- a/pkg/sentry/fs/inotify_watch.go +++ b/pkg/sentry/fs/inotify_watch.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 5ff800d2d..f2aee4512 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock_range_test.go b/pkg/sentry/fs/lock/lock_range_test.go index b0ab882b9..6221199d1 100644 --- a/pkg/sentry/fs/lock/lock_range_test.go +++ b/pkg/sentry/fs/lock/lock_range_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock_set_functions.go b/pkg/sentry/fs/lock/lock_set_functions.go index 395592a4b..8a3ace0c1 100644 --- a/pkg/sentry/fs/lock/lock_set_functions.go +++ b/pkg/sentry/fs/lock/lock_set_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/lock/lock_test.go b/pkg/sentry/fs/lock/lock_test.go index 67fa4b1dd..ba002aeb7 100644 --- a/pkg/sentry/fs/lock/lock_test.go +++ b/pkg/sentry/fs/lock/lock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go index 118e30f63..cf359a1f1 100644 --- a/pkg/sentry/fs/mock.go +++ b/pkg/sentry/fs/mock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go index 4d1693204..a169ea4c9 100644 --- a/pkg/sentry/fs/mount.go +++ b/pkg/sentry/fs/mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go index fb60a1aec..535f812c8 100644 --- a/pkg/sentry/fs/mount_overlay.go +++ b/pkg/sentry/fs/mount_overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mount_test.go b/pkg/sentry/fs/mount_test.go index d7605b2c9..9f7fbeff2 100644 --- a/pkg/sentry/fs/mount_test.go +++ b/pkg/sentry/fs/mount_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index f6f7be0aa..01eb4607e 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/mounts_test.go b/pkg/sentry/fs/mounts_test.go index 54000614f..56d726dd1 100644 --- a/pkg/sentry/fs/mounts_test.go +++ b/pkg/sentry/fs/mounts_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/offset.go b/pkg/sentry/fs/offset.go index 38aee765a..3f68da149 100644 --- a/pkg/sentry/fs/offset.go +++ b/pkg/sentry/fs/offset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go index f3e2d5cbe..db89a5f70 100644 --- a/pkg/sentry/fs/overlay.go +++ b/pkg/sentry/fs/overlay.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/path.go b/pkg/sentry/fs/path.go index 52139b648..e4dc02dbb 100644 --- a/pkg/sentry/fs/path.go +++ b/pkg/sentry/fs/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/path_test.go b/pkg/sentry/fs/path_test.go index 4ba1498f6..e6f57ebba 100644 --- a/pkg/sentry/fs/path_test.go +++ b/pkg/sentry/fs/path_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go index f756c45bf..15031234e 100644 --- a/pkg/sentry/fs/proc/cpuinfo.go +++ b/pkg/sentry/fs/proc/cpuinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/device/device.go b/pkg/sentry/fs/proc/device/device.go index 04b687bcf..0de466c73 100644 --- a/pkg/sentry/fs/proc/device/device.go +++ b/pkg/sentry/fs/proc/device/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index fc21dfbbd..d49dad685 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go index f2329e623..744b31c74 100644 --- a/pkg/sentry/fs/proc/fds.go +++ b/pkg/sentry/fs/proc/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go index c050a00be..7bb081d0e 100644 --- a/pkg/sentry/fs/proc/filesystems.go +++ b/pkg/sentry/fs/proc/filesystems.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go index 666a2d054..7c5f8484a 100644 --- a/pkg/sentry/fs/proc/fs.go +++ b/pkg/sentry/fs/proc/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/inode.go b/pkg/sentry/fs/proc/inode.go index 8dde2ea46..b03807043 100644 --- a/pkg/sentry/fs/proc/inode.go +++ b/pkg/sentry/fs/proc/inode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go index 3ee0e570a..2dfe7089a 100644 --- a/pkg/sentry/fs/proc/loadavg.go +++ b/pkg/sentry/fs/proc/loadavg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go index 75cbf3e77..d2b9b92c7 100644 --- a/pkg/sentry/fs/proc/meminfo.go +++ b/pkg/sentry/fs/proc/meminfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index fe62b167b..37ed30724 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go index d24b2d370..4a107c739 100644 --- a/pkg/sentry/fs/proc/net.go +++ b/pkg/sentry/fs/proc/net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/net_test.go b/pkg/sentry/fs/proc/net_test.go index 94677cc1d..9aed5fdca 100644 --- a/pkg/sentry/fs/proc/net_test.go +++ b/pkg/sentry/fs/proc/net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go index 64e1e1998..196fa5128 100644 --- a/pkg/sentry/fs/proc/proc.go +++ b/pkg/sentry/fs/proc/proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/rpcinet_proc.go b/pkg/sentry/fs/proc/rpcinet_proc.go index 81f64a28b..db53686f6 100644 --- a/pkg/sentry/fs/proc/rpcinet_proc.go +++ b/pkg/sentry/fs/proc/rpcinet_proc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 0a0eb45e2..10ea1f55d 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go index 35403ab7f..c4de565eb 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go index 18bd8e9b6..397f9ec6b 100644 --- a/pkg/sentry/fs/proc/stat.go +++ b/pkg/sentry/fs/proc/stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index a7bc9198e..b889ed625 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index 0ce77f04f..e49794a48 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys_net_state.go b/pkg/sentry/fs/proc/sys_net_state.go index 5f481a1cf..6eba709c6 100644 --- a/pkg/sentry/fs/proc/sys_net_state.go +++ b/pkg/sentry/fs/proc/sys_net_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go index ea0d94fce..78135ba13 100644 --- a/pkg/sentry/fs/proc/sys_net_test.go +++ b/pkg/sentry/fs/proc/sys_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 9f65a8337..0f400e80f 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index d433632cf..d649da0f1 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index d7ae26fcf..1ddf9fafa 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go index 58e0c793c..a5479990c 100644 --- a/pkg/sentry/fs/proc/version.go +++ b/pkg/sentry/fs/proc/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index c0400b67d..a6b6a5c33 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 5bcb6c364..9406a07ca 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index 35dabdad2..f7835fe05 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/tree.go b/pkg/sentry/fs/ramfs/tree.go index c1ac8a78b..8c6b31f70 100644 --- a/pkg/sentry/fs/ramfs/tree.go +++ b/pkg/sentry/fs/ramfs/tree.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/ramfs/tree_test.go b/pkg/sentry/fs/ramfs/tree_test.go index 8bee9cfc1..27abeb6ba 100644 --- a/pkg/sentry/fs/ramfs/tree_test.go +++ b/pkg/sentry/fs/ramfs/tree_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/restore.go b/pkg/sentry/fs/restore.go index a6645b41e..f10168125 100644 --- a/pkg/sentry/fs/restore.go +++ b/pkg/sentry/fs/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/save.go b/pkg/sentry/fs/save.go index 90988d385..2eaf6ab69 100644 --- a/pkg/sentry/fs/save.go +++ b/pkg/sentry/fs/save.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/seek.go b/pkg/sentry/fs/seek.go index 72f3fb632..0f43918ad 100644 --- a/pkg/sentry/fs/seek.go +++ b/pkg/sentry/fs/seek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sync.go b/pkg/sentry/fs/sync.go index 6dcc2fe8d..1fff8059c 100644 --- a/pkg/sentry/fs/sync.go +++ b/pkg/sentry/fs/sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/device.go b/pkg/sentry/fs/sys/device.go index 38ecd0c18..128d3a9d9 100644 --- a/pkg/sentry/fs/sys/device.go +++ b/pkg/sentry/fs/sys/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go index 8b728a4e4..db91de435 100644 --- a/pkg/sentry/fs/sys/devices.go +++ b/pkg/sentry/fs/sys/devices.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go index 44ae43754..f0c2322e0 100644 --- a/pkg/sentry/fs/sys/fs.go +++ b/pkg/sentry/fs/sys/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go index c5b56fe69..d20ef91fa 100644 --- a/pkg/sentry/fs/sys/sys.go +++ b/pkg/sentry/fs/sys/sys.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index ef9a08854..749961f51 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/device.go b/pkg/sentry/fs/tmpfs/device.go index aade93c26..179c3a46f 100644 --- a/pkg/sentry/fs/tmpfs/device.go +++ b/pkg/sentry/fs/tmpfs/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index d0c9b8bea..1ef256511 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/file_test.go b/pkg/sentry/fs/tmpfs/file_test.go index 743061190..b44c06556 100644 --- a/pkg/sentry/fs/tmpfs/file_test.go +++ b/pkg/sentry/fs/tmpfs/file_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go index 8e44421b6..b7c29a4d1 100644 --- a/pkg/sentry/fs/tmpfs/fs.go +++ b/pkg/sentry/fs/tmpfs/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index 4450e1363..f89d86c83 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 5bb4922cb..832914453 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index f8713471a..0fc777e67 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go index a53448c47..701b2f7d9 100644 --- a/pkg/sentry/fs/tty/fs.go +++ b/pkg/sentry/fs/tty/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go index c4a364edb..20d29d130 100644 --- a/pkg/sentry/fs/tty/line_discipline.go +++ b/pkg/sentry/fs/tty/line_discipline.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index e2686a074..45e167e5f 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go index 5e88d84d9..11fb92be3 100644 --- a/pkg/sentry/fs/tty/queue.go +++ b/pkg/sentry/fs/tty/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index ed080ca0f..0ae57a02c 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go index 79f9d76d7..2b4160ba5 100644 --- a/pkg/sentry/fs/tty/terminal.go +++ b/pkg/sentry/fs/tty/terminal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/fs/tty/tty_test.go b/pkg/sentry/fs/tty/tty_test.go index ad535838f..d2e75a511 100644 --- a/pkg/sentry/fs/tty/tty_test.go +++ b/pkg/sentry/fs/tty/tty_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/hostcpu/getcpu_amd64.s b/pkg/sentry/hostcpu/getcpu_amd64.s index 409db1450..aa00316da 100644 --- a/pkg/sentry/hostcpu/getcpu_amd64.s +++ b/pkg/sentry/hostcpu/getcpu_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/hostcpu/hostcpu.go b/pkg/sentry/hostcpu/hostcpu.go index 3adc847bb..d78f78402 100644 --- a/pkg/sentry/hostcpu/hostcpu.go +++ b/pkg/sentry/hostcpu/hostcpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/hostcpu/hostcpu_test.go b/pkg/sentry/hostcpu/hostcpu_test.go index 38de0e1f6..7d6885c9e 100644 --- a/pkg/sentry/hostcpu/hostcpu_test.go +++ b/pkg/sentry/hostcpu/hostcpu_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/inet/context.go b/pkg/sentry/inet/context.go index d05e96f15..8550c4793 100644 --- a/pkg/sentry/inet/context.go +++ b/pkg/sentry/inet/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/inet/inet.go b/pkg/sentry/inet/inet.go index 8206377cc..7c104fd47 100644 --- a/pkg/sentry/inet/inet.go +++ b/pkg/sentry/inet/inet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/inet/test_stack.go b/pkg/sentry/inet/test_stack.go index 05c1a1792..624371eb6 100644 --- a/pkg/sentry/inet/test_stack.go +++ b/pkg/sentry/inet/test_stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 1ea2cee36..5ce52e66c 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/auth.go b/pkg/sentry/kernel/auth/auth.go index 19f15fd36..847d121aa 100644 --- a/pkg/sentry/kernel/auth/auth.go +++ b/pkg/sentry/kernel/auth/auth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/capability_set.go b/pkg/sentry/kernel/auth/capability_set.go index 88d6243aa..7a0c967cd 100644 --- a/pkg/sentry/kernel/auth/capability_set.go +++ b/pkg/sentry/kernel/auth/capability_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/context.go b/pkg/sentry/kernel/auth/context.go index f7e945599..16d110610 100644 --- a/pkg/sentry/kernel/auth/context.go +++ b/pkg/sentry/kernel/auth/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index 2055da196..1511a0324 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/id.go b/pkg/sentry/kernel/auth/id.go index e5bed44d7..0a58ba17c 100644 --- a/pkg/sentry/kernel/auth/id.go +++ b/pkg/sentry/kernel/auth/id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index 43f439825..e5d6028d6 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/id_map_functions.go b/pkg/sentry/kernel/auth/id_map_functions.go index 8f1a189ec..432dbfb6d 100644 --- a/pkg/sentry/kernel/auth/id_map_functions.go +++ b/pkg/sentry/kernel/auth/id_map_functions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 159940a69..a40dd668f 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/context.go b/pkg/sentry/kernel/context.go index b629521eb..a1a084eab 100644 --- a/pkg/sentry/kernel/context.go +++ b/pkg/sentry/kernel/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/contexttest/contexttest.go b/pkg/sentry/kernel/contexttest/contexttest.go index eb56a6a07..ae67e2a25 100644 --- a/pkg/sentry/kernel/contexttest/contexttest.go +++ b/pkg/sentry/kernel/contexttest/contexttest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index befefb11c..2399ae6f2 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/epoll/epoll_state.go b/pkg/sentry/kernel/epoll/epoll_state.go index f6e3e4825..4c3c38f9e 100644 --- a/pkg/sentry/kernel/epoll/epoll_state.go +++ b/pkg/sentry/kernel/epoll/epoll_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/epoll/epoll_test.go b/pkg/sentry/kernel/epoll/epoll_test.go index d89c1b745..49b781b69 100644 --- a/pkg/sentry/kernel/epoll/epoll_test.go +++ b/pkg/sentry/kernel/epoll/epoll_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index b448ad813..5d3139eef 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/eventfd/eventfd_test.go b/pkg/sentry/kernel/eventfd/eventfd_test.go index 14e8996d9..1159638e5 100644 --- a/pkg/sentry/kernel/eventfd/eventfd_test.go +++ b/pkg/sentry/kernel/eventfd/eventfd_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go index 298d988ea..84cd08501 100644 --- a/pkg/sentry/kernel/fasync/fasync.go +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index 715f4714d..c5636d233 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fd_map_test.go b/pkg/sentry/kernel/fd_map_test.go index 9e76f0a2d..22db4c7cf 100644 --- a/pkg/sentry/kernel/fd_map_test.go +++ b/pkg/sentry/kernel/fd_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index 3cf0db280..d8115f59a 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index cd7d51621..bb38eb81e 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/futex/futex_test.go b/pkg/sentry/kernel/futex/futex_test.go index 9d44ee8e5..2de5239bf 100644 --- a/pkg/sentry/kernel/futex/futex_test.go +++ b/pkg/sentry/kernel/futex/futex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 9ceb9bd92..ebe12812c 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/kdefs/kdefs.go b/pkg/sentry/kernel/kdefs/kdefs.go index 8eafe810b..304da2032 100644 --- a/pkg/sentry/kernel/kdefs/kdefs.go +++ b/pkg/sentry/kernel/kdefs/kdefs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index a1b2d7161..0468dd678 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/kernel_state.go b/pkg/sentry/kernel/kernel_state.go index aae6f9ad2..48c3ff5a9 100644 --- a/pkg/sentry/kernel/kernel_state.go +++ b/pkg/sentry/kernel/kernel_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/memevent/memory_events.go b/pkg/sentry/kernel/memevent/memory_events.go index d09d6debf..0e2cee807 100644 --- a/pkg/sentry/kernel/memevent/memory_events.go +++ b/pkg/sentry/kernel/memevent/memory_events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/memevent/memory_events.proto b/pkg/sentry/kernel/memevent/memory_events.proto index 43b8deb76..bf8029ff5 100644 --- a/pkg/sentry/kernel/memevent/memory_events.proto +++ b/pkg/sentry/kernel/memevent/memory_events.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index deff6def9..c93f6598a 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pending_signals_state.go b/pkg/sentry/kernel/pending_signals_state.go index 72be6702f..2c902c7e3 100644 --- a/pkg/sentry/kernel/pending_signals_state.go +++ b/pkg/sentry/kernel/pending_signals_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index 54e059f8b..ba53fd482 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/device.go b/pkg/sentry/kernel/pipe/device.go index eec5c5de8..eb59e15a1 100644 --- a/pkg/sentry/kernel/pipe/device.go +++ b/pkg/sentry/kernel/pipe/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 1336b6293..99188dddf 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/node_test.go b/pkg/sentry/kernel/pipe/node_test.go index ad103b195..7ddecdad8 100644 --- a/pkg/sentry/kernel/pipe/node_test.go +++ b/pkg/sentry/kernel/pipe/node_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index 357d1162e..bd7649d2f 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/pipe_test.go b/pkg/sentry/kernel/pipe/pipe_test.go index 3b9895927..de340c40c 100644 --- a/pkg/sentry/kernel/pipe/pipe_test.go +++ b/pkg/sentry/kernel/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index f27379969..48fab45d1 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 1090432d7..ddcc5e09a 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index 6fea9769c..0f29fbc43 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/posixtimer.go b/pkg/sentry/kernel/posixtimer.go index 40b5acca3..a016b4087 100644 --- a/pkg/sentry/kernel/posixtimer.go +++ b/pkg/sentry/kernel/posixtimer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 15f2e2964..4423e7efd 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/ptrace_amd64.go b/pkg/sentry/kernel/ptrace_amd64.go index 1f88efca3..048eeaa3f 100644 --- a/pkg/sentry/kernel/ptrace_amd64.go +++ b/pkg/sentry/kernel/ptrace_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2019 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. diff --git a/pkg/sentry/kernel/ptrace_arm64.go b/pkg/sentry/kernel/ptrace_arm64.go index 4636405e6..4899c813f 100644 --- a/pkg/sentry/kernel/ptrace_arm64.go +++ b/pkg/sentry/kernel/ptrace_arm64.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2019 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. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 6d3314e81..c4fb2c56c 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sched/cpuset.go b/pkg/sentry/kernel/sched/cpuset.go index 41ac1067d..c6c436690 100644 --- a/pkg/sentry/kernel/sched/cpuset.go +++ b/pkg/sentry/kernel/sched/cpuset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sched/cpuset_test.go b/pkg/sentry/kernel/sched/cpuset_test.go index a036ed513..3af9f1197 100644 --- a/pkg/sentry/kernel/sched/cpuset_test.go +++ b/pkg/sentry/kernel/sched/cpuset_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sched/sched.go b/pkg/sentry/kernel/sched/sched.go index e59909baf..de18c9d02 100644 --- a/pkg/sentry/kernel/sched/sched.go +++ b/pkg/sentry/kernel/sched/sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index 4bed4d373..cc75eb08a 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index 2b7c1a9bc..9d0620e02 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go index 2e51e6ee5..abfcd0fb4 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_test.go +++ b/pkg/sentry/kernel/semaphore/semaphore_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index 070c2f930..610e199da 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/shm/device.go b/pkg/sentry/kernel/shm/device.go index bbc653ed8..3cb759072 100644 --- a/pkg/sentry/kernel/shm/device.go +++ b/pkg/sentry/kernel/shm/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index d4812a065..00393b5f0 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/signal.go b/pkg/sentry/kernel/signal.go index 22a56c6fc..b528ec0dc 100644 --- a/pkg/sentry/kernel/signal.go +++ b/pkg/sentry/kernel/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 60cbe85b8..ce8bcb5e5 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 293b21249..0572053db 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/syscalls_state.go b/pkg/sentry/kernel/syscalls_state.go index 981455d46..00358326b 100644 --- a/pkg/sentry/kernel/syscalls_state.go +++ b/pkg/sentry/kernel/syscalls_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 2aecf3eea..175d1b247 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/table_test.go b/pkg/sentry/kernel/table_test.go index 3b29d3c6a..8f7cdb9f3 100644 --- a/pkg/sentry/kernel/table_test.go +++ b/pkg/sentry/kernel/table_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index ed2175c37..f9378c2de 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_acct.go b/pkg/sentry/kernel/task_acct.go index 24230af89..1ca2a82eb 100644 --- a/pkg/sentry/kernel/task_acct.go +++ b/pkg/sentry/kernel/task_acct.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_block.go b/pkg/sentry/kernel/task_block.go index e5027e551..30a7f6b1e 100644 --- a/pkg/sentry/kernel/task_block.go +++ b/pkg/sentry/kernel/task_block.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index daf974920..bba8ddd39 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index ac38dd157..bbd294141 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index b49f902a5..5d1425d5c 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index a07956208..6e9701b01 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_futex.go b/pkg/sentry/kernel/task_futex.go index 351cf47d7..f98097c2c 100644 --- a/pkg/sentry/kernel/task_futex.go +++ b/pkg/sentry/kernel/task_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_identity.go b/pkg/sentry/kernel/task_identity.go index 6c9608f8d..17f08729a 100644 --- a/pkg/sentry/kernel/task_identity.go +++ b/pkg/sentry/kernel/task_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_log.go b/pkg/sentry/kernel/task_log.go index f4c881c2d..e0e57e8bd 100644 --- a/pkg/sentry/kernel/task_log.go +++ b/pkg/sentry/kernel/task_log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_net.go b/pkg/sentry/kernel/task_net.go index fc7cefc1f..04c684c1a 100644 --- a/pkg/sentry/kernel/task_net.go +++ b/pkg/sentry/kernel/task_net.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 7115aa967..4549b437e 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index 3d654bf93..5455f6ea9 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 7f2e0df72..654cf7525 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go index b7534c0a2..b42531e57 100644 --- a/pkg/sentry/kernel/task_start.go +++ b/pkg/sentry/kernel/task_start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_stop.go b/pkg/sentry/kernel/task_stop.go index 1302cadc1..e735a5dd0 100644 --- a/pkg/sentry/kernel/task_stop.go +++ b/pkg/sentry/kernel/task_stop.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 52f5fde8d..a9283d0df 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_test.go b/pkg/sentry/kernel/task_test.go index 3f37f505d..b895361d0 100644 --- a/pkg/sentry/kernel/task_test.go +++ b/pkg/sentry/kernel/task_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/task_usermem.go b/pkg/sentry/kernel/task_usermem.go index cb68799d3..461bd7316 100644 --- a/pkg/sentry/kernel/task_usermem.go +++ b/pkg/sentry/kernel/task_usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 58f3a7ec9..8bd53928e 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 4fd6cf4e2..656bbd46c 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/time/context.go b/pkg/sentry/kernel/time/context.go index 3675ea20d..c0660d362 100644 --- a/pkg/sentry/kernel/time/context.go +++ b/pkg/sentry/kernel/time/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index ca0f4ba2e..3846cf1ea 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index d7bd85e78..505a4fa4f 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/timekeeper_state.go b/pkg/sentry/kernel/timekeeper_state.go index f3a3ed543..6ce358a05 100644 --- a/pkg/sentry/kernel/timekeeper_state.go +++ b/pkg/sentry/kernel/timekeeper_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go index 6084bcb18..a92ad689e 100644 --- a/pkg/sentry/kernel/timekeeper_test.go +++ b/pkg/sentry/kernel/timekeeper_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/uncaught_signal.proto b/pkg/sentry/kernel/uncaught_signal.proto index c7f6a1978..0bdb062cb 100644 --- a/pkg/sentry/kernel/uncaught_signal.proto +++ b/pkg/sentry/kernel/uncaught_signal.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index ed5f0c031..96fe3cbb9 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 3a35f1d00..d40ad74f4 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/kernel/version.go b/pkg/sentry/kernel/version.go index 8d2f14209..5640dd71d 100644 --- a/pkg/sentry/kernel/version.go +++ b/pkg/sentry/kernel/version.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/context.go b/pkg/sentry/limits/context.go index bf413eb7d..9200edb52 100644 --- a/pkg/sentry/limits/context.go +++ b/pkg/sentry/limits/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/limits.go b/pkg/sentry/limits/limits.go index b0571739f..b6c22656b 100644 --- a/pkg/sentry/limits/limits.go +++ b/pkg/sentry/limits/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/limits_test.go b/pkg/sentry/limits/limits_test.go index 945428163..658a20f56 100644 --- a/pkg/sentry/limits/limits_test.go +++ b/pkg/sentry/limits/limits_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/limits/linux.go b/pkg/sentry/limits/linux.go index e09d0d2fb..a2b401e3d 100644 --- a/pkg/sentry/limits/linux.go +++ b/pkg/sentry/limits/linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/elf.go b/pkg/sentry/loader/elf.go index 385ad0102..97e32c8ba 100644 --- a/pkg/sentry/loader/elf.go +++ b/pkg/sentry/loader/elf.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/interpreter.go b/pkg/sentry/loader/interpreter.go index 35b83654d..b88062ae5 100644 --- a/pkg/sentry/loader/interpreter.go +++ b/pkg/sentry/loader/interpreter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index 79051befa..dc1a52398 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 8c196df84..207d8ed3d 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/loader/vdso_state.go b/pkg/sentry/loader/vdso_state.go index b327f0e1e..db378e90a 100644 --- a/pkg/sentry/loader/vdso_state.go +++ b/pkg/sentry/loader/vdso_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go index bd07e9aac..3cf2b338f 100644 --- a/pkg/sentry/memmap/mapping_set.go +++ b/pkg/sentry/memmap/mapping_set.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memmap/mapping_set_test.go b/pkg/sentry/memmap/mapping_set_test.go index 45d1d4688..c702555ce 100644 --- a/pkg/sentry/memmap/mapping_set_test.go +++ b/pkg/sentry/memmap/mapping_set_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go index 3f6f7ebd0..0106c857d 100644 --- a/pkg/sentry/memmap/memmap.go +++ b/pkg/sentry/memmap/memmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memutil/memutil.go b/pkg/sentry/memutil/memutil.go index 286d50ca4..a4154c42a 100644 --- a/pkg/sentry/memutil/memutil.go +++ b/pkg/sentry/memutil/memutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/memutil/memutil_unsafe.go b/pkg/sentry/memutil/memutil_unsafe.go index bc2c72f55..92eab8a26 100644 --- a/pkg/sentry/memutil/memutil_unsafe.go +++ b/pkg/sentry/memutil/memutil_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go index 4dddcf7b5..06f587fde 100644 --- a/pkg/sentry/mm/address_space.go +++ b/pkg/sentry/mm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go index 7075792e0..5c61acf36 100644 --- a/pkg/sentry/mm/aio_context.go +++ b/pkg/sentry/mm/aio_context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/aio_context_state.go b/pkg/sentry/mm/aio_context_state.go index 192a6f744..c37fc9f7b 100644 --- a/pkg/sentry/mm/aio_context_state.go +++ b/pkg/sentry/mm/aio_context_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/debug.go b/pkg/sentry/mm/debug.go index d075ee1ca..fe58cfc4c 100644 --- a/pkg/sentry/mm/debug.go +++ b/pkg/sentry/mm/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/io.go b/pkg/sentry/mm/io.go index 81787a6fd..e4c057d28 100644 --- a/pkg/sentry/mm/io.go +++ b/pkg/sentry/mm/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go index 2fe03172c..e6aa6f9ef 100644 --- a/pkg/sentry/mm/lifecycle.go +++ b/pkg/sentry/mm/lifecycle.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/metadata.go b/pkg/sentry/mm/metadata.go index 5ef1ba0b1..9768e51f1 100644 --- a/pkg/sentry/mm/metadata.go +++ b/pkg/sentry/mm/metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go index a3417a46e..d25aa5136 100644 --- a/pkg/sentry/mm/mm.go +++ b/pkg/sentry/mm/mm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/mm_test.go b/pkg/sentry/mm/mm_test.go index ae4fba478..f4917419f 100644 --- a/pkg/sentry/mm/mm_test.go +++ b/pkg/sentry/mm/mm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/pma.go b/pkg/sentry/mm/pma.go index 0cca743ef..ece561ff0 100644 --- a/pkg/sentry/mm/pma.go +++ b/pkg/sentry/mm/pma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/procfs.go b/pkg/sentry/mm/procfs.go index 7cdbf6e25..c8302a553 100644 --- a/pkg/sentry/mm/procfs.go +++ b/pkg/sentry/mm/procfs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/save_restore.go b/pkg/sentry/mm/save_restore.go index 46e0e0754..0385957bd 100644 --- a/pkg/sentry/mm/save_restore.go +++ b/pkg/sentry/mm/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/shm.go b/pkg/sentry/mm/shm.go index 3bc48c7e7..12913007b 100644 --- a/pkg/sentry/mm/shm.go +++ b/pkg/sentry/mm/shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go index 3b5161998..687959005 100644 --- a/pkg/sentry/mm/special_mappable.go +++ b/pkg/sentry/mm/special_mappable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index 7b675b9b5..a25318abb 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go index 931995254..ad901344b 100644 --- a/pkg/sentry/mm/vma.go +++ b/pkg/sentry/mm/vma.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/context.go b/pkg/sentry/pgalloc/context.go index adc97e78f..cb9809b1f 100644 --- a/pkg/sentry/pgalloc/context.go +++ b/pkg/sentry/pgalloc/context.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2019 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. diff --git a/pkg/sentry/pgalloc/pgalloc.go b/pkg/sentry/pgalloc/pgalloc.go index 0754e608f..411dafa07 100644 --- a/pkg/sentry/pgalloc/pgalloc.go +++ b/pkg/sentry/pgalloc/pgalloc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/pgalloc_test.go b/pkg/sentry/pgalloc/pgalloc_test.go index 726623c1a..14a39bb9e 100644 --- a/pkg/sentry/pgalloc/pgalloc_test.go +++ b/pkg/sentry/pgalloc/pgalloc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/pgalloc_unsafe.go b/pkg/sentry/pgalloc/pgalloc_unsafe.go index 33b0a68a8..a4b5d581c 100644 --- a/pkg/sentry/pgalloc/pgalloc_unsafe.go +++ b/pkg/sentry/pgalloc/pgalloc_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/pgalloc/save_restore.go b/pkg/sentry/pgalloc/save_restore.go index 21024e656..cf169af55 100644 --- a/pkg/sentry/pgalloc/save_restore.go +++ b/pkg/sentry/pgalloc/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/context.go b/pkg/sentry/platform/context.go index cca21a23e..793f57fd7 100644 --- a/pkg/sentry/platform/context.go +++ b/pkg/sentry/platform/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/interrupt/interrupt.go b/pkg/sentry/platform/interrupt/interrupt.go index 9c83f41eb..a4651f500 100644 --- a/pkg/sentry/platform/interrupt/interrupt.go +++ b/pkg/sentry/platform/interrupt/interrupt.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/interrupt/interrupt_test.go b/pkg/sentry/platform/interrupt/interrupt_test.go index fb3284395..0ecdf6e7a 100644 --- a/pkg/sentry/platform/interrupt/interrupt_test.go +++ b/pkg/sentry/platform/interrupt/interrupt_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/address_space.go b/pkg/sentry/platform/kvm/address_space.go index f2f7ab1e8..689122175 100644 --- a/pkg/sentry/platform/kvm/address_space.go +++ b/pkg/sentry/platform/kvm/address_space.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/allocator.go b/pkg/sentry/platform/kvm/allocator.go index b25cad155..42bcc9733 100644 --- a/pkg/sentry/platform/kvm/allocator.go +++ b/pkg/sentry/platform/kvm/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill.go b/pkg/sentry/platform/kvm/bluepill.go index f24f1c662..a926e6f8b 100644 --- a/pkg/sentry/platform/kvm/bluepill.go +++ b/pkg/sentry/platform/kvm/bluepill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.go b/pkg/sentry/platform/kvm/bluepill_amd64.go index 6520682d7..c258408f9 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64.s b/pkg/sentry/platform/kvm/bluepill_amd64.s index 65b01f358..2bc34a435 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64.s +++ b/pkg/sentry/platform/kvm/bluepill_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go index 21de2488e..92fde7ee0 100644 --- a/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_fault.go b/pkg/sentry/platform/kvm/bluepill_fault.go index e79a30ef2..3c452f5ba 100644 --- a/pkg/sentry/platform/kvm/bluepill_fault.go +++ b/pkg/sentry/platform/kvm/bluepill_fault.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/bluepill_unsafe.go b/pkg/sentry/platform/kvm/bluepill_unsafe.go index 2605f8c93..4184939e5 100644 --- a/pkg/sentry/platform/kvm/bluepill_unsafe.go +++ b/pkg/sentry/platform/kvm/bluepill_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/context.go b/pkg/sentry/platform/kvm/context.go index c75a4b415..0eb0020f7 100644 --- a/pkg/sentry/platform/kvm/context.go +++ b/pkg/sentry/platform/kvm/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm.go b/pkg/sentry/platform/kvm/kvm.go index c5a4435b1..ed0521c3f 100644 --- a/pkg/sentry/platform/kvm/kvm.go +++ b/pkg/sentry/platform/kvm/kvm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_amd64.go b/pkg/sentry/platform/kvm/kvm_amd64.go index 70d0ac63b..61493ccaf 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64.go +++ b/pkg/sentry/platform/kvm/kvm_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go index d0f6bb225..46c4b9113 100644 --- a/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/kvm_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_const.go b/pkg/sentry/platform/kvm/kvm_const.go index cac8d9937..d05f05c29 100644 --- a/pkg/sentry/platform/kvm/kvm_const.go +++ b/pkg/sentry/platform/kvm/kvm_const.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/kvm_test.go b/pkg/sentry/platform/kvm/kvm_test.go index 361200622..e83db71e9 100644 --- a/pkg/sentry/platform/kvm/kvm_test.go +++ b/pkg/sentry/platform/kvm/kvm_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index b8b3c9a4a..f5953b96e 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index ccfe837b5..b6821122a 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go index 69ba67ced..06a2e3b0c 100644 --- a/pkg/sentry/platform/kvm/machine_amd64_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/machine_unsafe.go b/pkg/sentry/platform/kvm/machine_unsafe.go index 22ae60b63..452d88d7f 100644 --- a/pkg/sentry/platform/kvm/machine_unsafe.go +++ b/pkg/sentry/platform/kvm/machine_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/physical_map.go b/pkg/sentry/platform/kvm/physical_map.go index 9d7dca5b3..450eb8201 100644 --- a/pkg/sentry/platform/kvm/physical_map.go +++ b/pkg/sentry/platform/kvm/physical_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/testutil/testutil.go b/pkg/sentry/platform/kvm/testutil/testutil.go index 0d496561d..6cf2359a3 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil.go +++ b/pkg/sentry/platform/kvm/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go index fcba33813..203d71528 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.go +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s index f1da41a44..491ec0c2a 100644 --- a/pkg/sentry/platform/kvm/testutil/testutil_amd64.s +++ b/pkg/sentry/platform/kvm/testutil/testutil_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/virtual_map.go b/pkg/sentry/platform/kvm/virtual_map.go index 0343e9267..28a1b4414 100644 --- a/pkg/sentry/platform/kvm/virtual_map.go +++ b/pkg/sentry/platform/kvm/virtual_map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/kvm/virtual_map_test.go b/pkg/sentry/platform/kvm/virtual_map_test.go index 935e0eb93..d03ec654a 100644 --- a/pkg/sentry/platform/kvm/virtual_map_test.go +++ b/pkg/sentry/platform/kvm/virtual_map_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/mmap_min_addr.go b/pkg/sentry/platform/mmap_min_addr.go index 1bcc1f8e9..90976735b 100644 --- a/pkg/sentry/platform/mmap_min_addr.go +++ b/pkg/sentry/platform/mmap_min_addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index 0e48417b9..ae37276ad 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid.go b/pkg/sentry/platform/procid/procid.go index 3f49ab093..78b92422c 100644 --- a/pkg/sentry/platform/procid/procid.go +++ b/pkg/sentry/platform/procid/procid.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_amd64.s b/pkg/sentry/platform/procid/procid_amd64.s index ef3439c03..272c9fc14 100644 --- a/pkg/sentry/platform/procid/procid_amd64.s +++ b/pkg/sentry/platform/procid/procid_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_arm64.s b/pkg/sentry/platform/procid/procid_arm64.s index 02e907b6b..7a1684a18 100644 --- a/pkg/sentry/platform/procid/procid_arm64.s +++ b/pkg/sentry/platform/procid/procid_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_net_test.go b/pkg/sentry/platform/procid/procid_net_test.go index e8dcc479d..b628e2285 100644 --- a/pkg/sentry/platform/procid/procid_net_test.go +++ b/pkg/sentry/platform/procid/procid_net_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/procid/procid_test.go b/pkg/sentry/platform/procid/procid_test.go index 7a57c7cdc..88dd0b3ae 100644 --- a/pkg/sentry/platform/procid/procid_test.go +++ b/pkg/sentry/platform/procid/procid_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go index 3c0713e95..6a890dd81 100644 --- a/pkg/sentry/platform/ptrace/ptrace.go +++ b/pkg/sentry/platform/ptrace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/ptrace_unsafe.go b/pkg/sentry/platform/ptrace/ptrace_unsafe.go index 223b23199..585f6c1fb 100644 --- a/pkg/sentry/platform/ptrace/ptrace_unsafe.go +++ b/pkg/sentry/platform/ptrace/ptrace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/stub_amd64.s b/pkg/sentry/platform/ptrace/stub_amd64.s index 63f98e40d..64c718d21 100644 --- a/pkg/sentry/platform/ptrace/stub_amd64.s +++ b/pkg/sentry/platform/ptrace/stub_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/stub_unsafe.go b/pkg/sentry/platform/ptrace/stub_unsafe.go index 48c16c4a1..54d5021a9 100644 --- a/pkg/sentry/platform/ptrace/stub_unsafe.go +++ b/pkg/sentry/platform/ptrace/stub_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go index 2a5d699ec..83b43057f 100644 --- a/pkg/sentry/platform/ptrace/subprocess.go +++ b/pkg/sentry/platform/ptrace/subprocess.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_amd64.go b/pkg/sentry/platform/ptrace/subprocess_amd64.go index d23a1133e..77a0e908f 100644 --- a/pkg/sentry/platform/ptrace/subprocess_amd64.go +++ b/pkg/sentry/platform/ptrace/subprocess_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index e2aab8135..2c07b4ac3 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go index 0c9263060..1bf7eab28 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ptrace/subprocess_unsafe.go b/pkg/sentry/platform/ptrace/subprocess_unsafe.go index ca6c4ac97..17736b05b 100644 --- a/pkg/sentry/platform/ptrace/subprocess_unsafe.go +++ b/pkg/sentry/platform/ptrace/subprocess_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/defs.go b/pkg/sentry/platform/ring0/defs.go index 98d0a6de0..5bbd4612d 100644 --- a/pkg/sentry/platform/ring0/defs.go +++ b/pkg/sentry/platform/ring0/defs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/defs_amd64.go b/pkg/sentry/platform/ring0/defs_amd64.go index 67242b92b..413c3dbc4 100644 --- a/pkg/sentry/platform/ring0/defs_amd64.go +++ b/pkg/sentry/platform/ring0/defs_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/entry_amd64.go b/pkg/sentry/platform/ring0/entry_amd64.go index 4a9affe64..a5ce67885 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.go +++ b/pkg/sentry/platform/ring0/entry_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/entry_amd64.s b/pkg/sentry/platform/ring0/entry_amd64.s index afb040a6f..8cb8c4996 100644 --- a/pkg/sentry/platform/ring0/entry_amd64.s +++ b/pkg/sentry/platform/ring0/entry_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/gen_offsets/main.go b/pkg/sentry/platform/ring0/gen_offsets/main.go index 11c49855f..a4927da2f 100644 --- a/pkg/sentry/platform/ring0/gen_offsets/main.go +++ b/pkg/sentry/platform/ring0/gen_offsets/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/kernel.go b/pkg/sentry/platform/ring0/kernel.go index 19ac6eb7c..900c0bba7 100644 --- a/pkg/sentry/platform/ring0/kernel.go +++ b/pkg/sentry/platform/ring0/kernel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/kernel_amd64.go b/pkg/sentry/platform/ring0/kernel_amd64.go index 5ed4342dd..3577b5127 100644 --- a/pkg/sentry/platform/ring0/kernel_amd64.go +++ b/pkg/sentry/platform/ring0/kernel_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/kernel_unsafe.go b/pkg/sentry/platform/ring0/kernel_unsafe.go index faf4240e5..16955ad91 100644 --- a/pkg/sentry/platform/ring0/kernel_unsafe.go +++ b/pkg/sentry/platform/ring0/kernel_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/lib_amd64.go b/pkg/sentry/platform/ring0/lib_amd64.go index 2b95a0141..9c5f26962 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.go +++ b/pkg/sentry/platform/ring0/lib_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/lib_amd64.s b/pkg/sentry/platform/ring0/lib_amd64.s index 98a130525..75d742750 100644 --- a/pkg/sentry/platform/ring0/lib_amd64.s +++ b/pkg/sentry/platform/ring0/lib_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/offsets_amd64.go b/pkg/sentry/platform/ring0/offsets_amd64.go index 806e07ec0..85cc3fdad 100644 --- a/pkg/sentry/platform/ring0/offsets_amd64.go +++ b/pkg/sentry/platform/ring0/offsets_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator.go b/pkg/sentry/platform/ring0/pagetables/allocator.go index ee6e90a11..23fd5c352 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go index f48647b3a..1b996b4e2 100644 --- a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go +++ b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables.go b/pkg/sentry/platform/ring0/pagetables/pagetables.go index c7207ec18..e5dcaada7 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go index 746f614e5..7aa6c524e 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go index 2f82c4353..a1ec4b109 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go index 3e5dc7dc7..36e424495 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go index 6bd8c3584..ff427fbe9 100644 --- a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go index 0d9a51aa5..0f029f25d 100644 --- a/pkg/sentry/platform/ring0/pagetables/pcids_x86.go +++ b/pkg/sentry/platform/ring0/pagetables/pcids_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go index c4c71d23e..8f9dacd93 100644 --- a/pkg/sentry/platform/ring0/pagetables/walker_amd64.go +++ b/pkg/sentry/platform/ring0/pagetables/walker_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/ring0.go b/pkg/sentry/platform/ring0/ring0.go index 10c51e88d..cdeb1b43a 100644 --- a/pkg/sentry/platform/ring0/ring0.go +++ b/pkg/sentry/platform/ring0/ring0.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/ring0/x86.go b/pkg/sentry/platform/ring0/x86.go index 4c6daec22..7e5ceafdb 100644 --- a/pkg/sentry/platform/ring0/x86.go +++ b/pkg/sentry/platform/ring0/x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/atomic_amd64.s b/pkg/sentry/platform/safecopy/atomic_amd64.s index f90b4bfd1..a0cd78f33 100644 --- a/pkg/sentry/platform/safecopy/atomic_amd64.s +++ b/pkg/sentry/platform/safecopy/atomic_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/safecopy.go b/pkg/sentry/platform/safecopy/safecopy.go index 69c66a3b7..5126871eb 100644 --- a/pkg/sentry/platform/safecopy/safecopy.go +++ b/pkg/sentry/platform/safecopy/safecopy.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/safecopy_test.go b/pkg/sentry/platform/safecopy/safecopy_test.go index 1a682d28a..5818f7f9b 100644 --- a/pkg/sentry/platform/safecopy/safecopy_test.go +++ b/pkg/sentry/platform/safecopy/safecopy_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/safecopy_unsafe.go b/pkg/sentry/platform/safecopy/safecopy_unsafe.go index f84527484..eef028e68 100644 --- a/pkg/sentry/platform/safecopy/safecopy_unsafe.go +++ b/pkg/sentry/platform/safecopy/safecopy_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/sighandler_amd64.s b/pkg/sentry/platform/safecopy/sighandler_amd64.s index db7701a29..475ae48e9 100644 --- a/pkg/sentry/platform/safecopy/sighandler_amd64.s +++ b/pkg/sentry/platform/safecopy/sighandler_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/platform/safecopy/sighandler_arm64.s b/pkg/sentry/platform/safecopy/sighandler_arm64.s index cdfca8207..53e4ac2c1 100644 --- a/pkg/sentry/platform/safecopy/sighandler_arm64.s +++ b/pkg/sentry/platform/safecopy/sighandler_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/block_unsafe.go b/pkg/sentry/safemem/block_unsafe.go index c3a9780d2..1f72deb61 100644 --- a/pkg/sentry/safemem/block_unsafe.go +++ b/pkg/sentry/safemem/block_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/io.go b/pkg/sentry/safemem/io.go index 6cb52439f..5c3d73eb7 100644 --- a/pkg/sentry/safemem/io.go +++ b/pkg/sentry/safemem/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/io_test.go b/pkg/sentry/safemem/io_test.go index 2eda8c3bb..629741bee 100644 --- a/pkg/sentry/safemem/io_test.go +++ b/pkg/sentry/safemem/io_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/safemem.go b/pkg/sentry/safemem/safemem.go index 090932d3e..3e70d33a2 100644 --- a/pkg/sentry/safemem/safemem.go +++ b/pkg/sentry/safemem/safemem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/seq_test.go b/pkg/sentry/safemem/seq_test.go index fddcaf714..eba4bb535 100644 --- a/pkg/sentry/safemem/seq_test.go +++ b/pkg/sentry/safemem/seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/safemem/seq_unsafe.go b/pkg/sentry/safemem/seq_unsafe.go index 83a6b7183..354a95dde 100644 --- a/pkg/sentry/safemem/seq_unsafe.go +++ b/pkg/sentry/safemem/seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/sighandling/sighandling.go b/pkg/sentry/sighandling/sighandling.go index 571245ce5..659b43363 100644 --- a/pkg/sentry/sighandling/sighandling.go +++ b/pkg/sentry/sighandling/sighandling.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/sighandling/sighandling_unsafe.go b/pkg/sentry/sighandling/sighandling_unsafe.go index db6e71487..aca77888a 100644 --- a/pkg/sentry/sighandling/sighandling_unsafe.go +++ b/pkg/sentry/sighandling/sighandling_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go index d44f5e88a..abda364c9 100644 --- a/pkg/sentry/socket/control/control.go +++ b/pkg/sentry/socket/control/control.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/device.go b/pkg/sentry/socket/epsocket/device.go index 3cc138eb0..ab4083efe 100644 --- a/pkg/sentry/socket/epsocket/device.go +++ b/pkg/sentry/socket/epsocket/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 768fa0dfa..520d82f68 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/provider.go b/pkg/sentry/socket/epsocket/provider.go index 0d9c2df24..5a89a63fb 100644 --- a/pkg/sentry/socket/epsocket/provider.go +++ b/pkg/sentry/socket/epsocket/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/save_restore.go b/pkg/sentry/socket/epsocket/save_restore.go index f19afb6c0..feaafb7cc 100644 --- a/pkg/sentry/socket/epsocket/save_restore.go +++ b/pkg/sentry/socket/epsocket/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 37c48f4bc..edefa225b 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/device.go b/pkg/sentry/socket/hostinet/device.go index c5133f3bb..4267e3691 100644 --- a/pkg/sentry/socket/hostinet/device.go +++ b/pkg/sentry/socket/hostinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/hostinet.go b/pkg/sentry/socket/hostinet/hostinet.go index 7858892ab..0d6f51d2b 100644 --- a/pkg/sentry/socket/hostinet/hostinet.go +++ b/pkg/sentry/socket/hostinet/hostinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/save_restore.go b/pkg/sentry/socket/hostinet/save_restore.go index 3827f082a..1dec33897 100644 --- a/pkg/sentry/socket/hostinet/save_restore.go +++ b/pkg/sentry/socket/hostinet/save_restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index 49349074f..71884d3db 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/socket_unsafe.go b/pkg/sentry/socket/hostinet/socket_unsafe.go index 59c8910ca..eed0c7837 100644 --- a/pkg/sentry/socket/hostinet/socket_unsafe.go +++ b/pkg/sentry/socket/hostinet/socket_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go index 4ce73c1f1..9c45991ba 100644 --- a/pkg/sentry/socket/hostinet/stack.go +++ b/pkg/sentry/socket/hostinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/message.go b/pkg/sentry/socket/netlink/message.go index a95172cba..5bd3b49ce 100644 --- a/pkg/sentry/socket/netlink/message.go +++ b/pkg/sentry/socket/netlink/message.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/port/port.go b/pkg/sentry/socket/netlink/port/port.go index 20b9a6e37..e9d3275b1 100644 --- a/pkg/sentry/socket/netlink/port/port.go +++ b/pkg/sentry/socket/netlink/port/port.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/port/port_test.go b/pkg/sentry/socket/netlink/port/port_test.go index 49b3b48ab..516f6cd6c 100644 --- a/pkg/sentry/socket/netlink/port/port_test.go +++ b/pkg/sentry/socket/netlink/port/port_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/provider.go b/pkg/sentry/socket/netlink/provider.go index 06786bd50..76cf12fd4 100644 --- a/pkg/sentry/socket/netlink/provider.go +++ b/pkg/sentry/socket/netlink/provider.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go index e414b829b..9f0a81403 100644 --- a/pkg/sentry/socket/netlink/route/protocol.go +++ b/pkg/sentry/socket/netlink/route/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index a34f9d3ca..dc688eb00 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/conn/conn.go b/pkg/sentry/socket/rpcinet/conn/conn.go index 64106c4b5..f537c7f63 100644 --- a/pkg/sentry/socket/rpcinet/conn/conn.go +++ b/pkg/sentry/socket/rpcinet/conn/conn.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/device.go b/pkg/sentry/socket/rpcinet/device.go index d2b9f9222..44c0a39b7 100644 --- a/pkg/sentry/socket/rpcinet/device.go +++ b/pkg/sentry/socket/rpcinet/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/notifier/notifier.go b/pkg/sentry/socket/rpcinet/notifier/notifier.go index f06d12231..601e05994 100644 --- a/pkg/sentry/socket/rpcinet/notifier/notifier.go +++ b/pkg/sentry/socket/rpcinet/notifier/notifier.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/rpcinet.go b/pkg/sentry/socket/rpcinet/rpcinet.go index 6c98e6acb..5d4fd4dac 100644 --- a/pkg/sentry/socket/rpcinet/rpcinet.go +++ b/pkg/sentry/socket/rpcinet/rpcinet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index cf8f69efb..c028ed4dd 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/stack.go b/pkg/sentry/socket/rpcinet/stack.go index cb8344ec6..a1be711df 100644 --- a/pkg/sentry/socket/rpcinet/stack.go +++ b/pkg/sentry/socket/rpcinet/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/rpcinet/stack_unsafe.go b/pkg/sentry/socket/rpcinet/stack_unsafe.go index d04fb2069..e53f578ba 100644 --- a/pkg/sentry/socket/rpcinet/stack_unsafe.go +++ b/pkg/sentry/socket/rpcinet/stack_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go index 62ba13782..7e840b452 100644 --- a/pkg/sentry/socket/socket.go +++ b/pkg/sentry/socket/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/device.go b/pkg/sentry/socket/unix/device.go index 41820dbb3..734d39ee6 100644 --- a/pkg/sentry/socket/unix/device.go +++ b/pkg/sentry/socket/unix/device.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/io.go b/pkg/sentry/socket/unix/io.go index 7d80e4393..382911d51 100644 --- a/pkg/sentry/socket/unix/io.go +++ b/pkg/sentry/socket/unix/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/connectioned.go b/pkg/sentry/socket/unix/transport/connectioned.go index 62641bb34..18e492862 100644 --- a/pkg/sentry/socket/unix/transport/connectioned.go +++ b/pkg/sentry/socket/unix/transport/connectioned.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/connectioned_state.go b/pkg/sentry/socket/unix/transport/connectioned_state.go index 608a6a97a..7e02a5db8 100644 --- a/pkg/sentry/socket/unix/transport/connectioned_state.go +++ b/pkg/sentry/socket/unix/transport/connectioned_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/connectionless.go b/pkg/sentry/socket/unix/transport/connectionless.go index 728863f3f..43ff875e4 100644 --- a/pkg/sentry/socket/unix/transport/connectionless.go +++ b/pkg/sentry/socket/unix/transport/connectionless.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/queue.go b/pkg/sentry/socket/unix/transport/queue.go index 45a58c600..b650caae7 100644 --- a/pkg/sentry/socket/unix/transport/queue.go +++ b/pkg/sentry/socket/unix/transport/queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go index 12b1576bd..d5f7f7aa8 100644 --- a/pkg/sentry/socket/unix/transport/unix.go +++ b/pkg/sentry/socket/unix/transport/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 01efd24d3..e9607aa01 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 224f8b709..27fde505b 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/state/state_metadata.go b/pkg/sentry/state/state_metadata.go index 7f047b808..b8e128c40 100644 --- a/pkg/sentry/state/state_metadata.go +++ b/pkg/sentry/state/state_metadata.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/state/state_unsafe.go b/pkg/sentry/state/state_unsafe.go index f02e12b2a..7745b6ac6 100644 --- a/pkg/sentry/state/state_unsafe.go +++ b/pkg/sentry/state/state_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/capability.go b/pkg/sentry/strace/capability.go index 9001181e7..f85d6636e 100644 --- a/pkg/sentry/strace/capability.go +++ b/pkg/sentry/strace/capability.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/strace/clone.go b/pkg/sentry/strace/clone.go index e18ce84dc..ff6a432c6 100644 --- a/pkg/sentry/strace/clone.go +++ b/pkg/sentry/strace/clone.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/futex.go b/pkg/sentry/strace/futex.go index f4aa7fcad..24301bda6 100644 --- a/pkg/sentry/strace/futex.go +++ b/pkg/sentry/strace/futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/linux64.go b/pkg/sentry/strace/linux64.go index 6043b8cb1..3650fd6e1 100644 --- a/pkg/sentry/strace/linux64.go +++ b/pkg/sentry/strace/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/open.go b/pkg/sentry/strace/open.go index 3bf348d7a..140727b02 100644 --- a/pkg/sentry/strace/open.go +++ b/pkg/sentry/strace/open.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/poll.go b/pkg/sentry/strace/poll.go index b6b05423c..15605187d 100644 --- a/pkg/sentry/strace/poll.go +++ b/pkg/sentry/strace/poll.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/strace/ptrace.go b/pkg/sentry/strace/ptrace.go index 8c4b79227..485aacb8a 100644 --- a/pkg/sentry/strace/ptrace.go +++ b/pkg/sentry/strace/ptrace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/signal.go b/pkg/sentry/strace/signal.go index 524be0e15..f82460e1c 100644 --- a/pkg/sentry/strace/signal.go +++ b/pkg/sentry/strace/signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go index 4c1a9d469..dbe53b9a2 100644 --- a/pkg/sentry/strace/socket.go +++ b/pkg/sentry/strace/socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go index 434a200d9..f4c1be4ce 100644 --- a/pkg/sentry/strace/strace.go +++ b/pkg/sentry/strace/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/strace.proto b/pkg/sentry/strace/strace.proto index f1fc539d6..4b2f73a5f 100644 --- a/pkg/sentry/strace/strace.proto +++ b/pkg/sentry/strace/strace.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/strace/syscalls.go b/pkg/sentry/strace/syscalls.go index 8c897fcbe..eae2d6c12 100644 --- a/pkg/sentry/strace/syscalls.go +++ b/pkg/sentry/strace/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/epoll.go b/pkg/sentry/syscalls/epoll.go index b90d191b7..ec1eab331 100644 --- a/pkg/sentry/syscalls/epoll.go +++ b/pkg/sentry/syscalls/epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 304a12dde..1ba3695fb 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go index d2aec963a..d83e12971 100644 --- a/pkg/sentry/syscalls/linux/flags.go +++ b/pkg/sentry/syscalls/linux/flags.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index b9b4ccbd1..9a460ebdf 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sigset.go b/pkg/sentry/syscalls/linux/sigset.go index a033b7c70..5438b664b 100644 --- a/pkg/sentry/syscalls/linux/sigset.go +++ b/pkg/sentry/syscalls/linux/sigset.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go index 61c2647bf..1b27b2415 100644 --- a/pkg/sentry/syscalls/linux/sys_aio.go +++ b/pkg/sentry/syscalls/linux/sys_aio.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_capability.go b/pkg/sentry/syscalls/linux/sys_capability.go index cf972dc28..622cb8d0d 100644 --- a/pkg/sentry/syscalls/linux/sys_capability.go +++ b/pkg/sentry/syscalls/linux/sys_capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go index 200c46355..1467feb4e 100644 --- a/pkg/sentry/syscalls/linux/sys_epoll.go +++ b/pkg/sentry/syscalls/linux/sys_epoll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_eventfd.go b/pkg/sentry/syscalls/linux/sys_eventfd.go index 903172890..ca4ead488 100644 --- a/pkg/sentry/syscalls/linux/sys_eventfd.go +++ b/pkg/sentry/syscalls/linux/sys_eventfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 967464c85..893322647 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go index f0c89cba4..7cef4b50c 100644 --- a/pkg/sentry/syscalls/linux/sys_futex.go +++ b/pkg/sentry/syscalls/linux/sys_futex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_getdents.go b/pkg/sentry/syscalls/linux/sys_getdents.go index 4b441b31b..1b597d5bc 100644 --- a/pkg/sentry/syscalls/linux/sys_getdents.go +++ b/pkg/sentry/syscalls/linux/sys_getdents.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_identity.go b/pkg/sentry/syscalls/linux/sys_identity.go index 8d594aa83..27e765a2d 100644 --- a/pkg/sentry/syscalls/linux/sys_identity.go +++ b/pkg/sentry/syscalls/linux/sys_identity.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_inotify.go b/pkg/sentry/syscalls/linux/sys_inotify.go index 26a505782..20269a769 100644 --- a/pkg/sentry/syscalls/linux/sys_inotify.go +++ b/pkg/sentry/syscalls/linux/sys_inotify.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_lseek.go b/pkg/sentry/syscalls/linux/sys_lseek.go index ad3bfd761..8aadc6d8c 100644 --- a/pkg/sentry/syscalls/linux/sys_lseek.go +++ b/pkg/sentry/syscalls/linux/sys_lseek.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go index 805b251b1..64a6e639c 100644 --- a/pkg/sentry/syscalls/linux/sys_mmap.go +++ b/pkg/sentry/syscalls/linux/sys_mmap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_mount.go b/pkg/sentry/syscalls/linux/sys_mount.go index e110a553f..cf613bad0 100644 --- a/pkg/sentry/syscalls/linux/sys_mount.go +++ b/pkg/sentry/syscalls/linux/sys_mount.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_pipe.go b/pkg/sentry/syscalls/linux/sys_pipe.go index 3652c429e..036845c13 100644 --- a/pkg/sentry/syscalls/linux/sys_pipe.go +++ b/pkg/sentry/syscalls/linux/sys_pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go index 17b6768e5..e32099dd4 100644 --- a/pkg/sentry/syscalls/linux/sys_poll.go +++ b/pkg/sentry/syscalls/linux/sys_poll.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go index 7a29bd9b7..117ae1a0e 100644 --- a/pkg/sentry/syscalls/linux/sys_prctl.go +++ b/pkg/sentry/syscalls/linux/sys_prctl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_random.go b/pkg/sentry/syscalls/linux/sys_random.go index 452dff058..fc3959a7e 100644 --- a/pkg/sentry/syscalls/linux/sys_random.go +++ b/pkg/sentry/syscalls/linux/sys_random.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go index 50c7d7a74..48b0fd49d 100644 --- a/pkg/sentry/syscalls/linux/sys_read.go +++ b/pkg/sentry/syscalls/linux/sys_read.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go index 443334693..8b0379779 100644 --- a/pkg/sentry/syscalls/linux/sys_rlimit.go +++ b/pkg/sentry/syscalls/linux/sys_rlimit.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_rusage.go b/pkg/sentry/syscalls/linux/sys_rusage.go index ab07c77f9..003d718da 100644 --- a/pkg/sentry/syscalls/linux/sys_rusage.go +++ b/pkg/sentry/syscalls/linux/sys_rusage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sched.go b/pkg/sentry/syscalls/linux/sys_sched.go index e679a6694..8aea03abe 100644 --- a/pkg/sentry/syscalls/linux/sys_sched.go +++ b/pkg/sentry/syscalls/linux/sys_sched.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_seccomp.go b/pkg/sentry/syscalls/linux/sys_seccomp.go index f08fdf5cb..b4262162a 100644 --- a/pkg/sentry/syscalls/linux/sys_seccomp.go +++ b/pkg/sentry/syscalls/linux/sys_seccomp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go index 86f850ef1..5bd61ab87 100644 --- a/pkg/sentry/syscalls/linux/sys_sem.go +++ b/pkg/sentry/syscalls/linux/sys_sem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_shm.go b/pkg/sentry/syscalls/linux/sys_shm.go index a0d3a73c5..d0eceac7c 100644 --- a/pkg/sentry/syscalls/linux/sys_shm.go +++ b/pkg/sentry/syscalls/linux/sys_shm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_signal.go b/pkg/sentry/syscalls/linux/sys_signal.go index a539354c5..7fbeb4fcd 100644 --- a/pkg/sentry/syscalls/linux/sys_signal.go +++ b/pkg/sentry/syscalls/linux/sys_signal.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go index c8748958a..69862f110 100644 --- a/pkg/sentry/syscalls/linux/sys_socket.go +++ b/pkg/sentry/syscalls/linux/sys_socket.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go index 49c225011..10fc201ef 100644 --- a/pkg/sentry/syscalls/linux/sys_stat.go +++ b/pkg/sentry/syscalls/linux/sys_stat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sync.go b/pkg/sentry/syscalls/linux/sys_sync.go index 68488330f..4352482fb 100644 --- a/pkg/sentry/syscalls/linux/sys_sync.go +++ b/pkg/sentry/syscalls/linux/sys_sync.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_sysinfo.go b/pkg/sentry/syscalls/linux/sys_sysinfo.go index 6f7acf98f..ecf88edc1 100644 --- a/pkg/sentry/syscalls/linux/sys_sysinfo.go +++ b/pkg/sentry/syscalls/linux/sys_sysinfo.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_syslog.go b/pkg/sentry/syscalls/linux/sys_syslog.go index 7193b7aed..9efc58d34 100644 --- a/pkg/sentry/syscalls/linux/sys_syslog.go +++ b/pkg/sentry/syscalls/linux/sys_syslog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index ddcb5b789..23c2f7035 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go index 063fbb106..b4f2609c0 100644 --- a/pkg/sentry/syscalls/linux/sys_time.go +++ b/pkg/sentry/syscalls/linux/sys_time.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go index 6baf4599b..04ea7a4e9 100644 --- a/pkg/sentry/syscalls/linux/sys_timer.go +++ b/pkg/sentry/syscalls/linux/sys_timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_timerfd.go b/pkg/sentry/syscalls/linux/sys_timerfd.go index f70d13682..ec0155cbb 100644 --- a/pkg/sentry/syscalls/linux/sys_timerfd.go +++ b/pkg/sentry/syscalls/linux/sys_timerfd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_tls.go b/pkg/sentry/syscalls/linux/sys_tls.go index 8ea78093b..1e8312e00 100644 --- a/pkg/sentry/syscalls/linux/sys_tls.go +++ b/pkg/sentry/syscalls/linux/sys_tls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_utsname.go b/pkg/sentry/syscalls/linux/sys_utsname.go index f7545b965..fa81fe10e 100644 --- a/pkg/sentry/syscalls/linux/sys_utsname.go +++ b/pkg/sentry/syscalls/linux/sys_utsname.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go index e405608c4..1da72d606 100644 --- a/pkg/sentry/syscalls/linux/sys_write.go +++ b/pkg/sentry/syscalls/linux/sys_write.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/linux/timespec.go b/pkg/sentry/syscalls/linux/timespec.go index 752ec326d..fa6fcdc0b 100644 --- a/pkg/sentry/syscalls/linux/timespec.go +++ b/pkg/sentry/syscalls/linux/timespec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/syscalls/syscalls.go b/pkg/sentry/syscalls/syscalls.go index 425ce900c..5d10b3824 100644 --- a/pkg/sentry/syscalls/syscalls.go +++ b/pkg/sentry/syscalls/syscalls.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/calibrated_clock.go b/pkg/sentry/time/calibrated_clock.go index a98bcd7de..c27e391c9 100644 --- a/pkg/sentry/time/calibrated_clock.go +++ b/pkg/sentry/time/calibrated_clock.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/calibrated_clock_test.go b/pkg/sentry/time/calibrated_clock_test.go index a9237630e..d6622bfe2 100644 --- a/pkg/sentry/time/calibrated_clock_test.go +++ b/pkg/sentry/time/calibrated_clock_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/clock_id.go b/pkg/sentry/time/clock_id.go index 1317a5dad..724f59dd9 100644 --- a/pkg/sentry/time/clock_id.go +++ b/pkg/sentry/time/clock_id.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/clocks.go b/pkg/sentry/time/clocks.go index e26386520..837e86094 100644 --- a/pkg/sentry/time/clocks.go +++ b/pkg/sentry/time/clocks.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/muldiv_amd64.s b/pkg/sentry/time/muldiv_amd64.s index bfcb8c724..028c6684e 100644 --- a/pkg/sentry/time/muldiv_amd64.s +++ b/pkg/sentry/time/muldiv_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/muldiv_arm64.s b/pkg/sentry/time/muldiv_arm64.s index 5fa82a136..5ad57a8a3 100644 --- a/pkg/sentry/time/muldiv_arm64.s +++ b/pkg/sentry/time/muldiv_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/parameters.go b/pkg/sentry/time/parameters.go index 8568b1193..63cf7c4a3 100644 --- a/pkg/sentry/time/parameters.go +++ b/pkg/sentry/time/parameters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/parameters_test.go b/pkg/sentry/time/parameters_test.go index 4a0c4e880..e1b9084ac 100644 --- a/pkg/sentry/time/parameters_test.go +++ b/pkg/sentry/time/parameters_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/sampler.go b/pkg/sentry/time/sampler.go index 445690d49..2140a99b7 100644 --- a/pkg/sentry/time/sampler.go +++ b/pkg/sentry/time/sampler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/sampler_test.go b/pkg/sentry/time/sampler_test.go index ec0e442b6..3e70a1134 100644 --- a/pkg/sentry/time/sampler_test.go +++ b/pkg/sentry/time/sampler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/sampler_unsafe.go b/pkg/sentry/time/sampler_unsafe.go index 0f8eb4fc8..e76180217 100644 --- a/pkg/sentry/time/sampler_unsafe.go +++ b/pkg/sentry/time/sampler_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/tsc_amd64.s b/pkg/sentry/time/tsc_amd64.s index e53d477f7..6a8eed664 100644 --- a/pkg/sentry/time/tsc_amd64.s +++ b/pkg/sentry/time/tsc_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/time/tsc_arm64.s b/pkg/sentry/time/tsc_arm64.s index c1c9760ef..da9fa4112 100644 --- a/pkg/sentry/time/tsc_arm64.s +++ b/pkg/sentry/time/tsc_arm64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/unimpl/events.go b/pkg/sentry/unimpl/events.go index f78f8c981..d92766e2d 100644 --- a/pkg/sentry/unimpl/events.go +++ b/pkg/sentry/unimpl/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/unimpl/unimplemented_syscall.proto b/pkg/sentry/unimpl/unimplemented_syscall.proto index 41579b016..0d7a94be7 100644 --- a/pkg/sentry/unimpl/unimplemented_syscall.proto +++ b/pkg/sentry/unimpl/unimplemented_syscall.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/uniqueid/context.go b/pkg/sentry/uniqueid/context.go index 399d98c29..e55b89689 100644 --- a/pkg/sentry/uniqueid/context.go +++ b/pkg/sentry/uniqueid/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/cpu.go b/pkg/sentry/usage/cpu.go index cbd7cfe19..bfc282d69 100644 --- a/pkg/sentry/usage/cpu.go +++ b/pkg/sentry/usage/cpu.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/io.go b/pkg/sentry/usage/io.go index 8e27a0a88..dfcd3a49d 100644 --- a/pkg/sentry/usage/io.go +++ b/pkg/sentry/usage/io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/memory.go b/pkg/sentry/usage/memory.go index 5be9ed9c6..c316f1597 100644 --- a/pkg/sentry/usage/memory.go +++ b/pkg/sentry/usage/memory.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/memory_unsafe.go b/pkg/sentry/usage/memory_unsafe.go index a3ae668a5..9e0014ca0 100644 --- a/pkg/sentry/usage/memory_unsafe.go +++ b/pkg/sentry/usage/memory_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usage/usage.go b/pkg/sentry/usage/usage.go index ab327f8e2..e3d33a965 100644 --- a/pkg/sentry/usage/usage.go +++ b/pkg/sentry/usage/usage.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go index 9e6a27bcf..9c1742a59 100644 --- a/pkg/sentry/usermem/access_type.go +++ b/pkg/sentry/usermem/access_type.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go index 2a75aa60c..e79210804 100644 --- a/pkg/sentry/usermem/addr.go +++ b/pkg/sentry/usermem/addr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/addr_range_seq_test.go b/pkg/sentry/usermem/addr_range_seq_test.go index bd6a1ec8a..82f735026 100644 --- a/pkg/sentry/usermem/addr_range_seq_test.go +++ b/pkg/sentry/usermem/addr_range_seq_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/addr_range_seq_unsafe.go b/pkg/sentry/usermem/addr_range_seq_unsafe.go index f5fd446fa..c09337c15 100644 --- a/pkg/sentry/usermem/addr_range_seq_unsafe.go +++ b/pkg/sentry/usermem/addr_range_seq_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/bytes_io.go b/pkg/sentry/usermem/bytes_io.go index 274f568d0..f98d82168 100644 --- a/pkg/sentry/usermem/bytes_io.go +++ b/pkg/sentry/usermem/bytes_io.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/bytes_io_unsafe.go b/pkg/sentry/usermem/bytes_io_unsafe.go index 7add8bc82..bb49d2ff3 100644 --- a/pkg/sentry/usermem/bytes_io_unsafe.go +++ b/pkg/sentry/usermem/bytes_io_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/usermem.go b/pkg/sentry/usermem/usermem.go index 4c7d5014a..31e4d6ada 100644 --- a/pkg/sentry/usermem/usermem.go +++ b/pkg/sentry/usermem/usermem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/usermem_arm64.go b/pkg/sentry/usermem/usermem_arm64.go index 7fd4ce963..fdfc30a66 100644 --- a/pkg/sentry/usermem/usermem_arm64.go +++ b/pkg/sentry/usermem/usermem_arm64.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/usermem/usermem_test.go b/pkg/sentry/usermem/usermem_test.go index 1991a9641..4a07118b7 100644 --- a/pkg/sentry/usermem/usermem_test.go +++ b/pkg/sentry/usermem/usermem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/usermem/usermem_unsafe.go b/pkg/sentry/usermem/usermem_unsafe.go index 3895e7871..876783e78 100644 --- a/pkg/sentry/usermem/usermem_unsafe.go +++ b/pkg/sentry/usermem/usermem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/sentry/usermem/usermem_x86.go b/pkg/sentry/usermem/usermem_x86.go index 9ec90f9ff..8059b72d2 100644 --- a/pkg/sentry/usermem/usermem_x86.go +++ b/pkg/sentry/usermem/usermem_x86.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sentry/watchdog/watchdog.go b/pkg/sentry/watchdog/watchdog.go index b4f1e3a4f..2fc4472dd 100644 --- a/pkg/sentry/watchdog/watchdog.go +++ b/pkg/sentry/watchdog/watchdog.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/commit_amd64.s b/pkg/sleep/commit_amd64.s index d08df7f37..bc4ac2c3c 100644 --- a/pkg/sleep/commit_amd64.s +++ b/pkg/sleep/commit_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/commit_asm.go b/pkg/sleep/commit_asm.go index 90eef4cbc..35e2cc337 100644 --- a/pkg/sleep/commit_asm.go +++ b/pkg/sleep/commit_asm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/commit_noasm.go b/pkg/sleep/commit_noasm.go index 967d22e24..686b1da3d 100644 --- a/pkg/sleep/commit_noasm.go +++ b/pkg/sleep/commit_noasm.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/empty.s b/pkg/sleep/empty.s index 85d52cd9c..fb37360ac 100644 --- a/pkg/sleep/empty.s +++ b/pkg/sleep/empty.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/sleep_test.go b/pkg/sleep/sleep_test.go index 8feb9ffc2..130806c86 100644 --- a/pkg/sleep/sleep_test.go +++ b/pkg/sleep/sleep_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/sleep/sleep_unsafe.go b/pkg/sleep/sleep_unsafe.go index 45fb6f0ea..62e0abc34 100644 --- a/pkg/sleep/sleep_unsafe.go +++ b/pkg/sleep/sleep_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/decode.go b/pkg/state/decode.go index 54b5ad8b8..73a59f871 100644 --- a/pkg/state/decode.go +++ b/pkg/state/decode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/encode.go b/pkg/state/encode.go index fe8512bbf..b0714170b 100644 --- a/pkg/state/encode.go +++ b/pkg/state/encode.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/encode_unsafe.go b/pkg/state/encode_unsafe.go index be94742a8..457e6dbb7 100644 --- a/pkg/state/encode_unsafe.go +++ b/pkg/state/encode_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/map.go b/pkg/state/map.go index 0035d7250..1fb9b47b8 100644 --- a/pkg/state/map.go +++ b/pkg/state/map.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/object.proto b/pkg/state/object.proto index d3b46ea97..952289069 100644 --- a/pkg/state/object.proto +++ b/pkg/state/object.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/printer.go b/pkg/state/printer.go index aee4b69fb..5174c3ba3 100644 --- a/pkg/state/printer.go +++ b/pkg/state/printer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/state.go b/pkg/state/state.go index 4486f83a7..cf7df803a 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index 22bcad9e1..7c24bbcda 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/statefile/statefile.go b/pkg/state/statefile/statefile.go index c21e3bb0e..ad4e3b43e 100644 --- a/pkg/state/statefile/statefile.go +++ b/pkg/state/statefile/statefile.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/statefile/statefile_test.go b/pkg/state/statefile/statefile_test.go index b4f400e01..60b769895 100644 --- a/pkg/state/statefile/statefile_test.go +++ b/pkg/state/statefile/statefile_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/state/stats.go b/pkg/state/stats.go index 17ca258fc..eb51cda47 100644 --- a/pkg/state/stats.go +++ b/pkg/state/stats.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserr/host_linux.go b/pkg/syserr/host_linux.go index 74bbe9f5b..fc6ef60a1 100644 --- a/pkg/syserr/host_linux.go +++ b/pkg/syserr/host_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go index 1a23919ef..bd489b424 100644 --- a/pkg/syserr/netstack.go +++ b/pkg/syserr/netstack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go index 232634dd4..4ddbd3322 100644 --- a/pkg/syserr/syserr.go +++ b/pkg/syserr/syserr.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserror/syserror.go b/pkg/syserror/syserror.go index 5558cccff..345653544 100644 --- a/pkg/syserror/syserror.go +++ b/pkg/syserror/syserror.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/syserror/syserror_test.go b/pkg/syserror/syserror_test.go index 0f0da5781..f2a10ee7b 100644 --- a/pkg/syserror/syserror_test.go +++ b/pkg/syserror/syserror_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/adapters/gonet/gonet.go b/pkg/tcpip/adapters/gonet/gonet.go index 628e28f57..df8bf435d 100644 --- a/pkg/tcpip/adapters/gonet/gonet.go +++ b/pkg/tcpip/adapters/gonet/gonet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/adapters/gonet/gonet_test.go b/pkg/tcpip/adapters/gonet/gonet_test.go index e84f73feb..2c81c5697 100644 --- a/pkg/tcpip/adapters/gonet/gonet_test.go +++ b/pkg/tcpip/adapters/gonet/gonet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/buffer/prependable.go b/pkg/tcpip/buffer/prependable.go index d3a9a0f88..43cbbc74c 100644 --- a/pkg/tcpip/buffer/prependable.go +++ b/pkg/tcpip/buffer/prependable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/buffer/view.go b/pkg/tcpip/buffer/view.go index 43cbb9461..1a9d40778 100644 --- a/pkg/tcpip/buffer/view.go +++ b/pkg/tcpip/buffer/view.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/buffer/view_test.go b/pkg/tcpip/buffer/view_test.go index 74a0a96fc..ebc3a17b7 100644 --- a/pkg/tcpip/buffer/view_test.go +++ b/pkg/tcpip/buffer/view_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go index 5dfb3ca1d..6e7edf3ab 100644 --- a/pkg/tcpip/checker/checker.go +++ b/pkg/tcpip/checker/checker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/hash/jenkins/jenkins.go b/pkg/tcpip/hash/jenkins/jenkins.go index e66d5f12b..52c22230e 100644 --- a/pkg/tcpip/hash/jenkins/jenkins.go +++ b/pkg/tcpip/hash/jenkins/jenkins.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/hash/jenkins/jenkins_test.go b/pkg/tcpip/hash/jenkins/jenkins_test.go index 9d86174aa..4c78b5808 100644 --- a/pkg/tcpip/hash/jenkins/jenkins_test.go +++ b/pkg/tcpip/hash/jenkins/jenkins_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/arp.go b/pkg/tcpip/header/arp.go index 22b259ccb..55fe7292c 100644 --- a/pkg/tcpip/header/arp.go +++ b/pkg/tcpip/header/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/checksum.go b/pkg/tcpip/header/checksum.go index 2e8c65fac..2eaa7938a 100644 --- a/pkg/tcpip/header/checksum.go +++ b/pkg/tcpip/header/checksum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/eth.go b/pkg/tcpip/header/eth.go index 77365bc41..76143f454 100644 --- a/pkg/tcpip/header/eth.go +++ b/pkg/tcpip/header/eth.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/gue.go b/pkg/tcpip/header/gue.go index 2ad13955a..10d358c0e 100644 --- a/pkg/tcpip/header/gue.go +++ b/pkg/tcpip/header/gue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/icmpv4.go b/pkg/tcpip/header/icmpv4.go index 3ac89cdae..782e1053c 100644 --- a/pkg/tcpip/header/icmpv4.go +++ b/pkg/tcpip/header/icmpv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/icmpv6.go b/pkg/tcpip/header/icmpv6.go index e317975e8..d0b10d849 100644 --- a/pkg/tcpip/header/icmpv6.go +++ b/pkg/tcpip/header/icmpv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/interfaces.go b/pkg/tcpip/header/interfaces.go index ac327d8a5..fb250ea30 100644 --- a/pkg/tcpip/header/interfaces.go +++ b/pkg/tcpip/header/interfaces.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipv4.go b/pkg/tcpip/header/ipv4.go index c3b8fb00e..96e461491 100644 --- a/pkg/tcpip/header/ipv4.go +++ b/pkg/tcpip/header/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go index 3d24736c7..66820a466 100644 --- a/pkg/tcpip/header/ipv6.go +++ b/pkg/tcpip/header/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipv6_fragment.go b/pkg/tcpip/header/ipv6_fragment.go index e36d5177b..6d896355a 100644 --- a/pkg/tcpip/header/ipv6_fragment.go +++ b/pkg/tcpip/header/ipv6_fragment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/ipversion_test.go b/pkg/tcpip/header/ipversion_test.go index 8301ba5cf..0c830180e 100644 --- a/pkg/tcpip/header/ipversion_test.go +++ b/pkg/tcpip/header/ipversion_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/tcp.go b/pkg/tcpip/header/tcp.go index e656ebb15..0cd89b992 100644 --- a/pkg/tcpip/header/tcp.go +++ b/pkg/tcpip/header/tcp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/tcp_test.go b/pkg/tcpip/header/tcp_test.go index 7cd98df3b..9a2b99489 100644 --- a/pkg/tcpip/header/tcp_test.go +++ b/pkg/tcpip/header/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/header/udp.go b/pkg/tcpip/header/udp.go index e8c860436..2205fec18 100644 --- a/pkg/tcpip/header/udp.go +++ b/pkg/tcpip/header/udp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index f7501a1bc..ee9dd8700 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 8f4d67074..4da376774 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index c8b037d57..31138e4ac 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/fdbased/endpoint_unsafe.go b/pkg/tcpip/link/fdbased/endpoint_unsafe.go index 36e7fe5a9..97a477b61 100644 --- a/pkg/tcpip/link/fdbased/endpoint_unsafe.go +++ b/pkg/tcpip/link/fdbased/endpoint_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/fdbased/mmap.go b/pkg/tcpip/link/fdbased/mmap.go index f1e71c233..430c85a42 100644 --- a/pkg/tcpip/link/fdbased/mmap.go +++ b/pkg/tcpip/link/fdbased/mmap.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go b/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go index e5ac7996d..135da2498 100644 --- a/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go +++ b/pkg/tcpip/link/fdbased/mmap_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 2dc4bcfda..2c1148123 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/muxed/injectable.go b/pkg/tcpip/link/muxed/injectable.go index b3e71c7fc..be07b7c29 100644 --- a/pkg/tcpip/link/muxed/injectable.go +++ b/pkg/tcpip/link/muxed/injectable.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go index 031449a05..5d40dfacc 100644 --- a/pkg/tcpip/link/muxed/injectable_test.go +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s index 9dade5421..b54131573 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go index 3ba96a123..0b51982c6 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_amd64_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go index 94ddad8ea..4eab77c74 100644 --- a/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go +++ b/pkg/tcpip/link/rawfile/blockingpoll_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/link/rawfile/errors.go index 7359849b1..8bde41637 100644 --- a/pkg/tcpip/link/rawfile/errors.go +++ b/pkg/tcpip/link/rawfile/errors.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/tcpip/link/rawfile/rawfile_unsafe.go index fe2779125..86db7a487 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/tcpip/link/rawfile/rawfile_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe.go b/pkg/tcpip/link/sharedmem/pipe/pipe.go index e014324cc..74c9f0311 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go index 30742ccb1..59ef69a8b 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_test.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go index f491d74a2..62d17029e 100644 --- a/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go +++ b/pkg/tcpip/link/sharedmem/pipe/pipe_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/rx.go b/pkg/tcpip/link/sharedmem/pipe/rx.go index 8d641c76f..f22e533ac 100644 --- a/pkg/tcpip/link/sharedmem/pipe/rx.go +++ b/pkg/tcpip/link/sharedmem/pipe/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/pipe/tx.go b/pkg/tcpip/link/sharedmem/pipe/tx.go index e75175d98..9841eb231 100644 --- a/pkg/tcpip/link/sharedmem/pipe/tx.go +++ b/pkg/tcpip/link/sharedmem/pipe/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/queue/queue_test.go b/pkg/tcpip/link/sharedmem/queue/queue_test.go index 391165bc3..d3f8f4b8b 100644 --- a/pkg/tcpip/link/sharedmem/queue/queue_test.go +++ b/pkg/tcpip/link/sharedmem/queue/queue_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/queue/rx.go b/pkg/tcpip/link/sharedmem/queue/rx.go index d3a5da08a..d9aecf2d9 100644 --- a/pkg/tcpip/link/sharedmem/queue/rx.go +++ b/pkg/tcpip/link/sharedmem/queue/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/queue/tx.go b/pkg/tcpip/link/sharedmem/queue/tx.go index 845108db1..a24dccd11 100644 --- a/pkg/tcpip/link/sharedmem/queue/tx.go +++ b/pkg/tcpip/link/sharedmem/queue/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/rx.go b/pkg/tcpip/link/sharedmem/rx.go index 3eeab769e..215cb607f 100644 --- a/pkg/tcpip/link/sharedmem/rx.go +++ b/pkg/tcpip/link/sharedmem/rx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 6e6aa5a13..e34b780f8 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 1f44e224c..65b9d7085 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go index b91adbaf7..f7e816a41 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sharedmem/tx.go b/pkg/tcpip/link/sharedmem/tx.go index 37da34831..ac3577aa6 100644 --- a/pkg/tcpip/link/sharedmem/tx.go +++ b/pkg/tcpip/link/sharedmem/tx.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go index 3d0d8d852..c16c19647 100644 --- a/pkg/tcpip/link/sniffer/pcap.go +++ b/pkg/tcpip/link/sniffer/pcap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 462a6e3a3..e87ae07d7 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/tun/tun_unsafe.go b/pkg/tcpip/link/tun/tun_unsafe.go index e4c589dda..09ca9b527 100644 --- a/pkg/tcpip/link/tun/tun_unsafe.go +++ b/pkg/tcpip/link/tun/tun_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index bd9f9845b..21690a226 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index a2df6be95..62054fb7f 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/arp/arp.go b/pkg/tcpip/network/arp/arp.go index 975919e80..a3f2bce3e 100644 --- a/pkg/tcpip/network/arp/arp.go +++ b/pkg/tcpip/network/arp/arp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/arp/arp_test.go b/pkg/tcpip/network/arp/arp_test.go index 14b9cb8b6..1b971b1a3 100644 --- a/pkg/tcpip/network/arp/arp_test.go +++ b/pkg/tcpip/network/arp/arp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/frag_heap.go b/pkg/tcpip/network/fragmentation/frag_heap.go index 55615c8e6..9ad3e5a8a 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap.go +++ b/pkg/tcpip/network/fragmentation/frag_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/frag_heap_test.go b/pkg/tcpip/network/fragmentation/frag_heap_test.go index 1b1b72e88..3a2486ba8 100644 --- a/pkg/tcpip/network/fragmentation/frag_heap_test.go +++ b/pkg/tcpip/network/fragmentation/frag_heap_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/fragmentation.go b/pkg/tcpip/network/fragmentation/fragmentation.go index a5dda0398..e90edb375 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation.go +++ b/pkg/tcpip/network/fragmentation/fragmentation.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/fragmentation_test.go b/pkg/tcpip/network/fragmentation/fragmentation_test.go index 5bf3463a9..99ded68a3 100644 --- a/pkg/tcpip/network/fragmentation/fragmentation_test.go +++ b/pkg/tcpip/network/fragmentation/fragmentation_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/reassembler.go b/pkg/tcpip/network/fragmentation/reassembler.go index c9ad2bef6..04f9ab964 100644 --- a/pkg/tcpip/network/fragmentation/reassembler.go +++ b/pkg/tcpip/network/fragmentation/reassembler.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/fragmentation/reassembler_test.go b/pkg/tcpip/network/fragmentation/reassembler_test.go index a2bc9707a..7eee0710d 100644 --- a/pkg/tcpip/network/fragmentation/reassembler_test.go +++ b/pkg/tcpip/network/fragmentation/reassembler_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/hash/hash.go b/pkg/tcpip/network/hash/hash.go index 07960ddf0..0c91905dc 100644 --- a/pkg/tcpip/network/hash/hash.go +++ b/pkg/tcpip/network/hash/hash.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ip_test.go b/pkg/tcpip/network/ip_test.go index 522009fac..4b822e2c6 100644 --- a/pkg/tcpip/network/ip_test.go +++ b/pkg/tcpip/network/ip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv4/icmp.go b/pkg/tcpip/network/ipv4/icmp.go index 1c3acda4b..9cb81245a 100644 --- a/pkg/tcpip/network/ipv4/icmp.go +++ b/pkg/tcpip/network/ipv4/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index cbdca98a5..c6af0db79 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv4/ipv4_test.go b/pkg/tcpip/network/ipv4/ipv4_test.go index 42e85564e..146143ab3 100644 --- a/pkg/tcpip/network/ipv4/ipv4_test.go +++ b/pkg/tcpip/network/ipv4/ipv4_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv6/icmp.go b/pkg/tcpip/network/ipv6/icmp.go index be28be36d..9c011e107 100644 --- a/pkg/tcpip/network/ipv6/icmp.go +++ b/pkg/tcpip/network/ipv6/icmp.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv6/icmp_test.go b/pkg/tcpip/network/ipv6/icmp_test.go index 8b57a0641..d8737a616 100644 --- a/pkg/tcpip/network/ipv6/icmp_test.go +++ b/pkg/tcpip/network/ipv6/icmp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/network/ipv6/ipv6.go b/pkg/tcpip/network/ipv6/ipv6.go index 9a743ea80..4b8cd496b 100644 --- a/pkg/tcpip/network/ipv6/ipv6.go +++ b/pkg/tcpip/network/ipv6/ipv6.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/ports/ports.go b/pkg/tcpip/ports/ports.go index d212a5792..a1712b590 100644 --- a/pkg/tcpip/ports/ports.go +++ b/pkg/tcpip/ports/ports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/ports/ports_test.go b/pkg/tcpip/ports/ports_test.go index 01e7320b4..8466c661b 100644 --- a/pkg/tcpip/ports/ports_test.go +++ b/pkg/tcpip/ports/ports_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index cf8900c4d..1681de56e 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index da6202f97..642607f83 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/seqnum/seqnum.go b/pkg/tcpip/seqnum/seqnum.go index f2b988839..b40a3c212 100644 --- a/pkg/tcpip/seqnum/seqnum.go +++ b/pkg/tcpip/seqnum/seqnum.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 40e4bdb4a..42b9768ae 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/linkaddrcache_test.go b/pkg/tcpip/stack/linkaddrcache_test.go index 77a09ca86..91b2ffea8 100644 --- a/pkg/tcpip/stack/linkaddrcache_test.go +++ b/pkg/tcpip/stack/linkaddrcache_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go index c18571b0f..8008d9870 100644 --- a/pkg/tcpip/stack/nic.go +++ b/pkg/tcpip/stack/nic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 6e1660051..c70533a35 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 8ae562dcd..3d4c282a9 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index cb9ffe9c2..f204ca790 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/stack_global_state.go b/pkg/tcpip/stack/stack_global_state.go index 3d7e4b719..dfec4258a 100644 --- a/pkg/tcpip/stack/stack_global_state.go +++ b/pkg/tcpip/stack/stack_global_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index b5375df3c..351f63221 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index a8ac18e72..e8b562ad9 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/stack/transport_test.go b/pkg/tcpip/stack/transport_test.go index 2df974bf2..8d74f1543 100644 --- a/pkg/tcpip/stack/transport_test.go +++ b/pkg/tcpip/stack/transport_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index b09137f08..9367c8c02 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/tcpip_test.go b/pkg/tcpip/tcpip_test.go index 1f7b04398..ebb1c1b56 100644 --- a/pkg/tcpip/tcpip_test.go +++ b/pkg/tcpip/tcpip_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/time.s b/pkg/tcpip/time.s index 85d52cd9c..fb37360ac 100644 --- a/pkg/tcpip/time.s +++ b/pkg/tcpip/time.s @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/time_unsafe.go b/pkg/tcpip/time_unsafe.go index 7ec5741af..1a307483b 100644 --- a/pkg/tcpip/time_unsafe.go +++ b/pkg/tcpip/time_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index 8f2e3aa20..00840cfcf 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/icmp/endpoint_state.go b/pkg/tcpip/transport/icmp/endpoint_state.go index 8a7909246..332b3cd33 100644 --- a/pkg/tcpip/transport/icmp/endpoint_state.go +++ b/pkg/tcpip/transport/icmp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/icmp/protocol.go b/pkg/tcpip/transport/icmp/protocol.go index 09ee2f892..954fde9d8 100644 --- a/pkg/tcpip/transport/icmp/protocol.go +++ b/pkg/tcpip/transport/icmp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/raw/raw.go b/pkg/tcpip/transport/raw/raw.go index f0f60ce91..7004c7ff4 100644 --- a/pkg/tcpip/transport/raw/raw.go +++ b/pkg/tcpip/transport/raw/raw.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/transport/raw/state.go b/pkg/tcpip/transport/raw/state.go index e3891a8b8..e8907ebb1 100644 --- a/pkg/tcpip/transport/raw/state.go +++ b/pkg/tcpip/transport/raw/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/accept.go b/pkg/tcpip/transport/tcp/accept.go index a3894ed8f..e506d7133 100644 --- a/pkg/tcpip/transport/tcp/accept.go +++ b/pkg/tcpip/transport/tcp/accept.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go index 6c4a4d95e..eaa67aeb7 100644 --- a/pkg/tcpip/transport/tcp/connect.go +++ b/pkg/tcpip/transport/tcp/connect.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/cubic.go b/pkg/tcpip/transport/tcp/cubic.go index 003525d86..e618cd2b9 100644 --- a/pkg/tcpip/transport/tcp/cubic.go +++ b/pkg/tcpip/transport/tcp/cubic.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index 2886cc707..43bcfa070 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 09eff5be1..982f491cc 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/endpoint_state.go b/pkg/tcpip/transport/tcp/endpoint_state.go index 7f9dabb4d..27b0be046 100644 --- a/pkg/tcpip/transport/tcp/endpoint_state.go +++ b/pkg/tcpip/transport/tcp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/forwarder.go b/pkg/tcpip/transport/tcp/forwarder.go index 6a7efaf1d..e088e24cb 100644 --- a/pkg/tcpip/transport/tcp/forwarder.go +++ b/pkg/tcpip/transport/tcp/forwarder.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/protocol.go b/pkg/tcpip/transport/tcp/protocol.go index b5fb160bc..b86473891 100644 --- a/pkg/tcpip/transport/tcp/protocol.go +++ b/pkg/tcpip/transport/tcp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/rcv.go b/pkg/tcpip/transport/tcp/rcv.go index fa6bdddba..b08a0e356 100644 --- a/pkg/tcpip/transport/tcp/rcv.go +++ b/pkg/tcpip/transport/tcp/rcv.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/reno.go b/pkg/tcpip/transport/tcp/reno.go index e4f8b7d5a..f83ebc717 100644 --- a/pkg/tcpip/transport/tcp/reno.go +++ b/pkg/tcpip/transport/tcp/reno.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/sack.go b/pkg/tcpip/transport/tcp/sack.go index 24e48fe7b..6a013d99b 100644 --- a/pkg/tcpip/transport/tcp/sack.go +++ b/pkg/tcpip/transport/tcp/sack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard.go b/pkg/tcpip/transport/tcp/sack_scoreboard.go index 21878ad82..99560d5b4 100644 --- a/pkg/tcpip/transport/tcp/sack_scoreboard.go +++ b/pkg/tcpip/transport/tcp/sack_scoreboard.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go index 3cf2ff451..8f6890cdf 100644 --- a/pkg/tcpip/transport/tcp/sack_scoreboard_test.go +++ b/pkg/tcpip/transport/tcp/sack_scoreboard_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment.go b/pkg/tcpip/transport/tcp/segment.go index c603fe713..187effb6b 100644 --- a/pkg/tcpip/transport/tcp/segment.go +++ b/pkg/tcpip/transport/tcp/segment.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment_heap.go b/pkg/tcpip/transport/tcp/segment_heap.go index 98422fadf..9fd061d7d 100644 --- a/pkg/tcpip/transport/tcp/segment_heap.go +++ b/pkg/tcpip/transport/tcp/segment_heap.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment_queue.go b/pkg/tcpip/transport/tcp/segment_queue.go index 0c637d7ad..3b020e580 100644 --- a/pkg/tcpip/transport/tcp/segment_queue.go +++ b/pkg/tcpip/transport/tcp/segment_queue.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/segment_state.go b/pkg/tcpip/transport/tcp/segment_state.go index 68b049f06..dd7e14aa6 100644 --- a/pkg/tcpip/transport/tcp/segment_state.go +++ b/pkg/tcpip/transport/tcp/segment_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/snd.go b/pkg/tcpip/transport/tcp/snd.go index 6317748cf..50743670e 100644 --- a/pkg/tcpip/transport/tcp/snd.go +++ b/pkg/tcpip/transport/tcp/snd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/snd_state.go b/pkg/tcpip/transport/tcp/snd_state.go index 86bbd643f..12eff8afc 100644 --- a/pkg/tcpip/transport/tcp/snd_state.go +++ b/pkg/tcpip/transport/tcp/snd_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/tcp_sack_test.go b/pkg/tcpip/transport/tcp/tcp_sack_test.go index 06b0702c5..dbfbd5c4f 100644 --- a/pkg/tcpip/transport/tcp/tcp_sack_test.go +++ b/pkg/tcpip/transport/tcp/tcp_sack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/tcp_test.go b/pkg/tcpip/transport/tcp/tcp_test.go index c5732ad1c..a8b290dae 100644 --- a/pkg/tcpip/transport/tcp/tcp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go index 87c640967..039bbcfba 100644 --- a/pkg/tcpip/transport/tcp/tcp_timestamp_test.go +++ b/pkg/tcpip/transport/tcp/tcp_timestamp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 6e2fed880..fa721a7f8 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcp/timer.go b/pkg/tcpip/transport/tcp/timer.go index 38240d2d5..fc1c7cbd2 100644 --- a/pkg/tcpip/transport/tcp/timer.go +++ b/pkg/tcpip/transport/tcp/timer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go index b94568fb1..f1dcd36d5 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go index aaeae9b18..435e136de 100644 --- a/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go +++ b/pkg/tcpip/transport/tcpconntrack/tcp_conntrack_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 1f9251de3..db65a4e88 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/endpoint_state.go b/pkg/tcpip/transport/udp/endpoint_state.go index b2daaf751..163dcbc13 100644 --- a/pkg/tcpip/transport/udp/endpoint_state.go +++ b/pkg/tcpip/transport/udp/endpoint_state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/forwarder.go b/pkg/tcpip/transport/udp/forwarder.go index d80c47e34..25bdd2929 100644 --- a/pkg/tcpip/transport/udp/forwarder.go +++ b/pkg/tcpip/transport/udp/forwarder.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/pkg/tcpip/transport/udp/protocol.go b/pkg/tcpip/transport/udp/protocol.go index 616a9f388..8b47cce17 100644 --- a/pkg/tcpip/transport/udp/protocol.go +++ b/pkg/tcpip/transport/udp/protocol.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 2f4e94c58..86a8fa19b 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tmutex/tmutex.go b/pkg/tmutex/tmutex.go index df61d89f5..c4685020d 100644 --- a/pkg/tmutex/tmutex.go +++ b/pkg/tmutex/tmutex.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/tmutex/tmutex_test.go b/pkg/tmutex/tmutex_test.go index a4537cb3b..ce34c7962 100644 --- a/pkg/tmutex/tmutex_test.go +++ b/pkg/tmutex/tmutex_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/unet/unet.go b/pkg/unet/unet.go index 114fb8c5b..2aa1af4ff 100644 --- a/pkg/unet/unet.go +++ b/pkg/unet/unet.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/unet/unet_test.go b/pkg/unet/unet_test.go index db5485539..763b23c7c 100644 --- a/pkg/unet/unet_test.go +++ b/pkg/unet/unet_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/unet/unet_unsafe.go b/pkg/unet/unet_unsafe.go index 1d6ec286c..fa0916439 100644 --- a/pkg/unet/unet_unsafe.go +++ b/pkg/unet/unet_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/urpc/urpc.go b/pkg/urpc/urpc.go index 719f0e92f..0f155ec74 100644 --- a/pkg/urpc/urpc.go +++ b/pkg/urpc/urpc.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/urpc/urpc_test.go b/pkg/urpc/urpc_test.go index f1b9a85ca..5bf2c5ed2 100644 --- a/pkg/urpc/urpc_test.go +++ b/pkg/urpc/urpc_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index a6c9dff3c..8a65ed164 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/pkg/waiter/waiter_test.go b/pkg/waiter/waiter_test.go index 60853f9c1..c1b94a4f3 100644 --- a/pkg/waiter/waiter_test.go +++ b/pkg/waiter/waiter_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index b3499bcde..c1b33c551 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/compat_amd64.go b/runsc/boot/compat_amd64.go index 0c9472f18..99df5e614 100644 --- a/runsc/boot/compat_amd64.go +++ b/runsc/boot/compat_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/compat_test.go b/runsc/boot/compat_test.go index f1940dd72..ccec3d20c 100644 --- a/runsc/boot/compat_test.go +++ b/runsc/boot/compat_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/config.go b/runsc/boot/config.go index ba47effc1..b6771de30 100644 --- a/runsc/boot/config.go +++ b/runsc/boot/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index 712c50ee9..ab7c58838 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/debug.go b/runsc/boot/debug.go index d224d08b7..79f7387ac 100644 --- a/runsc/boot/debug.go +++ b/runsc/boot/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/events.go b/runsc/boot/events.go index 717adfedd..ffd99f5e9 100644 --- a/runsc/boot/events.go +++ b/runsc/boot/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/fds.go b/runsc/boot/fds.go index a3d21d963..4e428b49c 100644 --- a/runsc/boot/fds.go +++ b/runsc/boot/fds.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index 9c72e3b1a..652da1cef 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/extra_filters.go b/runsc/boot/filter/extra_filters.go index 67f3101fe..5c5ec4e06 100644 --- a/runsc/boot/filter/extra_filters.go +++ b/runsc/boot/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/extra_filters_msan.go b/runsc/boot/filter/extra_filters_msan.go index fb95283ab..ac5a0f1aa 100644 --- a/runsc/boot/filter/extra_filters_msan.go +++ b/runsc/boot/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/extra_filters_race.go b/runsc/boot/filter/extra_filters_race.go index 02a122c95..ba3c1ce87 100644 --- a/runsc/boot/filter/extra_filters_race.go +++ b/runsc/boot/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index fb197f9b1..17479e0dd 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 07061b9b3..aeb1c52cc 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/limits.go b/runsc/boot/limits.go index 32e62cdf7..3364aa5e6 100644 --- a/runsc/boot/limits.go +++ b/runsc/boot/limits.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 75ec19c32..0b5be0a42 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go index 01578cfc5..9a864ad3f 100644 --- a/runsc/boot/loader_test.go +++ b/runsc/boot/loader_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 35baa36ad..598ec969e 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/boot/strace.go b/runsc/boot/strace.go index 028bcc1f4..19c7f8fbd 100644 --- a/runsc/boot/strace.go +++ b/runsc/boot/strace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index 2b338b6c6..7431b17d6 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cgroup/cgroup_test.go b/runsc/cgroup/cgroup_test.go index ecc184f74..548c80e9a 100644 --- a/runsc/cgroup/cgroup_test.go +++ b/runsc/cgroup/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index ff2fa2fb9..ac937f7bc 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/capability.go b/runsc/cmd/capability.go index e5da021e5..312e5b471 100644 --- a/runsc/cmd/capability.go +++ b/runsc/cmd/capability.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/capability_test.go b/runsc/cmd/capability_test.go index dd278b32d..ee74d33d8 100644 --- a/runsc/cmd/capability_test.go +++ b/runsc/cmd/capability_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index f722df055..96d3c3378 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/chroot.go b/runsc/cmd/chroot.go index ed1dafef1..1a774db04 100644 --- a/runsc/cmd/chroot.go +++ b/runsc/cmd/chroot.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go index 208cf5304..aa7b1a636 100644 --- a/runsc/cmd/cmd.go +++ b/runsc/cmd/cmd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index 30c8fa283..629c198fd 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go index 3ee9a9b49..000f694c7 100644 --- a/runsc/cmd/debug.go +++ b/runsc/cmd/debug.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index 3206b267a..9039723e9 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/delete_test.go b/runsc/cmd/delete_test.go index 4a5b4774a..45fc91016 100644 --- a/runsc/cmd/delete_test.go +++ b/runsc/cmd/delete_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/do.go b/runsc/cmd/do.go index 343461130..67d415733 100644 --- a/runsc/cmd/do.go +++ b/runsc/cmd/do.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index 208d2f74b..c6bc8fc3a 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 718d01067..ad2508405 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/exec_test.go b/runsc/cmd/exec_test.go index 686c5e150..6f0f258c0 100644 --- a/runsc/cmd/exec_test.go +++ b/runsc/cmd/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index 82487887c..bccb29397 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/gofer_test.go b/runsc/cmd/gofer_test.go index 8e692feb9..cbea7f127 100644 --- a/runsc/cmd/gofer_test.go +++ b/runsc/cmd/gofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index e67f82473..aed5f3291 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index 1dcea2af0..1f5ca2473 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/path.go b/runsc/cmd/path.go index 1276f0dbd..0e9ef7fa5 100644 --- a/runsc/cmd/path.go +++ b/runsc/cmd/path.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index 2c93e5f3e..11b36aa10 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index 060d796f2..3a3e6f17a 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go index 66b23c38e..27b06713a 100644 --- a/runsc/cmd/restore.go +++ b/runsc/cmd/restore.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index 5551d1450..9a2ade41e 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index be1c1b678..4d5f5c139 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/spec.go b/runsc/cmd/spec.go index 063bd39c5..344da13ba 100644 --- a/runsc/cmd/spec.go +++ b/runsc/cmd/spec.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 9e2e0c11d..657726251 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index c3ef65ab5..f0d449b19 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index 6498dd15c..a55a682f3 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/console/console.go b/runsc/console/console.go index 2eb9a8807..64b23639a 100644 --- a/runsc/console/console.go +++ b/runsc/console/console.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/console_test.go b/runsc/container/console_test.go index 0b0dfb4cb..b8af27c15 100644 --- a/runsc/container/console_test.go +++ b/runsc/container/console_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/container.go b/runsc/container/container.go index a30c217f7..884bbc0fb 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index 603c4d929..9458dbb90 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/hook.go b/runsc/container/hook.go index 6b9e5550a..acae6781e 100644 --- a/runsc/container/hook.go +++ b/runsc/container/hook.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index 8922e6dbe..e554237cf 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/shared_volume_test.go b/runsc/container/shared_volume_test.go index 8f81ed630..9d5a592a5 100644 --- a/runsc/container/shared_volume_test.go +++ b/runsc/container/shared_volume_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/runsc/container/status.go b/runsc/container/status.go index 234ffb0dd..91d9112f1 100644 --- a/runsc/container/status.go +++ b/runsc/container/status.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/container/test_app.go b/runsc/container/test_app.go index b5071ada6..62923f1ef 100644 --- a/runsc/container/test_app.go +++ b/runsc/container/test_app.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index 75a087848..a1ad49fb2 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/extra_filters.go b/runsc/fsgofer/filter/extra_filters.go index 67f3101fe..5c5ec4e06 100644 --- a/runsc/fsgofer/filter/extra_filters.go +++ b/runsc/fsgofer/filter/extra_filters.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/extra_filters_msan.go b/runsc/fsgofer/filter/extra_filters_msan.go index 7e142b790..553060bc3 100644 --- a/runsc/fsgofer/filter/extra_filters_msan.go +++ b/runsc/fsgofer/filter/extra_filters_msan.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/extra_filters_race.go b/runsc/fsgofer/filter/extra_filters_race.go index 3cd29472a..28555f898 100644 --- a/runsc/fsgofer/filter/extra_filters_race.go +++ b/runsc/fsgofer/filter/extra_filters_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index c120d57a6..ff8154369 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index c964a2a3b..158f22ddc 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index e74df7ede..695836927 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go index 94413db86..58af5e44d 100644 --- a/runsc/fsgofer/fsgofer_unsafe.go +++ b/runsc/fsgofer/fsgofer_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/main.go b/runsc/main.go index b35726a74..11bc73f75 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index 6c6b665a0..2a68d7043 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/sandbox/network_unsafe.go b/runsc/sandbox/network_unsafe.go index f7447f002..2a2a0fb7e 100644 --- a/runsc/sandbox/network_unsafe.go +++ b/runsc/sandbox/network_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 48a0dafe2..dac35ca0b 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/fs.go b/runsc/specutils/fs.go index 98c3b19c0..1f3afb4e4 100644 --- a/runsc/specutils/fs.go +++ b/runsc/specutils/fs.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/namespace.go b/runsc/specutils/namespace.go index 35da789f4..7d194335c 100644 --- a/runsc/specutils/namespace.go +++ b/runsc/specutils/namespace.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go index ac85bec71..c72207fb4 100644 --- a/runsc/specutils/specutils.go +++ b/runsc/specutils/specutils.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/specutils/specutils_test.go b/runsc/specutils/specutils_test.go index 02af6e6ad..2c86fffe8 100644 --- a/runsc/specutils/specutils_test.go +++ b/runsc/specutils/specutils_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/image/image.go b/runsc/test/image/image.go index bcb6f876f..297f1ab92 100644 --- a/runsc/test/image/image.go +++ b/runsc/test/image/image.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/image/image_test.go b/runsc/test/image/image_test.go index f7e750d71..0c45602f9 100644 --- a/runsc/test/image/image_test.go +++ b/runsc/test/image/image_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/image/mysql.sql b/runsc/test/image/mysql.sql index c1271e719..51554b98d 100644 --- a/runsc/test/image/mysql.sql +++ b/runsc/test/image/mysql.sql @@ -1,4 +1,4 @@ -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/image/ruby.rb b/runsc/test/image/ruby.rb index 25d1ac129..aced49c6d 100644 --- a/runsc/test/image/ruby.rb +++ b/runsc/test/image/ruby.rb @@ -1,4 +1,4 @@ -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/image/ruby.sh b/runsc/test/image/ruby.sh index d3a9b5656..ebe8d5b0e 100644 --- a/runsc/test/image/ruby.sh +++ b/runsc/test/image/ruby.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/install.sh b/runsc/test/install.sh index 32e1e884e..457df2d26 100755 --- a/runsc/test/install.sh +++ b/runsc/test/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/runsc/test/integration/exec_test.go b/runsc/test/integration/exec_test.go index d87957e2d..7af064d79 100644 --- a/runsc/test/integration/exec_test.go +++ b/runsc/test/integration/exec_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/integration/integration.go b/runsc/test/integration/integration.go index e15321c87..4cd5f6c24 100644 --- a/runsc/test/integration/integration.go +++ b/runsc/test/integration/integration.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/integration/integration_test.go b/runsc/test/integration/integration_test.go index 4a2770d48..b2e86aacc 100644 --- a/runsc/test/integration/integration_test.go +++ b/runsc/test/integration/integration_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/cgroup_test.go b/runsc/test/root/cgroup_test.go index 91839048c..edb6dee1d 100644 --- a/runsc/test/root/cgroup_test.go +++ b/runsc/test/root/cgroup_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/chroot_test.go b/runsc/test/root/chroot_test.go index 0deca0532..da2f473b9 100644 --- a/runsc/test/root/chroot_test.go +++ b/runsc/test/root/chroot_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/crictl_test.go b/runsc/test/root/crictl_test.go index 37fe53ba3..3cc176104 100644 --- a/runsc/test/root/crictl_test.go +++ b/runsc/test/root/crictl_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/root.go b/runsc/test/root/root.go index 586ea0fe3..349c752cc 100644 --- a/runsc/test/root/root.go +++ b/runsc/test/root/root.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/busybox.go b/runsc/test/root/testdata/busybox.go index 544571c63..e4dbd2843 100644 --- a/runsc/test/root/testdata/busybox.go +++ b/runsc/test/root/testdata/busybox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/containerd_config.go b/runsc/test/root/testdata/containerd_config.go index 949354987..e12f1ec88 100644 --- a/runsc/test/root/testdata/containerd_config.go +++ b/runsc/test/root/testdata/containerd_config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/httpd.go b/runsc/test/root/testdata/httpd.go index f65b1da5d..45d5e33d4 100644 --- a/runsc/test/root/testdata/httpd.go +++ b/runsc/test/root/testdata/httpd.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/httpd_mount_paths.go b/runsc/test/root/testdata/httpd_mount_paths.go index 5ca14340e..ac3f4446a 100644 --- a/runsc/test/root/testdata/httpd_mount_paths.go +++ b/runsc/test/root/testdata/httpd_mount_paths.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/root/testdata/sandbox.go b/runsc/test/root/testdata/sandbox.go index 194242a27..0db210370 100644 --- a/runsc/test/root/testdata/sandbox.go +++ b/runsc/test/root/testdata/sandbox.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/crictl.go b/runsc/test/testutil/crictl.go index 84bb4475a..4f9ee0c05 100644 --- a/runsc/test/testutil/crictl.go +++ b/runsc/test/testutil/crictl.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/docker.go b/runsc/test/testutil/docker.go index b651319ed..29ef505b4 100644 --- a/runsc/test/testutil/docker.go +++ b/runsc/test/testutil/docker.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/testutil.go b/runsc/test/testutil/testutil.go index 79f0a8b6b..6a4c045a8 100644 --- a/runsc/test/testutil/testutil.go +++ b/runsc/test/testutil/testutil.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/test/testutil/testutil_race.go b/runsc/test/testutil/testutil_race.go index 9267af150..86db6ffa1 100644 --- a/runsc/test/testutil/testutil_race.go +++ b/runsc/test/testutil/testutil_race.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/tools/dockercfg/dockercfg.go b/runsc/tools/dockercfg/dockercfg.go index cc7a67816..6fb134558 100644 --- a/runsc/tools/dockercfg/dockercfg.go +++ b/runsc/tools/dockercfg/dockercfg.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/runsc/version.go b/runsc/version.go index 4894f2de6..ce0573a9b 100644 --- a/runsc/version.go +++ b/runsc/version.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/gtest/gtest.go b/test/syscalls/gtest/gtest.go index dfe5037cd..bdec8eb07 100644 --- a/test/syscalls/gtest/gtest.go +++ b/test/syscalls/gtest/gtest.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/32bit.cc b/test/syscalls/linux/32bit.cc index 78baf548e..a7cbee06b 100644 --- a/test/syscalls/linux/32bit.cc +++ b/test/syscalls/linux/32bit.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/accept_bind.cc b/test/syscalls/linux/accept_bind.cc index c2bb4a7ce..56377feab 100644 --- a/test/syscalls/linux/accept_bind.cc +++ b/test/syscalls/linux/accept_bind.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/accept_bind_stream.cc b/test/syscalls/linux/accept_bind_stream.cc index 1501e526e..b6cdb3f4f 100644 --- a/test/syscalls/linux/accept_bind_stream.cc +++ b/test/syscalls/linux/accept_bind_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/access.cc b/test/syscalls/linux/access.cc index 6ea070a5d..bcc25cef4 100644 --- a/test/syscalls/linux/access.cc +++ b/test/syscalls/linux/access.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/affinity.cc b/test/syscalls/linux/affinity.cc index 81bd9bcb5..f2d8375b6 100644 --- a/test/syscalls/linux/affinity.cc +++ b/test/syscalls/linux/affinity.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/aio.cc b/test/syscalls/linux/aio.cc index b96aab9b9..68dc05417 100644 --- a/test/syscalls/linux/aio.cc +++ b/test/syscalls/linux/aio.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/alarm.cc b/test/syscalls/linux/alarm.cc index e0ddbb415..d89269985 100644 --- a/test/syscalls/linux/alarm.cc +++ b/test/syscalls/linux/alarm.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/arch_prctl.cc b/test/syscalls/linux/arch_prctl.cc index 5687ceb86..81bf5a775 100644 --- a/test/syscalls/linux/arch_prctl.cc +++ b/test/syscalls/linux/arch_prctl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/bad.cc b/test/syscalls/linux/bad.cc index a2634a8bf..f246a799e 100644 --- a/test/syscalls/linux/bad.cc +++ b/test/syscalls/linux/bad.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/base_poll_test.cc b/test/syscalls/linux/base_poll_test.cc index bba0108ea..ab7a19dd0 100644 --- a/test/syscalls/linux/base_poll_test.cc +++ b/test/syscalls/linux/base_poll_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/base_poll_test.h b/test/syscalls/linux/base_poll_test.h index 9b9b81933..088831f9f 100644 --- a/test/syscalls/linux/base_poll_test.h +++ b/test/syscalls/linux/base_poll_test.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/bind.cc b/test/syscalls/linux/bind.cc index f5aa9c500..de8cca53b 100644 --- a/test/syscalls/linux/bind.cc +++ b/test/syscalls/linux/bind.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/brk.cc b/test/syscalls/linux/brk.cc index 33d353959..a03a44465 100644 --- a/test/syscalls/linux/brk.cc +++ b/test/syscalls/linux/brk.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chdir.cc b/test/syscalls/linux/chdir.cc index a4b54f0ee..3182c228b 100644 --- a/test/syscalls/linux/chdir.cc +++ b/test/syscalls/linux/chdir.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chmod.cc b/test/syscalls/linux/chmod.cc index 2f42fe326..79e98597f 100644 --- a/test/syscalls/linux/chmod.cc +++ b/test/syscalls/linux/chmod.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chown.cc b/test/syscalls/linux/chown.cc index ad892cf6a..eb1762ddf 100644 --- a/test/syscalls/linux/chown.cc +++ b/test/syscalls/linux/chown.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/chroot.cc b/test/syscalls/linux/chroot.cc index 6c200f63e..a4354ff62 100644 --- a/test/syscalls/linux/chroot.cc +++ b/test/syscalls/linux/chroot.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/clock_getres.cc b/test/syscalls/linux/clock_getres.cc index 8f8842299..c408b936c 100644 --- a/test/syscalls/linux/clock_getres.cc +++ b/test/syscalls/linux/clock_getres.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/clock_gettime.cc b/test/syscalls/linux/clock_gettime.cc index 4ecb5f5b1..082ae1c39 100644 --- a/test/syscalls/linux/clock_gettime.cc +++ b/test/syscalls/linux/clock_gettime.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/clock_nanosleep.cc b/test/syscalls/linux/clock_nanosleep.cc index 61c67a5ff..52a69d230 100644 --- a/test/syscalls/linux/clock_nanosleep.cc +++ b/test/syscalls/linux/clock_nanosleep.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/concurrency.cc b/test/syscalls/linux/concurrency.cc index 7978845c1..4e0a13f8b 100644 --- a/test/syscalls/linux/concurrency.cc +++ b/test/syscalls/linux/concurrency.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/creat.cc b/test/syscalls/linux/creat.cc index df2cc0d5c..3c270d6da 100644 --- a/test/syscalls/linux/creat.cc +++ b/test/syscalls/linux/creat.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/dev.cc b/test/syscalls/linux/dev.cc index a140d3b30..b86ebe233 100644 --- a/test/syscalls/linux/dev.cc +++ b/test/syscalls/linux/dev.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/dup.cc b/test/syscalls/linux/dup.cc index e8de2f4c4..4f773bc75 100644 --- a/test/syscalls/linux/dup.cc +++ b/test/syscalls/linux/dup.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/epoll.cc b/test/syscalls/linux/epoll.cc index b4a3bfcba..a4f8f3cec 100644 --- a/test/syscalls/linux/epoll.cc +++ b/test/syscalls/linux/epoll.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/eventfd.cc b/test/syscalls/linux/eventfd.cc index 8111da30e..5e5c39d44 100644 --- a/test/syscalls/linux/eventfd.cc +++ b/test/syscalls/linux/eventfd.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exceptions.cc b/test/syscalls/linux/exceptions.cc index 3f0aa8bf1..0da4c817d 100644 --- a/test/syscalls/linux/exceptions.cc +++ b/test/syscalls/linux/exceptions.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec.cc b/test/syscalls/linux/exec.cc index 30bc4b608..06c322a99 100644 --- a/test/syscalls/linux/exec.cc +++ b/test/syscalls/linux/exec.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec.h b/test/syscalls/linux/exec.h index b82bfffd1..5c0f7e654 100644 --- a/test/syscalls/linux/exec.h +++ b/test/syscalls/linux/exec.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_assert_closed_workload.cc b/test/syscalls/linux/exec_assert_closed_workload.cc index 4448431e1..95643618d 100644 --- a/test/syscalls/linux/exec_assert_closed_workload.cc +++ b/test/syscalls/linux/exec_assert_closed_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_basic_workload.cc b/test/syscalls/linux/exec_basic_workload.cc index d4bdf511f..1bbd6437e 100644 --- a/test/syscalls/linux/exec_basic_workload.cc +++ b/test/syscalls/linux/exec_basic_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_binary.cc b/test/syscalls/linux/exec_binary.cc index c10d85398..bdd6eb10b 100644 --- a/test/syscalls/linux/exec_binary.cc +++ b/test/syscalls/linux/exec_binary.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_proc_exe_workload.cc b/test/syscalls/linux/exec_proc_exe_workload.cc index b9a4ac749..b3fbd5042 100644 --- a/test/syscalls/linux/exec_proc_exe_workload.cc +++ b/test/syscalls/linux/exec_proc_exe_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exec_state_workload.cc b/test/syscalls/linux/exec_state_workload.cc index b66e22565..725c2977f 100644 --- a/test/syscalls/linux/exec_state_workload.cc +++ b/test/syscalls/linux/exec_state_workload.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exit.cc b/test/syscalls/linux/exit.cc index 7246a7b3b..99de2b376 100644 --- a/test/syscalls/linux/exit.cc +++ b/test/syscalls/linux/exit.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/exit_script.sh b/test/syscalls/linux/exit_script.sh index f014fcf99..527518e06 100755 --- a/test/syscalls/linux/exit_script.sh +++ b/test/syscalls/linux/exit_script.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/test/syscalls/linux/fadvise64.cc b/test/syscalls/linux/fadvise64.cc index 041e8b7b6..2af7aa6d9 100644 --- a/test/syscalls/linux/fadvise64.cc +++ b/test/syscalls/linux/fadvise64.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fallocate.cc b/test/syscalls/linux/fallocate.cc index e51538734..61b8acc7a 100644 --- a/test/syscalls/linux/fallocate.cc +++ b/test/syscalls/linux/fallocate.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fault.cc b/test/syscalls/linux/fault.cc index cfa7d0d1f..f6e19026f 100644 --- a/test/syscalls/linux/fault.cc +++ b/test/syscalls/linux/fault.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fchdir.cc b/test/syscalls/linux/fchdir.cc index 2b13e36c3..08bcae1e8 100644 --- a/test/syscalls/linux/fchdir.cc +++ b/test/syscalls/linux/fchdir.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fcntl.cc b/test/syscalls/linux/fcntl.cc index 32a90a163..2f8e7c9dd 100644 --- a/test/syscalls/linux/fcntl.cc +++ b/test/syscalls/linux/fcntl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/file_base.h b/test/syscalls/linux/file_base.h index 43f568111..b5b972c07 100644 --- a/test/syscalls/linux/file_base.h +++ b/test/syscalls/linux/file_base.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/flock.cc b/test/syscalls/linux/flock.cc index 1388d3839..d89cfcbd7 100644 --- a/test/syscalls/linux/flock.cc +++ b/test/syscalls/linux/flock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fork.cc b/test/syscalls/linux/fork.cc index 73ac885b5..dd6e1a422 100644 --- a/test/syscalls/linux/fork.cc +++ b/test/syscalls/linux/fork.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fpsig_fork.cc b/test/syscalls/linux/fpsig_fork.cc index e8f1dfa8a..e7e9f06a1 100644 --- a/test/syscalls/linux/fpsig_fork.cc +++ b/test/syscalls/linux/fpsig_fork.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fpsig_nested.cc b/test/syscalls/linux/fpsig_nested.cc index 2fa40b42d..395463aed 100644 --- a/test/syscalls/linux/fpsig_nested.cc +++ b/test/syscalls/linux/fpsig_nested.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/fsync.cc b/test/syscalls/linux/fsync.cc index b34229248..e7e057f06 100644 --- a/test/syscalls/linux/fsync.cc +++ b/test/syscalls/linux/fsync.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/futex.cc b/test/syscalls/linux/futex.cc index c7a709a0a..bfec95466 100644 --- a/test/syscalls/linux/futex.cc +++ b/test/syscalls/linux/futex.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getcpu.cc b/test/syscalls/linux/getcpu.cc index 3a52b25fa..f4d94bd6a 100644 --- a/test/syscalls/linux/getcpu.cc +++ b/test/syscalls/linux/getcpu.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getdents.cc b/test/syscalls/linux/getdents.cc index e8a7bcd43..d146c8db7 100644 --- a/test/syscalls/linux/getdents.cc +++ b/test/syscalls/linux/getdents.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getrandom.cc b/test/syscalls/linux/getrandom.cc index be5325497..f97f60029 100644 --- a/test/syscalls/linux/getrandom.cc +++ b/test/syscalls/linux/getrandom.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/getrusage.cc b/test/syscalls/linux/getrusage.cc index 1ae603858..9bdb1e4cd 100644 --- a/test/syscalls/linux/getrusage.cc +++ b/test/syscalls/linux/getrusage.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/inotify.cc b/test/syscalls/linux/inotify.cc index b99d339e5..6a3539e22 100644 --- a/test/syscalls/linux/inotify.cc +++ b/test/syscalls/linux/inotify.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ioctl.cc b/test/syscalls/linux/ioctl.cc index c7741a177..c525d41d2 100644 --- a/test/syscalls/linux/ioctl.cc +++ b/test/syscalls/linux/ioctl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc index 0a149c2e5..7612919d4 100644 --- a/test/syscalls/linux/ip_socket_test_util.cc +++ b/test/syscalls/linux/ip_socket_test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ip_socket_test_util.h b/test/syscalls/linux/ip_socket_test_util.h index cac790e64..6898effb8 100644 --- a/test/syscalls/linux/ip_socket_test_util.h +++ b/test/syscalls/linux/ip_socket_test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/itimer.cc b/test/syscalls/linux/itimer.cc index ddfbc28fc..57ffd1595 100644 --- a/test/syscalls/linux/itimer.cc +++ b/test/syscalls/linux/itimer.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/kill.cc b/test/syscalls/linux/kill.cc index cd98de41f..18ad923b8 100644 --- a/test/syscalls/linux/kill.cc +++ b/test/syscalls/linux/kill.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/link.cc b/test/syscalls/linux/link.cc index ed74437bc..a91703070 100644 --- a/test/syscalls/linux/link.cc +++ b/test/syscalls/linux/link.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/lseek.cc b/test/syscalls/linux/lseek.cc index 6a4f1423c..a8af8e545 100644 --- a/test/syscalls/linux/lseek.cc +++ b/test/syscalls/linux/lseek.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/madvise.cc b/test/syscalls/linux/madvise.cc index a79c8c75d..f6ad4d18b 100644 --- a/test/syscalls/linux/madvise.cc +++ b/test/syscalls/linux/madvise.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/memfd.cc b/test/syscalls/linux/memfd.cc index c2513682d..7e103124b 100644 --- a/test/syscalls/linux/memfd.cc +++ b/test/syscalls/linux/memfd.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/memory_accounting.cc b/test/syscalls/linux/memory_accounting.cc index b4b680c34..a6e20f9c3 100644 --- a/test/syscalls/linux/memory_accounting.cc +++ b/test/syscalls/linux/memory_accounting.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mempolicy.cc b/test/syscalls/linux/mempolicy.cc index 9f8033bdf..4ac4cb88f 100644 --- a/test/syscalls/linux/mempolicy.cc +++ b/test/syscalls/linux/mempolicy.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mincore.cc b/test/syscalls/linux/mincore.cc index c572bf5ec..5c1240c89 100644 --- a/test/syscalls/linux/mincore.cc +++ b/test/syscalls/linux/mincore.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mkdir.cc b/test/syscalls/linux/mkdir.cc index 50807b68f..cf138d328 100644 --- a/test/syscalls/linux/mkdir.cc +++ b/test/syscalls/linux/mkdir.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mknod.cc b/test/syscalls/linux/mknod.cc index 361ca299b..b1675b9c7 100644 --- a/test/syscalls/linux/mknod.cc +++ b/test/syscalls/linux/mknod.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mlock.cc b/test/syscalls/linux/mlock.cc index a492b2404..aee4f7d1a 100644 --- a/test/syscalls/linux/mlock.cc +++ b/test/syscalls/linux/mlock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mmap.cc b/test/syscalls/linux/mmap.cc index a4fb9d1e0..5b5b4c2e8 100644 --- a/test/syscalls/linux/mmap.cc +++ b/test/syscalls/linux/mmap.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mount.cc b/test/syscalls/linux/mount.cc index 201b83e87..3a17672aa 100644 --- a/test/syscalls/linux/mount.cc +++ b/test/syscalls/linux/mount.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/mremap.cc b/test/syscalls/linux/mremap.cc index 01116c1ab..7298d4ca8 100644 --- a/test/syscalls/linux/mremap.cc +++ b/test/syscalls/linux/mremap.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/msync.cc b/test/syscalls/linux/msync.cc index 5afbfce72..ac7146017 100644 --- a/test/syscalls/linux/msync.cc +++ b/test/syscalls/linux/msync.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/munmap.cc b/test/syscalls/linux/munmap.cc index e20039950..067241f4d 100644 --- a/test/syscalls/linux/munmap.cc +++ b/test/syscalls/linux/munmap.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/open.cc b/test/syscalls/linux/open.cc index 22e4666c2..42646bb02 100644 --- a/test/syscalls/linux/open.cc +++ b/test/syscalls/linux/open.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/open_create.cc b/test/syscalls/linux/open_create.cc index b2cbd63d1..e5a85ef9d 100644 --- a/test/syscalls/linux/open_create.cc +++ b/test/syscalls/linux/open_create.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/partial_bad_buffer.cc b/test/syscalls/linux/partial_bad_buffer.cc index 71288ebc4..83b1ad4e4 100644 --- a/test/syscalls/linux/partial_bad_buffer.cc +++ b/test/syscalls/linux/partial_bad_buffer.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pause.cc b/test/syscalls/linux/pause.cc index 4e1148c24..8c05efd6f 100644 --- a/test/syscalls/linux/pause.cc +++ b/test/syscalls/linux/pause.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pipe.cc b/test/syscalls/linux/pipe.cc index abd10b11b..8698295b3 100644 --- a/test/syscalls/linux/pipe.cc +++ b/test/syscalls/linux/pipe.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/poll.cc b/test/syscalls/linux/poll.cc index cd2161bb1..9e5aa7fd0 100644 --- a/test/syscalls/linux/poll.cc +++ b/test/syscalls/linux/poll.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ppoll.cc b/test/syscalls/linux/ppoll.cc index f8c388c00..8245a11e8 100644 --- a/test/syscalls/linux/ppoll.cc +++ b/test/syscalls/linux/ppoll.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/prctl.cc b/test/syscalls/linux/prctl.cc index 854dec714..bce42dc74 100644 --- a/test/syscalls/linux/prctl.cc +++ b/test/syscalls/linux/prctl.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/prctl_setuid.cc b/test/syscalls/linux/prctl_setuid.cc index c1b561464..00dd6523e 100644 --- a/test/syscalls/linux/prctl_setuid.cc +++ b/test/syscalls/linux/prctl_setuid.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pread64.cc b/test/syscalls/linux/pread64.cc index 4e5bcfcde..5e3eb1735 100644 --- a/test/syscalls/linux/pread64.cc +++ b/test/syscalls/linux/pread64.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/preadv.cc b/test/syscalls/linux/preadv.cc index 4a31123d8..eebd129f2 100644 --- a/test/syscalls/linux/preadv.cc +++ b/test/syscalls/linux/preadv.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/preadv2.cc b/test/syscalls/linux/preadv2.cc index 58a4f9224..aac960130 100644 --- a/test/syscalls/linux/preadv2.cc +++ b/test/syscalls/linux/preadv2.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/priority.cc b/test/syscalls/linux/priority.cc index 3906c7132..1d9bdfa70 100644 --- a/test/syscalls/linux/priority.cc +++ b/test/syscalls/linux/priority.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/priority_execve.cc b/test/syscalls/linux/priority_execve.cc index 5604bd3d0..5cb343bad 100644 --- a/test/syscalls/linux/priority_execve.cc +++ b/test/syscalls/linux/priority_execve.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index 7ba274226..654f26242 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/proc_net.cc b/test/syscalls/linux/proc_net.cc index 6060d0644..03d0665eb 100644 --- a/test/syscalls/linux/proc_net.cc +++ b/test/syscalls/linux/proc_net.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/proc_net_unix.cc b/test/syscalls/linux/proc_net_unix.cc index ea7c93012..6d745f728 100644 --- a/test/syscalls/linux/proc_net_unix.cc +++ b/test/syscalls/linux/proc_net_unix.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/proc_pid_smaps.cc b/test/syscalls/linux/proc_pid_smaps.cc index cf5c462f3..7f2e8f203 100644 --- a/test/syscalls/linux/proc_pid_smaps.cc +++ b/test/syscalls/linux/proc_pid_smaps.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/proc_pid_uid_gid_map.cc b/test/syscalls/linux/proc_pid_uid_gid_map.cc index 96c58c564..df70b7eb9 100644 --- a/test/syscalls/linux/proc_pid_uid_gid_map.cc +++ b/test/syscalls/linux/proc_pid_uid_gid_map.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/pselect.cc b/test/syscalls/linux/pselect.cc index 3294f6c14..4e43c4d7f 100644 --- a/test/syscalls/linux/pselect.cc +++ b/test/syscalls/linux/pselect.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/ptrace.cc b/test/syscalls/linux/ptrace.cc index e0c56f1fc..4c212836c 100644 --- a/test/syscalls/linux/ptrace.cc +++ b/test/syscalls/linux/ptrace.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pty.cc b/test/syscalls/linux/pty.cc index 5b2dc9ccb..0485d187c 100644 --- a/test/syscalls/linux/pty.cc +++ b/test/syscalls/linux/pty.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pwrite64.cc b/test/syscalls/linux/pwrite64.cc index 485b1e48d..e1603fc2d 100644 --- a/test/syscalls/linux/pwrite64.cc +++ b/test/syscalls/linux/pwrite64.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/pwritev2.cc b/test/syscalls/linux/pwritev2.cc index a6949f08e..db519f4e0 100644 --- a/test/syscalls/linux/pwritev2.cc +++ b/test/syscalls/linux/pwritev2.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/raw_socket_ipv4.cc b/test/syscalls/linux/raw_socket_ipv4.cc index 8b8d032cb..e20b5cb50 100644 --- a/test/syscalls/linux/raw_socket_ipv4.cc +++ b/test/syscalls/linux/raw_socket_ipv4.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/read.cc b/test/syscalls/linux/read.cc index eb1b5bc10..4430fa3c2 100644 --- a/test/syscalls/linux/read.cc +++ b/test/syscalls/linux/read.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv.cc b/test/syscalls/linux/readv.cc index 0b933673a..f327ec3a9 100644 --- a/test/syscalls/linux/readv.cc +++ b/test/syscalls/linux/readv.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv_common.cc b/test/syscalls/linux/readv_common.cc index 349b80d7f..35d2dd9e3 100644 --- a/test/syscalls/linux/readv_common.cc +++ b/test/syscalls/linux/readv_common.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv_common.h b/test/syscalls/linux/readv_common.h index e261d545a..b16179fca 100644 --- a/test/syscalls/linux/readv_common.h +++ b/test/syscalls/linux/readv_common.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/readv_socket.cc b/test/syscalls/linux/readv_socket.cc index cf22c395e..3c315cc02 100644 --- a/test/syscalls/linux/readv_socket.cc +++ b/test/syscalls/linux/readv_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/rename.cc b/test/syscalls/linux/rename.cc index c0cbc7cd9..c9d76c2e2 100644 --- a/test/syscalls/linux/rename.cc +++ b/test/syscalls/linux/rename.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/rlimits.cc b/test/syscalls/linux/rlimits.cc index 7b255d0f6..860f0f688 100644 --- a/test/syscalls/linux/rlimits.cc +++ b/test/syscalls/linux/rlimits.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/rtsignal.cc b/test/syscalls/linux/rtsignal.cc index ff948f9d5..81d193ffd 100644 --- a/test/syscalls/linux/rtsignal.cc +++ b/test/syscalls/linux/rtsignal.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sched.cc b/test/syscalls/linux/sched.cc index 60cb6c443..735e99411 100644 --- a/test/syscalls/linux/sched.cc +++ b/test/syscalls/linux/sched.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sched_yield.cc b/test/syscalls/linux/sched_yield.cc index fc45aa5c2..5d24f5b58 100644 --- a/test/syscalls/linux/sched_yield.cc +++ b/test/syscalls/linux/sched_yield.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/seccomp.cc b/test/syscalls/linux/seccomp.cc index 27740d7ef..e77586852 100644 --- a/test/syscalls/linux/seccomp.cc +++ b/test/syscalls/linux/seccomp.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/select.cc b/test/syscalls/linux/select.cc index 41e6043cc..88c010aec 100644 --- a/test/syscalls/linux/select.cc +++ b/test/syscalls/linux/select.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/semaphore.cc b/test/syscalls/linux/semaphore.cc index 1c47b6851..421318fcb 100644 --- a/test/syscalls/linux/semaphore.cc +++ b/test/syscalls/linux/semaphore.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sendfile.cc b/test/syscalls/linux/sendfile.cc index 15fd01ff0..2fbb3f4ef 100644 --- a/test/syscalls/linux/sendfile.cc +++ b/test/syscalls/linux/sendfile.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sendfile_socket.cc b/test/syscalls/linux/sendfile_socket.cc index e2ccf17ce..66adda515 100644 --- a/test/syscalls/linux/sendfile_socket.cc +++ b/test/syscalls/linux/sendfile_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/shm.cc b/test/syscalls/linux/shm.cc index 2c0f9b04a..eb7a3966f 100644 --- a/test/syscalls/linux/shm.cc +++ b/test/syscalls/linux/shm.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigaction.cc b/test/syscalls/linux/sigaction.cc index cdd2dbf31..9a53fd3e0 100644 --- a/test/syscalls/linux/sigaction.cc +++ b/test/syscalls/linux/sigaction.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigaltstack.cc b/test/syscalls/linux/sigaltstack.cc index 5741720f4..7d4a12c1d 100644 --- a/test/syscalls/linux/sigaltstack.cc +++ b/test/syscalls/linux/sigaltstack.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigaltstack_check.cc b/test/syscalls/linux/sigaltstack_check.cc index b71f812a8..5ac1b661d 100644 --- a/test/syscalls/linux/sigaltstack_check.cc +++ b/test/syscalls/linux/sigaltstack_check.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigiret.cc b/test/syscalls/linux/sigiret.cc index 1b7cecccb..a47c781ea 100644 --- a/test/syscalls/linux/sigiret.cc +++ b/test/syscalls/linux/sigiret.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigprocmask.cc b/test/syscalls/linux/sigprocmask.cc index 1aea1ecb8..654c6a47f 100644 --- a/test/syscalls/linux/sigprocmask.cc +++ b/test/syscalls/linux/sigprocmask.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigstop.cc b/test/syscalls/linux/sigstop.cc index e21d23d51..9c7210e17 100644 --- a/test/syscalls/linux/sigstop.cc +++ b/test/syscalls/linux/sigstop.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sigtimedwait.cc b/test/syscalls/linux/sigtimedwait.cc index 1df9c013f..1e5bf5942 100644 --- a/test/syscalls/linux/sigtimedwait.cc +++ b/test/syscalls/linux/sigtimedwait.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_abstract.cc b/test/syscalls/linux/socket_abstract.cc index 639cd4e59..2faf678f7 100644 --- a/test/syscalls/linux/socket_abstract.cc +++ b/test/syscalls/linux/socket_abstract.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_blocking.cc b/test/syscalls/linux/socket_blocking.cc index c1bca467f..00c50d1bf 100644 --- a/test/syscalls/linux/socket_blocking.cc +++ b/test/syscalls/linux/socket_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_blocking.h b/test/syscalls/linux/socket_blocking.h index 5cddee54b..db26e5ef5 100644 --- a/test/syscalls/linux/socket_blocking.h +++ b/test/syscalls/linux/socket_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_filesystem.cc b/test/syscalls/linux/socket_filesystem.cc index 2653be158..f7cb72df4 100644 --- a/test/syscalls/linux/socket_filesystem.cc +++ b/test/syscalls/linux/socket_filesystem.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_generic.cc b/test/syscalls/linux/socket_generic.cc index d04d5abe0..f99f3fe62 100644 --- a/test/syscalls/linux/socket_generic.cc +++ b/test/syscalls/linux/socket_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_generic.h b/test/syscalls/linux/socket_generic.h index cd826abcf..00ae7bfc3 100644 --- a/test/syscalls/linux/socket_generic.h +++ b/test/syscalls/linux/socket_generic.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index 14d7827c2..f86a0f30c 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_loopback_blocking.cc b/test/syscalls/linux/socket_ip_loopback_blocking.cc index 9cec7a71d..d7fc20aad 100644 --- a/test/syscalls/linux/socket_ip_loopback_blocking.cc +++ b/test/syscalls/linux/socket_ip_loopback_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_generic.cc b/test/syscalls/linux/socket_ip_tcp_generic.cc index 54f00cd9b..5b198f49d 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic.cc +++ b/test/syscalls/linux/socket_ip_tcp_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_generic.h b/test/syscalls/linux/socket_ip_tcp_generic.h index f38500d14..a3eff3c73 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic.h +++ b/test/syscalls/linux/socket_ip_tcp_generic.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc b/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc index 1963d5deb..2c6ae17bf 100644 --- a/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc +++ b/test/syscalls/linux/socket_ip_tcp_generic_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_loopback.cc b/test/syscalls/linux/socket_ip_tcp_loopback.cc index 7e36c35d2..831de53b8 100644 --- a/test/syscalls/linux/socket_ip_tcp_loopback.cc +++ b/test/syscalls/linux/socket_ip_tcp_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc b/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc index 9e2a18d3e..d1ea8ef12 100644 --- a/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc +++ b/test/syscalls/linux/socket_ip_tcp_loopback_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc b/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc index 54053360f..96c1b3b3d 100644 --- a/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc +++ b/test/syscalls/linux/socket_ip_tcp_loopback_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_tcp_udp_generic.cc b/test/syscalls/linux/socket_ip_tcp_udp_generic.cc index 5bf1de7c6..251817a9f 100644 --- a/test/syscalls/linux/socket_ip_tcp_udp_generic.cc +++ b/test/syscalls/linux/socket_ip_tcp_udp_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_generic.cc b/test/syscalls/linux/socket_ip_udp_generic.cc index ac15154f2..044394ba7 100644 --- a/test/syscalls/linux/socket_ip_udp_generic.cc +++ b/test/syscalls/linux/socket_ip_udp_generic.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_generic.h b/test/syscalls/linux/socket_ip_udp_generic.h index 8b8fc7c6e..106c54e9f 100644 --- a/test/syscalls/linux/socket_ip_udp_generic.h +++ b/test/syscalls/linux/socket_ip_udp_generic.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_loopback.cc b/test/syscalls/linux/socket_ip_udp_loopback.cc index 0e4463649..fc124e9ef 100644 --- a/test/syscalls/linux/socket_ip_udp_loopback.cc +++ b/test/syscalls/linux/socket_ip_udp_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc b/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc index 0c3b669bf..1c3d1c0ad 100644 --- a/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc +++ b/test/syscalls/linux/socket_ip_udp_loopback_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc b/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc index 7bf8597fe..7554b08d5 100644 --- a/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc +++ b/test/syscalls/linux/socket_ip_udp_loopback_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc index 8e1c13ff4..3a068aacf 100644 --- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h index b23de08d1..fb582b224 100644 --- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc index 773d84b13..040bb176e 100644 --- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc +++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc index c99958ed5..709172580 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.h b/test/syscalls/linux/socket_ipv4_udp_unbound.h index a780c0144..8e07bfbbf 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound.h +++ b/test/syscalls/linux/socket_ipv4_udp_unbound.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc index 9dd9e1bd6..53dcd58cd 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h index 5cf9fa8eb..45e1d37ea 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc index 535a5fa10..ffbb8e6eb 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc index d6a8e428c..cb0105471 100644 --- a/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc +++ b/test/syscalls/linux/socket_ipv4_udp_unbound_loopback.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netdevice.cc b/test/syscalls/linux/socket_netdevice.cc index b4e9fe51b..6a5fa8965 100644 --- a/test/syscalls/linux/socket_netdevice.cc +++ b/test/syscalls/linux/socket_netdevice.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc index ed4ae1c71..c8693225f 100644 --- a/test/syscalls/linux/socket_netlink_route.cc +++ b/test/syscalls/linux/socket_netlink_route.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netlink_util.cc b/test/syscalls/linux/socket_netlink_util.cc index edf549544..728d25434 100644 --- a/test/syscalls/linux/socket_netlink_util.cc +++ b/test/syscalls/linux/socket_netlink_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_netlink_util.h b/test/syscalls/linux/socket_netlink_util.h index 44b1f148c..bea449107 100644 --- a/test/syscalls/linux/socket_netlink_util.h +++ b/test/syscalls/linux/socket_netlink_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_blocking.cc b/test/syscalls/linux/socket_non_blocking.cc index 1bcc6fb7f..73e6dc618 100644 --- a/test/syscalls/linux/socket_non_blocking.cc +++ b/test/syscalls/linux/socket_non_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_blocking.h b/test/syscalls/linux/socket_non_blocking.h index 287e096bb..bd3e02fd2 100644 --- a/test/syscalls/linux/socket_non_blocking.h +++ b/test/syscalls/linux/socket_non_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream.cc b/test/syscalls/linux/socket_non_stream.cc index d170008a4..3c599b6e8 100644 --- a/test/syscalls/linux/socket_non_stream.cc +++ b/test/syscalls/linux/socket_non_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream.h b/test/syscalls/linux/socket_non_stream.h index 02dd2a958..469fbe6a2 100644 --- a/test/syscalls/linux/socket_non_stream.h +++ b/test/syscalls/linux/socket_non_stream.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream_blocking.cc b/test/syscalls/linux/socket_non_stream_blocking.cc index 9e92628c3..76127d181 100644 --- a/test/syscalls/linux/socket_non_stream_blocking.cc +++ b/test/syscalls/linux/socket_non_stream_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_non_stream_blocking.h b/test/syscalls/linux/socket_non_stream_blocking.h index bde355452..6e205a039 100644 --- a/test/syscalls/linux/socket_non_stream_blocking.h +++ b/test/syscalls/linux/socket_non_stream_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream.cc b/test/syscalls/linux/socket_stream.cc index c8a8ad0f6..0417dd347 100644 --- a/test/syscalls/linux/socket_stream.cc +++ b/test/syscalls/linux/socket_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream.h b/test/syscalls/linux/socket_stream.h index 35e591e17..b837b8f8c 100644 --- a/test/syscalls/linux/socket_stream.h +++ b/test/syscalls/linux/socket_stream.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_blocking.cc b/test/syscalls/linux/socket_stream_blocking.cc index f0f86c01c..8367460d2 100644 --- a/test/syscalls/linux/socket_stream_blocking.cc +++ b/test/syscalls/linux/socket_stream_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_blocking.h b/test/syscalls/linux/socket_stream_blocking.h index 06113ad03..9fd19ff90 100644 --- a/test/syscalls/linux/socket_stream_blocking.h +++ b/test/syscalls/linux/socket_stream_blocking.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_nonblock.cc b/test/syscalls/linux/socket_stream_nonblock.cc index a3202ffe4..b00748b97 100644 --- a/test/syscalls/linux/socket_stream_nonblock.cc +++ b/test/syscalls/linux/socket_stream_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_stream_nonblock.h b/test/syscalls/linux/socket_stream_nonblock.h index 491f53848..c3b7fad91 100644 --- a/test/syscalls/linux/socket_stream_nonblock.h +++ b/test/syscalls/linux/socket_stream_nonblock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc index 0be23e541..da69de37c 100644 --- a/test/syscalls/linux/socket_test_util.cc +++ b/test/syscalls/linux/socket_test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h index dfabdf179..058313986 100644 --- a/test/syscalls/linux/socket_test_util.h +++ b/test/syscalls/linux/socket_test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix.cc b/test/syscalls/linux/socket_unix.cc index fafb23ad1..bb3397fa2 100644 --- a/test/syscalls/linux/socket_unix.cc +++ b/test/syscalls/linux/socket_unix.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix.h b/test/syscalls/linux/socket_unix.h index d2a16afb2..3625cc404 100644 --- a/test/syscalls/linux/socket_unix.h +++ b/test/syscalls/linux/socket_unix.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_abstract.cc b/test/syscalls/linux/socket_unix_abstract.cc index c4a3c889c..8241bf997 100644 --- a/test/syscalls/linux/socket_unix_abstract.cc +++ b/test/syscalls/linux/socket_unix_abstract.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_abstract_nonblock.cc b/test/syscalls/linux/socket_unix_abstract_nonblock.cc index a69ee027e..9de0f6dfe 100644 --- a/test/syscalls/linux/socket_unix_abstract_nonblock.cc +++ b/test/syscalls/linux/socket_unix_abstract_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_blocking_local.cc b/test/syscalls/linux/socket_unix_blocking_local.cc index 57af118c5..320915b0f 100644 --- a/test/syscalls/linux/socket_unix_blocking_local.cc +++ b/test/syscalls/linux/socket_unix_blocking_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram.cc b/test/syscalls/linux/socket_unix_dgram.cc index 5dd5e6d77..3e0f611d2 100644 --- a/test/syscalls/linux/socket_unix_dgram.cc +++ b/test/syscalls/linux/socket_unix_dgram.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram.h b/test/syscalls/linux/socket_unix_dgram.h index 722a3d8e6..0764ef85b 100644 --- a/test/syscalls/linux/socket_unix_dgram.h +++ b/test/syscalls/linux/socket_unix_dgram.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram_local.cc b/test/syscalls/linux/socket_unix_dgram_local.cc index da8f59704..4ba2c80ae 100644 --- a/test/syscalls/linux/socket_unix_dgram_local.cc +++ b/test/syscalls/linux/socket_unix_dgram_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_dgram_non_blocking.cc b/test/syscalls/linux/socket_unix_dgram_non_blocking.cc index 3becb513d..9fe86cee8 100644 --- a/test/syscalls/linux/socket_unix_dgram_non_blocking.cc +++ b/test/syscalls/linux/socket_unix_dgram_non_blocking.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_domain.cc b/test/syscalls/linux/socket_unix_domain.cc index f081c601f..fa3efc7f8 100644 --- a/test/syscalls/linux/socket_unix_domain.cc +++ b/test/syscalls/linux/socket_unix_domain.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_filesystem.cc b/test/syscalls/linux/socket_unix_filesystem.cc index 6a67da75f..5dbe67773 100644 --- a/test/syscalls/linux/socket_unix_filesystem.cc +++ b/test/syscalls/linux/socket_unix_filesystem.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_filesystem_nonblock.cc b/test/syscalls/linux/socket_unix_filesystem_nonblock.cc index c13a1e564..137db53c4 100644 --- a/test/syscalls/linux/socket_unix_filesystem_nonblock.cc +++ b/test/syscalls/linux/socket_unix_filesystem_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_non_stream.cc b/test/syscalls/linux/socket_unix_non_stream.cc index a565978f9..dafe82494 100644 --- a/test/syscalls/linux/socket_unix_non_stream.cc +++ b/test/syscalls/linux/socket_unix_non_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_non_stream.h b/test/syscalls/linux/socket_unix_non_stream.h index e4214d949..7478ab172 100644 --- a/test/syscalls/linux/socket_unix_non_stream.h +++ b/test/syscalls/linux/socket_unix_non_stream.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc b/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc index 6c435669b..98cf1fe8a 100644 --- a/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc +++ b/test/syscalls/linux/socket_unix_non_stream_blocking_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_pair.cc b/test/syscalls/linux/socket_unix_pair.cc index c575fdcb2..bacfc11e4 100644 --- a/test/syscalls/linux/socket_unix_pair.cc +++ b/test/syscalls/linux/socket_unix_pair.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_pair_nonblock.cc b/test/syscalls/linux/socket_unix_pair_nonblock.cc index 1ae7f9b5e..583506f08 100644 --- a/test/syscalls/linux/socket_unix_pair_nonblock.cc +++ b/test/syscalls/linux/socket_unix_pair_nonblock.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_seqpacket.cc b/test/syscalls/linux/socket_unix_seqpacket.cc index ad0af77e9..6f6367dd5 100644 --- a/test/syscalls/linux/socket_unix_seqpacket.cc +++ b/test/syscalls/linux/socket_unix_seqpacket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_seqpacket.h b/test/syscalls/linux/socket_unix_seqpacket.h index da8eb2b2b..30d9b9edf 100644 --- a/test/syscalls/linux/socket_unix_seqpacket.h +++ b/test/syscalls/linux/socket_unix_seqpacket.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_seqpacket_local.cc b/test/syscalls/linux/socket_unix_seqpacket_local.cc index e6484d9b4..b903a9e8f 100644 --- a/test/syscalls/linux/socket_unix_seqpacket_local.cc +++ b/test/syscalls/linux/socket_unix_seqpacket_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream.cc b/test/syscalls/linux/socket_unix_stream.cc index 95f454251..659c93945 100644 --- a/test/syscalls/linux/socket_unix_stream.cc +++ b/test/syscalls/linux/socket_unix_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream_blocking_local.cc b/test/syscalls/linux/socket_unix_stream_blocking_local.cc index ec0fc6955..ce0f1e50d 100644 --- a/test/syscalls/linux/socket_unix_stream_blocking_local.cc +++ b/test/syscalls/linux/socket_unix_stream_blocking_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream_local.cc b/test/syscalls/linux/socket_unix_stream_local.cc index bf4c5f2eb..6b840189c 100644 --- a/test/syscalls/linux/socket_unix_stream_local.cc +++ b/test/syscalls/linux/socket_unix_stream_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_stream_nonblock_local.cc b/test/syscalls/linux/socket_unix_stream_nonblock_local.cc index df80b105a..ebec4e0ec 100644 --- a/test/syscalls/linux/socket_unix_stream_nonblock_local.cc +++ b/test/syscalls/linux/socket_unix_stream_nonblock_local.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_abstract.cc b/test/syscalls/linux/socket_unix_unbound_abstract.cc index b6fe7a9ce..4b5832de8 100644 --- a/test/syscalls/linux/socket_unix_unbound_abstract.cc +++ b/test/syscalls/linux/socket_unix_unbound_abstract.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_dgram.cc b/test/syscalls/linux/socket_unix_unbound_dgram.cc index 1ec11a08d..2ddc5c11f 100644 --- a/test/syscalls/linux/socket_unix_unbound_dgram.cc +++ b/test/syscalls/linux/socket_unix_unbound_dgram.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_filesystem.cc b/test/syscalls/linux/socket_unix_unbound_filesystem.cc index d09142aa6..8cb03c450 100644 --- a/test/syscalls/linux/socket_unix_unbound_filesystem.cc +++ b/test/syscalls/linux/socket_unix_unbound_filesystem.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_seqpacket.cc b/test/syscalls/linux/socket_unix_unbound_seqpacket.cc index 21209b244..0575f2e1d 100644 --- a/test/syscalls/linux/socket_unix_unbound_seqpacket.cc +++ b/test/syscalls/linux/socket_unix_unbound_seqpacket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/socket_unix_unbound_stream.cc b/test/syscalls/linux/socket_unix_unbound_stream.cc index b95f9569e..091d546b3 100644 --- a/test/syscalls/linux/socket_unix_unbound_stream.cc +++ b/test/syscalls/linux/socket_unix_unbound_stream.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/stat.cc b/test/syscalls/linux/stat.cc index 746318d09..80ba67496 100644 --- a/test/syscalls/linux/stat.cc +++ b/test/syscalls/linux/stat.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/stat_times.cc b/test/syscalls/linux/stat_times.cc index 8346e9a8e..9b53739a0 100644 --- a/test/syscalls/linux/stat_times.cc +++ b/test/syscalls/linux/stat_times.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/statfs.cc b/test/syscalls/linux/statfs.cc index e1e7fc707..aca51d30f 100644 --- a/test/syscalls/linux/statfs.cc +++ b/test/syscalls/linux/statfs.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sticky.cc b/test/syscalls/linux/sticky.cc index 58cf0d014..59fb5dfe6 100644 --- a/test/syscalls/linux/sticky.cc +++ b/test/syscalls/linux/sticky.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/symlink.cc b/test/syscalls/linux/symlink.cc index 318917f4b..494072a9b 100644 --- a/test/syscalls/linux/symlink.cc +++ b/test/syscalls/linux/symlink.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sync.cc b/test/syscalls/linux/sync.cc index 5b777b6eb..fe479390d 100644 --- a/test/syscalls/linux/sync.cc +++ b/test/syscalls/linux/sync.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sync_file_range.cc b/test/syscalls/linux/sync_file_range.cc index d11f58481..36cc42043 100644 --- a/test/syscalls/linux/sync_file_range.cc +++ b/test/syscalls/linux/sync_file_range.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sysinfo.cc b/test/syscalls/linux/sysinfo.cc index a0dd82640..1a71256da 100644 --- a/test/syscalls/linux/sysinfo.cc +++ b/test/syscalls/linux/sysinfo.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/syslog.cc b/test/syscalls/linux/syslog.cc index 5bd0d1cc3..9a7407d96 100644 --- a/test/syscalls/linux/syslog.cc +++ b/test/syscalls/linux/syslog.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/sysret.cc b/test/syscalls/linux/sysret.cc index 8e10220eb..819fa655a 100644 --- a/test/syscalls/linux/sysret.cc +++ b/test/syscalls/linux/sysret.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/tcp_socket.cc b/test/syscalls/linux/tcp_socket.cc index 33620a874..e3f9f9f9d 100644 --- a/test/syscalls/linux/tcp_socket.cc +++ b/test/syscalls/linux/tcp_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/temp_umask.h b/test/syscalls/linux/temp_umask.h index f202dfa59..81a25440c 100644 --- a/test/syscalls/linux/temp_umask.h +++ b/test/syscalls/linux/temp_umask.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/tgkill.cc b/test/syscalls/linux/tgkill.cc index 2d258ef11..80acae5de 100644 --- a/test/syscalls/linux/tgkill.cc +++ b/test/syscalls/linux/tgkill.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/time.cc b/test/syscalls/linux/time.cc index 5a3dfd026..c7eead17e 100644 --- a/test/syscalls/linux/time.cc +++ b/test/syscalls/linux/time.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/timerfd.cc b/test/syscalls/linux/timerfd.cc index b85321795..9df53612f 100644 --- a/test/syscalls/linux/timerfd.cc +++ b/test/syscalls/linux/timerfd.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/timers.cc b/test/syscalls/linux/timers.cc index 14506eb12..fd42e81e1 100644 --- a/test/syscalls/linux/timers.cc +++ b/test/syscalls/linux/timers.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/tkill.cc b/test/syscalls/linux/tkill.cc index 3e8ce5327..bae377c69 100644 --- a/test/syscalls/linux/tkill.cc +++ b/test/syscalls/linux/tkill.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/truncate.cc b/test/syscalls/linux/truncate.cc index 2616a9147..e5cc5d97c 100644 --- a/test/syscalls/linux/truncate.cc +++ b/test/syscalls/linux/truncate.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/udp_bind.cc b/test/syscalls/linux/udp_bind.cc index 547eb2a6c..6d92bdbeb 100644 --- a/test/syscalls/linux/udp_bind.cc +++ b/test/syscalls/linux/udp_bind.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/udp_socket.cc b/test/syscalls/linux/udp_socket.cc index f39281d5c..31db8a2ad 100644 --- a/test/syscalls/linux/udp_socket.cc +++ b/test/syscalls/linux/udp_socket.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/uidgid.cc b/test/syscalls/linux/uidgid.cc index d78a09b1e..bf1ca8679 100644 --- a/test/syscalls/linux/uidgid.cc +++ b/test/syscalls/linux/uidgid.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/uname.cc b/test/syscalls/linux/uname.cc index d22a34bd7..0a5d91017 100644 --- a/test/syscalls/linux/uname.cc +++ b/test/syscalls/linux/uname.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unix_domain_socket_test_util.cc b/test/syscalls/linux/unix_domain_socket_test_util.cc index 2d7a530b9..6f49e3660 100644 --- a/test/syscalls/linux/unix_domain_socket_test_util.cc +++ b/test/syscalls/linux/unix_domain_socket_test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unix_domain_socket_test_util.h b/test/syscalls/linux/unix_domain_socket_test_util.h index 1b09aeae7..aae990245 100644 --- a/test/syscalls/linux/unix_domain_socket_test_util.h +++ b/test/syscalls/linux/unix_domain_socket_test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unlink.cc b/test/syscalls/linux/unlink.cc index b10aae025..b6f65e027 100644 --- a/test/syscalls/linux/unlink.cc +++ b/test/syscalls/linux/unlink.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/unshare.cc b/test/syscalls/linux/unshare.cc index 9dd6ec4b6..e32619efe 100644 --- a/test/syscalls/linux/unshare.cc +++ b/test/syscalls/linux/unshare.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/utimes.cc b/test/syscalls/linux/utimes.cc index bf776cd93..80716859a 100644 --- a/test/syscalls/linux/utimes.cc +++ b/test/syscalls/linux/utimes.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vdso.cc b/test/syscalls/linux/vdso.cc index 0f6e1c7c6..19c80add8 100644 --- a/test/syscalls/linux/vdso.cc +++ b/test/syscalls/linux/vdso.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vdso_clock_gettime.cc b/test/syscalls/linux/vdso_clock_gettime.cc index 0e936594b..759a50569 100644 --- a/test/syscalls/linux/vdso_clock_gettime.cc +++ b/test/syscalls/linux/vdso_clock_gettime.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vfork.cc b/test/syscalls/linux/vfork.cc index 9999a909e..631a53654 100644 --- a/test/syscalls/linux/vfork.cc +++ b/test/syscalls/linux/vfork.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/vsyscall.cc b/test/syscalls/linux/vsyscall.cc index cb6840cc6..2c2303358 100644 --- a/test/syscalls/linux/vsyscall.cc +++ b/test/syscalls/linux/vsyscall.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/wait.cc b/test/syscalls/linux/wait.cc index fcd606bec..50d0725a7 100644 --- a/test/syscalls/linux/wait.cc +++ b/test/syscalls/linux/wait.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/linux/write.cc b/test/syscalls/linux/write.cc index 7f80b2fa8..9b219cfd6 100644 --- a/test/syscalls/linux/write.cc +++ b/test/syscalls/linux/write.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/syscall_test_runner.go b/test/syscalls/syscall_test_runner.go index c4af28103..28f312b8b 100644 --- a/test/syscalls/syscall_test_runner.go +++ b/test/syscalls/syscall_test_runner.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/syscalls/syscall_test_runner.sh b/test/syscalls/syscall_test_runner.sh index 87d62786b..864bb2de4 100755 --- a/test/syscalls/syscall_test_runner.sh +++ b/test/syscalls/syscall_test_runner.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/test/util/capability_util.cc b/test/util/capability_util.cc index d1dd95e76..5d733887b 100644 --- a/test/util/capability_util.cc +++ b/test/util/capability_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/capability_util.h b/test/util/capability_util.h index 8708f5e69..e968a2583 100644 --- a/test/util/capability_util.h +++ b/test/util/capability_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/cleanup.h b/test/util/cleanup.h index fb4724f97..c76482ef4 100644 --- a/test/util/cleanup.h +++ b/test/util/cleanup.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/epoll_util.cc b/test/util/epoll_util.cc index 0b95aa8cd..2e5051468 100644 --- a/test/util/epoll_util.cc +++ b/test/util/epoll_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/epoll_util.h b/test/util/epoll_util.h index 521e7a3d3..f233b37d5 100644 --- a/test/util/epoll_util.h +++ b/test/util/epoll_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/eventfd_util.h b/test/util/eventfd_util.h index 1fdb07d3b..cb9ce829c 100644 --- a/test/util/eventfd_util.h +++ b/test/util/eventfd_util.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/util/file_descriptor.h b/test/util/file_descriptor.h index be8812d01..fc5caa55b 100644 --- a/test/util/file_descriptor.h +++ b/test/util/file_descriptor.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/fs_util.cc b/test/util/fs_util.cc index 6bd424417..bc90bd78e 100644 --- a/test/util/fs_util.cc +++ b/test/util/fs_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/fs_util.h b/test/util/fs_util.h index 9412b2f71..eb7cdaa24 100644 --- a/test/util/fs_util.h +++ b/test/util/fs_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/fs_util_test.cc b/test/util/fs_util_test.cc index ce70d58aa..4e12076a1 100644 --- a/test/util/fs_util_test.cc +++ b/test/util/fs_util_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/logging.cc b/test/util/logging.cc index 86ea71df3..cc71d77b0 100644 --- a/test/util/logging.cc +++ b/test/util/logging.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/logging.h b/test/util/logging.h index 6e957b172..589166fab 100644 --- a/test/util/logging.h +++ b/test/util/logging.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/memory_util.h b/test/util/memory_util.h index 8f6e99ba6..8c77778ea 100644 --- a/test/util/memory_util.h +++ b/test/util/memory_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/mount_util.h b/test/util/mount_util.h index 468170646..7782e6bf2 100644 --- a/test/util/mount_util.h +++ b/test/util/mount_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/multiprocess_util.cc b/test/util/multiprocess_util.cc index 12637db8c..95f5f3b4f 100644 --- a/test/util/multiprocess_util.cc +++ b/test/util/multiprocess_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/multiprocess_util.h b/test/util/multiprocess_util.h index ba5f2601f..0aecd3439 100644 --- a/test/util/multiprocess_util.h +++ b/test/util/multiprocess_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/posix_error.cc b/test/util/posix_error.cc index ead9ede16..cebf7e0ac 100644 --- a/test/util/posix_error.cc +++ b/test/util/posix_error.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/posix_error.h b/test/util/posix_error.h index 2a66e2e94..b604f4f8f 100644 --- a/test/util/posix_error.h +++ b/test/util/posix_error.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/posix_error_test.cc b/test/util/posix_error_test.cc index c5427b8e5..d67270842 100644 --- a/test/util/posix_error_test.cc +++ b/test/util/posix_error_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/proc_util.cc b/test/util/proc_util.cc index 2d9eb1986..9d4db37c3 100644 --- a/test/util/proc_util.cc +++ b/test/util/proc_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/proc_util.h b/test/util/proc_util.h index e1ee2db9c..af209a51e 100644 --- a/test/util/proc_util.h +++ b/test/util/proc_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/proc_util_test.cc b/test/util/proc_util_test.cc index 75335415a..71dd2355e 100644 --- a/test/util/proc_util_test.cc +++ b/test/util/proc_util_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/rlimit_util.cc b/test/util/rlimit_util.cc index a9912c372..684253f78 100644 --- a/test/util/rlimit_util.cc +++ b/test/util/rlimit_util.cc @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/util/rlimit_util.h b/test/util/rlimit_util.h index fa5cc70dc..873252a32 100644 --- a/test/util/rlimit_util.h +++ b/test/util/rlimit_util.h @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 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. diff --git a/test/util/save_util.cc b/test/util/save_util.cc index 5540e2146..05f52b80d 100644 --- a/test/util/save_util.cc +++ b/test/util/save_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/save_util.h b/test/util/save_util.h index 919e4af3d..90460701e 100644 --- a/test/util/save_util.h +++ b/test/util/save_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/signal_util.cc b/test/util/signal_util.cc index 3e2df32a6..26738864f 100644 --- a/test/util/signal_util.cc +++ b/test/util/signal_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/signal_util.h b/test/util/signal_util.h index 80f1808f6..7fd2af015 100644 --- a/test/util/signal_util.h +++ b/test/util/signal_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/temp_path.cc b/test/util/temp_path.cc index 48ce82d20..c5d8fc635 100644 --- a/test/util/temp_path.cc +++ b/test/util/temp_path.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/temp_path.h b/test/util/temp_path.h index 33eb6a72c..89302e0fd 100644 --- a/test/util/temp_path.h +++ b/test/util/temp_path.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_main.cc b/test/util/test_main.cc index 4c6b5e860..5c7ee0064 100644 --- a/test/util/test_main.cc +++ b/test/util/test_main.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_util.cc b/test/util/test_util.cc index 9b7cfa4dc..c52fd9a4a 100644 --- a/test/util/test_util.cc +++ b/test/util/test_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_util.h b/test/util/test_util.h index 905412b24..8f5eb5089 100644 --- a/test/util/test_util.h +++ b/test/util/test_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/test_util_test.cc b/test/util/test_util_test.cc index 5889651d1..b7300d9e5 100644 --- a/test/util/test_util_test.cc +++ b/test/util/test_util_test.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/thread_util.h b/test/util/thread_util.h index df09ac8cf..860e77531 100644 --- a/test/util/thread_util.h +++ b/test/util/thread_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/timer_util.cc b/test/util/timer_util.cc index 681fafb69..43a26b0d3 100644 --- a/test/util/timer_util.cc +++ b/test/util/timer_util.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/test/util/timer_util.h b/test/util/timer_util.h index 9bdc51a57..2cebfa5d1 100644 --- a/test/util/timer_util.h +++ b/test/util/timer_util.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/third_party/gvsync/atomicptr_unsafe.go b/third_party/gvsync/atomicptr_unsafe.go index da9f16240..53a943282 100644 --- a/third_party/gvsync/atomicptr_unsafe.go +++ b/third_party/gvsync/atomicptr_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/atomicptrtest/atomicptr_test.go b/third_party/gvsync/atomicptrtest/atomicptr_test.go index 15d0936d4..8fdc5112e 100644 --- a/third_party/gvsync/atomicptrtest/atomicptr_test.go +++ b/third_party/gvsync/atomicptrtest/atomicptr_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/downgradable_rwmutex_test.go b/third_party/gvsync/downgradable_rwmutex_test.go index 6517dd5dc..40c384b8b 100644 --- a/third_party/gvsync/downgradable_rwmutex_test.go +++ b/third_party/gvsync/downgradable_rwmutex_test.go @@ -1,5 +1,5 @@ // Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/downgradable_rwmutex_unsafe.go b/third_party/gvsync/downgradable_rwmutex_unsafe.go index 131f0a2ba..4d43eb765 100644 --- a/third_party/gvsync/downgradable_rwmutex_unsafe.go +++ b/third_party/gvsync/downgradable_rwmutex_unsafe.go @@ -1,5 +1,5 @@ // Copyright 2009 The Go Authors. All rights reserved. -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/gvsync.go b/third_party/gvsync/gvsync.go index 46a2565fd..3bbef13c3 100644 --- a/third_party/gvsync/gvsync.go +++ b/third_party/gvsync/gvsync.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/memmove_unsafe.go b/third_party/gvsync/memmove_unsafe.go index d483fc739..4c8aa9ab6 100644 --- a/third_party/gvsync/memmove_unsafe.go +++ b/third_party/gvsync/memmove_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/norace_unsafe.go b/third_party/gvsync/norace_unsafe.go index f9c88d13f..e3852db8c 100644 --- a/third_party/gvsync/norace_unsafe.go +++ b/third_party/gvsync/norace_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/race_unsafe.go b/third_party/gvsync/race_unsafe.go index 2cdcdf7f7..13c02a830 100644 --- a/third_party/gvsync/race_unsafe.go +++ b/third_party/gvsync/race_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/seqatomic_unsafe.go b/third_party/gvsync/seqatomic_unsafe.go index ef61503e2..c52d378f1 100644 --- a/third_party/gvsync/seqatomic_unsafe.go +++ b/third_party/gvsync/seqatomic_unsafe.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/seqatomictest/seqatomic_test.go b/third_party/gvsync/seqatomictest/seqatomic_test.go index d0c373bae..2da73cf96 100644 --- a/third_party/gvsync/seqatomictest/seqatomic_test.go +++ b/third_party/gvsync/seqatomictest/seqatomic_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/third_party/gvsync/seqcount.go b/third_party/gvsync/seqcount.go index c7ae91cfa..2c9c2c3d6 100644 --- a/third_party/gvsync/seqcount.go +++ b/third_party/gvsync/seqcount.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/third_party/gvsync/seqcount_test.go b/third_party/gvsync/seqcount_test.go index ee6579ed8..085e574b3 100644 --- a/third_party/gvsync/seqcount_test.go +++ b/third_party/gvsync/seqcount_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2019 The gVisor Authors. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/tools/go_generics/generics.go b/tools/go_generics/generics.go index eaf5c4970..ca414d8cb 100644 --- a/tools/go_generics/generics.go +++ b/tools/go_generics/generics.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_stmts/input.go b/tools/go_generics/generics_tests/all_stmts/input.go index 19184a3fe..4791d1ff1 100644 --- a/tools/go_generics/generics_tests/all_stmts/input.go +++ b/tools/go_generics/generics_tests/all_stmts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_stmts/output/output.go b/tools/go_generics/generics_tests/all_stmts/output/output.go index 51582346c..a53d84535 100644 --- a/tools/go_generics/generics_tests/all_stmts/output/output.go +++ b/tools/go_generics/generics_tests/all_stmts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_types/input.go b/tools/go_generics/generics_tests/all_types/input.go index ed6e97c29..3575d02ec 100644 --- a/tools/go_generics/generics_tests/all_types/input.go +++ b/tools/go_generics/generics_tests/all_types/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_types/lib/lib.go b/tools/go_generics/generics_tests/all_types/lib/lib.go index 7e73e678e..988786496 100644 --- a/tools/go_generics/generics_tests/all_types/lib/lib.go +++ b/tools/go_generics/generics_tests/all_types/lib/lib.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/all_types/output/output.go b/tools/go_generics/generics_tests/all_types/output/output.go index ec09a6be4..41fd147a1 100644 --- a/tools/go_generics/generics_tests/all_types/output/output.go +++ b/tools/go_generics/generics_tests/all_types/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/consts/input.go b/tools/go_generics/generics_tests/consts/input.go index 394bcc262..04b95fcc6 100644 --- a/tools/go_generics/generics_tests/consts/input.go +++ b/tools/go_generics/generics_tests/consts/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/consts/output/output.go b/tools/go_generics/generics_tests/consts/output/output.go index 91a07fdc2..18d316cc9 100644 --- a/tools/go_generics/generics_tests/consts/output/output.go +++ b/tools/go_generics/generics_tests/consts/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/imports/input.go b/tools/go_generics/generics_tests/imports/input.go index 22e6641a6..0f032c2a1 100644 --- a/tools/go_generics/generics_tests/imports/input.go +++ b/tools/go_generics/generics_tests/imports/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/imports/output/output.go b/tools/go_generics/generics_tests/imports/output/output.go index 2555c0004..2488ca58c 100644 --- a/tools/go_generics/generics_tests/imports/output/output.go +++ b/tools/go_generics/generics_tests/imports/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/remove_typedef/input.go b/tools/go_generics/generics_tests/remove_typedef/input.go index d9c9b8530..cf632bae7 100644 --- a/tools/go_generics/generics_tests/remove_typedef/input.go +++ b/tools/go_generics/generics_tests/remove_typedef/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/remove_typedef/output/output.go b/tools/go_generics/generics_tests/remove_typedef/output/output.go index f111a9426..d44fd8e1c 100644 --- a/tools/go_generics/generics_tests/remove_typedef/output/output.go +++ b/tools/go_generics/generics_tests/remove_typedef/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/simple/input.go b/tools/go_generics/generics_tests/simple/input.go index 711687cf5..2a917f16c 100644 --- a/tools/go_generics/generics_tests/simple/input.go +++ b/tools/go_generics/generics_tests/simple/input.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/generics_tests/simple/output/output.go b/tools/go_generics/generics_tests/simple/output/output.go index 139c9bf9d..6bfa0b25b 100644 --- a/tools/go_generics/generics_tests/simple/output/output.go +++ b/tools/go_generics/generics_tests/simple/output/output.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/globals/globals_visitor.go b/tools/go_generics/globals/globals_visitor.go index daaa17b1d..7ae48c662 100644 --- a/tools/go_generics/globals/globals_visitor.go +++ b/tools/go_generics/globals/globals_visitor.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/globals/scope.go b/tools/go_generics/globals/scope.go index b75a91689..96c965ea2 100644 --- a/tools/go_generics/globals/scope.go +++ b/tools/go_generics/globals/scope.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/go_generics_unittest.sh b/tools/go_generics/go_generics_unittest.sh index e7553a071..44b22db91 100755 --- a/tools/go_generics/go_generics_unittest.sh +++ b/tools/go_generics/go_generics_unittest.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/tools/go_generics/go_merge/main.go b/tools/go_generics/go_merge/main.go index 2f83facf8..f6a331123 100644 --- a/tools/go_generics/go_merge/main.go +++ b/tools/go_generics/go_merge/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/imports.go b/tools/go_generics/imports.go index 57f7c3dce..3a7230c97 100644 --- a/tools/go_generics/imports.go +++ b/tools/go_generics/imports.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/remove.go b/tools/go_generics/remove.go index 139d03955..568a6bbd3 100644 --- a/tools/go_generics/remove.go +++ b/tools/go_generics/remove.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/rules_tests/template.go b/tools/go_generics/rules_tests/template.go index f3f31ae8e..aace61da1 100644 --- a/tools/go_generics/rules_tests/template.go +++ b/tools/go_generics/rules_tests/template.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_generics/rules_tests/template_test.go b/tools/go_generics/rules_tests/template_test.go index 3a38c8629..b2a3446ef 100644 --- a/tools/go_generics/rules_tests/template_test.go +++ b/tools/go_generics/rules_tests/template_test.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/go_stateify/main.go b/tools/go_stateify/main.go index 9e2c8e106..db7a7107b 100644 --- a/tools/go_stateify/main.go +++ b/tools/go_stateify/main.go @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/tools/tag_release.sh b/tools/tag_release.sh index 6906a952f..02a49cdf1 100755 --- a/tools/tag_release.sh +++ b/tools/tag_release.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2019 Google LLC +# Copyright 2019 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. diff --git a/tools/workspace_status.sh b/tools/workspace_status.sh index a0e646e45..64a905fc9 100755 --- a/tools/workspace_status.sh +++ b/tools/workspace_status.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/vdso/barrier.h b/vdso/barrier.h index 5b6c763f6..edba4afb5 100644 --- a/vdso/barrier.h +++ b/vdso/barrier.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/check_vdso.py b/vdso/check_vdso.py index 6f7d7e7ec..e41b09709 100644 --- a/vdso/check_vdso.py +++ b/vdso/check_vdso.py @@ -1,4 +1,4 @@ -# Copyright 2018 Google LLC +# Copyright 2018 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. diff --git a/vdso/compiler.h b/vdso/compiler.h index d65f148fb..54a510000 100644 --- a/vdso/compiler.h +++ b/vdso/compiler.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/cycle_clock.h b/vdso/cycle_clock.h index 309e07a3f..5d3fbb257 100644 --- a/vdso/cycle_clock.h +++ b/vdso/cycle_clock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/seqlock.h b/vdso/seqlock.h index ab2f3fda3..7a173174b 100644 --- a/vdso/seqlock.h +++ b/vdso/seqlock.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/syscalls.h b/vdso/syscalls.h index 90fb424ce..f5865bb72 100644 --- a/vdso/syscalls.h +++ b/vdso/syscalls.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/vdso.cc b/vdso/vdso.cc index 550729035..6265ad217 100644 --- a/vdso/vdso.cc +++ b/vdso/vdso.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/vdso_time.cc b/vdso/vdso_time.cc index 9fc262f60..1bb4bb86b 100644 --- a/vdso/vdso_time.cc +++ b/vdso/vdso_time.cc @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. diff --git a/vdso/vdso_time.h b/vdso/vdso_time.h index 464dadff2..70d079efc 100644 --- a/vdso/vdso_time.h +++ b/vdso/vdso_time.h @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 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. -- cgit v1.2.3 From 264d012d81d210c6d949554667c6fbf8e330587a Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Fri, 3 May 2019 13:04:46 -0700 Subject: Add netfilter ABI for iptables support. Change-Id: Ifbd2abf63ea8062a89b83e948d3e9735480d8216 PiperOrigin-RevId: 246559904 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/netfilter.go | 240 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+) create mode 100644 pkg/abi/linux/netfilter.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 7648c9469..fdf193873 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -32,6 +32,7 @@ go_library( "linux.go", "mm.go", "netdevice.go", + "netfilter.go", "netlink.go", "netlink_route.go", "poll.go", diff --git a/pkg/abi/linux/netfilter.go b/pkg/abi/linux/netfilter.go new file mode 100644 index 000000000..7f399142b --- /dev/null +++ b/pkg/abi/linux/netfilter.go @@ -0,0 +1,240 @@ +// Copyright 2019 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 linux + +// This file contains structures required to support netfilter, specifically +// the iptables tool. + +// Hooks into the network stack. These correspond to values in +// include/uapi/linux/netfilter.h. +const ( + NF_INET_PRE_ROUTING = 0 + NF_INET_LOCAL_IN = 1 + NF_INET_FORWARD = 2 + NF_INET_LOCAL_OUT = 3 + NF_INET_POST_ROUTING = 4 + NF_INET_NUMHOOKS = 5 +) + +// Verdicts that can be returned by targets. These correspond to values in +// include/uapi/linux/netfilter.h +const ( + NF_DROP = 0 + NF_ACCEPT = 1 + NF_STOLEN = 2 + NF_QUEUE = 3 + NF_REPEAT = 4 + NF_STOP = 5 + NF_MAX_VERDICT = NF_STOP + // NF_RETURN is defined in include/uapi/linux/netfilter/x_tables.h. + NF_RETURN = -NF_REPEAT - 1 +) + +// Socket options. These correspond to values in +// include/uapi/linux/netfilter_ipv4/ip_tables.h. +const ( + IPT_BASE_CTL = 64 + IPT_SO_SET_REPLACE = IPT_BASE_CTL + IPT_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1 + IPT_SO_SET_MAX = IPT_SO_SET_ADD_COUNTERS + + IPT_SO_GET_INFO = IPT_BASE_CTL + IPT_SO_GET_ENTRIES = IPT_BASE_CTL + 1 + IPT_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 2 + IPT_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 3 + IPT_SO_GET_MAX = IPT_SO_GET_REVISION_TARGET +) + +// Name lengths. These correspond to values in +// include/uapi/linux/netfilter/x_tables.h. +const ( + XT_FUNCTION_MAXNAMELEN = 30 + XT_EXTENSION_MAXNAMELEN = 29 + XT_TABLE_MAXNAMELEN = 32 +) + +// IPTEntry is an iptable rule. It corresponds to struct ipt_entry in +// include/uapi/linux/netfilter_ipv4/ip_tables.h. +type IPTEntry struct { + // IP is used to filter packets based on the IP header. + IP IPTIP + + // NFCache relates to kernel-internal caching and isn't used by + // userspace. + NFCache uint32 + + // TargetOffset is the byte offset from the beginning of this IPTEntry + // to the start of the entry's target. + TargetOffset uint16 + + // NextOffset is the byte offset from the beginning of this IPTEntry to + // the start of the next entry. It is thus also the size of the entry. + NextOffset uint16 + + // Comeback is a return pointer. It is not used by userspace. + Comeback uint32 + + // Counters holds the packet and byte counts for this rule. + Counters XTCounters + + // Elems holds the data for all this rule's matches followed by the + // target. It is variable length -- users have to iterate over any + // matches and use TargetOffset and NextOffset to make sense of the + // data. + // + // Elems is omitted here because it would cause IPTEntry to be an extra + // byte larger (see http://www.catb.org/esr/structure-packing/). + // + // Elems [0]byte +} + +// IPTIP contains information for matching a packet's IP header. +// It corresponds to struct ipt_ip in +// include/uapi/linux/netfilter_ipv4/ip_tables.h. +type IPTIP struct { + // Src is the source IP address. + Src InetAddr + + // Dst is the destination IP address. + Dst InetAddr + + // SrcMask is the source IP mask. + SrcMask InetAddr + + // DstMask is the destination IP mask. + DstMask InetAddr + + // InputInterface is the input network interface. + InputInterface [IFNAMSIZ]byte + + // OutputInterface is the output network interface. + OutputInterface [IFNAMSIZ]byte + + // InputInterfaceMask is the intput interface mask. + InputInterfaceMast [IFNAMSIZ]byte + + // OuputInterfaceMask is the output interface mask. + OuputInterfaceMask [IFNAMSIZ]byte + + // Protocol is the transport protocol. + Protocol uint16 + + // Flags define matching behavior for the IP header. + Flags uint8 + + // InverseFlags invert the meaning of fields in struct IPTIP. + InverseFlags uint8 +} + +// XTCounters holds packet and byte counts for a rule. It corresponds to struct +// xt_counters in include/uapi/linux/netfilter/x_tables.h. +type XTCounters struct { + // Pcnt is the packet count. + Pcnt uint64 + + // Bcnt is the byte count. + Bcnt uint64 +} + +// XTEntryMatch holds a match for a rule. For example, a user using the +// addrtype iptables match extension would put the data for that match into an +// XTEntryMatch. iptables-extensions(8) has a list of possible matches. +// +// XTEntryMatch corresponds to struct xt_entry_match in +// include/uapi/linux/netfilter/x_tables.h. That struct contains a union +// exposing different data to the user and kernel, but this struct holds only +// the user data. +type XTEntryMatch struct { + MatchSize uint16 + Name [XT_EXTENSION_MAXNAMELEN]byte + Revision uint8 + // Data is omitted here because it would cause XTEntryTarget to be an + // extra byte larger (see http://www.catb.org/esr/structure-packing/). + // Data [0]byte +} + +// XTEntryTarget holds a target for a rule. For example, it can specify that +// packets matching the rule should DROP, ACCEPT, or use an extension target. +// iptables-extension(8) has a list of possible targets. +// +// XTEntryTarget corresponds to struct xt_entry_target in +// include/uapi/linux/netfilter/x_tables.h. That struct contains a union +// exposing different data to the user and kernel, but this struct holds only +// the user data. +type XTEntryTarget struct { + MatchSize uint16 + Name [XT_EXTENSION_MAXNAMELEN]byte + Revision uint8 + // Data is omitted here because it would cause XTEntryTarget to be an + // extra byte larger (see http://www.catb.org/esr/structure-packing/). + // Data [0]byte +} + +// XTStandardTarget is a builtin target, one of ACCEPT, DROP, JUMP, QUEUE, or +// RETURN. It corresponds to struct xt_standard_target in +// include/uapi/linux/netfilter/x_tables.h. +type XTStandardTarget struct { + Target XTEntryTarget + Verdict int32 +} + +// XTErrorTarget triggers an error when reached. It is also used to mark the +// beginning of user-defined chains by putting the name of the chain in +// ErrorName. It corresponds to struct xt_error_target in +// include/uapi/linux/netfilter/x_tables.h. +type XTErrorTarget struct { + Target XTEntryTarget + ErrorName [XT_FUNCTION_MAXNAMELEN]byte +} + +// IPTGetinfo is the argument for the IPT_SO_GET_INFO sockopt. It corresponds +// to struct ipt_getinfo in include/uapi/linux/netfilter_ipv4/ip_tables.h. +type IPTGetinfo struct { + Name [XT_TABLE_MAXNAMELEN]byte + ValidHooks uint32 + HookEntry [NF_INET_NUMHOOKS]uint32 + Underflow [NF_INET_NUMHOOKS]uint32 + NumEntries uint32 + Size uint32 +} + +// IPTGetEntries is the argument for the IPT_SO_GET_ENTRIES sockopt. It +// corresponds to struct ipt_get_entries in +// include/uapi/linux/netfilter_ipv4/ip_tables.h. +type IPTGetEntries struct { + Name [XT_TABLE_MAXNAMELEN]byte + Size uint32 + // Entrytable is omitted here because it would cause IPTGetEntries to + // be an extra byte longer (see + // http://www.catb.org/esr/structure-packing/). + // Entrytable [0]IPTEntry +} + +// IPTReplace is the argument for the IPT_SO_SET_REPLACE sockopt. It +// corresponds to struct ipt_replace in +// include/uapi/linux/netfilter_ipv4/ip_tables.h. +type IPTReplace struct { + Name [XT_TABLE_MAXNAMELEN]byte + ValidHooks uint32 + NumEntries uint32 + Size uint32 + HookEntry [NF_INET_NUMHOOKS]uint32 + Underflow [NF_INET_NUMHOOKS]uint32 + NumCounters uint32 + Counters *XTCounters + // Entries is omitted here because it would cause IPTReplace to be an + // extra byte longer (see http://www.catb.org/esr/structure-packing/). + // Entries [0]IPTEntry +} -- cgit v1.2.3 From 1bee43be13549b01e18d87df194ac219845de5cf Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Thu, 9 May 2019 15:34:44 -0700 Subject: Implement fallocate(2) Closes #225 PiperOrigin-RevId: 247508791 Change-Id: I04f47cf2770b30043e5a272aba4ba6e11d0476cc --- pkg/abi/linux/file.go | 11 +++ pkg/p9/BUILD | 1 + pkg/p9/client_file.go | 12 +++ pkg/p9/file.go | 4 + pkg/p9/handlers.go | 34 +++++++++ pkg/p9/local_server/local_server.go | 5 ++ pkg/p9/messages.go | 59 ++++++++++++++ pkg/p9/p9.go | 81 ++++++++++++++++++++ pkg/p9/version.go | 7 +- pkg/sentry/fs/ashmem/device.go | 1 + pkg/sentry/fs/binder/binder.go | 1 + pkg/sentry/fs/dev/full.go | 3 +- pkg/sentry/fs/dev/null.go | 9 ++- pkg/sentry/fs/dev/random.go | 9 ++- pkg/sentry/fs/fsutil/BUILD | 1 + pkg/sentry/fs/fsutil/host_mappable.go | 10 ++- pkg/sentry/fs/fsutil/inode.go | 25 ++++++ pkg/sentry/fs/fsutil/inode_cached.go | 28 +++++++ pkg/sentry/fs/fsutil/inode_cached_test.go | 9 +++ pkg/sentry/fs/gofer/context_file.go | 7 ++ pkg/sentry/fs/gofer/inode.go | 24 ++++++ pkg/sentry/fs/host/inode.go | 18 +++++ pkg/sentry/fs/inode.go | 7 ++ pkg/sentry/fs/inode_operations.go | 4 + pkg/sentry/fs/inode_overlay.go | 7 ++ pkg/sentry/fs/inode_overlay_test.go | 1 + pkg/sentry/fs/mock.go | 5 ++ pkg/sentry/fs/proc/inode.go | 1 + pkg/sentry/fs/proc/seqfile/seqfile.go | 3 +- pkg/sentry/fs/proc/uid_gid_map.go | 3 +- pkg/sentry/fs/ramfs/dir.go | 1 + pkg/sentry/fs/ramfs/socket.go | 3 +- pkg/sentry/fs/ramfs/symlink.go | 5 +- pkg/sentry/fs/sys/devices.go | 3 +- pkg/sentry/fs/tmpfs/inode_file.go | 27 +++++++ pkg/sentry/fs/tmpfs/tmpfs.go | 8 +- pkg/sentry/fs/tty/dir.go | 5 +- pkg/sentry/kernel/pipe/node.go | 4 + pkg/sentry/syscalls/linux/sys_file.go | 38 ++++++++- runsc/boot/compat.go | 2 +- runsc/fsgofer/filter/config.go | 10 ++- runsc/fsgofer/fsgofer.go | 12 +++ test/syscalls/linux/BUILD | 2 + test/syscalls/linux/fallocate.cc | 123 +++++++++++++++++++++++++----- 44 files changed, 589 insertions(+), 44 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/file.go b/pkg/abi/linux/file.go index 753fec3ed..81ff9fe9e 100644 --- a/pkg/abi/linux/file.go +++ b/pkg/abi/linux/file.go @@ -254,3 +254,14 @@ const ( F_SEAL_GROW = 0x0004 // Prevent file from growing. F_SEAL_WRITE = 0x0008 // Prevent writes. ) + +// Constants related to fallocate(2). Source: include/uapi/linux/falloc.h +const ( + FALLOC_FL_KEEP_SIZE = 0x01 + FALLOC_FL_PUNCH_HOLE = 0x02 + FALLOC_FL_NO_HIDE_STALE = 0x04 + FALLOC_FL_COLLAPSE_RANGE = 0x08 + FALLOC_FL_ZERO_RANGE = 0x10 + FALLOC_FL_INSERT_RANGE = 0x20 + FALLOC_FL_UNSHARE_RANGE = 0x40 +) diff --git a/pkg/p9/BUILD b/pkg/p9/BUILD index 5d972309d..36b2ec5f6 100644 --- a/pkg/p9/BUILD +++ b/pkg/p9/BUILD @@ -26,6 +26,7 @@ go_library( "//pkg/fd", "//pkg/log", "//pkg/unet", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/p9/client_file.go b/pkg/p9/client_file.go index 63c65129a..471c3a80b 100644 --- a/pkg/p9/client_file.go +++ b/pkg/p9/client_file.go @@ -171,6 +171,18 @@ func (c *clientFile) SetAttr(valid SetAttrMask, attr SetAttr) error { return c.client.sendRecv(&Tsetattr{FID: c.fid, Valid: valid, SetAttr: attr}, &Rsetattr{}) } +// Allocate implements File.Allocate. +func (c *clientFile) Allocate(mode AllocateMode, offset, length uint64) error { + if atomic.LoadUint32(&c.closed) != 0 { + return syscall.EBADF + } + if !versionSupportsTallocate(c.client.version) { + return syscall.EOPNOTSUPP + } + + return c.client.sendRecv(&Tallocate{FID: c.fid, Mode: mode, Offset: offset, Length: length}, &Rallocate{}) +} + // Remove implements File.Remove. // // N.B. This method is no longer part of the file interface and should be diff --git a/pkg/p9/file.go b/pkg/p9/file.go index a52a0f3e7..89e814d50 100644 --- a/pkg/p9/file.go +++ b/pkg/p9/file.go @@ -89,6 +89,10 @@ type File interface { // On the server, SetAttr has a write concurrency guarantee. SetAttr(valid SetAttrMask, attr SetAttr) error + // Allocate allows the caller to directly manipulate the allocated disk space + // for the file. See fallocate(2) for more details. + Allocate(mode AllocateMode, offset, length uint64) error + // Close is called when all references are dropped on the server side, // and Close should be called by the client to drop all references. // diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index 6da2ce4e3..533ead98a 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -877,6 +877,40 @@ func (t *Tsetattr) handle(cs *connState) message { return &Rsetattr{} } +// handle implements handler.handle. +func (t *Tallocate) handle(cs *connState) message { + // Lookup the FID. + ref, ok := cs.LookupFID(t.FID) + if !ok { + return newErr(syscall.EBADF) + } + defer ref.DecRef() + + if err := ref.safelyWrite(func() error { + // Has it been opened already? + openFlags, opened := ref.OpenFlags() + if !opened { + return syscall.EINVAL + } + + // Can it be written? Check permissions. + if openFlags&OpenFlagsModeMask == ReadOnly { + return syscall.EBADF + } + + // We don't allow allocate on files that have been deleted. + if ref.isDeleted() { + return syscall.EINVAL + } + + return ref.file.Allocate(t.Mode, t.Offset, t.Length) + }); err != nil { + return newErr(err) + } + + return &Rallocate{} +} + // handle implements handler.handle. func (t *Txattrwalk) handle(cs *connState) message { // Lookup the FID. diff --git a/pkg/p9/local_server/local_server.go b/pkg/p9/local_server/local_server.go index f4077a9d4..d49d94550 100644 --- a/pkg/p9/local_server/local_server.go +++ b/pkg/p9/local_server/local_server.go @@ -323,6 +323,11 @@ func (l *local) Renamed(parent p9.File, newName string) { l.path = path.Join(parent.(*local).path, newName) } +// Allocate implements p9.File.Allocate. +func (l *local) Allocate(mode p9.AllocateMode, offset, length uint64) error { + return syscall.Fallocate(int(l.file.Fd()), mode.ToLinux(), int64(offset), int64(length)) +} + func main() { log.SetLevel(log.Debug) diff --git a/pkg/p9/messages.go b/pkg/p9/messages.go index 3c7898cc1..703753c31 100644 --- a/pkg/p9/messages.go +++ b/pkg/p9/messages.go @@ -1424,6 +1424,63 @@ func (r *Rsetattr) String() string { return fmt.Sprintf("Rsetattr{}") } +// Tallocate is an allocate request. This is an extension to 9P protocol, not +// present in the 9P2000.L standard. +type Tallocate struct { + FID FID + Mode AllocateMode + Offset uint64 + Length uint64 +} + +// Decode implements encoder.Decode. +func (t *Tallocate) Decode(b *buffer) { + t.FID = b.ReadFID() + t.Mode.Decode(b) + t.Offset = b.Read64() + t.Length = b.Read64() +} + +// Encode implements encoder.Encode. +func (t *Tallocate) Encode(b *buffer) { + b.WriteFID(t.FID) + t.Mode.Encode(b) + b.Write64(t.Offset) + b.Write64(t.Length) +} + +// Type implements message.Type. +func (*Tallocate) Type() MsgType { + return MsgTallocate +} + +// String implements fmt.Stringer. +func (t *Tallocate) String() string { + return fmt.Sprintf("Tallocate{FID: %d, Offset: %d, Length: %d}", t.FID, t.Offset, t.Length) +} + +// Rallocate is an allocate response. +type Rallocate struct { +} + +// Decode implements encoder.Decode. +func (*Rallocate) Decode(b *buffer) { +} + +// Encode implements encoder.Encode. +func (*Rallocate) Encode(b *buffer) { +} + +// Type implements message.Type. +func (*Rallocate) Type() MsgType { + return MsgRallocate +} + +// String implements fmt.Stringer. +func (r *Rallocate) String() string { + return fmt.Sprintf("Rallocate{}") +} + // Txattrwalk walks extended attributes. type Txattrwalk struct { // FID is the FID to check for attributes. @@ -2297,4 +2354,6 @@ func init() { msgRegistry.register(MsgRusymlink, func() message { return &Rusymlink{} }) msgRegistry.register(MsgTlconnect, func() message { return &Tlconnect{} }) msgRegistry.register(MsgRlconnect, func() message { return &Rlconnect{} }) + msgRegistry.register(MsgTallocate, func() message { return &Tallocate{} }) + msgRegistry.register(MsgRallocate, func() message { return &Rallocate{} }) } diff --git a/pkg/p9/p9.go b/pkg/p9/p9.go index 78c7d3f86..4039862e6 100644 --- a/pkg/p9/p9.go +++ b/pkg/p9/p9.go @@ -22,6 +22,8 @@ import ( "strings" "sync/atomic" "syscall" + + "golang.org/x/sys/unix" ) // OpenFlags is the mode passed to Open and Create operations. @@ -374,6 +376,8 @@ const ( MsgRusymlink = 135 MsgTlconnect = 136 MsgRlconnect = 137 + MsgTallocate = 138 + MsgRallocate = 139 ) // QIDType represents the file type for QIDs. @@ -1058,3 +1062,80 @@ func (d *Dirent) Encode(b *buffer) { b.WriteQIDType(d.Type) b.WriteString(d.Name) } + +// AllocateMode are possible modes to p9.File.Allocate(). +type AllocateMode struct { + KeepSize bool + PunchHole bool + NoHideStale bool + CollapseRange bool + ZeroRange bool + InsertRange bool + Unshare bool +} + +// ToLinux converts to a value compatible with fallocate(2)'s mode. +func (a *AllocateMode) ToLinux() uint32 { + rv := uint32(0) + if a.KeepSize { + rv |= unix.FALLOC_FL_KEEP_SIZE + } + if a.PunchHole { + rv |= unix.FALLOC_FL_PUNCH_HOLE + } + if a.NoHideStale { + rv |= unix.FALLOC_FL_NO_HIDE_STALE + } + if a.CollapseRange { + rv |= unix.FALLOC_FL_COLLAPSE_RANGE + } + if a.ZeroRange { + rv |= unix.FALLOC_FL_ZERO_RANGE + } + if a.InsertRange { + rv |= unix.FALLOC_FL_INSERT_RANGE + } + if a.Unshare { + rv |= unix.FALLOC_FL_UNSHARE_RANGE + } + return rv +} + +// Decode implements encoder.Decode. +func (a *AllocateMode) Decode(b *buffer) { + mask := b.Read32() + a.KeepSize = mask&0x01 != 0 + a.PunchHole = mask&0x02 != 0 + a.NoHideStale = mask&0x04 != 0 + a.CollapseRange = mask&0x08 != 0 + a.ZeroRange = mask&0x10 != 0 + a.InsertRange = mask&0x20 != 0 + a.Unshare = mask&0x40 != 0 +} + +// Encode implements encoder.Encode. +func (a *AllocateMode) Encode(b *buffer) { + mask := uint32(0) + if a.KeepSize { + mask |= 0x01 + } + if a.PunchHole { + mask |= 0x02 + } + if a.NoHideStale { + mask |= 0x04 + } + if a.CollapseRange { + mask |= 0x08 + } + if a.ZeroRange { + mask |= 0x10 + } + if a.InsertRange { + mask |= 0x20 + } + if a.Unshare { + mask |= 0x40 + } + b.Write32(mask) +} diff --git a/pkg/p9/version.go b/pkg/p9/version.go index a36a499a1..c2a2885ae 100644 --- a/pkg/p9/version.go +++ b/pkg/p9/version.go @@ -26,7 +26,7 @@ const ( // // Clients are expected to start requesting this version number and // to continuously decrement it until a Tversion request succeeds. - highestSupportedVersion uint32 = 6 + highestSupportedVersion uint32 = 7 // lowestSupportedVersion is the lowest supported version X in a // version string of the format 9P2000.L.Google.X. @@ -143,3 +143,8 @@ func VersionSupportsAnonymous(v uint32) bool { func VersionSupportsMultiUser(v uint32) bool { return v >= 6 } + +// versionSupportsTallocate returns true if version v supports Allocate(). +func versionSupportsTallocate(v uint32) bool { + return v >= 7 +} diff --git a/pkg/sentry/fs/ashmem/device.go b/pkg/sentry/fs/ashmem/device.go index 5e005bc2e..22e1530e9 100644 --- a/pkg/sentry/fs/ashmem/device.go +++ b/pkg/sentry/fs/ashmem/device.go @@ -29,6 +29,7 @@ import ( type Device struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopAllocate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopTruncate `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index acbbd5466..a992253e6 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -46,6 +46,7 @@ const ( type Device struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopAllocate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopTruncate `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 6b11afa44..17d68b5c4 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -30,6 +30,7 @@ import ( type fullDevice struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopAllocate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopTruncate `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` @@ -59,7 +60,6 @@ func (f *fullDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.Fi // +stateify savable type fullFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` @@ -69,6 +69,7 @@ type fullFileOperations struct { fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` readZeros `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*fullFileOperations)(nil) diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index 069212b6d..ee13183c8 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -29,6 +29,7 @@ import ( type nullDevice struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopAllocate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopTruncate `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` @@ -60,17 +61,17 @@ func (n *nullDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.Fi // +stateify savable type nullFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRead `state:"nosave"` - fsutil.FileNoopWrite `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` + fsutil.FileNoopWrite `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*nullFileOperations)(nil) @@ -101,16 +102,16 @@ func (zd *zeroDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.F // +stateify savable type zeroFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNoopWrite `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoIoctl `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` readZeros `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*zeroFileOperations)(nil) diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index de0f3e5e5..b0a412382 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -29,6 +29,7 @@ import ( type randomDevice struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopAllocate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopTruncate `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` @@ -57,16 +58,16 @@ func (*randomDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.Fi // +stateify savable type randomFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` - fsutil.FileNotDirReaddir `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` - fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` - fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNoopWrite `state:"nosave"` + fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*randomFileOperations)(nil) diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 01098675d..44f43b965 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -113,5 +113,6 @@ go_test( "//pkg/sentry/memmap", "//pkg/sentry/safemem", "//pkg/sentry/usermem", + "//pkg/syserror", ], ) diff --git a/pkg/sentry/fs/fsutil/host_mappable.go b/pkg/sentry/fs/fsutil/host_mappable.go index 28686f3b3..ad0518b8f 100644 --- a/pkg/sentry/fs/fsutil/host_mappable.go +++ b/pkg/sentry/fs/fsutil/host_mappable.go @@ -149,7 +149,7 @@ func (h *HostMappable) Truncate(ctx context.Context, newSize int64) error { } // Invalidate COW mappings that may exist beyond the new size in case the file - // is being shrunk. Other mappinsg don't need to be invalidated because + // is being shrunk. Other mappings don't need to be invalidated because // translate will just return identical mappings after invalidation anyway, // and SIGBUS will be raised and handled when the mappings are touched. // @@ -167,6 +167,14 @@ func (h *HostMappable) Truncate(ctx context.Context, newSize int64) error { return nil } +// Allocate reserves space in the backing file. +func (h *HostMappable) Allocate(ctx context.Context, offset int64, length int64) error { + h.truncateMu.RLock() + err := h.backingFile.Allocate(ctx, offset, length) + h.truncateMu.RUnlock() + return err +} + // Write writes to the file backing this mappable. func (h *HostMappable) Write(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { h.truncateMu.RLock() diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index b6366d906..151be1d0d 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -34,6 +34,7 @@ type SimpleFileInode struct { InodeNoExtendedAttributes `state:"nosave"` InodeNoopRelease `state:"nosave"` InodeNoopWriteOut `state:"nosave"` + InodeNotAllocatable `state:"nosave"` InodeNotDirectory `state:"nosave"` InodeNotMappable `state:"nosave"` InodeNotOpenable `state:"nosave"` @@ -61,6 +62,7 @@ type NoReadWriteFileInode struct { InodeNoExtendedAttributes `state:"nosave"` InodeNoopRelease `state:"nosave"` InodeNoopWriteOut `state:"nosave"` + InodeNotAllocatable `state:"nosave"` InodeNotDirectory `state:"nosave"` InodeNotMappable `state:"nosave"` InodeNotSocket `state:"nosave"` @@ -465,3 +467,26 @@ func (InodeDenyWriteChecker) Check(ctx context.Context, inode *fs.Inode, p fs.Pe } return fs.ContextCanAccessFile(ctx, inode, p) } + +//InodeNotAllocatable can be used by Inodes that do not support Allocate(). +type InodeNotAllocatable struct{} + +func (InodeNotAllocatable) Allocate(_ context.Context, _ *fs.Inode, _, _ int64) error { + return syserror.EOPNOTSUPP +} + +// InodeNoopAllocate implements fs.InodeOperations.Allocate as a noop. +type InodeNoopAllocate struct{} + +// Allocate implements fs.InodeOperations.Allocate. +func (InodeNoopAllocate) Allocate(_ context.Context, _ *fs.Inode, _, _ int64) error { + return nil +} + +// InodeIsDirAllocate implements fs.InodeOperations.Allocate for directories. +type InodeIsDirAllocate struct{} + +// Allocate implements fs.InodeOperations.Allocate. +func (InodeIsDirAllocate) Allocate(_ context.Context, _ *fs.Inode, _, _ int64) error { + return syserror.EISDIR +} diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go index 76644e69d..03cad37f3 100644 --- a/pkg/sentry/fs/fsutil/inode_cached.go +++ b/pkg/sentry/fs/fsutil/inode_cached.go @@ -135,6 +135,10 @@ type CachedFileObject interface { // the file was opened. SetMaskedAttributes(ctx context.Context, mask fs.AttrMask, attr fs.UnstableAttr) error + // Allocate allows the caller to reserve disk space for the inode. + // It's equivalent to fallocate(2) with 'mode=0'. + Allocate(ctx context.Context, offset int64, length int64) error + // Sync instructs the remote filesystem to sync the file to stable storage. Sync(ctx context.Context) error @@ -336,6 +340,30 @@ func (c *CachingInodeOperations) Truncate(ctx context.Context, inode *fs.Inode, return nil } +// Allocate implements fs.InodeOperations.Allocate. +func (c *CachingInodeOperations) Allocate(ctx context.Context, offset, length int64) error { + newSize := offset + length + + // c.attr.Size is protected by both c.attrMu and c.dataMu. + c.attrMu.Lock() + defer c.attrMu.Unlock() + c.dataMu.Lock() + defer c.dataMu.Unlock() + + if newSize <= c.attr.Size { + return nil + } + + now := ktime.NowFromContext(ctx) + if err := c.backingFile.Allocate(ctx, offset, length); err != nil { + return err + } + + c.attr.Size = newSize + c.touchModificationTimeLocked(now) + return nil +} + // WriteOut implements fs.InodeOperations.WriteOut. func (c *CachingInodeOperations) WriteOut(ctx context.Context, inode *fs.Inode) error { c.attrMu.Lock() diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go index 3f10efc12..be3d4b6fc 100644 --- a/pkg/sentry/fs/fsutil/inode_cached_test.go +++ b/pkg/sentry/fs/fsutil/inode_cached_test.go @@ -26,6 +26,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" + "gvisor.googlesource.com/gvisor/pkg/syserror" ) type noopBackingFile struct{} @@ -50,6 +51,10 @@ func (noopBackingFile) FD() int { return -1 } +func (noopBackingFile) Allocate(ctx context.Context, offset int64, length int64) error { + return nil +} + func TestSetPermissions(t *testing.T) { ctx := contexttest.Context(t) @@ -237,6 +242,10 @@ func (*sliceBackingFile) FD() int { return -1 } +func (f *sliceBackingFile) Allocate(ctx context.Context, offset int64, length int64) error { + return syserror.EOPNOTSUPP +} + type noopMappingSpace struct{} // Invalidate implements memmap.MappingSpace.Invalidate. diff --git a/pkg/sentry/fs/gofer/context_file.go b/pkg/sentry/fs/gofer/context_file.go index 842a34af8..be53ac4d9 100644 --- a/pkg/sentry/fs/gofer/context_file.go +++ b/pkg/sentry/fs/gofer/context_file.go @@ -59,6 +59,13 @@ func (c *contextFile) setAttr(ctx context.Context, valid p9.SetAttrMask, attr p9 return err } +func (c *contextFile) allocate(ctx context.Context, mode p9.AllocateMode, offset, length uint64) error { + ctx.UninterruptibleSleepStart(false) + err := c.file.Allocate(mode, offset, length) + ctx.UninterruptibleSleepFinish(false) + return err +} + func (c *contextFile) rename(ctx context.Context, directory contextFile, name string) error { ctx.UninterruptibleSleepStart(false) err := c.file.Rename(directory.file, name) diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index f6f20844d..dcb3b2880 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -322,6 +322,15 @@ func (i *inodeFileState) unstableAttr(ctx context.Context) (fs.UnstableAttr, err return unstable(ctx, valid, pattr, i.s.mounter, i.s.client), nil } +func (i *inodeFileState) Allocate(ctx context.Context, offset, length int64) error { + i.handlesMu.RLock() + defer i.handlesMu.RUnlock() + + // No options are supported for now. + mode := p9.AllocateMode{} + return i.writeHandles.File.allocate(ctx, mode, uint64(offset), uint64(length)) +} + // session extracts the gofer's session from the MountSource. func (i *inodeOperations) session() *session { return i.fileState.s @@ -498,6 +507,21 @@ func (i *inodeOperations) Truncate(ctx context.Context, inode *fs.Inode, length return i.fileState.file.setAttr(ctx, p9.SetAttrMask{Size: true}, p9.SetAttr{Size: uint64(length)}) } +// Allocate implements fs.InodeOperations.Allocate. +func (i *inodeOperations) Allocate(ctx context.Context, inode *fs.Inode, offset, length int64) error { + // This can only be called for files anyway. + if i.session().cachePolicy.useCachingInodeOps(inode) { + return i.cachingInodeOps.Allocate(ctx, offset, length) + } + if i.session().cachePolicy == cacheRemoteRevalidating { + return i.fileState.hostMappable.Allocate(ctx, offset, length) + } + + // No options are supported for now. + mode := p9.AllocateMode{} + return i.fileState.file.allocate(ctx, mode, uint64(offset), uint64(length)) +} + // WriteOut implements fs.InodeOperations.WriteOut. func (i *inodeOperations) WriteOut(ctx context.Context, inode *fs.Inode) error { if !i.session().cachePolicy.cacheUAttrs(inode) { diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index 20e077f77..d36ac9a87 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -163,6 +163,11 @@ func (i *inodeFileState) unstableAttr(ctx context.Context) (fs.UnstableAttr, err return unstableAttr(i.mops, &s), nil } +// SetMaskedAttributes implements fsutil.CachedFileObject.SetMaskedAttributes. +func (i *inodeFileState) Allocate(_ context.Context, offset, length int64) error { + return syscall.Fallocate(i.FD(), 0, offset, length) +} + // inodeOperations implements fs.InodeOperations. var _ fs.InodeOperations = (*inodeOperations)(nil) @@ -397,6 +402,19 @@ func (i *inodeOperations) Truncate(ctx context.Context, inode *fs.Inode, size in return i.cachingInodeOps.Truncate(ctx, inode, size) } +// Allocate implements fs.InodeOperations.Allocate. +func (i *inodeOperations) Allocate(ctx context.Context, inode *fs.Inode, offset, length int64) error { + // Is the file not memory-mappable? + if !canMap(inode) { + // Then just send the call to the FD, the host will synchronize the metadata + // update with any host inode and page cache. + return i.fileState.Allocate(ctx, offset, length) + } + // Otherwise we need to go through cachingInodeOps, even if the host page + // cache is in use, to invalidate private copies of truncated pages. + return i.cachingInodeOps.Allocate(ctx, offset, length) +} + // WriteOut implements fs.InodeOperations.WriteOut. func (i *inodeOperations) WriteOut(ctx context.Context, inode *fs.Inode) error { // Have we been using host kernel metadata caches? diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go index d764ef93d..22f316daf 100644 --- a/pkg/sentry/fs/inode.go +++ b/pkg/sentry/fs/inode.go @@ -340,6 +340,13 @@ func (i *Inode) Truncate(ctx context.Context, d *Dirent, size int64) error { return i.InodeOperations.Truncate(ctx, i, size) } +func (i *Inode) Allocate(ctx context.Context, d *Dirent, offset int64, length int64) error { + if i.overlay != nil { + return overlayAllocate(ctx, i.overlay, d, offset, length) + } + return i.InodeOperations.Allocate(ctx, i, offset, length) +} + // Readlink calls i.InodeOperations.Readlnk with i as the Inode. func (i *Inode) Readlink(ctx context.Context) (string, error) { if i.overlay != nil { diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go index ac287e1e4..abafe4791 100644 --- a/pkg/sentry/fs/inode_operations.go +++ b/pkg/sentry/fs/inode_operations.go @@ -223,6 +223,10 @@ type InodeOperations interface { // Implementations need not check that length >= 0. Truncate(ctx context.Context, inode *Inode, size int64) error + // Allocate allows the caller to reserve disk space for the inode. + // It's equivalent to fallocate(2) with 'mode=0'. + Allocate(ctx context.Context, inode *Inode, offset int64, length int64) error + // WriteOut writes cached Inode state to a backing filesystem in a // synchronous manner. // diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go index 3d015328e..ead487097 100644 --- a/pkg/sentry/fs/inode_overlay.go +++ b/pkg/sentry/fs/inode_overlay.go @@ -582,6 +582,13 @@ func overlayTruncate(ctx context.Context, o *overlayEntry, d *Dirent, size int64 return o.upper.InodeOperations.Truncate(ctx, o.upper, size) } +func overlayAllocate(ctx context.Context, o *overlayEntry, d *Dirent, offset, length int64) error { + if err := copyUp(ctx, d); err != nil { + return err + } + return o.upper.InodeOperations.Allocate(ctx, o.upper, offset, length) +} + func overlayReadlink(ctx context.Context, o *overlayEntry) (string, error) { o.copyMu.RLock() defer o.copyMu.RUnlock() diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go index 66b3da2d0..52ce1d29e 100644 --- a/pkg/sentry/fs/inode_overlay_test.go +++ b/pkg/sentry/fs/inode_overlay_test.go @@ -422,6 +422,7 @@ type inode struct { fsutil.InodeNoExtendedAttributes `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go index cf359a1f1..a71144b2c 100644 --- a/pkg/sentry/fs/mock.go +++ b/pkg/sentry/fs/mock.go @@ -150,6 +150,11 @@ func (n *MockInodeOperations) Truncate(ctx context.Context, inode *Inode, size i return nil } +// Allocate implements fs.InodeOperations.Allocate. +func (n *MockInodeOperations) Allocate(ctx context.Context, inode *Inode, offset, length int64) error { + return nil +} + // Remove implements fs.InodeOperations.Remove. func (n *MockInodeOperations) Remove(context.Context, *Inode, string) error { return nil diff --git a/pkg/sentry/fs/proc/inode.go b/pkg/sentry/fs/proc/inode.go index b03807043..379569823 100644 --- a/pkg/sentry/fs/proc/inode.go +++ b/pkg/sentry/fs/proc/inode.go @@ -55,6 +55,7 @@ func (i *taskOwnedInodeOps) UnstableAttr(ctx context.Context, inode *fs.Inode) ( type staticFileInodeOps struct { fsutil.InodeDenyWriteChecker `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` + fsutil.InodeNoopAllocate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopTruncate `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 10ea1f55d..6b0ae9e60 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -93,6 +93,7 @@ type SeqFile struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` @@ -183,7 +184,6 @@ func (s *SeqFile) updateSourceLocked(ctx context.Context, record int) { // // +stateify savable type seqFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` @@ -192,6 +192,7 @@ type seqFileOperations struct { fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` seqFile *SeqFile } diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index d649da0f1..5df3cee13 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -38,6 +38,7 @@ type idMapInodeOperations struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` @@ -81,7 +82,6 @@ func (imio *idMapInodeOperations) GetFile(ctx context.Context, dirent *fs.Dirent // +stateify savable type idMapFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` @@ -90,6 +90,7 @@ type idMapFileOperations struct { fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` iops *idMapInodeOperations } diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index a6b6a5c33..eb98b59cc 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -50,6 +50,7 @@ type CreateOps struct { // +stateify savable type Dir struct { fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeIsDirAllocate `state:"nosave"` fsutil.InodeIsDirTruncate `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index 9406a07ca..a7cb1bb86 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -30,6 +30,7 @@ type Socket struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSymlink `state:"nosave"` @@ -67,7 +68,6 @@ func (s *Socket) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFl // +stateify savable type socketFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` @@ -78,6 +78,7 @@ type socketFileOperations struct { fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*socketFileOperations)(nil) diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index f7835fe05..dd2585b02 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -29,10 +29,11 @@ type Symlink struct { fsutil.InodeGenericChecker `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` - fsutil.InodeNotTruncatable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` + fsutil.InodeNotTruncatable `state:"nosave"` fsutil.InodeVirtual `state:"nosave"` fsutil.InodeSimpleAttributes @@ -88,7 +89,6 @@ func (s *Symlink) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileF // +stateify savable type symlinkFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` @@ -99,6 +99,7 @@ type symlinkFileOperations struct { fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*symlinkFileOperations)(nil) diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go index db91de435..bacc93af8 100644 --- a/pkg/sentry/fs/sys/devices.go +++ b/pkg/sentry/fs/sys/devices.go @@ -30,12 +30,13 @@ type cpunum struct { fsutil.InodeNoExtendedAttributes `state:"nosave"` fsutil.InodeNoopRelease `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` fsutil.InodeNotDirectory `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` fsutil.InodeNotSymlink `state:"nosave"` - fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeNotVirtual `state:"nosave"` fsutil.InodeSimpleAttributes fsutil.InodeStaticFileGetter diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go index f89d86c83..c90062a22 100644 --- a/pkg/sentry/fs/tmpfs/inode_file.go +++ b/pkg/sentry/fs/tmpfs/inode_file.go @@ -259,6 +259,33 @@ func (f *fileInodeOperations) Truncate(ctx context.Context, _ *fs.Inode, size in return nil } +// Allocate implements fs.InodeOperations.Allocate. +func (f *fileInodeOperations) Allocate(ctx context.Context, _ *fs.Inode, offset, length int64) error { + newSize := offset + length + + f.attrMu.Lock() + defer f.attrMu.Unlock() + f.dataMu.Lock() + defer f.dataMu.Unlock() + + if newSize <= f.attr.Size { + return nil + } + + // Check if current seals allow growth. + if f.seals&linux.F_SEAL_GROW != 0 { + return syserror.EPERM + } + + f.attr.Size = newSize + + now := ktime.NowFromContext(ctx) + f.attr.ModificationTime = now + f.attr.StatusChangeTime = now + + return nil +} + // AddLink implements fs.InodeOperations.AddLink. func (f *fileInodeOperations) AddLink() { f.attrMu.Lock() diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go index 832914453..6ad5c5adb 100644 --- a/pkg/sentry/fs/tmpfs/tmpfs.go +++ b/pkg/sentry/fs/tmpfs/tmpfs.go @@ -242,11 +242,16 @@ func (d *Dir) Rename(ctx context.Context, oldParent *fs.Inode, oldName string, n return rename(ctx, oldParent, oldName, newParent, newName, replacement) } -// StatFS implments fs.InodeOperations.StatFS. +// StatFS implements fs.InodeOperations.StatFS. func (*Dir) StatFS(context.Context) (fs.Info, error) { return fsInfo, nil } +// Allocate implements fs.InodeOperations.Allocate. +func (d *Dir) Allocate(ctx context.Context, node *fs.Inode, offset, length int64) error { + return d.ramfsDir.Allocate(ctx, node, offset, length) +} + // Symlink is a symlink. // // +stateify savable @@ -281,6 +286,7 @@ func (s *Symlink) StatFS(context.Context) (fs.Info, error) { type Socket struct { ramfs.Socket fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeNotAllocatable `state:"nosave"` } // NewSocket returns a new socket with the provided permissions. diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 0fc777e67..8dc40e1f2 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -53,13 +53,14 @@ import ( // +stateify savable type dirInodeOperations struct { fsutil.InodeGenericChecker `state:"nosave"` + fsutil.InodeIsDirAllocate `state:"nosave"` + fsutil.InodeIsDirTruncate `state:"nosave"` fsutil.InodeNoExtendedAttributes `state:"nosave"` fsutil.InodeNoopWriteOut `state:"nosave"` fsutil.InodeNotMappable `state:"nosave"` fsutil.InodeNotRenameable `state:"nosave"` - fsutil.InodeNotSymlink `state:"nosave"` fsutil.InodeNotSocket `state:"nosave"` - fsutil.InodeNotTruncatable `state:"nosave"` + fsutil.InodeNotSymlink `state:"nosave"` fsutil.InodeVirtual `state:"nosave"` fsutil.InodeSimpleAttributes diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 99188dddf..7c3739360 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -191,3 +191,7 @@ func (*inodeOperations) newHandleLocked(wakeupChan *chan struct{}) { *wakeupChan = nil } } + +func (*inodeOperations) Allocate(_ context.Context, _ *fs.Inode, _, _ int64) error { + return syserror.EPIPE +} diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 893322647..1764bb4b6 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -1900,9 +1900,9 @@ func Renameat(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc } // Fallocate implements linux system call fallocate(2). -// (well, not really, but at least we return the expected error codes) func Fallocate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { fd := kdefs.FD(args[0].Int()) + mode := args[1].Int64() offset := args[2].Int64() length := args[3].Int64() @@ -1915,8 +1915,42 @@ func Fallocate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys if offset < 0 || length <= 0 { return 0, nil, syserror.EINVAL } + if mode != 0 { + t.Kernel().EmitUnimplementedEvent(t) + return 0, nil, syserror.ENOTSUP + } + if !file.Flags().Write { + return 0, nil, syserror.EBADF + } + if fs.IsPipe(file.Dirent.Inode.StableAttr) { + return 0, nil, syserror.ESPIPE + } + if fs.IsDir(file.Dirent.Inode.StableAttr) { + return 0, nil, syserror.EISDIR + } + if !fs.IsRegular(file.Dirent.Inode.StableAttr) { + return 0, nil, syserror.ENODEV + } + size := offset + length + if size < 0 { + return 0, nil, syserror.EFBIG + } + if uint64(size) >= t.ThreadGroup().Limits().Get(limits.FileSize).Cur { + t.SendSignal(&arch.SignalInfo{ + Signo: int32(syscall.SIGXFSZ), + Code: arch.SignalInfoUser, + }) + return 0, nil, syserror.EFBIG + } + + if err := file.Dirent.Inode.Allocate(t, file.Dirent, offset, length); err != nil { + return 0, nil, err + } + + // File length modified, generate notification. + file.Dirent.InotifyEvent(linux.IN_MODIFY, 0) - return 0, nil, syserror.EOPNOTSUPP + return 0, nil, nil } // Flock implements linux syscall flock(2). diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go index c1b33c551..c369e4d64 100644 --- a/runsc/boot/compat.go +++ b/runsc/boot/compat.go @@ -99,7 +99,7 @@ func (c *compatEmitter) emitUnimplementedSyscall(us *spb.UnimplementedSyscall) { // args: cmd, ... tr = newArgsTracker(0) - case syscall.SYS_IOCTL, syscall.SYS_EPOLL_CTL, syscall.SYS_SHMCTL, syscall.SYS_FUTEX: + case syscall.SYS_IOCTL, syscall.SYS_EPOLL_CTL, syscall.SYS_SHMCTL, syscall.SYS_FUTEX, syscall.SYS_FALLOCATE: // args: fd/addr, cmd, ... tr = newArgsTracker(1) diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index a1ad49fb2..4faab2946 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -62,8 +62,14 @@ var allowedSyscalls = seccomp.SyscallRules{ }, syscall.SYS_EXIT: {}, syscall.SYS_EXIT_GROUP: {}, - syscall.SYS_FCHMOD: {}, - syscall.SYS_FCHOWNAT: {}, + syscall.SYS_FALLOCATE: []seccomp.Rule{ + { + seccomp.AllowAny{}, + seccomp.AllowValue(0), + }, + }, + syscall.SYS_FCHMOD: {}, + syscall.SYS_FCHOWNAT: {}, syscall.SYS_FCNTL: []seccomp.Rule{ { seccomp.AllowAny{}, diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index 3a0806837..b185015b6 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -731,6 +731,18 @@ func (l *localFile) SetAttr(valid p9.SetAttrMask, attr p9.SetAttr) error { return err } +// Allocate implements p9.File. +func (l *localFile) Allocate(mode p9.AllocateMode, offset, length uint64) error { + if !l.isOpen() { + return syscall.EBADF + } + + if err := syscall.Fallocate(l.file.FD(), mode.ToLinux(), int64(offset), int64(length)); err != nil { + return extractErrno(err) + } + return nil +} + // Rename implements p9.File; this should never be called. func (l *localFile) Rename(p9.File, string) error { panic("rename called directly") diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index d99733fc9..7ff4e4883 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -649,6 +649,8 @@ cc_binary( srcs = ["fallocate.cc"], linkstatic = 1, deps = [ + ":file_base", + "//test/util:cleanup", "//test/util:file_descriptor", "//test/util:temp_path", "//test/util:test_main", diff --git a/test/syscalls/linux/fallocate.cc b/test/syscalls/linux/fallocate.cc index 61b8acc7a..1c3d00287 100644 --- a/test/syscalls/linux/fallocate.cc +++ b/test/syscalls/linux/fallocate.cc @@ -12,45 +12,130 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include +#include +#include +#include +#include #include #include "gtest/gtest.h" +#include "test/syscalls/linux/file_base.h" +#include "test/util/cleanup.h" #include "test/util/file_descriptor.h" #include "test/util/temp_path.h" #include "test/util/test_util.h" namespace gvisor { namespace testing { - namespace { -// These tests are very rudimentary because fallocate is not -// implemented. We just want to make sure the expected error codes are -// returned. +int fallocate(int fd, int mode, off_t offset, off_t len) { + return syscall(__NR_fallocate, fd, mode, offset, len); +} + +class AllocateTest : public FileTest { + void SetUp() override { FileTest::SetUp(); } +}; + +TEST_F(AllocateTest, Fallocate) { + // Check that it starts at size zero. + struct stat buf; + ASSERT_THAT(fstat(test_file_fd_.get(), &buf), SyscallSucceeds()); + EXPECT_EQ(buf.st_size, 0); + + // Grow to ten bytes. + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 0, 10), SyscallSucceeds()); + ASSERT_THAT(fstat(test_file_fd_.get(), &buf), SyscallSucceeds()); + EXPECT_EQ(buf.st_size, 10); -TEST(FallocateTest, NotImplemented) { - auto temp_path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(temp_path.path(), O_RDWR)); + // Allocate to a smaller size should be noop. + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 0, 5), SyscallSucceeds()); + ASSERT_THAT(fstat(test_file_fd_.get(), &buf), SyscallSucceeds()); + EXPECT_EQ(buf.st_size, 10); - // Test that a completely unassigned fallocate mode returns EOPNOTSUPP. - ASSERT_THAT(fallocate(fd.get(), 0x80, 0, 32768), - SyscallFailsWithErrno(EOPNOTSUPP)); + // Grow again. + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 0, 20), SyscallSucceeds()); + ASSERT_THAT(fstat(test_file_fd_.get(), &buf), SyscallSucceeds()); + EXPECT_EQ(buf.st_size, 20); + + // Grow with offset. + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 10, 20), SyscallSucceeds()); + ASSERT_THAT(fstat(test_file_fd_.get(), &buf), SyscallSucceeds()); + EXPECT_EQ(buf.st_size, 30); + + // Grow with offset beyond EOF. + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 39, 1), SyscallSucceeds()); + ASSERT_THAT(fstat(test_file_fd_.get(), &buf), SyscallSucceeds()); + EXPECT_EQ(buf.st_size, 40); } -TEST(FallocateTest, BadOffset) { - auto temp_path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(temp_path.path(), O_RDWR)); - ASSERT_THAT(fallocate(fd.get(), 0, -1, 32768), SyscallFailsWithErrno(EINVAL)); +TEST_F(AllocateTest, FallocateInvalid) { + // Invalid FD + EXPECT_THAT(fallocate(-1, 0, 0, 10), SyscallFailsWithErrno(EBADF)); + + // Negative offset and size. + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, -1, 10), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 0, -1), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, -1, -1), + SyscallFailsWithErrno(EINVAL)); } -TEST(FallocateTest, BadLength) { - auto temp_path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(temp_path.path(), O_RDWR)); - ASSERT_THAT(fallocate(fd.get(), 0, 0, -1), SyscallFailsWithErrno(EINVAL)); +TEST_F(AllocateTest, FallocateReadonly) { + auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY)); + EXPECT_THAT(fallocate(fd.get(), 0, 0, 10), SyscallFailsWithErrno(EBADF)); } -} // namespace +TEST_F(AllocateTest, FallocatePipe) { + int pipes[2]; + EXPECT_THAT(pipe(pipes), SyscallSucceeds()); + auto cleanup = Cleanup([&pipes] { + EXPECT_THAT(close(pipes[0]), SyscallSucceeds()); + EXPECT_THAT(close(pipes[1]), SyscallSucceeds()); + }); + + EXPECT_THAT(fallocate(pipes[1], 0, 0, 10), SyscallFailsWithErrno(ESPIPE)); +} + +TEST_F(AllocateTest, FallocateChar) { + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDWR)); + EXPECT_THAT(fallocate(fd.get(), 0, 0, 10), SyscallFailsWithErrno(ENODEV)); +} + +TEST_F(AllocateTest, FallocateRlimit) { + // Get the current rlimit and restore after test run. + struct rlimit initial_lim; + ASSERT_THAT(getrlimit(RLIMIT_FSIZE, &initial_lim), SyscallSucceeds()); + auto cleanup = Cleanup([&initial_lim] { + EXPECT_THAT(setrlimit(RLIMIT_FSIZE, &initial_lim), SyscallSucceeds()); + }); + + // Try growing past the file size limit. + sigset_t new_mask; + sigemptyset(&new_mask); + sigaddset(&new_mask, SIGXFSZ); + sigprocmask(SIG_BLOCK, &new_mask, nullptr); + struct rlimit setlim = {}; + setlim.rlim_cur = 1024; + setlim.rlim_max = RLIM_INFINITY; + ASSERT_THAT(setrlimit(RLIMIT_FSIZE, &setlim), SyscallSucceeds()); + + EXPECT_THAT(fallocate(test_file_fd_.get(), 0, 0, 1025), + SyscallFailsWithErrno(EFBIG)); + + struct timespec timelimit = {}; + timelimit.tv_sec = 10; + EXPECT_EQ(sigtimedwait(&new_mask, nullptr, &timelimit), SIGXFSZ); + ASSERT_THAT(sigprocmask(SIG_UNBLOCK, &new_mask, nullptr), SyscallSucceeds()); +} + +} // namespace } // namespace testing } // namespace gvisor -- cgit v1.2.3 From 9cdae51feca5cee9faa198161b92a0aeece52d6c Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Tue, 21 May 2019 15:17:05 -0700 Subject: Add basic plumbing for splice and stub implementation. This does not actually implement an efficient splice or sendfile. Rather, it adds a generic plumbing to the file internals so that this can be added. All file implementations use the stub fileutil.NoSplice implementation, which causes sendfile and splice to fall back to an internal copy. A basic splice system call interface is added, along with a test. PiperOrigin-RevId: 249335960 Change-Id: Ic5568be2af0a505c19e7aec66d5af2480ab0939b --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/splice.go | 23 ++ pkg/sentry/fs/BUILD | 4 +- pkg/sentry/fs/ashmem/area.go | 3 +- pkg/sentry/fs/binder/binder.go | 3 +- pkg/sentry/fs/dev/full.go | 3 +- pkg/sentry/fs/dev/null.go | 4 +- pkg/sentry/fs/dev/random.go | 1 + pkg/sentry/fs/fdpipe/pipe.go | 1 + pkg/sentry/fs/file.go | 139 +++++++---- pkg/sentry/fs/file_operations.go | 47 ++++ pkg/sentry/fs/file_overlay.go | 79 ++++--- pkg/sentry/fs/file_test.go | 24 -- pkg/sentry/fs/filetest/filetest.go | 1 + pkg/sentry/fs/fsutil/file.go | 16 ++ pkg/sentry/fs/fsutil/inode.go | 3 +- pkg/sentry/fs/gofer/file.go | 5 +- pkg/sentry/fs/host/file.go | 1 + pkg/sentry/fs/inotify.go | 10 + pkg/sentry/fs/proc/exec_args.go | 3 +- pkg/sentry/fs/proc/rpcinet_proc.go | 3 +- pkg/sentry/fs/proc/seqfile/seqfile.go | 1 + pkg/sentry/fs/proc/sys.go | 3 +- pkg/sentry/fs/proc/sys_net.go | 6 +- pkg/sentry/fs/proc/task.go | 10 +- pkg/sentry/fs/proc/uid_gid_map.go | 1 + pkg/sentry/fs/proc/uptime.go | 5 +- pkg/sentry/fs/ramfs/socket.go | 7 +- pkg/sentry/fs/ramfs/symlink.go | 7 +- pkg/sentry/fs/splice.go | 187 +++++++++++++++ pkg/sentry/fs/timerfd/timerfd.go | 5 +- pkg/sentry/fs/tmpfs/file_regular.go | 3 +- pkg/sentry/fs/tty/dir.go | 3 +- pkg/sentry/fs/tty/master.go | 3 +- pkg/sentry/fs/tty/slave.go | 3 +- pkg/sentry/kernel/epoll/epoll.go | 3 +- pkg/sentry/kernel/eventfd/eventfd.go | 5 +- pkg/sentry/kernel/pipe/reader_writer.go | 3 +- pkg/sentry/loader/vdso.go | 3 +- pkg/sentry/socket/epsocket/epsocket.go | 3 +- pkg/sentry/socket/hostinet/socket.go | 3 +- pkg/sentry/socket/netlink/socket.go | 3 +- pkg/sentry/socket/rpcinet/socket.go | 3 +- pkg/sentry/socket/unix/unix.go | 3 +- pkg/sentry/syscalls/linux/BUILD | 1 + pkg/sentry/syscalls/linux/linux64.go | 2 +- pkg/sentry/syscalls/linux/sys_file.go | 98 -------- pkg/sentry/syscalls/linux/sys_splice.go | 293 +++++++++++++++++++++++ test/syscalls/BUILD | 2 + test/syscalls/linux/BUILD | 16 ++ test/syscalls/linux/splice.cc | 404 ++++++++++++++++++++++++++++++++ 51 files changed, 1221 insertions(+), 242 deletions(-) create mode 100644 pkg/abi/linux/splice.go delete mode 100644 pkg/sentry/fs/file_test.go create mode 100644 pkg/sentry/fs/splice.go create mode 100644 pkg/sentry/syscalls/linux/sys_splice.go create mode 100644 test/syscalls/linux/splice.cc (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index fdf193873..96e8d4641 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -45,6 +45,7 @@ go_library( "shm.go", "signal.go", "socket.go", + "splice.go", "tcp.go", "time.go", "timer.go", diff --git a/pkg/abi/linux/splice.go b/pkg/abi/linux/splice.go new file mode 100644 index 000000000..650eb87e8 --- /dev/null +++ b/pkg/abi/linux/splice.go @@ -0,0 +1,23 @@ +// Copyright 2019 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 linux + +// Constants for splice(2), sendfile(2) and tee(2). +const ( + SPLICE_F_MOVE = 1 << iota + SPLICE_F_NONBLOCK + SPLICE_F_MORE + SPLICE_F_GIFT +) diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 1fd9e30f6..142a00840 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -40,6 +40,7 @@ go_library( "restore.go", "save.go", "seek.go", + "splice.go", "sync.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs", @@ -51,6 +52,7 @@ go_library( "//pkg/metric", "//pkg/p9", "//pkg/refs", + "//pkg/secio", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", @@ -66,7 +68,6 @@ go_library( "//pkg/sentry/usermem", "//pkg/state", "//pkg/syserror", - "//pkg/tcpip", "//pkg/waiter", ], ) @@ -122,7 +123,6 @@ go_test( srcs = [ "dirent_cache_test.go", "dirent_refs_test.go", - "file_test.go", "mount_test.go", "path_test.go", ], diff --git a/pkg/sentry/fs/ashmem/area.go b/pkg/sentry/fs/ashmem/area.go index b53746519..b4b0cc08b 100644 --- a/pkg/sentry/fs/ashmem/area.go +++ b/pkg/sentry/fs/ashmem/area.go @@ -42,11 +42,12 @@ const ( // // +stateify savable type Area struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` ad *Device diff --git a/pkg/sentry/fs/binder/binder.go b/pkg/sentry/fs/binder/binder.go index a992253e6..c78f1fc40 100644 --- a/pkg/sentry/fs/binder/binder.go +++ b/pkg/sentry/fs/binder/binder.go @@ -86,10 +86,11 @@ func (bd *Device) GetFile(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) // // +stateify savable type Proc struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` bd *Device task *kernel.Task diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go index 17d68b5c4..8f6c6da2d 100644 --- a/pkg/sentry/fs/dev/full.go +++ b/pkg/sentry/fs/dev/full.go @@ -60,6 +60,7 @@ func (f *fullDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.Fi // +stateify savable type fullFileOperations struct { + waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` @@ -68,8 +69,8 @@ type fullFileOperations struct { fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` readZeros `state:"nosave"` - waiter.AlwaysReady `state:"nosave"` } var _ fs.FileOperations = (*fullFileOperations)(nil) diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go index ee13183c8..3f1accef8 100644 --- a/pkg/sentry/fs/dev/null.go +++ b/pkg/sentry/fs/dev/null.go @@ -64,6 +64,7 @@ type nullFileOperations struct { fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRead `state:"nosave"` @@ -104,14 +105,15 @@ func (zd *zeroDevice) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.F type zeroFileOperations struct { fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNoopWrite `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` - readZeros `state:"nosave"` waiter.AlwaysReady `state:"nosave"` + readZeros `state:"nosave"` } var _ fs.FileOperations = (*zeroFileOperations)(nil) diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go index b0a412382..e5a01a906 100644 --- a/pkg/sentry/fs/dev/random.go +++ b/pkg/sentry/fs/dev/random.go @@ -61,6 +61,7 @@ type randomFileOperations struct { fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 95e66ea8d..4ef7ea08a 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -43,6 +43,7 @@ type pipeOperations struct { fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` waiter.Queue `state:"nosave"` diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go index 62b35dabc..8f1baca23 100644 --- a/pkg/sentry/fs/file.go +++ b/pkg/sentry/fs/file.go @@ -21,7 +21,6 @@ import ( "time" "gvisor.googlesource.com/gvisor/pkg/amutex" - "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/metric" "gvisor.googlesource.com/gvisor/pkg/refs" "gvisor.googlesource.com/gvisor/pkg/sentry/context" @@ -35,8 +34,13 @@ import ( ) var ( - // RecordWaitTime controls writing metrics for filesystem reads. Enabling this comes at a small - // CPU cost due to performing two monotonic clock reads per read call. + // RecordWaitTime controls writing metrics for filesystem reads. + // Enabling this comes at a small CPU cost due to performing two + // monotonic clock reads per read call. + // + // Note that this is only performed in the direct read path, and may + // not be consistently applied for other forms of reads, such as + // splice. RecordWaitTime = false reads = metric.MustCreateNewUint64Metric("/fs/reads", false /* sync */, "Number of file reads.") @@ -306,14 +310,28 @@ func (f *File) Writev(ctx context.Context, src usermem.IOSequence) (int64, error return 0, syserror.ErrInterrupted } - offset, err := f.checkWriteLocked(ctx, &src, f.offset) - if err != nil { + // Handle append mode. + if f.Flags().Append { + if err := f.offsetForAppend(ctx, &f.offset); err != nil { + f.mu.Unlock() + return 0, err + } + } + + // Enforce file limits. + limit, ok := f.checkLimit(ctx, f.offset) + switch { + case ok && limit == 0: f.mu.Unlock() - return 0, err + return 0, syserror.ErrExceedsFileSizeLimit + case ok: + src = src.TakeFirst64(limit) } - n, err := f.FileOperations.Write(ctx, f, src, offset) + + // We must hold the lock during the write. + n, err := f.FileOperations.Write(ctx, f, src, f.offset) if n >= 0 { - atomic.StoreInt64(&f.offset, offset+n) + atomic.StoreInt64(&f.offset, f.offset+n) } f.mu.Unlock() return n, err @@ -325,51 +343,67 @@ func (f *File) Writev(ctx context.Context, src usermem.IOSequence) (int64, error // // Otherwise same as Writev. func (f *File) Pwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) { - if !f.mu.Lock(ctx) { - return 0, syserror.ErrInterrupted + // "POSIX requires that opening a file with the O_APPEND flag should + // have no effect on the location at which pwrite() writes data. + // However, on Linux, if a file is opened with O_APPEND, pwrite() + // appends data to the end of the file, regardless of the value of + // offset." + if f.Flags().Append { + if !f.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer f.mu.Unlock() + if err := f.offsetForAppend(ctx, &offset); err != nil { + f.mu.Unlock() + return 0, err + } } - offset, err := f.checkWriteLocked(ctx, &src, offset) - if err != nil { - f.mu.Unlock() - return 0, err + // Enforce file limits. + limit, ok := f.checkLimit(ctx, offset) + switch { + case ok && limit == 0: + return 0, syserror.ErrExceedsFileSizeLimit + case ok: + src = src.TakeFirst64(limit) } - n, err := f.FileOperations.Write(ctx, f, src, offset) - f.mu.Unlock() - return n, err + + return f.FileOperations.Write(ctx, f, src, offset) } -// checkWriteLocked returns the offset to write at or an error if the write -// would not succeed. May update src to fit a write operation into a file -// size limit. -func (f *File) checkWriteLocked(ctx context.Context, src *usermem.IOSequence, offset int64) (int64, error) { - // Handle append only files. Note that this is still racy for network - // filesystems. - if f.Flags().Append { - uattr, err := f.Dirent.Inode.UnstableAttr(ctx) - if err != nil { - // This is an odd error, most likely it is evidence - // that something is terribly wrong with the filesystem. - // Return a generic EIO error. - log.Warningf("Failed to check write of inode %#v: %v", f.Dirent.Inode.StableAttr, err) - return offset, syserror.EIO - } - offset = uattr.Size +// offsetForAppend sets the given offset to the end of the file. +// +// Precondition: the underlying file mutex should be held. +func (f *File) offsetForAppend(ctx context.Context, offset *int64) error { + uattr, err := f.Dirent.Inode.UnstableAttr(ctx) + if err != nil { + // This is an odd error, we treat it as evidence that + // something is terribly wrong with the filesystem. + return syserror.EIO } - // Is this a regular file? + // Update the offset. + *offset = uattr.Size + + return nil +} + +// checkLimit checks the offset that the write will be performed at. The +// returned boolean indicates that the write must be limited. The returned +// integer indicates the new maximum write length. +func (f *File) checkLimit(ctx context.Context, offset int64) (int64, bool) { if IsRegular(f.Dirent.Inode.StableAttr) { // Enforce size limits. fileSizeLimit := limits.FromContext(ctx).Get(limits.FileSize).Cur if fileSizeLimit <= math.MaxInt64 { if offset >= int64(fileSizeLimit) { - return offset, syserror.ErrExceedsFileSizeLimit + return 0, true } - *src = src.TakeFirst64(int64(fileSizeLimit) - offset) + return int64(fileSizeLimit) - offset, true } } - return offset, nil + return 0, false } // Fsync calls f.FileOperations.Fsync with f as the File. @@ -466,8 +500,13 @@ func (f *File) Async(newAsync func() FileAsync) FileAsync { return f.async } -// FileReader implements io.Reader and io.ReaderAt. -type FileReader struct { +// lockedReader implements io.Reader and io.ReaderAt. +// +// Note this reads the underlying file using the file operations directly. It +// is the responsibility of the caller to ensure that locks are appropriately +// held and offsets updated if required. This should be used only by internal +// functions that perform these operations and checks at other times. +type lockedReader struct { // Ctx is the context for the file reader. Ctx context.Context @@ -476,19 +515,21 @@ type FileReader struct { } // Read implements io.Reader.Read. -func (r *FileReader) Read(buf []byte) (int, error) { - n, err := r.File.Readv(r.Ctx, usermem.BytesIOSequence(buf)) +func (r *lockedReader) Read(buf []byte) (int, error) { + n, err := r.File.FileOperations.Read(r.Ctx, r.File, usermem.BytesIOSequence(buf), r.File.offset) return int(n), err } // ReadAt implements io.Reader.ReadAt. -func (r *FileReader) ReadAt(buf []byte, offset int64) (int, error) { - n, err := r.File.Preadv(r.Ctx, usermem.BytesIOSequence(buf), offset) +func (r *lockedReader) ReadAt(buf []byte, offset int64) (int, error) { + n, err := r.File.FileOperations.Read(r.Ctx, r.File, usermem.BytesIOSequence(buf), offset) return int(n), err } -// FileWriter implements io.Writer and io.WriterAt. -type FileWriter struct { +// lockedWriter implements io.Writer and io.WriterAt. +// +// The same constraints as lockedReader apply; see above. +type lockedWriter struct { // Ctx is the context for the file writer. Ctx context.Context @@ -497,13 +538,13 @@ type FileWriter struct { } // Write implements io.Writer.Write. -func (w *FileWriter) Write(buf []byte) (int, error) { - n, err := w.File.Writev(w.Ctx, usermem.BytesIOSequence(buf)) +func (w *lockedWriter) Write(buf []byte) (int, error) { + n, err := w.File.FileOperations.Write(w.Ctx, w.File, usermem.BytesIOSequence(buf), w.File.offset) return int(n), err } // WriteAt implements io.Writer.WriteAt. -func (w *FileWriter) WriteAt(buf []byte, offset int64) (int, error) { - n, err := w.File.Pwritev(w.Ctx, usermem.BytesIOSequence(buf), offset) +func (w *lockedWriter) WriteAt(buf []byte, offset int64) (int, error) { + n, err := w.File.FileOperations.Write(w.Ctx, w.File, usermem.BytesIOSequence(buf), offset) return int(n), err } diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go index ab0acb6eb..0f2dfa273 100644 --- a/pkg/sentry/fs/file_operations.go +++ b/pkg/sentry/fs/file_operations.go @@ -22,6 +22,38 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) +// SpliceOpts define how a splice works. +type SpliceOpts struct { + // Length is the length of the splice operation. + Length int64 + + // SrcOffset indicates whether the existing source file offset should + // be used. If this is true, then the Start value below is used. + // + // When passed to FileOperations object, this should always be true as + // the offset will be provided by a layer above, unless the object in + // question is a pipe or socket. This value can be relied upon for such + // an indicator. + SrcOffset bool + + // SrcStart is the start of the source file. This is used only if + // SrcOffset is false. + SrcStart int64 + + // Dup indicates that the contents should not be consumed from the + // source (e.g. in the case of a socket or a pipe), but duplicated. + Dup bool + + // DstOffset indicates that the destination file offset should be used. + // + // See SrcOffset for additional information. + DstOffset bool + + // DstStart is the start of the destination file. This is used only if + // DstOffset is false. + DstStart int64 +} + // FileOperations are operations on a File that diverge per file system. // // Operations that take a *File may use only the following interfaces: @@ -67,6 +99,15 @@ type FileOperations interface { // Read must not be called if !FileFlags.Read. Read(ctx context.Context, file *File, dst usermem.IOSequence, offset int64) (int64, error) + // WriteTo is a variant of read that takes another file as a + // destination. For a splice (copy or move from one file to another), + // first a WriteTo on the source is attempted, followed by a ReadFrom + // on the destination, following by a buffered copy with standard Read + // and Write operations. + // + // The same preconditions as Read apply. + WriteTo(ctx context.Context, file *File, dst *File, opts SpliceOpts) (int64, error) + // Write writes src to file at offset and returns the number of bytes // written which must be greater than or equal to 0. Like Read, file // systems that do not support writing at an offset (i.e. pipefs, sockfs) @@ -81,6 +122,12 @@ type FileOperations interface { // Write must not be called if !FileFlags.Write. Write(ctx context.Context, file *File, src usermem.IOSequence, offset int64) (int64, error) + // ReadFrom is a variant of write that takes a another file as a + // source. See WriteTo for details regarding how this is called. + // + // The same preconditions as Write apply; FileFlags.Write must be set. + ReadFrom(ctx context.Context, file *File, src *File, opts SpliceOpts) (int64, error) + // Fsync writes buffered modifications of file and/or flushes in-flight // operations to backing storage based on syncType. The range to sync is // [start, end]. The end is inclusive so that the last byte of a maximally diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go index 948ce9c6f..273de1e14 100644 --- a/pkg/sentry/fs/file_overlay.go +++ b/pkg/sentry/fs/file_overlay.go @@ -17,7 +17,6 @@ package fs import ( "sync" - "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/refs" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" @@ -222,31 +221,50 @@ func (f *overlayFileOperations) IterateDir(ctx context.Context, dirCtx *DirCtx, return offset + n, err } -// Read implements FileOperations.Read. -func (f *overlayFileOperations) Read(ctx context.Context, file *File, dst usermem.IOSequence, offset int64) (int64, error) { - o := file.Dirent.Inode.overlay +// onTop performs the given operation on the top-most available layer. +func (f *overlayFileOperations) onTop(ctx context.Context, file *File, fn func(*File, FileOperations) error) error { + file.Dirent.Inode.overlay.copyMu.RLock() + defer file.Dirent.Inode.overlay.copyMu.RUnlock() - o.copyMu.RLock() - defer o.copyMu.RUnlock() + // Only lower layer is available. + if file.Dirent.Inode.overlay.upper == nil { + return fn(f.lower, f.lower.FileOperations) + } - if o.upper != nil { - // We may need to acquire an open file handle to read from if - // copy up has occurred. Otherwise we risk reading from the - // wrong source. - f.upperMu.Lock() - if f.upper == nil { - var err error - f.upper, err = overlayFile(ctx, o.upper, file.Flags()) - if err != nil { - f.upperMu.Unlock() - log.Warningf("failed to acquire handle with flags %v: %v", file.Flags(), err) - return 0, syserror.EIO - } + f.upperMu.Lock() + if f.upper == nil { + upper, err := overlayFile(ctx, file.Dirent.Inode.overlay.upper, file.Flags()) + if err != nil { + // Something very wrong; return a generic filesystem + // error to avoid propagating internals. + f.upperMu.Unlock() + return syserror.EIO } - f.upperMu.Unlock() - return f.upper.FileOperations.Read(ctx, f.upper, dst, offset) + + // Save upper file. + f.upper = upper } - return f.lower.FileOperations.Read(ctx, f.lower, dst, offset) + f.upperMu.Unlock() + + return fn(f.upper, f.upper.FileOperations) +} + +// Read implements FileOperations.Read. +func (f *overlayFileOperations) Read(ctx context.Context, file *File, dst usermem.IOSequence, offset int64) (n int64, err error) { + err = f.onTop(ctx, file, func(file *File, ops FileOperations) error { + n, err = ops.Read(ctx, file, dst, offset) + return err // Will overwrite itself. + }) + return +} + +// WriteTo implements FileOperations.WriteTo. +func (f *overlayFileOperations) WriteTo(ctx context.Context, file *File, dst *File, opts SpliceOpts) (n int64, err error) { + err = f.onTop(ctx, file, func(file *File, ops FileOperations) error { + n, err = ops.WriteTo(ctx, file, dst, opts) + return err // Will overwrite itself. + }) + return } // Write implements FileOperations.Write. @@ -257,15 +275,20 @@ func (f *overlayFileOperations) Write(ctx context.Context, file *File, src userm return f.upper.FileOperations.Write(ctx, f.upper, src, offset) } +// ReadFrom implements FileOperations.ReadFrom. +func (f *overlayFileOperations) ReadFrom(ctx context.Context, file *File, src *File, opts SpliceOpts) (n int64, err error) { + // See above; f.upper must be non-nil. + return f.upper.FileOperations.ReadFrom(ctx, f.upper, src, opts) +} + // Fsync implements FileOperations.Fsync. -func (f *overlayFileOperations) Fsync(ctx context.Context, file *File, start, end int64, syncType SyncType) error { - var err error +func (f *overlayFileOperations) Fsync(ctx context.Context, file *File, start, end int64, syncType SyncType) (err error) { f.upperMu.Lock() if f.upper != nil { err = f.upper.FileOperations.Fsync(ctx, f.upper, start, end, syncType) } f.upperMu.Unlock() - if f.lower != nil { + if err == nil && f.lower != nil { // N.B. Fsync on the lower filesystem can cause writes of file // attributes (i.e. access time) despite the fact that we must // treat the lower filesystem as read-only. @@ -277,15 +300,14 @@ func (f *overlayFileOperations) Fsync(ctx context.Context, file *File, start, en } // Flush implements FileOperations.Flush. -func (f *overlayFileOperations) Flush(ctx context.Context, file *File) error { +func (f *overlayFileOperations) Flush(ctx context.Context, file *File) (err error) { // Flush whatever handles we have. - var err error f.upperMu.Lock() if f.upper != nil { err = f.upper.FileOperations.Flush(ctx, f.upper) } f.upperMu.Unlock() - if f.lower != nil { + if err == nil && f.lower != nil { err = f.lower.FileOperations.Flush(ctx, f.lower) } return err @@ -329,6 +351,7 @@ func (*overlayFileOperations) ConfigureMMap(ctx context.Context, file *File, opt if !o.isMappableLocked() { return syserror.ENODEV } + // FIXME(jamieliu): This is a copy/paste of fsutil.GenericConfigureMMap, // which we can't use because the overlay implementation is in package fs, // so depending on fs/fsutil would create a circular dependency. Move diff --git a/pkg/sentry/fs/file_test.go b/pkg/sentry/fs/file_test.go deleted file mode 100644 index d867a0257..000000000 --- a/pkg/sentry/fs/file_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2018 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 fs - -import "io" - -var ( - _ = io.Reader(&FileReader{}) - _ = io.ReaderAt(&FileReader{}) - _ = io.Writer(&FileWriter{}) - _ = io.WriterAt(&FileWriter{}) -) diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go index f6b827800..c0b1b088d 100644 --- a/pkg/sentry/fs/filetest/filetest.go +++ b/pkg/sentry/fs/filetest/filetest.go @@ -38,6 +38,7 @@ type TestFileOperations struct { fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` waiter.AlwaysReady `state:"nosave"` } diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go index e355d8594..9381963d0 100644 --- a/pkg/sentry/fs/fsutil/file.go +++ b/pkg/sentry/fs/fsutil/file.go @@ -223,6 +223,20 @@ func (FileNoIoctl) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallAr return 0, syserror.ENOTTY } +// FileNoSplice implements fs.FileOperations.ReadFrom and +// fs.FileOperations.WriteTo for files that don't support splice. +type FileNoSplice struct{} + +// WriteTo implements fs.FileOperations.WriteTo. +func (FileNoSplice) WriteTo(context.Context, *fs.File, *fs.File, fs.SpliceOpts) (int64, error) { + return 0, syserror.ENOSYS +} + +// ReadFrom implements fs.FileOperations.ReadFrom. +func (FileNoSplice) ReadFrom(context.Context, *fs.File, *fs.File, fs.SpliceOpts) (int64, error) { + return 0, syserror.ENOSYS +} + // DirFileOperations implements most of fs.FileOperations for directories, // except for Readdir and UnstableAttr which the embedding type must implement. type DirFileOperations struct { @@ -233,6 +247,7 @@ type DirFileOperations struct { FileNoopFlush FileNoopFsync FileNoopRelease + FileNoSplice } // Read implements fs.FileOperations.Read @@ -303,6 +318,7 @@ type NoReadWriteFile struct { FileNoWrite `state:"nosave"` FileNotDirReaddir `state:"nosave"` FileUseInodeUnstableAttr `state:"nosave"` + FileNoSplice `state:"nosave"` } var _ fs.FileOperations = (*NoReadWriteFile)(nil) diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go index a22b6ce9c..925887335 100644 --- a/pkg/sentry/fs/fsutil/inode.go +++ b/pkg/sentry/fs/fsutil/inode.go @@ -250,16 +250,17 @@ func (i *InodeSimpleExtendedAttributes) Listxattr(_ *fs.Inode) (map[string]struc // // +stateify savable type staticFile struct { - waiter.AlwaysReady `state:"nosave"` FileGenericSeek `state:"nosave"` FileNoIoctl `state:"nosave"` FileNoMMap `state:"nosave"` + FileNoSplice `state:"nosave"` FileNoopFsync `state:"nosave"` FileNoopFlush `state:"nosave"` FileNoopRelease `state:"nosave"` FileNoopWrite `state:"nosave"` FileNotDirReaddir `state:"nosave"` FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` FileStaticContentReader } diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index bc2be546e..fb4f50113 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -46,8 +46,9 @@ var ( // // +stateify savable type fileOperations struct { - fsutil.FileNoIoctl `state:"nosave"` - waiter.AlwaysReady `state:"nosave"` + fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosplice"` + waiter.AlwaysReady `state:"nosave"` // inodeOperations is the inodeOperations backing the file. It is protected // by a reference held by File.Dirent.Inode which is stable until diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index 82e2ae3b9..ad0a3ec85 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -37,6 +37,7 @@ import ( // +stateify savable type fileOperations struct { fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosplice"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 2652582c3..7dfd31020 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -171,11 +171,21 @@ func (i *Inotify) Read(ctx context.Context, _ *File, dst usermem.IOSequence, _ i return writeLen, nil } +// WriteTo implements FileOperations.WriteTo. +func (*Inotify) WriteTo(context.Context, *File, *File, SpliceOpts) (int64, error) { + return 0, syserror.ENOSYS +} + // Fsync implements FileOperations.Fsync. func (*Inotify) Fsync(context.Context, *File, int64, int64, SyncType) error { return syserror.EINVAL } +// ReadFrom implements FileOperations.ReadFrom. +func (*Inotify) ReadFrom(context.Context, *File, *File, SpliceOpts) (int64, error) { + return 0, syserror.ENOSYS +} + // Flush implements FileOperations.Flush. func (*Inotify) Flush(context.Context, *File) error { return nil diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go index d49dad685..cb28f6bc3 100644 --- a/pkg/sentry/fs/proc/exec_args.go +++ b/pkg/sentry/fs/proc/exec_args.go @@ -77,16 +77,17 @@ func (i *execArgInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs. // +stateify savable type execArgFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` // arg is the type of exec argument this file contains. arg execArgType diff --git a/pkg/sentry/fs/proc/rpcinet_proc.go b/pkg/sentry/fs/proc/rpcinet_proc.go index db53686f6..e36c0bfa6 100644 --- a/pkg/sentry/fs/proc/rpcinet_proc.go +++ b/pkg/sentry/fs/proc/rpcinet_proc.go @@ -60,15 +60,16 @@ func (i *rpcInetInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs. // rpcInetFile implements fs.FileOperations as RPCs. type rpcInetFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` inode *rpcInetInode } diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go index 6b0ae9e60..8364d86ed 100644 --- a/pkg/sentry/fs/proc/seqfile/seqfile.go +++ b/pkg/sentry/fs/proc/seqfile/seqfile.go @@ -187,6 +187,7 @@ type seqFileOperations struct { fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go index b889ed625..59846af4f 100644 --- a/pkg/sentry/fs/proc/sys.go +++ b/pkg/sentry/fs/proc/sys.go @@ -134,7 +134,6 @@ var _ fs.InodeOperations = (*hostname)(nil) // +stateify savable type hostnameFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoSeek `state:"nosave"` @@ -143,7 +142,9 @@ type hostnameFile struct { fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoWrite `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` } // Read implements fs.FileOperations.Read. diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go index e49794a48..dbf1a987c 100644 --- a/pkg/sentry/fs/proc/sys_net.go +++ b/pkg/sentry/fs/proc/sys_net.go @@ -85,15 +85,16 @@ func (m *tcpMemInode) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.F // +stateify savable type tcpMemFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` tcpMemInode *tcpMemInode } @@ -198,15 +199,16 @@ func (s *tcpSack) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileF // +stateify savable type tcpSackFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` tcpSack *tcpSack diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go index 66d76d194..494b195cd 100644 --- a/pkg/sentry/fs/proc/task.go +++ b/pkg/sentry/fs/proc/task.go @@ -672,16 +672,17 @@ func (c *comm) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFlag // +stateify savable type commFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` t *kernel.Task } @@ -728,16 +729,17 @@ func (a *auxvec) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFl // +stateify savable type auxvecFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` t *kernel.Task } diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go index 5df3cee13..a14b1b45f 100644 --- a/pkg/sentry/fs/proc/uid_gid_map.go +++ b/pkg/sentry/fs/proc/uid_gid_map.go @@ -85,6 +85,7 @@ type idMapFileOperations struct { fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go index 1ddf9fafa..35c3851e1 100644 --- a/pkg/sentry/fs/proc/uptime.go +++ b/pkg/sentry/fs/proc/uptime.go @@ -54,16 +54,17 @@ func (u *uptime) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFl // +stateify savable type uptimeFile struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` startTime ktime.Time } diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go index a7cb1bb86..7d8bca70e 100644 --- a/pkg/sentry/fs/ramfs/socket.go +++ b/pkg/sentry/fs/ramfs/socket.go @@ -70,13 +70,14 @@ func (s *Socket) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileFl type socketFileOperations struct { fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoRead `state:"nosave"` + fsutil.FileNoSeek `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` - fsutil.FileNoRead `state:"nosave"` - fsutil.FileNoSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` waiter.AlwaysReady `state:"nosave"` } diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go index dd2585b02..21c246169 100644 --- a/pkg/sentry/fs/ramfs/symlink.go +++ b/pkg/sentry/fs/ramfs/symlink.go @@ -91,13 +91,14 @@ func (s *Symlink) GetFile(ctx context.Context, dirent *fs.Dirent, flags fs.FileF type symlinkFileOperations struct { fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoRead `state:"nosave"` + fsutil.FileNoSeek `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoWrite `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` - fsutil.FileNoRead `state:"nosave"` - fsutil.FileNoSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoWrite `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` waiter.AlwaysReady `state:"nosave"` } diff --git a/pkg/sentry/fs/splice.go b/pkg/sentry/fs/splice.go new file mode 100644 index 000000000..65937f44d --- /dev/null +++ b/pkg/sentry/fs/splice.go @@ -0,0 +1,187 @@ +// Copyright 2019 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 fs + +import ( + "io" + "sync/atomic" + + "gvisor.googlesource.com/gvisor/pkg/secio" + "gvisor.googlesource.com/gvisor/pkg/sentry/context" + "gvisor.googlesource.com/gvisor/pkg/syserror" +) + +// Splice moves data to this file, directly from another. +// +// Offsets are updated only if DstOffset and SrcOffset are set. +func Splice(ctx context.Context, dst *File, src *File, opts SpliceOpts) (int64, error) { + // Verify basic file flag permissions. + if !dst.Flags().Write || !src.Flags().Read { + return 0, syserror.EBADF + } + + // Check whether or not the objects being sliced are stream-oriented + // (i.e. pipes or sockets). If yes, we elide checks and offset locks. + srcPipe := IsPipe(src.Dirent.Inode.StableAttr) || IsSocket(src.Dirent.Inode.StableAttr) + dstPipe := IsPipe(dst.Dirent.Inode.StableAttr) || IsSocket(dst.Dirent.Inode.StableAttr) + + if !dstPipe && !opts.DstOffset && !srcPipe && !opts.SrcOffset { + switch { + case dst.UniqueID < src.UniqueID: + // Acquire dst first. + if !dst.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer dst.mu.Unlock() + if !src.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer src.mu.Unlock() + case dst.UniqueID > src.UniqueID: + // Acquire src first. + if !src.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer src.mu.Unlock() + if !dst.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer dst.mu.Unlock() + case dst.UniqueID == src.UniqueID: + // Acquire only one lock; it's the same file. This is a + // bit of a edge case, but presumably it's possible. + if !dst.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer dst.mu.Unlock() + } + // Use both offsets (locked). + opts.DstStart = dst.offset + opts.SrcStart = src.offset + } else if !dstPipe && !opts.DstOffset { + // Acquire only dst. + if !dst.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer dst.mu.Unlock() + opts.DstStart = dst.offset // Safe: locked. + } else if !srcPipe && !opts.SrcOffset { + // Acquire only src. + if !src.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer src.mu.Unlock() + opts.SrcStart = src.offset // Safe: locked. + } + + // Check append-only mode and the limit. + if !dstPipe { + if dst.Flags().Append { + if opts.DstOffset { + // We need to acquire the lock. + if !dst.mu.Lock(ctx) { + return 0, syserror.ErrInterrupted + } + defer dst.mu.Unlock() + } + // Figure out the appropriate offset to use. + if err := dst.offsetForAppend(ctx, &opts.DstStart); err != nil { + return 0, err + } + } + + // Enforce file limits. + limit, ok := dst.checkLimit(ctx, opts.DstStart) + switch { + case ok && limit == 0: + return 0, syserror.ErrExceedsFileSizeLimit + case ok && limit < opts.Length: + opts.Length = limit // Cap the write. + } + } + + // Attempt to do a WriteTo; this is likely the most efficient. + // + // The underlying implementation may be able to donate buffers. + newOpts := SpliceOpts{ + Length: opts.Length, + SrcStart: opts.SrcStart, + SrcOffset: !srcPipe, + Dup: opts.Dup, + DstStart: opts.DstStart, + DstOffset: !dstPipe, + } + n, err := src.FileOperations.WriteTo(ctx, src, dst, newOpts) + if n == 0 && err != nil { + // Attempt as a ReadFrom. If a WriteTo, a ReadFrom may also + // be more efficient than a copy if buffers are cached or readily + // available. (It's unlikely that they can actually be donate + n, err = dst.FileOperations.ReadFrom(ctx, dst, src, newOpts) + } + if n == 0 && err != nil { + // If we've failed up to here, and at least one of the sources + // is a pipe or socket, then we can't properly support dup. + // Return an error indicating that this operation is not + // supported. + if (srcPipe || dstPipe) && newOpts.Dup { + return 0, syserror.EINVAL + } + + // We failed to splice the files. But that's fine; we just fall + // back to a slow path in this case. This copies without doing + // any mode changes, so should still be more efficient. + var ( + r io.Reader + w io.Writer + ) + fw := &lockedWriter{ + Ctx: ctx, + File: dst, + } + if newOpts.DstOffset { + // Use the provided offset. + w = secio.NewOffsetWriter(fw, newOpts.DstStart) + } else { + // Writes will proceed with no offset. + w = fw + } + fr := &lockedReader{ + Ctx: ctx, + File: src, + } + if newOpts.SrcOffset { + // Limit to the given offset and length. + r = io.NewSectionReader(fr, opts.SrcStart, opts.Length) + } else { + // Limit just to the given length. + r = &io.LimitedReader{fr, opts.Length} + } + + // Copy between the two. + n, err = io.Copy(w, r) + } + + // Update offsets, if required. + if n > 0 { + if !dstPipe && !opts.DstOffset { + atomic.StoreInt64(&dst.offset, dst.offset+n) + } + if !srcPipe && !opts.SrcOffset { + atomic.StoreInt64(&src.offset, src.offset+n) + } + } + + return n, err +} diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go index 749961f51..bce5f091d 100644 --- a/pkg/sentry/fs/timerfd/timerfd.go +++ b/pkg/sentry/fs/timerfd/timerfd.go @@ -36,9 +36,10 @@ type TimerOperations struct { fsutil.FileZeroSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` - fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` events waiter.Queue `state:"zerovalue"` diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go index 1ef256511..d1c163879 100644 --- a/pkg/sentry/fs/tmpfs/file_regular.go +++ b/pkg/sentry/fs/tmpfs/file_regular.go @@ -28,14 +28,15 @@ import ( // // +stateify savable type regularFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoopFsync `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` // iops is the InodeOperations of a regular tmpfs file. It is // guaranteed to be the same as file.Dirent.Inode.InodeOperations, diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go index 8dc40e1f2..2603354c4 100644 --- a/pkg/sentry/fs/tty/dir.go +++ b/pkg/sentry/fs/tty/dir.go @@ -286,14 +286,15 @@ func (d *dirInodeOperations) masterClose(t *Terminal) { // // +stateify savable type dirFileOperations struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileGenericSeek `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` // di is the inode operations. di *dirInodeOperations diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go index 45e167e5f..afdf44cd1 100644 --- a/pkg/sentry/fs/tty/master.go +++ b/pkg/sentry/fs/tty/master.go @@ -98,8 +98,9 @@ type masterFileOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` // d is the containing dir. diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go index 0ae57a02c..2abf32e57 100644 --- a/pkg/sentry/fs/tty/slave.go +++ b/pkg/sentry/fs/tty/slave.go @@ -87,8 +87,9 @@ type slaveFileOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` // si is the inode operations. diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index 2399ae6f2..bbacba1f4 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -102,8 +102,9 @@ type EventPoll struct { fsutil.FileNotDirReaddir `state:"zerovalue"` fsutil.FileNoFsync `state:"zerovalue"` fsutil.FileNoopFlush `state:"zerovalue"` - fsutil.FileNoMMap `state:"zerovalue"` fsutil.FileNoIoctl `state:"zerovalue"` + fsutil.FileNoMMap `state:"zerovalue"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` // Wait queue is used to notify interested parties when the event poll diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index 5d3139eef..2f900be38 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -42,9 +42,10 @@ type EventOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` - fsutil.FileNoMMap `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` + fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` // Mutex that protects accesses to the fields of this event. diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index ddcc5e09a..59899be49 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -38,8 +38,9 @@ type ReaderWriter struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` *Pipe } diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 207d8ed3d..4e73527cf 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -52,15 +52,16 @@ func (f *fileContext) Value(key interface{}) interface{} { // byteReader implements fs.FileOperations for reading from a []byte source. type byteReader struct { - waiter.AlwaysReady `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` fsutil.FileNoIoctl `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoopRelease `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FilePipeSeek `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` + waiter.AlwaysReady `state:"nosave"` data []byte } diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index 520d82f68..31a449cf2 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -212,9 +212,10 @@ type commonEndpoint interface { type SocketOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` - fsutil.FileNoFsync `state:"nosave"` fsutil.FileNoopFlush `state:"nosave"` + fsutil.FileNoFsync `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` socket.SendReceiveTimeout *waiter.Queue diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index 71884d3db..41f9693bb 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -49,8 +49,9 @@ type socketOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` socket.SendReceiveTimeout diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index dc688eb00..afd06ca33 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -68,8 +68,9 @@ type Socket struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` socket.SendReceiveTimeout diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index c028ed4dd..55e0b6665 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -48,8 +48,9 @@ type socketOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` socket.SendReceiveTimeout diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 26788ec31..931056d51 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -48,8 +48,9 @@ type SocketOperations struct { fsutil.FilePipeSeek `state:"nosave"` fsutil.FileNotDirReaddir `state:"nosave"` fsutil.FileNoFsync `state:"nosave"` - fsutil.FileNoopFlush `state:"nosave"` fsutil.FileNoMMap `state:"nosave"` + fsutil.FileNoSplice `state:"nosave"` + fsutil.FileNoopFlush `state:"nosave"` fsutil.FileUseInodeUnstableAttr `state:"nosave"` refs.AtomicRefCount socket.SendReceiveTimeout diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD index 6e2843b36..f76989ae2 100644 --- a/pkg/sentry/syscalls/linux/BUILD +++ b/pkg/sentry/syscalls/linux/BUILD @@ -34,6 +34,7 @@ go_library( "sys_shm.go", "sys_signal.go", "sys_socket.go", + "sys_splice.go", "sys_stat.go", "sys_sync.go", "sys_sysinfo.go", diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go index 9a460ebdf..3e4d312af 100644 --- a/pkg/sentry/syscalls/linux/linux64.go +++ b/pkg/sentry/syscalls/linux/linux64.go @@ -407,7 +407,7 @@ var AMD64 = &kernel.SyscallTable{ 273: syscalls.Error(syscall.ENOSYS), // @Syscall(GetRobustList, note:Obsolete) 274: syscalls.Error(syscall.ENOSYS), - // 275: @Syscall(Splice), TODO(b/29354098) + 275: Splice, // 276: @Syscall(Tee), TODO(b/29354098) 277: SyncFileRange, // 278: @Syscall(Vmsplice), TODO(b/29354098) diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 1764bb4b6..8a80cd430 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -15,7 +15,6 @@ package linux import ( - "io" "syscall" "gvisor.googlesource.com/gvisor/pkg/abi/linux" @@ -2025,103 +2024,6 @@ func Flock(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall return 0, nil, nil } -// Sendfile implements linux system call sendfile(2). -func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { - outFD := kdefs.FD(args[0].Int()) - inFD := kdefs.FD(args[1].Int()) - offsetAddr := args[2].Pointer() - count := int64(args[3].SizeT()) - - // Don't send a negative number of bytes. - if count < 0 { - return 0, nil, syserror.EINVAL - } - - if count > int64(kernel.MAX_RW_COUNT) { - count = int64(kernel.MAX_RW_COUNT) - } - - // Get files. - outFile := t.FDMap().GetFile(outFD) - if outFile == nil { - return 0, nil, syserror.EBADF - } - defer outFile.DecRef() - - inFile := t.FDMap().GetFile(inFD) - if inFile == nil { - return 0, nil, syserror.EBADF - } - defer inFile.DecRef() - - // Verify that the outfile is writable. - outFlags := outFile.Flags() - if !outFlags.Write { - return 0, nil, syserror.EBADF - } - - // Verify that the outfile Append flag is not set. - if outFlags.Append { - return 0, nil, syserror.EINVAL - } - - // Verify that we have a regular infile. - // http://elixir.free-electrons.com/linux/latest/source/fs/splice.c#L933 - if !fs.IsRegular(inFile.Dirent.Inode.StableAttr) { - return 0, nil, syserror.EINVAL - } - - // Verify that the infile is readable. - if !inFile.Flags().Read { - return 0, nil, syserror.EBADF - } - - // Setup for sending data. - var n int64 - var err error - w := &fs.FileWriter{t, outFile} - hasOffset := offsetAddr != 0 - // If we have a provided offset. - if hasOffset { - // Verify that when offset address is not null, infile must be seekable - if !inFile.Flags().Pread { - return 0, nil, syserror.ESPIPE - } - // Copy in the offset. - var offset int64 - if _, err := t.CopyIn(offsetAddr, &offset); err != nil { - return 0, nil, err - } - if offset < 0 { - return 0, nil, syserror.EINVAL - } - // Send data using Preadv. - r := io.NewSectionReader(&fs.FileReader{t, inFile}, offset, count) - n, err = io.Copy(w, r) - // Copy out the new offset. - if _, err := t.CopyOut(offsetAddr, n+offset); err != nil { - return 0, nil, err - } - // If we don't have a provided offset. - } else { - // Send data using readv. - inOff := inFile.Offset() - r := &io.LimitedReader{R: &fs.FileReader{t, inFile}, N: count} - n, err = io.Copy(w, r) - inOff += n - if inFile.Offset() != inOff { - // Adjust file position in case more bytes were read than written. - if _, err := inFile.Seek(t, fs.SeekSet, inOff); err != nil { - return 0, nil, syserror.EIO - } - } - } - - // We can only pass a single file to handleIOError, so pick inFile - // arbitrarily. - return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "sendfile", inFile) -} - const ( memfdPrefix = "/memfd:" memfdAllFlags = uint32(linux.MFD_CLOEXEC | linux.MFD_ALLOW_SEALING) diff --git a/pkg/sentry/syscalls/linux/sys_splice.go b/pkg/sentry/syscalls/linux/sys_splice.go new file mode 100644 index 000000000..37303606f --- /dev/null +++ b/pkg/sentry/syscalls/linux/sys_splice.go @@ -0,0 +1,293 @@ +// Copyright 2019 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 linux + +import ( + "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" + "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.googlesource.com/gvisor/pkg/waiter" +) + +// doSplice implements a blocking splice operation. +func doSplice(t *kernel.Task, outFile, inFile *fs.File, opts fs.SpliceOpts, nonBlocking bool) (int64, error) { + var ( + total int64 + n int64 + err error + ch chan struct{} + inW bool + outW bool + ) + for opts.Length > 0 { + n, err = fs.Splice(t, outFile, inFile, opts) + opts.Length -= n + total += n + if err != syserror.ErrWouldBlock { + break + } else if err == syserror.ErrWouldBlock && nonBlocking { + break + } + + // Are we a registered waiter? + if ch == nil { + ch = make(chan struct{}, 1) + } + if !inW && inFile.Readiness(EventMaskRead) == 0 && !inFile.Flags().NonBlocking { + w, _ := waiter.NewChannelEntry(ch) + inFile.EventRegister(&w, EventMaskRead) + defer inFile.EventUnregister(&w) + inW = true // Registered. + } else if !outW && outFile.Readiness(EventMaskWrite) == 0 && !outFile.Flags().NonBlocking { + w, _ := waiter.NewChannelEntry(ch) + outFile.EventRegister(&w, EventMaskWrite) + defer outFile.EventUnregister(&w) + outW = true // Registered. + } + + // Was anything registered? If no, everything is non-blocking. + if !inW && !outW { + break + } + + // Block until there's data. + if err = t.Block(ch); err != nil { + break + } + } + + return total, err +} + +// Sendfile implements linux system call sendfile(2). +func Sendfile(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + outFD := kdefs.FD(args[0].Int()) + inFD := kdefs.FD(args[1].Int()) + offsetAddr := args[2].Pointer() + count := int64(args[3].SizeT()) + + // Don't send a negative number of bytes. + if count < 0 { + return 0, nil, syserror.EINVAL + } + + // Get files. + outFile := t.FDMap().GetFile(outFD) + if outFile == nil { + return 0, nil, syserror.EBADF + } + defer outFile.DecRef() + + inFile := t.FDMap().GetFile(inFD) + if inFile == nil { + return 0, nil, syserror.EBADF + } + defer inFile.DecRef() + + // Verify that the outfile Append flag is not set. Note that fs.Splice + // itself validates that the output file is writable. + if outFile.Flags().Append { + return 0, nil, syserror.EBADF + } + + // Verify that we have a regular infile. This is a requirement; the + // same check appears in Linux (fs/splice.c:splice_direct_to_actor). + if !fs.IsRegular(inFile.Dirent.Inode.StableAttr) { + return 0, nil, syserror.EINVAL + } + + var ( + n int64 + err error + ) + if offsetAddr != 0 { + // Verify that when offset address is not null, infile must be + // seekable. The fs.Splice routine itself validates basic read. + if !inFile.Flags().Pread { + return 0, nil, syserror.ESPIPE + } + + // Copy in the offset. + var offset int64 + if _, err := t.CopyIn(offsetAddr, &offset); err != nil { + return 0, nil, err + } + + // The offset must be valid. + if offset < 0 { + return 0, nil, syserror.EINVAL + } + + // Do the splice. + n, err = doSplice(t, outFile, inFile, fs.SpliceOpts{ + Length: count, + SrcOffset: true, + SrcStart: offset, + }, false) + + // Copy out the new offset. + if _, err := t.CopyOut(offsetAddr, n+offset); err != nil { + return 0, nil, err + } + } else { + // Send data using splice. + n, err = doSplice(t, outFile, inFile, fs.SpliceOpts{ + Length: count, + }, false) + } + + // We can only pass a single file to handleIOError, so pick inFile + // arbitrarily. This is used only for debugging purposes. + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "sendfile", inFile) +} + +// Splice implements splice(2). +func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + inFD := kdefs.FD(args[0].Int()) + inOffset := args[1].Pointer() + outFD := kdefs.FD(args[2].Int()) + outOffset := args[3].Pointer() + count := int64(args[4].SizeT()) + flags := args[5].Int() + + // Check for invalid flags. + if flags&^(linux.SPLICE_F_MOVE|linux.SPLICE_F_NONBLOCK|linux.SPLICE_F_MORE|linux.SPLICE_F_GIFT) != 0 { + return 0, nil, syserror.EINVAL + } + + // Only non-blocking is meaningful. Note that unlike in Linux, this + // flag is applied consistently. We will have either fully blocking or + // non-blocking behavior below, regardless of the underlying files + // being spliced to. It's unclear if this is a bug or not yet. + nonBlocking := (flags & linux.SPLICE_F_NONBLOCK) != 0 + + // Get files. + outFile := t.FDMap().GetFile(outFD) + if outFile == nil { + return 0, nil, syserror.EBADF + } + defer outFile.DecRef() + + inFile := t.FDMap().GetFile(inFD) + if inFile == nil { + return 0, nil, syserror.EBADF + } + defer inFile.DecRef() + + // Construct our options. + // + // Note that exactly one of the underlying buffers must be a pipe. We + // don't actually have this constraint internally, but we enforce it + // for the semantics of the call. + opts := fs.SpliceOpts{ + Length: count, + } + switch { + case fs.IsPipe(inFile.Dirent.Inode.StableAttr) && !fs.IsPipe(outFile.Dirent.Inode.StableAttr): + if inOffset != 0 { + return 0, nil, syserror.ESPIPE + } + if outOffset != 0 { + var offset int64 + if _, err := t.CopyIn(outOffset, &offset); err != nil { + return 0, nil, err + } + // Use the destination offset. + opts.DstOffset = true + opts.DstStart = offset + } + case !fs.IsPipe(inFile.Dirent.Inode.StableAttr) && fs.IsPipe(outFile.Dirent.Inode.StableAttr): + if outOffset != 0 { + return 0, nil, syserror.ESPIPE + } + if inOffset != 0 { + var offset int64 + if _, err := t.CopyIn(inOffset, &offset); err != nil { + return 0, nil, err + } + // Use the source offset. + opts.SrcOffset = true + opts.SrcStart = offset + } + case fs.IsPipe(inFile.Dirent.Inode.StableAttr) && fs.IsPipe(outFile.Dirent.Inode.StableAttr): + if inOffset != 0 || outOffset != 0 { + return 0, nil, syserror.ESPIPE + } + default: + return 0, nil, syserror.EINVAL + } + + // We may not refer to the same pipe; otherwise it's a continuous loop. + if inFile.Dirent.Inode.StableAttr.InodeID == outFile.Dirent.Inode.StableAttr.InodeID { + return 0, nil, syserror.EINVAL + } + + // Splice data. + n, err := doSplice(t, outFile, inFile, opts, nonBlocking) + + // See above; inFile is chosen arbitrarily here. + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "splice", inFile) +} + +// Tee imlements tee(2). +func Tee(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + inFD := kdefs.FD(args[0].Int()) + outFD := kdefs.FD(args[1].Int()) + count := int64(args[2].SizeT()) + flags := args[3].Int() + + // Check for invalid flags. + if flags&^(linux.SPLICE_F_MOVE|linux.SPLICE_F_NONBLOCK|linux.SPLICE_F_MORE|linux.SPLICE_F_GIFT) != 0 { + return 0, nil, syserror.EINVAL + } + + // Only non-blocking is meaningful. + nonBlocking := (flags & linux.SPLICE_F_NONBLOCK) != 0 + + // Get files. + outFile := t.FDMap().GetFile(outFD) + if outFile == nil { + return 0, nil, syserror.EBADF + } + defer outFile.DecRef() + + inFile := t.FDMap().GetFile(inFD) + if inFile == nil { + return 0, nil, syserror.EBADF + } + defer inFile.DecRef() + + // All files must be pipes. + if !fs.IsPipe(inFile.Dirent.Inode.StableAttr) || !fs.IsPipe(outFile.Dirent.Inode.StableAttr) { + return 0, nil, syserror.EINVAL + } + + // We may not refer to the same pipe; see above. + if inFile.Dirent.Inode.StableAttr.InodeID == outFile.Dirent.Inode.StableAttr.InodeID { + return 0, nil, syserror.EINVAL + } + + // Splice data. + n, err := doSplice(t, outFile, inFile, fs.SpliceOpts{ + Length: count, + Dup: true, + }, nonBlocking) + + // See above; inFile is chosen arbitrarily here. + return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "tee", inFile) +} diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index 79be06494..b531d7629 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -277,6 +277,8 @@ syscall_test(test = "//test/syscalls/linux:sendfile_socket_test") syscall_test(test = "//test/syscalls/linux:sendfile_test") +syscall_test(test = "//test/syscalls/linux:splice_test") + syscall_test(test = "//test/syscalls/linux:sigaction_test") # TODO(b/119826902): Enable once the test passes in runsc. diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index ee40be569..d4e49bb3a 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1747,6 +1747,22 @@ cc_binary( ], ) +cc_binary( + name = "splice_test", + testonly = 1, + srcs = ["splice.cc"], + linkstatic = 1, + deps = [ + "//test/util:file_descriptor", + "//test/util:temp_path", + "//test/util:test_main", + "//test/util:test_util", + "//test/util:thread_util", + "@com_google_absl//absl/strings", + "@com_google_googletest//:gtest", + ], +) + cc_binary( name = "sigaction_test", testonly = 1, diff --git a/test/syscalls/linux/splice.cc b/test/syscalls/linux/splice.cc new file mode 100644 index 000000000..1875f4533 --- /dev/null +++ b/test/syscalls/linux/splice.cc @@ -0,0 +1,404 @@ +// Copyright 2019 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. + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "test/util/file_descriptor.h" +#include "test/util/temp_path.h" +#include "test/util/test_util.h" +#include "test/util/thread_util.h" + +namespace gvisor { +namespace testing { + +namespace { + +TEST(SpliceTest, TwoRegularFiles) { + // Create temp files. + const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const TempPath out_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + + // Open the input file as read only. + const FileDescriptor inf = + ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDONLY)); + + // Open the output file as write only. + const FileDescriptor outf = + ASSERT_NO_ERRNO_AND_VALUE(Open(out_file.path(), O_WRONLY)); + + // Verify that it is rejected as expected; regardless of offsets. + loff_t in_offset = 0; + loff_t out_offset = 0; + EXPECT_THAT(splice(inf.get(), &in_offset, outf.get(), &out_offset, 1, 0), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(splice(inf.get(), nullptr, outf.get(), &out_offset, 1, 0), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(splice(inf.get(), &in_offset, outf.get(), nullptr, 1, 0), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(splice(inf.get(), nullptr, outf.get(), nullptr, 1, 0), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(SpliceTest, SamePipe) { + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Fill the pipe. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Attempt to splice to itself. + EXPECT_THAT(splice(rfd.get(), nullptr, wfd.get(), nullptr, kPageSize, 0), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(TeeTest, SamePipe) { + SKIP_IF(IsRunningOnGvisor()); + + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Fill the pipe. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Attempt to tee to itself. + EXPECT_THAT(tee(rfd.get(), wfd.get(), kPageSize, 0), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(TeeTest, RegularFile) { + SKIP_IF(IsRunningOnGvisor()); + + // Open some file. + const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const FileDescriptor inf = + ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR)); + + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Attempt to tee from the file. + EXPECT_THAT(tee(inf.get(), wfd.get(), kPageSize, 0), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(tee(rfd.get(), inf.get(), kPageSize, 0), + SyscallFailsWithErrno(EINVAL)); +} + +TEST(SpliceTest, PipeOffsets) { + // Create two new pipes. + int first[2], second[2]; + ASSERT_THAT(pipe(first), SyscallSucceeds()); + const FileDescriptor rfd1(first[0]); + const FileDescriptor wfd1(first[1]); + ASSERT_THAT(pipe(second), SyscallSucceeds()); + const FileDescriptor rfd2(second[0]); + const FileDescriptor wfd2(second[1]); + + // All pipe offsets should be rejected. + loff_t in_offset = 0; + loff_t out_offset = 0; + EXPECT_THAT(splice(rfd1.get(), &in_offset, wfd2.get(), &out_offset, 1, 0), + SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(splice(rfd1.get(), nullptr, wfd2.get(), &out_offset, 1, 0), + SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(splice(rfd1.get(), &in_offset, wfd2.get(), nullptr, 1, 0), + SyscallFailsWithErrno(ESPIPE)); +} + +TEST(SpliceTest, ToPipe) { + // Open the input file. + const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const FileDescriptor inf = + ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR)); + + // Fill with some random data. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(inf.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + ASSERT_THAT(lseek(inf.get(), 0, SEEK_SET), SyscallSucceedsWithValue(0)); + + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Splice to the pipe. + EXPECT_THAT(splice(inf.get(), nullptr, wfd.get(), nullptr, kPageSize, 0), + SyscallSucceedsWithValue(kPageSize)); + + // Contents should be equal. + std::vector rbuf(kPageSize); + ASSERT_THAT(read(rfd.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0); +} + +TEST(SpliceTest, ToPipeOffset) { + // Open the input file. + const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const FileDescriptor inf = + ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR)); + + // Fill with some random data. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(inf.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Splice to the pipe. + loff_t in_offset = kPageSize / 2; + EXPECT_THAT( + splice(inf.get(), &in_offset, wfd.get(), nullptr, kPageSize / 2, 0), + SyscallSucceedsWithValue(kPageSize / 2)); + + // Contents should be equal to only the second part. + std::vector rbuf(kPageSize / 2); + ASSERT_THAT(read(rfd.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize / 2)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data() + (kPageSize / 2), rbuf.size()), 0); +} + +TEST(SpliceTest, FromPipe) { + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Fill with some random data. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Open the input file. + const TempPath out_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const FileDescriptor outf = + ASSERT_NO_ERRNO_AND_VALUE(Open(out_file.path(), O_RDWR)); + + // Splice to the output file. + EXPECT_THAT(splice(rfd.get(), nullptr, outf.get(), nullptr, kPageSize, 0), + SyscallSucceedsWithValue(kPageSize)); + + // The offset of the output should be equal to kPageSize. We assert that and + // reset to zero so that we can read the contents and ensure they match. + EXPECT_THAT(lseek(outf.get(), 0, SEEK_CUR), + SyscallSucceedsWithValue(kPageSize)); + ASSERT_THAT(lseek(outf.get(), 0, SEEK_SET), SyscallSucceedsWithValue(0)); + + // Contents should be equal. + std::vector rbuf(kPageSize); + ASSERT_THAT(read(outf.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0); +} + +TEST(SpliceTest, FromPipeOffset) { + // Create a new pipe. + int fds[2]; + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + const FileDescriptor rfd(fds[0]); + const FileDescriptor wfd(fds[1]); + + // Fill with some random data. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Open the input file. + const TempPath out_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + const FileDescriptor outf = + ASSERT_NO_ERRNO_AND_VALUE(Open(out_file.path(), O_RDWR)); + + // Splice to the output file. + loff_t out_offset = kPageSize / 2; + EXPECT_THAT(splice(rfd.get(), nullptr, outf.get(), &out_offset, kPageSize, 0), + SyscallSucceedsWithValue(kPageSize)); + + // Content should reflect the splice. We write to a specific offset in the + // file, so the internals should now be allocated sparsely. + std::vector rbuf(kPageSize); + ASSERT_THAT(read(outf.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + std::vector zbuf(kPageSize / 2); + memset(zbuf.data(), 0, zbuf.size()); + EXPECT_EQ(memcmp(rbuf.data(), zbuf.data(), zbuf.size()), 0); + EXPECT_EQ(memcmp(rbuf.data() + kPageSize / 2, buf.data(), kPageSize / 2), 0); +} + +TEST(SpliceTest, TwoPipes) { + // Create two new pipes. + int first[2], second[2]; + ASSERT_THAT(pipe(first), SyscallSucceeds()); + const FileDescriptor rfd1(first[0]); + const FileDescriptor wfd1(first[1]); + ASSERT_THAT(pipe(second), SyscallSucceeds()); + const FileDescriptor rfd2(second[0]); + const FileDescriptor wfd2(second[1]); + + // Fill with some random data. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ASSERT_THAT(write(wfd1.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + + // Splice to the second pipe, using two operations. + EXPECT_THAT( + splice(rfd1.get(), nullptr, wfd2.get(), nullptr, kPageSize / 2, 0), + SyscallSucceedsWithValue(kPageSize / 2)); + EXPECT_THAT( + splice(rfd1.get(), nullptr, wfd2.get(), nullptr, kPageSize / 2, 0), + SyscallSucceedsWithValue(kPageSize / 2)); + + // Content should reflect the splice. + std::vector rbuf(kPageSize); + ASSERT_THAT(read(rfd2.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data(), kPageSize), 0); +} + +TEST(SpliceTest, Blocking) { + // Create two new pipes. + int first[2], second[2]; + ASSERT_THAT(pipe(first), SyscallSucceeds()); + const FileDescriptor rfd1(first[0]); + const FileDescriptor wfd1(first[1]); + ASSERT_THAT(pipe(second), SyscallSucceeds()); + const FileDescriptor rfd2(second[0]); + const FileDescriptor wfd2(second[1]); + + // This thread writes to the main pipe. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ScopedThread t([&]() { + ASSERT_THAT(write(wfd1.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + }); + + // Attempt a splice immediately; it should block. + EXPECT_THAT(splice(rfd1.get(), nullptr, wfd2.get(), nullptr, kPageSize, 0), + SyscallSucceedsWithValue(kPageSize)); + + // Thread should be joinable. + t.Join(); + + // Content should reflect the splice. + std::vector rbuf(kPageSize); + ASSERT_THAT(read(rfd2.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data(), kPageSize), 0); +} + +TEST(TeeTest, Blocking) { + SKIP_IF(IsRunningOnGvisor()); + + // Create two new pipes. + int first[2], second[2]; + ASSERT_THAT(pipe(first), SyscallSucceeds()); + const FileDescriptor rfd1(first[0]); + const FileDescriptor wfd1(first[1]); + ASSERT_THAT(pipe(second), SyscallSucceeds()); + const FileDescriptor rfd2(second[0]); + const FileDescriptor wfd2(second[1]); + + // This thread writes to the main pipe. + std::vector buf(kPageSize); + RandomizeBuffer(buf.data(), buf.size()); + ScopedThread t([&]() { + ASSERT_THAT(write(wfd1.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(kPageSize)); + }); + + // Attempt a tee immediately; it should block. + EXPECT_THAT(tee(rfd1.get(), wfd2.get(), kPageSize, 0), + SyscallSucceedsWithValue(kPageSize)); + + // Thread should be joinable. + t.Join(); + + // Content should reflect the splice, in both pipes. + std::vector rbuf(kPageSize); + ASSERT_THAT(read(rfd2.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data(), kPageSize), 0); + ASSERT_THAT(read(rfd1.get(), rbuf.data(), rbuf.size()), + SyscallSucceedsWithValue(kPageSize)); + EXPECT_EQ(memcmp(rbuf.data(), buf.data(), kPageSize), 0); +} + +TEST(SpliceTest, NonBlocking) { + // Create two new pipes. + int first[2], second[2]; + ASSERT_THAT(pipe(first), SyscallSucceeds()); + const FileDescriptor rfd1(first[0]); + const FileDescriptor wfd1(first[1]); + ASSERT_THAT(pipe(second), SyscallSucceeds()); + const FileDescriptor rfd2(second[0]); + const FileDescriptor wfd2(second[1]); + + // Splice with no data to back it. + EXPECT_THAT(splice(rfd1.get(), nullptr, wfd2.get(), nullptr, kPageSize, + SPLICE_F_NONBLOCK), + SyscallFailsWithErrno(EAGAIN)); +} + +TEST(TeeTest, NonBlocking) { + SKIP_IF(IsRunningOnGvisor()); + + // Create two new pipes. + int first[2], second[2]; + ASSERT_THAT(pipe(first), SyscallSucceeds()); + const FileDescriptor rfd1(first[0]); + const FileDescriptor wfd1(first[1]); + ASSERT_THAT(pipe(second), SyscallSucceeds()); + const FileDescriptor rfd2(second[0]); + const FileDescriptor wfd2(second[1]); + + // Splice with no data to back it. + EXPECT_THAT(tee(rfd1.get(), wfd2.get(), kPageSize, SPLICE_F_NONBLOCK), + SyscallFailsWithErrno(EAGAIN)); +} + +} // namespace + +} // namespace testing +} // namespace gvisor -- cgit v1.2.3 From ae1bb08871758844fa23fc7255ffeb0392f9dee6 Mon Sep 17 00:00:00 2001 From: Adin Scannell Date: Tue, 21 May 2019 20:11:26 -0700 Subject: Clean up pipe internals and add fcntl support Pipe internals are made more efficient by avoiding garbage collection. A pool is now used that can be shared by all pipes, and buffers are chained via an intrusive list. The documentation for pipe structures and methods is also simplified and clarified. The pipe tests are now parameterized, so that they are run on all different variants (named pipes, small buffers, default buffers). The pipe buffer sizes are exposed by fcntl, which is now supported by this change. A size change test has been added to the suite. These new tests uncovered a bug regarding the semantics of open named pipes with O_NONBLOCK, which is also fixed by this CL. This fix also addresses the lack of the O_LARGEFILE flag for named pipes. PiperOrigin-RevId: 249375888 Change-Id: I48e61e9c868aedb0cadda2dff33f09a560dee773 --- pkg/abi/linux/fcntl.go | 4 +- pkg/sentry/kernel/pipe/BUILD | 8 +- pkg/sentry/kernel/pipe/buffer.go | 90 ++++ pkg/sentry/kernel/pipe/buffer_test.go | 32 ++ pkg/sentry/kernel/pipe/buffers.go | 48 -- pkg/sentry/kernel/pipe/node.go | 7 +- pkg/sentry/kernel/pipe/pipe.go | 315 ++++++++----- pkg/sentry/kernel/pipe/pipe_test.go | 7 +- pkg/sentry/kernel/pipe/reader.go | 3 + pkg/sentry/kernel/pipe/reader_writer.go | 6 +- pkg/sentry/kernel/pipe/writer.go | 3 + pkg/sentry/syscalls/linux/sys_file.go | 14 + test/syscalls/BUILD | 6 +- test/syscalls/linux/BUILD | 2 + test/syscalls/linux/pipe.cc | 761 +++++++++++++++++++------------- 15 files changed, 828 insertions(+), 478 deletions(-) create mode 100644 pkg/sentry/kernel/pipe/buffer.go create mode 100644 pkg/sentry/kernel/pipe/buffer_test.go delete mode 100644 pkg/sentry/kernel/pipe/buffers.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/fcntl.go b/pkg/abi/linux/fcntl.go index cc8f2702d..b30350193 100644 --- a/pkg/abi/linux/fcntl.go +++ b/pkg/abi/linux/fcntl.go @@ -17,7 +17,6 @@ package linux // Comands from linux/fcntl.h. const ( F_DUPFD = 0 - F_DUPFD_CLOEXEC = 1030 F_GETFD = 1 F_GETFL = 3 F_GETOWN = 9 @@ -26,6 +25,9 @@ const ( F_SETLK = 6 F_SETLKW = 7 F_SETOWN = 8 + F_DUPFD_CLOEXEC = 1024 + 6 + F_SETPIPE_SZ = 1024 + 7 + F_GETPIPE_SZ = 1024 + 8 ) // Flags for fcntl. diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 6b23117d9..b07d15a2a 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -10,16 +10,16 @@ go_template_instance( prefix = "buffer", template = "//pkg/ilist:generic_list", types = { - "Element": "*Buffer", - "Linker": "*Buffer", + "Element": "*buffer", + "Linker": "*buffer", }, ) go_library( name = "pipe", srcs = [ + "buffer.go", "buffer_list.go", - "buffers.go", "device.go", "node.go", "pipe.go", @@ -37,6 +37,7 @@ go_library( "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", + "//pkg/sentry/safemem", "//pkg/sentry/usermem", "//pkg/syserror", "//pkg/waiter", @@ -47,6 +48,7 @@ go_test( name = "pipe_test", size = "small", srcs = [ + "buffer_test.go", "node_test.go", "pipe_test.go", ], diff --git a/pkg/sentry/kernel/pipe/buffer.go b/pkg/sentry/kernel/pipe/buffer.go new file mode 100644 index 000000000..4360dc44f --- /dev/null +++ b/pkg/sentry/kernel/pipe/buffer.go @@ -0,0 +1,90 @@ +// Copyright 2018 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 pipe + +import ( + "sync" + + "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" +) + +// buffer encapsulates a queueable byte buffer. +// +// Note that the total size is slightly less than two pages. This +// is done intentionally to ensure that the buffer object aligns +// with runtime internals. We have no hard size or alignment +// requirements. This two page size will effectively minimize +// internal fragmentation, but still have a large enough chunk +// to limit excessive segmentation. +// +// +stateify savable +type buffer struct { + data [8144]byte + read int + write int + bufferEntry +} + +// Reset resets internal data. +// +// This must be called before use. +func (b *buffer) Reset() { + b.read = 0 + b.write = 0 +} + +// Empty indicates the buffer is empty. +// +// This indicates there is no data left to read. +func (b *buffer) Empty() bool { + return b.read == b.write +} + +// Full indicates the buffer is full. +// +// This indicates there is no capacity left to write. +func (b *buffer) Full() bool { + return b.write == len(b.data) +} + +// WriteFromBlocks implements safemem.Writer.WriteFromBlocks. +func (b *buffer) WriteFromBlocks(srcs safemem.BlockSeq) (uint64, error) { + dst := safemem.BlockSeqOf(safemem.BlockFromSafeSlice(b.data[b.write:])) + n, err := safemem.CopySeq(dst, srcs) + b.write += int(n) + return n, err +} + +// ReadToBlocks implements safemem.Reader.ReadToBlocks. +func (b *buffer) ReadToBlocks(dsts safemem.BlockSeq) (uint64, error) { + src := safemem.BlockSeqOf(safemem.BlockFromSafeSlice(b.data[b.read:b.write])) + n, err := safemem.CopySeq(dsts, src) + b.read += int(n) + return n, err +} + +// bufferPool is a pool for buffers. +var bufferPool = sync.Pool{ + New: func() interface{} { + return new(buffer) + }, +} + +// newBuffer grabs a new buffer from the pool. +func newBuffer() *buffer { + b := bufferPool.Get().(*buffer) + b.Reset() + return b +} diff --git a/pkg/sentry/kernel/pipe/buffer_test.go b/pkg/sentry/kernel/pipe/buffer_test.go new file mode 100644 index 000000000..4b7dbc43f --- /dev/null +++ b/pkg/sentry/kernel/pipe/buffer_test.go @@ -0,0 +1,32 @@ +// Copyright 2019 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 pipe + +import ( + "testing" + "unsafe" + + "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" +) + +func TestBufferSize(t *testing.T) { + bufferSize := unsafe.Sizeof(buffer{}) + if bufferSize < usermem.PageSize { + t.Errorf("buffer is less than a page") + } + if bufferSize > (2 * usermem.PageSize) { + t.Errorf("buffer is greater than two pages") + } +} diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go deleted file mode 100644 index ba53fd482..000000000 --- a/pkg/sentry/kernel/pipe/buffers.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2018 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 pipe - -// Buffer encapsulates a queueable byte buffer that can -// easily be truncated. It is designed only for use with pipes. -// -// +stateify savable -type Buffer struct { - bufferEntry - data []byte -} - -// newBuffer initializes a Buffer. -func newBuffer(buf []byte) *Buffer { - return &Buffer{data: buf} -} - -// bytes returns the bytes contained in the buffer. -func (b *Buffer) bytes() []byte { - return b.data -} - -// size returns the number of bytes contained in the buffer. -func (b *Buffer) size() int { - return len(b.data) -} - -// truncate removes the first n bytes from the buffer. -func (b *Buffer) truncate(n int) int { - if n > len(b.data) { - panic("Trying to truncate past end of array.") - } - b.data = b.data[n:] - return len(b.data) -} diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index 7c3739360..926c4c623 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -67,7 +67,6 @@ func NewInodeOperations(ctx context.Context, perms fs.FilePermissions, p *Pipe) InodeSimpleAttributes: fsutil.NewInodeSimpleAttributes(ctx, fs.FileOwnerFromContext(ctx), perms, linux.PIPEFS_MAGIC), p: p, } - } // GetFile implements fs.InodeOperations.GetFile. Named pipes have special blocking @@ -87,7 +86,7 @@ func (i *inodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags fs.Fi switch { case flags.Read && !flags.Write: // O_RDONLY. - r := i.p.ROpen(ctx) + r := i.p.Open(ctx, flags) i.newHandleLocked(&i.rWakeup) if i.p.isNamed && !flags.NonBlocking && !i.p.HasWriters() { @@ -103,7 +102,7 @@ func (i *inodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags fs.Fi return r, nil case flags.Write && !flags.Read: // O_WRONLY. - w := i.p.WOpen(ctx) + w := i.p.Open(ctx, flags) i.newHandleLocked(&i.wWakeup) if i.p.isNamed && !i.p.HasReaders() { @@ -123,7 +122,7 @@ func (i *inodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags fs.Fi case flags.Read && flags.Write: // O_RDWR. // Pipes opened for read-write always succeeds without blocking. - rw := i.p.RWOpen(ctx) + rw := i.p.Open(ctx, flags) i.newHandleLocked(&i.rWakeup) i.newHandleLocked(&i.wWakeup) return rw, nil diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index bd7649d2f..b65204492 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -12,11 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package pipe provides an in-memory implementation of a unidirectional -// pipe. -// -// The goal of this pipe is to emulate the pipe syscall in all of its -// edge cases and guarantees of atomic IO. +// Package pipe provides a pipe implementation. package pipe import ( @@ -32,8 +28,29 @@ import ( "gvisor.googlesource.com/gvisor/pkg/waiter" ) -// DefaultPipeSize is the system-wide default size of a pipe in bytes. -const DefaultPipeSize = 65536 +const ( + // MinimumPipeSize is a hard limit of the minimum size of a pipe. + MinimumPipeSize = 64 << 10 + + // DefaultPipeSize is the system-wide default size of a pipe in bytes. + DefaultPipeSize = MinimumPipeSize + + // MaximumPipeSize is a hard limit on the maximum size of a pipe. + MaximumPipeSize = 8 << 20 +) + +// Sizer is an interface for setting and getting the size of a pipe. +// +// It is implemented by Pipe and, through embedding, all other types. +type Sizer interface { + // PipeSize returns the pipe capacity in bytes. + PipeSize() int64 + + // SetPipeSize sets the new pipe capacity in bytes. + // + // The new size is returned (which may be capped). + SetPipeSize(int64) (int64, error) +} // Pipe is an encapsulation of a platform-independent pipe. // It manages a buffered byte queue shared between a reader/writer @@ -43,49 +60,76 @@ const DefaultPipeSize = 65536 type Pipe struct { waiter.Queue `state:"nosave"` - // Whether this is a named or anonymous pipe. + // isNamed indicates whether this is a named pipe. + // + // This value is immutable. isNamed bool + // atomicIOBytes is the maximum number of bytes that the pipe will + // guarantee atomic reads or writes atomically. + // + // This value is immutable. + atomicIOBytes int64 + // The dirent backing this pipe. Shared by all readers and writers. + // + // This value is immutable. Dirent *fs.Dirent - // The buffered byte queue. - data bufferList + // The number of active readers for this pipe. + // + // Access atomically. + readers int32 - // Max size of the pipe in bytes. When this max has been reached, - // writers will get EWOULDBLOCK. - max int + // The number of active writes for this pipe. + // + // Access atomically. + writers int32 - // Current size of the pipe in bytes. - size int + // mu protects all pipe internal state below. + mu sync.Mutex `state:"nosave"` - // Max number of bytes the pipe can guarantee to read or write - // atomically. - atomicIOBytes int + // data is the buffer queue of pipe contents. + // + // This is protected by mu. + data bufferList - // The number of active readers for this pipe. Load/store atomically. - readers int32 + // max is the maximum size of the pipe in bytes. When this max has been + // reached, writers will get EWOULDBLOCK. + // + // This is protected by mu. + max int64 - // The number of active writes for this pipe. Load/store atomically. - writers int32 + // size is the current size of the pipe in bytes. + // + // This is protected by mu. + size int64 - // This flag indicates if this pipe ever had a writer. Note that this does - // not necessarily indicate there is *currently* a writer, just that there - // has been a writer at some point since the pipe was created. + // hadWriter indicates if this pipe ever had a writer. Note that this + // does not necessarily indicate there is *currently* a writer, just + // that there has been a writer at some point since the pipe was + // created. // - // Protected by mu. + // This is protected by mu. hadWriter bool - - // Lock protecting all pipe internal state. - mu sync.Mutex `state:"nosave"` } -// NewPipe initializes and returns a pipe. A pipe created by this function is -// persistent, and will remain valid even without any open fds to it. Named -// pipes for mknod(2) are created via this function. Note that the -// implementation of blocking semantics for opening the read and write ends of a -// named pipe are left to filesystems. -func NewPipe(ctx context.Context, isNamed bool, sizeBytes, atomicIOBytes int) *Pipe { +// NewPipe initializes and returns a pipe. +// +// N.B. The size and atomicIOBytes will be bounded. +func NewPipe(ctx context.Context, isNamed bool, sizeBytes, atomicIOBytes int64) *Pipe { + if sizeBytes < MinimumPipeSize { + sizeBytes = MinimumPipeSize + } + if sizeBytes > MaximumPipeSize { + sizeBytes = MaximumPipeSize + } + if atomicIOBytes <= 0 { + atomicIOBytes = 1 + } + if atomicIOBytes > sizeBytes { + atomicIOBytes = sizeBytes + } p := &Pipe{ isNamed: isNamed, max: sizeBytes, @@ -110,48 +154,45 @@ func NewPipe(ctx context.Context, isNamed bool, sizeBytes, atomicIOBytes int) *P return p } -// NewConnectedPipe initializes a pipe and returns a pair of objects (which -// implement kio.File) representing the read and write ends of the pipe. A pipe -// created by this function becomes invalid as soon as either the read or write -// end is closed, and errors on subsequent operations on either end. Pipes -// for pipe(2) and pipe2(2) are generally created this way. -func NewConnectedPipe(ctx context.Context, sizeBytes int, atomicIOBytes int) (*fs.File, *fs.File) { +// NewConnectedPipe initializes a pipe and returns a pair of objects +// representing the read and write ends of the pipe. +func NewConnectedPipe(ctx context.Context, sizeBytes, atomicIOBytes int64) (*fs.File, *fs.File) { p := NewPipe(ctx, false /* isNamed */, sizeBytes, atomicIOBytes) - return p.ROpen(ctx), p.WOpen(ctx) -} - -// ROpen opens the pipe for reading. -func (p *Pipe) ROpen(ctx context.Context) *fs.File { - p.rOpen() - return fs.NewFile(ctx, p.Dirent, fs.FileFlags{Read: true}, &Reader{ - ReaderWriter: ReaderWriter{Pipe: p}, - }) -} - -// WOpen opens the pipe for writing. -func (p *Pipe) WOpen(ctx context.Context) *fs.File { - p.wOpen() - return fs.NewFile(ctx, p.Dirent, fs.FileFlags{Write: true}, &Writer{ - ReaderWriter: ReaderWriter{Pipe: p}, - }) + return p.Open(ctx, fs.FileFlags{Read: true}), p.Open(ctx, fs.FileFlags{Write: true}) } -// RWOpen opens the pipe for both reading and writing. -func (p *Pipe) RWOpen(ctx context.Context) *fs.File { - p.rOpen() - p.wOpen() - return fs.NewFile(ctx, p.Dirent, fs.FileFlags{Read: true, Write: true}, &ReaderWriter{ - Pipe: p, - }) +// Open opens the pipe and returns a new file. +// +// Precondition: at least one of flags.Read or flags.Write must be set. +func (p *Pipe) Open(ctx context.Context, flags fs.FileFlags) *fs.File { + switch { + case flags.Read && flags.Write: + p.rOpen() + p.wOpen() + return fs.NewFile(ctx, p.Dirent, flags, &ReaderWriter{ + Pipe: p, + }) + case flags.Read: + p.rOpen() + return fs.NewFile(ctx, p.Dirent, flags, &Reader{ + ReaderWriter: ReaderWriter{Pipe: p}, + }) + case flags.Write: + p.wOpen() + return fs.NewFile(ctx, p.Dirent, flags, &Writer{ + ReaderWriter: ReaderWriter{Pipe: p}, + }) + default: + // Precondition violated. + panic("invalid pipe flags") + } } // read reads data from the pipe into dst and returns the number of bytes // read, or returns ErrWouldBlock if the pipe is empty. +// +// Precondition: this pipe must have readers. func (p *Pipe) read(ctx context.Context, dst usermem.IOSequence) (int64, error) { - if !p.HasReaders() { - return 0, syscall.EBADF - } - // Don't block for a zero-length read even if the pipe is empty. if dst.NumBytes() == 0 { return 0, nil @@ -159,8 +200,8 @@ func (p *Pipe) read(ctx context.Context, dst usermem.IOSequence) (int64, error) p.mu.Lock() defer p.mu.Unlock() - // If there is nothing to read at the moment but there is a writer, tell the - // caller to block. + + // Is the pipe empty? if p.size == 0 { if !p.HasWriters() { // There are no writers, return EOF. @@ -168,64 +209,94 @@ func (p *Pipe) read(ctx context.Context, dst usermem.IOSequence) (int64, error) } return 0, syserror.ErrWouldBlock } - var n int64 - for buffer := p.data.Front(); buffer != nil; buffer = p.data.Front() { - n0, err := dst.CopyOut(ctx, buffer.bytes()) - n += int64(n0) - p.size -= n0 - if buffer.truncate(n0) == 0 { - p.data.Remove(buffer) + + // Limit how much we consume. + if dst.NumBytes() > p.size { + dst = dst.TakeFirst64(p.size) + } + + done := int64(0) + for dst.NumBytes() > 0 { + // Pop the first buffer. + first := p.data.Front() + if first == nil { + break } - dst = dst.DropFirst(n0) - if dst.NumBytes() == 0 || err != nil { - return n, err + + // Copy user data. + n, err := dst.CopyOutFrom(ctx, first) + done += int64(n) + p.size -= n + dst = dst.DropFirst64(n) + + // Empty buffer? + if first.Empty() { + // Push to the free list. + p.data.Remove(first) + bufferPool.Put(first) + } + + // Handle errors. + if err != nil { + return done, err } } - return n, nil + + return done, nil } // write writes data from sv into the pipe and returns the number of bytes // written. If no bytes are written because the pipe is full (or has less than // atomicIOBytes free capacity), write returns ErrWouldBlock. +// +// Precondition: this pipe must have writers. func (p *Pipe) write(ctx context.Context, src usermem.IOSequence) (int64, error) { p.mu.Lock() defer p.mu.Unlock() - if !p.HasWriters() { - return 0, syscall.EBADF - } + // Can't write to a pipe with no readers. if !p.HasReaders() { return 0, syscall.EPIPE } // POSIX requires that a write smaller than atomicIOBytes (PIPE_BUF) be - // atomic, but requires no atomicity for writes larger than this. However, - // Linux appears to provide stronger semantics than this in practice: - // unmerged writes are done one PAGE_SIZE buffer at a time, so for larger - // writes, the writing of each PIPE_BUF-sized chunk is atomic. We implement - // this by writing at most atomicIOBytes at a time if we can't service the - // write in its entirety. - canWrite := src.NumBytes() - if canWrite > int64(p.max-p.size) { - if p.max-p.size >= p.atomicIOBytes { - canWrite = int64(p.atomicIOBytes) - } else { + // atomic, but requires no atomicity for writes larger than this. + wanted := src.NumBytes() + if avail := p.max - p.size; wanted > avail { + if wanted <= p.atomicIOBytes { return 0, syserror.ErrWouldBlock } + // Limit to the available capacity. + src = src.TakeFirst64(avail) } - // Copy data from user memory into a pipe-owned buffer. - buf := make([]byte, canWrite) - n, err := src.CopyIn(ctx, buf) - if n > 0 { - p.data.PushBack(newBuffer(buf[:n])) + done := int64(0) + for src.NumBytes() > 0 { + // Need a new buffer? + last := p.data.Back() + if last == nil || last.Full() { + // Add a new buffer to the data list. + last = newBuffer() + p.data.PushBack(last) + } + + // Copy user data. + n, err := src.CopyInTo(ctx, last) + done += int64(n) p.size += n + src = src.DropFirst64(n) + + // Handle errors. + if err != nil { + return done, err + } } - if int64(n) < src.NumBytes() && err == nil { + if wanted > done { // Partial write due to full pipe. - err = syserror.ErrWouldBlock + return done, syserror.ErrWouldBlock } - return int64(n), err + + return done, nil } // rOpen signals a new reader of the pipe. @@ -267,6 +338,9 @@ func (p *Pipe) HasWriters() bool { return atomic.LoadInt32(&p.writers) > 0 } +// rReadinessLocked calculates the read readiness. +// +// Precondition: mu must be held. func (p *Pipe) rReadinessLocked() waiter.EventMask { ready := waiter.EventMask(0) if p.HasReaders() && p.data.Front() != nil { @@ -290,6 +364,9 @@ func (p *Pipe) rReadiness() waiter.EventMask { return p.rReadinessLocked() } +// wReadinessLocked calculates the write readiness. +// +// Precondition: mu must be held. func (p *Pipe) wReadinessLocked() waiter.EventMask { ready := waiter.EventMask(0) if p.HasWriters() && p.size < p.max { @@ -317,8 +394,36 @@ func (p *Pipe) rwReadiness() waiter.EventMask { return p.rReadinessLocked() | p.wReadinessLocked() } -func (p *Pipe) queuedSize() int { +// queued returns the amount of queued data. +func (p *Pipe) queued() int64 { p.mu.Lock() defer p.mu.Unlock() return p.size } + +// PipeSize implements PipeSizer.PipeSize. +func (p *Pipe) PipeSize() int64 { + p.mu.Lock() + defer p.mu.Unlock() + return p.max +} + +// SetPipeSize implements PipeSize.SetPipeSize. +func (p *Pipe) SetPipeSize(size int64) (int64, error) { + if size < 0 { + return 0, syserror.EINVAL + } + if size < MinimumPipeSize { + size = MinimumPipeSize // Per spec. + } + if size > MaximumPipeSize { + return 0, syserror.EPERM + } + p.mu.Lock() + defer p.mu.Unlock() + if size < p.size { + return 0, syserror.EBUSY + } + p.max = size + return size, nil +} diff --git a/pkg/sentry/kernel/pipe/pipe_test.go b/pkg/sentry/kernel/pipe/pipe_test.go index de340c40c..298c6587b 100644 --- a/pkg/sentry/kernel/pipe/pipe_test.go +++ b/pkg/sentry/kernel/pipe/pipe_test.go @@ -58,15 +58,16 @@ func TestPipeReadBlock(t *testing.T) { func TestPipeWriteBlock(t *testing.T) { const atomicIOBytes = 2 + const capacity = MinimumPipeSize ctx := contexttest.Context(t) - r, w := NewConnectedPipe(ctx, 10, atomicIOBytes) + r, w := NewConnectedPipe(ctx, capacity, atomicIOBytes) defer r.DecRef() defer w.DecRef() - msg := []byte("here's some bytes") + msg := make([]byte, capacity+1) n, err := w.Writev(ctx, usermem.BytesIOSequence(msg)) - if wantN, wantErr := int64(atomicIOBytes), syserror.ErrWouldBlock; n != wantN || err != wantErr { + if wantN, wantErr := int64(capacity), syserror.ErrWouldBlock; n != wantN || err != wantErr { t.Fatalf("Writev: got (%d, %v), wanted (%d, %v)", n, err, wantN, wantErr) } } diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 48fab45d1..656be824d 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -27,8 +27,11 @@ type Reader struct { } // Release implements fs.FileOperations.Release. +// +// This overrides ReaderWriter.Release. func (r *Reader) Release() { r.Pipe.rClose() + // Wake up writers. r.Pipe.Notify(waiter.EventOut) } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index 59899be49..e560b9be9 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -15,7 +15,6 @@ package pipe import ( - "fmt" "math" "syscall" @@ -49,6 +48,7 @@ type ReaderWriter struct { func (rw *ReaderWriter) Release() { rw.Pipe.rClose() rw.Pipe.wClose() + // Wake up readers and writers. rw.Pipe.Notify(waiter.EventIn | waiter.EventOut) } @@ -81,9 +81,9 @@ func (rw *ReaderWriter) Ioctl(ctx context.Context, io usermem.IO, args arch.Sysc // Switch on ioctl request. switch int(args[1].Int()) { case linux.FIONREAD: - v := rw.queuedSize() + v := rw.queued() if v > math.MaxInt32 { - panic(fmt.Sprintf("Impossibly large pipe queued size: %d", v)) + v = math.MaxInt32 // Silently truncate. } // Copy result to user-space. _, err := usermem.CopyObjectOut(ctx, io, args[2].Pointer(), int32(v), usermem.IOOpts{ diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index 0f29fbc43..8d5b68541 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -27,8 +27,11 @@ type Writer struct { } // Release implements fs.FileOperations.Release. +// +// This overrides ReaderWriter.Release. func (w *Writer) Release() { w.Pipe.wClose() + // Wake up readers. w.Pipe.Notify(waiter.EventHUp) } diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 8a80cd430..19f579930 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -27,6 +27,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/fasync" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs" + "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/pipe" ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time" "gvisor.googlesource.com/gvisor/pkg/sentry/limits" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -943,6 +944,19 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall } err := tmpfs.AddSeals(file.Dirent.Inode, args[2].Uint()) return 0, nil, err + case linux.F_GETPIPE_SZ: + sz, ok := file.FileOperations.(pipe.Sizer) + if !ok { + return 0, nil, syserror.EINVAL + } + return uintptr(sz.PipeSize()), nil, nil + case linux.F_SETPIPE_SZ: + sz, ok := file.FileOperations.(pipe.Sizer) + if !ok { + return 0, nil, syserror.EINVAL + } + n, err := sz.SetPipeSize(int64(args[2].Int())) + return uintptr(n), nil, err default: // Everything else is not yet supported. return 0, nil, syserror.EINVAL diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index b531d7629..0d6b6ccc7 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -191,7 +191,11 @@ syscall_test(test = "//test/syscalls/linux:partial_bad_buffer_test") syscall_test(test = "//test/syscalls/linux:pause_test") -syscall_test(test = "//test/syscalls/linux:pipe_test") +syscall_test( + size = "large", + shard_count = 5, + test = "//test/syscalls/linux:pipe_test", +) syscall_test(test = "//test/syscalls/linux:poll_test") diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index d4e49bb3a..4e239617b 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1237,6 +1237,8 @@ cc_binary( linkstatic = 1, deps = [ "//test/util:file_descriptor", + "//test/util:posix_error", + "//test/util:temp_path", "//test/util:test_main", "//test/util:test_util", "//test/util:thread_util", diff --git a/test/syscalls/linux/pipe.cc b/test/syscalls/linux/pipe.cc index 8698295b3..bce351e08 100644 --- a/test/syscalls/linux/pipe.cc +++ b/test/syscalls/linux/pipe.cc @@ -26,6 +26,8 @@ #include "absl/time/clock.h" #include "absl/time/time.h" #include "test/util/file_descriptor.h" +#include "test/util/posix_error.h" +#include "test/util/temp_path.h" #include "test/util/test_util.h" #include "test/util/thread_util.h" @@ -34,449 +36,588 @@ namespace testing { namespace { -// Buffer size of a pipe. -// -// TODO(b/35762278): Get this from F_GETPIPE_SZ. -constexpr int kPipeSize = 65536; +// Used as a non-zero sentinel value, below. +constexpr int kTestValue = 0x12345678; + +// Used for synchronization in race tests. +const absl::Duration syncDelay = absl::Seconds(2); + +struct PipeCreator { + std::string name_; + + // void (fds, is_blocking, is_namedpipe). + std::function create_; +}; + +class PipeTest : public ::testing::TestWithParam { + protected: + FileDescriptor rfd; + FileDescriptor wfd; -class PipeTest : public ::testing::Test { public: static void SetUpTestCase() { // Tests intentionally generate SIGPIPE. TEST_PCHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); } + // Initializes rfd and wfd as a blocking pipe. + // + // The return value indicates success: the test should be skipped otherwise. + bool CreateBlocking() { return create(true); } + + // Initializes rfd and wfd as a non-blocking pipe. + // + // The return value is per CreateBlocking. + bool CreateNonBlocking() { return create(false); } + + // Returns true iff the pipe represents a named pipe. + bool IsNamedPipe() { return namedpipe_; } + + int Size() { + int s1 = fcntl(rfd.get(), F_GETPIPE_SZ); + int s2 = fcntl(wfd.get(), F_GETPIPE_SZ); + EXPECT_GT(s1, 0); + EXPECT_GT(s2, 0); + EXPECT_EQ(s1, s2); + return s1; + } + static void TearDownTestCase() { TEST_PCHECK(signal(SIGPIPE, SIG_DFL) != SIG_ERR); } + + private: + bool namedpipe_ = false; + + bool create(bool wants_blocking) { + // Generate the pipe. + int fds[2] = {-1, -1}; + bool is_blocking = false; + GetParam().create_(fds, &is_blocking, &namedpipe_); + if (fds[0] < 0 || fds[1] < 0) { + return false; + } + + // Save descriptors. + rfd.reset(fds[0]); + wfd.reset(fds[1]); + + // Adjust blocking, if needed. + if (!is_blocking && wants_blocking) { + // Clear the blocking flag. + EXPECT_THAT(fcntl(fds[0], F_SETFL, 0), SyscallSucceeds()); + EXPECT_THAT(fcntl(fds[1], F_SETFL, 0), SyscallSucceeds()); + } else if (is_blocking && !wants_blocking) { + // Set the descriptors to blocking. + EXPECT_THAT(fcntl(fds[0], F_SETFL, O_NONBLOCK), SyscallSucceeds()); + EXPECT_THAT(fcntl(fds[1], F_SETFL, O_NONBLOCK), SyscallSucceeds()); + } + + return true; + } }; -TEST_F(PipeTest, Basic) { - // fds[0] is read end, fds[1] is write end. - int fds[2]; - int i = 0x12345678; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); +TEST_P(PipeTest, Inode) { + SKIP_IF(!CreateBlocking()); // Ensure that the inode number is the same for each end. struct stat rst; - ASSERT_THAT(fstat(fds[0], &rst), SyscallSucceeds()); + ASSERT_THAT(fstat(rfd.get(), &rst), SyscallSucceeds()); struct stat wst; - ASSERT_THAT(fstat(fds[1], &wst), SyscallSucceeds()); + ASSERT_THAT(fstat(wfd.get(), &wst), SyscallSucceeds()); EXPECT_EQ(rst.st_ino, wst.st_ino); - - ASSERT_THAT(write(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - ASSERT_THAT(read(fds[1], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); - int j; - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); - EXPECT_EQ(i, j); - - ASSERT_THAT(fcntl(fds[0], F_GETFL), SyscallSucceeds()); - ASSERT_THAT(fcntl(fds[1], F_GETFL), SyscallSucceedsWithValue(O_WRONLY)); - - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); } -TEST_F(PipeTest, BasicCloExec) { - // fds[0] is read end, fds[1] is write end. - int fds[2]; - int i = 0x12345678; - ASSERT_THAT(pipe2(fds, O_CLOEXEC), SyscallSucceeds()); +TEST_P(PipeTest, Permissions) { + SKIP_IF(!CreateBlocking()); - ASSERT_THAT(write(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - ASSERT_THAT(read(fds[1], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); + // Attempt bad operations. + int buf = kTestValue; + ASSERT_THAT(write(rfd.get(), &buf, sizeof(buf)), + SyscallFailsWithErrno(EBADF)); + EXPECT_THAT(read(wfd.get(), &buf, sizeof(buf)), SyscallFailsWithErrno(EBADF)); +} - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); - int j; - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); - EXPECT_EQ(i, j); +TEST_P(PipeTest, Flags) { + SKIP_IF(!CreateBlocking()); + + if (IsNamedPipe()) { + // May be stubbed to zero; define locally. + constexpr int kLargefile = 0100000; + EXPECT_THAT(fcntl(rfd.get(), F_GETFL), + SyscallSucceedsWithValue(kLargefile | O_RDONLY)); + EXPECT_THAT(fcntl(wfd.get(), F_GETFL), + SyscallSucceedsWithValue(kLargefile | O_WRONLY)); + } else { + EXPECT_THAT(fcntl(rfd.get(), F_GETFL), SyscallSucceedsWithValue(O_RDONLY)); + EXPECT_THAT(fcntl(wfd.get(), F_GETFL), SyscallSucceedsWithValue(O_WRONLY)); + } +} - ASSERT_THAT(fcntl(fds[0], F_GETFL), SyscallSucceeds()); - ASSERT_THAT(fcntl(fds[1], F_GETFL), SyscallSucceeds()); +TEST_P(PipeTest, Write) { + SKIP_IF(!CreateBlocking()); - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); + int wbuf = kTestValue; + int rbuf = ~kTestValue; + ASSERT_THAT(write(wfd.get(), &wbuf, sizeof(wbuf)), + SyscallSucceedsWithValue(sizeof(wbuf))); + ASSERT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallSucceedsWithValue(sizeof(rbuf))); + EXPECT_EQ(wbuf, rbuf); } -TEST_F(PipeTest, BasicNoBlock) { - // fds[0] is read end, fds[1] is write end. - int fds[2]; - int i = 0x12345678; - ASSERT_THAT(pipe2(fds, O_NONBLOCK), SyscallSucceeds()); - - ASSERT_THAT(write(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - ASSERT_THAT(read(fds[1], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - - ASSERT_THAT(read(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EWOULDBLOCK)); - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); - int j; - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); - EXPECT_EQ(i, j); - ASSERT_THAT(read(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EWOULDBLOCK)); - - ASSERT_THAT(fcntl(fds[0], F_GETFL), SyscallSucceedsWithValue(O_NONBLOCK)); - ASSERT_THAT(fcntl(fds[1], F_GETFL), - SyscallSucceedsWithValue(O_NONBLOCK | O_WRONLY)); - - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); +TEST_P(PipeTest, NonBlocking) { + SKIP_IF(!CreateNonBlocking()); + + int wbuf = kTestValue; + int rbuf = ~kTestValue; + EXPECT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallFailsWithErrno(EWOULDBLOCK)); + ASSERT_THAT(write(wfd.get(), &wbuf, sizeof(wbuf)), + SyscallSucceedsWithValue(sizeof(wbuf))); + + ASSERT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallSucceedsWithValue(sizeof(rbuf))); + EXPECT_EQ(wbuf, rbuf); + EXPECT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallFailsWithErrno(EWOULDBLOCK)); } -TEST_F(PipeTest, BasicBothOptions) { - // fds[0] is read end, fds[1] is write end. +TEST(Pipe2Test, CloExec) { int fds[2]; - int i = 0x12345678; - ASSERT_THAT(pipe2(fds, O_NONBLOCK | O_CLOEXEC), SyscallSucceeds()); - - ASSERT_THAT(write(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - ASSERT_THAT(read(fds[1], &i, sizeof(i)), SyscallFailsWithErrno(EBADF)); - - ASSERT_THAT(read(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EWOULDBLOCK)); - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); - int j; - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); - EXPECT_EQ(i, j); - ASSERT_THAT(read(fds[0], &i, sizeof(i)), SyscallFailsWithErrno(EWOULDBLOCK)); - - ASSERT_THAT(fcntl(fds[0], F_GETFL), SyscallSucceedsWithValue(O_NONBLOCK)); - ASSERT_THAT(fcntl(fds[1], F_GETFL), - SyscallSucceedsWithValue(O_NONBLOCK | O_WRONLY)); - - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); + ASSERT_THAT(pipe2(fds, O_CLOEXEC), SyscallSucceeds()); + EXPECT_THAT(fcntl(fds[0], F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC)); + EXPECT_THAT(fcntl(fds[1], F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC)); + EXPECT_THAT(close(fds[0]), SyscallSucceeds()); + EXPECT_THAT(close(fds[1]), SyscallSucceeds()); } -TEST_F(PipeTest, BasicBadOptions) { +TEST(Pipe2Test, BadOptions) { int fds[2]; - ASSERT_THAT(pipe2(fds, 0xDEAD), SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(pipe2(fds, 0xDEAD), SyscallFailsWithErrno(EINVAL)); } -TEST_F(PipeTest, Seek) { - // fds[0] is read end, fds[1] is write end. - int fds[2]; - int i = 0x12345678; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - - ASSERT_THAT(lseek(fds[0], 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[0], 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[0], 4, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 4, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - - ASSERT_THAT(lseek(fds[0], 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[0], 4, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 4, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); - int j; - - ASSERT_THAT(lseek(fds[0], 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[0], 4, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 4, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); - - ASSERT_THAT(lseek(fds[0], 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[0], 4, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - ASSERT_THAT(lseek(fds[1], 4, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); - - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); - EXPECT_EQ(i, j); - - ASSERT_THAT(fcntl(fds[0], F_GETFL), SyscallSucceeds()); - ASSERT_THAT(fcntl(fds[1], F_GETFL), SyscallSucceedsWithValue(O_WRONLY)); - - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); +TEST_P(PipeTest, Seek) { + SKIP_IF(!CreateBlocking()); + + for (int i = 0; i < 4; i++) { + // Attempt absolute seeks. + EXPECT_THAT(lseek(rfd.get(), 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(rfd.get(), 4, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(wfd.get(), 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(wfd.get(), 4, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); + + // Attempt relative seeks. + EXPECT_THAT(lseek(rfd.get(), 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(rfd.get(), 4, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(wfd.get(), 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(wfd.get(), 4, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); + + // Attempt end-of-file seeks. + EXPECT_THAT(lseek(rfd.get(), 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(rfd.get(), -4, SEEK_END), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(wfd.get(), 0, SEEK_CUR), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(lseek(wfd.get(), -4, SEEK_END), SyscallFailsWithErrno(ESPIPE)); + + // Add some more data to the pipe. + int buf = kTestValue; + ASSERT_THAT(write(wfd.get(), &buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(buf))); + } } -TEST_F(PipeTest, AbsoluteOffsetSyscallsFail) { - // Syscalls for IO at absolute offsets fail because pipes are not seekable. - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - - std::vector buf(4096); - struct iovec iov; +TEST_P(PipeTest, OffsetCalls) { + SKIP_IF(!CreateBlocking()); - EXPECT_THAT(pread(fds[1], buf.data(), buf.size(), 0), + int buf; + EXPECT_THAT(pread(wfd.get(), &buf, sizeof(buf), 0), SyscallFailsWithErrno(ESPIPE)); - EXPECT_THAT(pwrite(fds[0], buf.data(), buf.size(), 0), + EXPECT_THAT(pwrite(rfd.get(), &buf, sizeof(buf), 0), SyscallFailsWithErrno(ESPIPE)); - EXPECT_THAT(preadv(fds[1], &iov, 1, 0), SyscallFailsWithErrno(ESPIPE)); - EXPECT_THAT(pwritev(fds[0], &iov, 1, 0), SyscallFailsWithErrno(ESPIPE)); - EXPECT_THAT(close(fds[0]), SyscallSucceeds()); - EXPECT_THAT(close(fds[1]), SyscallSucceeds()); + struct iovec iov; + EXPECT_THAT(preadv(wfd.get(), &iov, 1, 0), SyscallFailsWithErrno(ESPIPE)); + EXPECT_THAT(pwritev(rfd.get(), &iov, 1, 0), SyscallFailsWithErrno(ESPIPE)); } -TEST_F(PipeTest, WriterSideCloses) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - int rfd = fds[0]; - int i = 123; - ScopedThread t([rfd]() { - int j; - ASSERT_THAT(read(rfd, &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); +TEST_P(PipeTest, WriterSideCloses) { + SKIP_IF(!CreateBlocking()); + + ScopedThread t([this]() { + int buf = ~kTestValue; + ASSERT_THAT(read(rfd.get(), &buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(buf))); + EXPECT_EQ(buf, kTestValue); // This will return when the close() completes. - ASSERT_THAT(read(rfd, &j, sizeof(j)), SyscallSucceeds()); + ASSERT_THAT(read(rfd.get(), &buf, sizeof(buf)), SyscallSucceeds()); // This will return straight away. - ASSERT_THAT(read(rfd, &j, sizeof(j)), SyscallSucceeds()); + ASSERT_THAT(read(rfd.get(), &buf, sizeof(buf)), + SyscallSucceedsWithValue(0)); }); + // Sleep a bit so the thread can block. - absl::SleepFor(absl::Seconds(1.0)); - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); + absl::SleepFor(syncDelay); + + // Write to unblock. + int buf = kTestValue; + ASSERT_THAT(write(wfd.get(), &buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(buf))); + // Sleep a bit so the thread can block again. - absl::SleepFor(absl::Seconds(3.0)); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); - t.Join(); + absl::SleepFor(syncDelay); - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); + // Allow the thread to complete. + ASSERT_THAT(close(wfd.release()), SyscallSucceeds()); + t.Join(); } -TEST_F(PipeTest, WriterSideClosesReadDataFirst) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - int i = 123; - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); - int j; - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceedsWithValue(sizeof(j))); - ASSERT_EQ(j, i); - ASSERT_THAT(read(fds[0], &j, sizeof(j)), SyscallSucceeds()); - - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); +TEST_P(PipeTest, WriterSideClosesReadDataFirst) { + SKIP_IF(!CreateBlocking()); + + int wbuf = kTestValue; + ASSERT_THAT(write(wfd.get(), &wbuf, sizeof(wbuf)), + SyscallSucceedsWithValue(sizeof(wbuf))); + ASSERT_THAT(close(wfd.release()), SyscallSucceeds()); + + int rbuf; + ASSERT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallSucceedsWithValue(sizeof(rbuf))); + EXPECT_EQ(wbuf, rbuf); + EXPECT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallSucceedsWithValue(0)); } -TEST_F(PipeTest, ReaderSideCloses) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - int i = 123; - ASSERT_THAT(write(fds[1], &i, sizeof(i)), SyscallFailsWithErrno(EPIPE)); +TEST_P(PipeTest, ReaderSideCloses) { + SKIP_IF(!CreateBlocking()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); + ASSERT_THAT(close(rfd.release()), SyscallSucceeds()); + int buf = kTestValue; + EXPECT_THAT(write(wfd.get(), &buf, sizeof(buf)), + SyscallFailsWithErrno(EPIPE)); } -TEST_F(PipeTest, CloseTwice) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); - ASSERT_THAT(close(fds[0]), SyscallFailsWithErrno(EBADF)); - ASSERT_THAT(close(fds[1]), SyscallFailsWithErrno(EBADF)); - - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - ASSERT_THAT(close(fds[0]), SyscallFailsWithErrno(EBADF)); - ASSERT_THAT(close(fds[1]), SyscallFailsWithErrno(EBADF)); +TEST_P(PipeTest, CloseTwice) { + SKIP_IF(!CreateBlocking()); + + int _rfd = rfd.release(); + int _wfd = wfd.release(); + ASSERT_THAT(close(_rfd), SyscallSucceeds()); + ASSERT_THAT(close(_wfd), SyscallSucceeds()); + EXPECT_THAT(close(_rfd), SyscallFailsWithErrno(EBADF)); + EXPECT_THAT(close(_wfd), SyscallFailsWithErrno(EBADF)); } // Blocking write returns EPIPE when read end is closed if nothing has been // written. -TEST_F(PipeTest, BlockWriteClosed) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - int wfd = fds[1]; +TEST_P(PipeTest, BlockWriteClosed) { + SKIP_IF(!CreateBlocking()); absl::Notification notify; - ScopedThread t([wfd, ¬ify]() { - std::vector buf(kPipeSize); + ScopedThread t([this, ¬ify]() { + std::vector buf(Size()); // Exactly fill the pipe buffer. - ASSERT_THAT(WriteFd(wfd, buf.data(), buf.size()), + ASSERT_THAT(WriteFd(wfd.get(), buf.data(), buf.size()), SyscallSucceedsWithValue(buf.size())); notify.Notify(); // Attempt to write one more byte. Blocks. // N.B. Don't use WriteFd, we don't want a retry. - ASSERT_THAT(write(wfd, buf.data(), 1), SyscallFailsWithErrno(EPIPE)); + EXPECT_THAT(write(wfd.get(), buf.data(), 1), SyscallFailsWithErrno(EPIPE)); }); notify.WaitForNotification(); - absl::SleepFor(absl::Seconds(1.0)); - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - + ASSERT_THAT(close(rfd.release()), SyscallSucceeds()); t.Join(); - - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); } // Blocking write returns EPIPE when read end is closed even if something has // been written. -// -// FIXME(b/35924046): Pipe writes blocking early allows S/R to interrupt the -// write(2) call before the buffer is full. Then the next call will will return -// non-zero instead of EPIPE. -TEST_F(PipeTest, BlockPartialWriteClosed_NoRandomSave) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - int wfd = fds[1]; +TEST_P(PipeTest, BlockPartialWriteClosed) { + SKIP_IF(!CreateBlocking()); - ScopedThread t([wfd]() { - std::vector buf(2 * kPipeSize); + ScopedThread t([this]() { + std::vector buf(2 * Size()); // Write more than fits in the buffer. Blocks then returns partial write // when the other end is closed. The next call returns EPIPE. - if (IsRunningOnGvisor()) { - // FIXME(b/35924046): Pipe writes block early on gVisor, resulting in a - // shorter than expected partial write. - ASSERT_THAT(write(wfd, buf.data(), buf.size()), - SyscallSucceedsWithValue(::testing::Gt(0))); - } else { - ASSERT_THAT(write(wfd, buf.data(), buf.size()), - SyscallSucceedsWithValue(kPipeSize)); - } - ASSERT_THAT(write(wfd, buf.data(), buf.size()), + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(Size())); + EXPECT_THAT(write(wfd.get(), buf.data(), buf.size()), SyscallFailsWithErrno(EPIPE)); }); // Leave time for write to become blocked. - absl::SleepFor(absl::Seconds(1.0)); - - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); + absl::SleepFor(syncDelay); + // Unblock the above. + ASSERT_THAT(close(rfd.release()), SyscallSucceeds()); t.Join(); - - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); } -TEST_F(PipeTest, ReadFromClosedFd_NoRandomSave) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - int rfd = fds[0]; +TEST_P(PipeTest, ReadFromClosedFd_NoRandomSave) { + SKIP_IF(!CreateBlocking()); + absl::Notification notify; - ScopedThread t([rfd, ¬ify]() { - int f; + ScopedThread t([this, ¬ify]() { notify.Notify(); - ASSERT_THAT(read(rfd, &f, sizeof(f)), SyscallSucceedsWithValue(sizeof(f))); - ASSERT_EQ(123, f); + int buf; + ASSERT_THAT(read(rfd.get(), &buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(buf))); + ASSERT_EQ(kTestValue, buf); }); notify.WaitForNotification(); + // Make sure that the thread gets to read(). - absl::SleepFor(absl::Seconds(5.0)); + absl::SleepFor(syncDelay); + { // We cannot save/restore here as the read end of pipe is closed but there // is ongoing read() above. We will not be able to restart the read() // successfully in restore run since the read fd is closed. const DisableSave ds; - ASSERT_THAT(close(fds[0]), SyscallSucceeds()); - int i = 123; - ASSERT_THAT(write(fds[1], &i, sizeof(i)), - SyscallSucceedsWithValue(sizeof(i))); + ASSERT_THAT(close(rfd.release()), SyscallSucceeds()); + int buf = kTestValue; + ASSERT_THAT(write(wfd.get(), &buf, sizeof(buf)), + SyscallSucceedsWithValue(sizeof(buf))); t.Join(); } - ASSERT_THAT(close(fds[1]), SyscallSucceeds()); } -TEST_F(PipeTest, FionRead) { - // fds[0] is read end, fds[1] is write end. - int fds[2]; - int data[2] = {0x12345678, 0x9101112}; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); +TEST_P(PipeTest, FionRead) { + SKIP_IF(!CreateBlocking()); - int n = -1; - EXPECT_THAT(ioctl(fds[0], FIONREAD, &n), SyscallSucceedsWithValue(0)); + int n; + ASSERT_THAT(ioctl(rfd.get(), FIONREAD, &n), SyscallSucceedsWithValue(0)); EXPECT_EQ(n, 0); - n = -1; - EXPECT_THAT(ioctl(fds[1], FIONREAD, &n), SyscallSucceedsWithValue(0)); + ASSERT_THAT(ioctl(wfd.get(), FIONREAD, &n), SyscallSucceedsWithValue(0)); EXPECT_EQ(n, 0); - EXPECT_THAT(write(fds[1], data, sizeof(data)), - SyscallSucceedsWithValue(sizeof(data))); + std::vector buf(Size()); + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(buf.size())); - n = -1; - EXPECT_THAT(ioctl(fds[0], FIONREAD, &n), SyscallSucceedsWithValue(0)); - EXPECT_EQ(n, sizeof(data)); - n = -1; - EXPECT_THAT(ioctl(fds[1], FIONREAD, &n), SyscallSucceedsWithValue(0)); - EXPECT_EQ(n, sizeof(data)); + EXPECT_THAT(ioctl(rfd.get(), FIONREAD, &n), SyscallSucceedsWithValue(0)); + EXPECT_EQ(n, buf.size()); + EXPECT_THAT(ioctl(wfd.get(), FIONREAD, &n), SyscallSucceedsWithValue(0)); + EXPECT_EQ(n, buf.size()); } // Test that opening an empty anonymous pipe RDONLY via /proc/self/fd/N does not // block waiting for a writer. -TEST_F(PipeTest, OpenViaProcSelfFD) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - FileDescriptor rfd(fds[0]); - FileDescriptor wfd(fds[1]); +TEST_P(PipeTest, OpenViaProcSelfFD) { + SKIP_IF(!CreateBlocking()); + SKIP_IF(IsNamedPipe()); // Close the write end of the pipe. - wfd.release(); + ASSERT_THAT(close(wfd.release()), SyscallSucceeds()); // Open other side via /proc/self/fd. It should not block. FileDescriptor proc_self_fd = ASSERT_NO_ERRNO_AND_VALUE( - Open(absl::StrCat("/proc/self/fd/", fds[0]), O_RDONLY)); + Open(absl::StrCat("/proc/self/fd/", rfd.get()), O_RDONLY)); } // Test that opening and reading from an anonymous pipe (with existing writes) // RDONLY via /proc/self/fd/N returns the existing data. -TEST_F(PipeTest, OpenViaProcSelfFDWithWrites) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - FileDescriptor rfd(fds[0]); - FileDescriptor wfd(fds[1]); +TEST_P(PipeTest, OpenViaProcSelfFDWithWrites) { + SKIP_IF(!CreateBlocking()); + SKIP_IF(IsNamedPipe()); // Write to the pipe and then close the write fd. - char data = 'x'; - ASSERT_THAT(write(fds[1], &data, 1), SyscallSucceedsWithValue(1)); - wfd.release(); + int wbuf = kTestValue; + ASSERT_THAT(write(wfd.get(), &wbuf, sizeof(wbuf)), + SyscallSucceedsWithValue(sizeof(wbuf))); + ASSERT_THAT(close(wfd.release()), SyscallSucceeds()); // Open read side via /proc/self/fd, and read from it. FileDescriptor proc_self_fd = ASSERT_NO_ERRNO_AND_VALUE( - Open(absl::StrCat("/proc/self/fd/", fds[0]), O_RDONLY)); - char got; - ASSERT_THAT(read(proc_self_fd.get(), &got, 1), SyscallSucceedsWithValue(1)); + Open(absl::StrCat("/proc/self/fd/", rfd.get()), O_RDONLY)); + int rbuf; + ASSERT_THAT(read(proc_self_fd.get(), &rbuf, sizeof(rbuf)), + SyscallSucceedsWithValue(sizeof(rbuf))); + EXPECT_EQ(wbuf, rbuf); +} + +// Test that accesses of /proc//fd correctly decrement the refcount. +TEST_P(PipeTest, ProcFDReleasesFile) { + SKIP_IF(!CreateBlocking()); - // We should get what we sent. - EXPECT_EQ(got, data); + // Stat the pipe FD, which shouldn't alter the refcount. + struct stat wst; + ASSERT_THAT(lstat(absl::StrCat("/proc/self/fd/", wfd.get()).c_str(), &wst), + SyscallSucceeds()); + + // Close the write end and ensure that read indicates EOF. + wfd.reset(); + char buf; + ASSERT_THAT(read(rfd.get(), &buf, 1), SyscallSucceedsWithValue(0)); } -TEST_F(PipeTest, LargeFile) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - FileDescriptor rfd(fds[0]); - FileDescriptor wfd(fds[1]); +// Same for /proc//fdinfo. +TEST_P(PipeTest, ProcFDInfoReleasesFile) { + SKIP_IF(!CreateBlocking()); + + // Stat the pipe FD, which shouldn't alter the refcount. + struct stat wst; + ASSERT_THAT( + lstat(absl::StrCat("/proc/self/fdinfo/", wfd.get()).c_str(), &wst), + SyscallSucceeds()); + + // Close the write end and ensure that read indicates EOF. + wfd.reset(); + char buf; + ASSERT_THAT(read(rfd.get(), &buf, 1), SyscallSucceedsWithValue(0)); +} + +TEST_P(PipeTest, SizeChange) { + SKIP_IF(!CreateBlocking()); + + // Set the minimum possible size. + ASSERT_THAT(fcntl(rfd.get(), F_SETPIPE_SZ, 0), SyscallSucceeds()); + int min = Size(); + EXPECT_GT(min, 0); // Should be rounded up. + + // Set from the read end. + ASSERT_THAT(fcntl(rfd.get(), F_SETPIPE_SZ, min + 1), SyscallSucceeds()); + int med = Size(); + EXPECT_GT(med, min); // Should have grown, may be rounded. + + // Set from the write end. + ASSERT_THAT(fcntl(wfd.get(), F_SETPIPE_SZ, med + 1), SyscallSucceeds()); + int max = Size(); + EXPECT_GT(max, med); // Ditto. +} - int rflags; - EXPECT_THAT(rflags = fcntl(rfd.get(), F_GETFL), SyscallSucceeds()); +TEST_P(PipeTest, SizeChangeMax) { + SKIP_IF(!CreateBlocking()); - // The kernel did *not* set O_LARGEFILE. - EXPECT_EQ(rflags, 0); + // Assert there's some maximum. + EXPECT_THAT(fcntl(rfd.get(), F_SETPIPE_SZ, 0x7fffffffffffffff), + SyscallFailsWithErrno(EINVAL)); + EXPECT_THAT(fcntl(wfd.get(), F_SETPIPE_SZ, 0x7fffffffffffffff), + SyscallFailsWithErrno(EINVAL)); } -// Test that accesses of /proc//fd/ and /proc//fdinfo/ -// correctly decrement the refcount of that file descriptor. -TEST_F(PipeTest, ProcFDReleasesFile) { - std::vector paths = {"/proc/self/fd/", "/proc/self/fdinfo/"}; - for (const std::string& path : paths) { - int fds[2]; - ASSERT_THAT(pipe(fds), SyscallSucceeds()); - FileDescriptor rfd(fds[0]); - FileDescriptor wfd(fds[1]); - - // Stat the pipe FD, which shouldn't alter the refcount of the write end of - // the pipe. - struct stat wst; - ASSERT_THAT(lstat(absl::StrCat(path.c_str(), wfd.get()).c_str(), &wst), - SyscallSucceeds()); - // Close the write end of the pipe and ensure that read indicates EOF. - wfd.reset(); - char buf; - ASSERT_THAT(read(rfd.get(), &buf, 1), SyscallSucceedsWithValue(0)); +TEST_P(PipeTest, SizeChangeFull) { + SKIP_IF(!CreateBlocking()); + + // Ensure that we adjust to a large enough size to avoid rounding when we + // perform the size decrease. If rounding occurs, we may not actually + // adjust the size and the call below will return success. It was found via + // experimentation that this granularity avoids the rounding for Linux. + constexpr int kDelta = 64 * 1024; + ASSERT_THAT(fcntl(wfd.get(), F_SETPIPE_SZ, Size() + kDelta), + SyscallSucceeds()); + + // Fill the buffer and try to change down. + std::vector buf(Size()); + ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()), + SyscallSucceedsWithValue(buf.size())); + EXPECT_THAT(fcntl(wfd.get(), F_SETPIPE_SZ, Size() - kDelta), + SyscallFailsWithErrno(EBUSY)); +} + +TEST_P(PipeTest, Streaming) { + SKIP_IF(!CreateBlocking()); + + // We make too many calls to go through full save cycles. + DisableSave ds; + + absl::Notification notify; + ScopedThread t([this, ¬ify]() { + // Don't start until it's full. + notify.WaitForNotification(); + for (int i = 0; i < 2 * Size(); i++) { + int rbuf; + ASSERT_THAT(read(rfd.get(), &rbuf, sizeof(rbuf)), + SyscallSucceedsWithValue(sizeof(rbuf))); + EXPECT_EQ(rbuf, i); + } + }); + for (int i = 0; i < 2 * Size(); i++) { + int wbuf = i; + ASSERT_THAT(write(wfd.get(), &wbuf, sizeof(wbuf)), + SyscallSucceedsWithValue(sizeof(wbuf))); + // Did that write just fill up the buffer? Wake up the reader. Once only. + if ((i * sizeof(wbuf)) < Size() && ((i + 1) * sizeof(wbuf)) >= Size()) { + notify.Notify(); + } } } +std::string PipeCreatorName(::testing::TestParamInfo info) { + return info.param.name_; // Use the name specified. +} + +INSTANTIATE_TEST_SUITE_P( + Pipes, PipeTest, + ::testing::Values( + PipeCreator{ + "pipe", + [](int fds[2], bool* is_blocking, bool* is_namedpipe) { + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + *is_blocking = true; + *is_namedpipe = false; + }, + }, + PipeCreator{ + "pipe2blocking", + [](int fds[2], bool* is_blocking, bool* is_namedpipe) { + ASSERT_THAT(pipe2(fds, 0), SyscallSucceeds()); + *is_blocking = true; + *is_namedpipe = false; + }, + }, + PipeCreator{ + "pipe2nonblocking", + [](int fds[2], bool* is_blocking, bool* is_namedpipe) { + ASSERT_THAT(pipe2(fds, O_NONBLOCK), SyscallSucceeds()); + *is_blocking = false; + *is_namedpipe = false; + }, + }, + PipeCreator{ + "smallbuffer", + [](int fds[2], bool* is_blocking, bool* is_namedpipe) { + // Set to the minimum available size (will round up). + ASSERT_THAT(pipe(fds), SyscallSucceeds()); + ASSERT_THAT(fcntl(fds[0], F_SETPIPE_SZ, 0), SyscallSucceeds()); + *is_blocking = true; + *is_namedpipe = false; + }, + }, + PipeCreator{ + "namednonblocking", + [](int fds[2], bool* is_blocking, bool* is_namedpipe) { + // Create a new file-based pipe (non-blocking). + auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + ASSERT_THAT(unlink(file.path().c_str()), SyscallSucceeds()); + SKIP_IF(mkfifo(file.path().c_str(), 0644) != 0); + fds[0] = open(file.path().c_str(), O_NONBLOCK | O_RDONLY); + fds[1] = open(file.path().c_str(), O_NONBLOCK | O_WRONLY); + MaybeSave(); + *is_blocking = false; + *is_namedpipe = true; + }, + }, + PipeCreator{ + "namedblocking", + [](int fds[2], bool* is_blocking, bool* is_namedpipe) { + // Create a new file-based pipe (blocking). + auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + ASSERT_THAT(unlink(file.path().c_str()), SyscallSucceeds()); + SKIP_IF(mkfifo(file.path().c_str(), 0644) != 0); + ScopedThread t([&file, &fds]() { + fds[1] = open(file.path().c_str(), O_WRONLY); + }); + fds[0] = open(file.path().c_str(), O_RDONLY); + t.Join(); + MaybeSave(); + *is_blocking = true; + *is_namedpipe = true; + }, + }), + PipeCreatorName); + } // namespace } // namespace testing } // namespace gvisor -- cgit v1.2.3 From 69eac1198f3dae9a41ddf1903e9dda7972ed5d77 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 22 May 2019 11:14:29 -0700 Subject: Move wait constants to abi/linux package Updates #214 PiperOrigin-RevId: 249483756 Change-Id: I0d3cf4112bed75a863d5eb08c2063fbc506cd875 --- pkg/abi/linux/BUILD | 1 + pkg/abi/linux/wait.go | 36 ++++++++++++++++++++++++++++ pkg/sentry/syscalls/linux/sys_thread.go | 42 +++++++++++++-------------------- 3 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 pkg/abi/linux/wait.go (limited to 'pkg/abi') diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD index 96e8d4641..fbd0e4674 100644 --- a/pkg/abi/linux/BUILD +++ b/pkg/abi/linux/BUILD @@ -52,6 +52,7 @@ go_library( "tty.go", "uio.go", "utsname.go", + "wait.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/abi/linux", visibility = ["//visibility:public"], diff --git a/pkg/abi/linux/wait.go b/pkg/abi/linux/wait.go new file mode 100644 index 000000000..4bdc280d1 --- /dev/null +++ b/pkg/abi/linux/wait.go @@ -0,0 +1,36 @@ +// Copyright 2019 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 linux + +// Options for waitpid(2), wait4(2), and/or waitid(2), from +// include/uapi/linux/wait.h. +const ( + WNOHANG = 0x00000001 + WUNTRACED = 0x00000002 + WSTOPPED = WUNTRACED + WEXITED = 0x00000004 + WCONTINUED = 0x00000008 + WNOWAIT = 0x01000000 + WNOTHREAD = 0x20000000 + WALL = 0x40000000 + WCLONE = 0x80000000 +) + +// ID types for waitid(2), from include/uapi/linux/wait.h. +const ( + P_ALL = 0x0 + P_PID = 0x1 + P_PGID = 0x2 +) diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go index 23c2f7035..cc441460c 100644 --- a/pkg/sentry/syscalls/linux/sys_thread.go +++ b/pkg/sentry/syscalls/linux/sys_thread.go @@ -42,14 +42,6 @@ const ( exitSignalMask = 0xff ) -// Possible values for the idtype argument to waitid(2), defined in Linux's -// include/uapi/linux/wait.h. -const ( - _P_ALL = 0 - _P_PID = 1 - _P_PGID = 2 -) - // Getppid implements linux syscall getppid(2). func Getppid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { parent := t.Parent() @@ -191,7 +183,7 @@ func Vfork(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall // wait4 waits for the given child process to exit. func wait4(t *kernel.Task, pid int, statusAddr usermem.Addr, options int, rusageAddr usermem.Addr) (uintptr, error) { - if options&^(syscall.WNOHANG|syscall.WUNTRACED|syscall.WCONTINUED|syscall.WALL|syscall.WCLONE) != 0 { + if options&^(linux.WNOHANG|linux.WUNTRACED|linux.WCONTINUED|linux.WALL|linux.WCLONE) != 0 { return 0, syscall.EINVAL } wopts := kernel.WaitOptions{ @@ -215,24 +207,24 @@ func wait4(t *kernel.Task, pid int, statusAddr usermem.Addr, options int, rusage wopts.SpecificTID = kernel.ThreadID(pid) } - switch options & (syscall.WCLONE | syscall.WALL) { + switch options & (linux.WCLONE | linux.WALL) { case 0: wopts.NonCloneTasks = true - case syscall.WCLONE: + case linux.WCLONE: wopts.CloneTasks = true - case syscall.WALL: + case linux.WALL: wopts.NonCloneTasks = true wopts.CloneTasks = true default: return 0, syscall.EINVAL } - if options&syscall.WUNTRACED != 0 { + if options&linux.WUNTRACED != 0 { wopts.Events |= kernel.EventChildGroupStop } - if options&syscall.WCONTINUED != 0 { + if options&linux.WCONTINUED != 0 { wopts.Events |= kernel.EventGroupContinue } - if options&syscall.WNOHANG == 0 { + if options&linux.WNOHANG == 0 { wopts.BlockInterruptErr = kernel.ERESTARTSYS } @@ -286,36 +278,36 @@ func Waitid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal options := int(args[3].Uint()) rusageAddr := args[4].Pointer() - if options&^(syscall.WNOHANG|syscall.WEXITED|syscall.WSTOPPED|syscall.WCONTINUED|syscall.WNOWAIT) != 0 { + if options&^(linux.WNOHANG|linux.WEXITED|linux.WSTOPPED|linux.WCONTINUED|linux.WNOWAIT) != 0 { return 0, nil, syscall.EINVAL } - if options&(syscall.WEXITED|syscall.WSTOPPED|syscall.WCONTINUED) == 0 { + if options&(linux.WEXITED|linux.WSTOPPED|linux.WCONTINUED) == 0 { return 0, nil, syscall.EINVAL } wopts := kernel.WaitOptions{ NonCloneTasks: true, Events: kernel.EventTraceeStop, - ConsumeEvent: options&syscall.WNOWAIT == 0, + ConsumeEvent: options&linux.WNOWAIT == 0, } switch idtype { - case _P_ALL: - case _P_PID: + case linux.P_ALL: + case linux.P_PID: wopts.SpecificTID = kernel.ThreadID(id) - case _P_PGID: + case linux.P_PGID: wopts.SpecificPGID = kernel.ProcessGroupID(id) default: return 0, nil, syscall.EINVAL } - if options&syscall.WEXITED != 0 { + if options&linux.WEXITED != 0 { wopts.Events |= kernel.EventExit } - if options&syscall.WSTOPPED != 0 { + if options&linux.WSTOPPED != 0 { wopts.Events |= kernel.EventChildGroupStop } - if options&syscall.WCONTINUED != 0 { + if options&linux.WCONTINUED != 0 { wopts.Events |= kernel.EventGroupContinue } - if options&syscall.WNOHANG == 0 { + if options&linux.WNOHANG == 0 { wopts.BlockInterruptErr = kernel.ERESTARTSYS } -- cgit v1.2.3 From 6cdec6fadf7515a2d8feddcbc3058927897cbbc9 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 24 May 2019 13:23:01 -0700 Subject: Wrap comments and reword in common present tense PiperOrigin-RevId: 249888234 Change-Id: Icfef32c3ed34809c34100c07e93e9581c786776e --- pkg/abi/linux/prctl.go | 93 +++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) (limited to 'pkg/abi') diff --git a/pkg/abi/linux/prctl.go b/pkg/abi/linux/prctl.go index dae2de290..0428282dd 100644 --- a/pkg/abi/linux/prctl.go +++ b/pkg/abi/linux/prctl.go @@ -16,80 +16,80 @@ package linux // PR_* flags, from for prctl(2). const ( - // PR_SET_PDEATHSIG will set the process' death signal. + // PR_SET_PDEATHSIG sets the process' death signal. PR_SET_PDEATHSIG = 1 - // PR_GET_PDEATHSIG will get the process' death signal. + // PR_GET_PDEATHSIG gets the process' death signal. PR_GET_PDEATHSIG = 2 - // PR_GET_DUMPABLE will get the process's dumpable flag. + // PR_GET_DUMPABLE gets the process' dumpable flag. PR_GET_DUMPABLE = 3 - // PR_SET_DUMPABLE will set the process's dumpable flag. + // PR_SET_DUMPABLE sets the process' dumpable flag. PR_SET_DUMPABLE = 4 - // PR_GET_KEEPCAPS will get the value of the keep capabilities flag. + // PR_GET_KEEPCAPS gets the value of the keep capabilities flag. PR_GET_KEEPCAPS = 7 - // PR_SET_KEEPCAPS will set the value of the keep capabilities flag. + // PR_SET_KEEPCAPS sets the value of the keep capabilities flag. PR_SET_KEEPCAPS = 8 - // PR_GET_TIMING will get the process's timing method. + // PR_GET_TIMING gets the process' timing method. PR_GET_TIMING = 13 - // PR_SET_TIMING will set the process's timing method. + // PR_SET_TIMING sets the process' timing method. PR_SET_TIMING = 14 - // PR_SET_NAME will set the process' name. + // PR_SET_NAME sets the process' name. PR_SET_NAME = 15 - // PR_GET_NAME will get the process' name. + // PR_GET_NAME gets the process' name. PR_GET_NAME = 16 - // PR_GET_SECCOMP will get a process' seccomp mode. + // PR_GET_SECCOMP gets a process' seccomp mode. PR_GET_SECCOMP = 21 - // PR_SET_SECCOMP will set a process' seccomp mode. + // PR_SET_SECCOMP sets a process' seccomp mode. PR_SET_SECCOMP = 22 - // PR_CAPBSET_READ will get the capability bounding set. + // PR_CAPBSET_READ gets the capability bounding set. PR_CAPBSET_READ = 23 - // PR_CAPBSET_DROP will set the capability bounding set. + // PR_CAPBSET_DROP sets the capability bounding set. PR_CAPBSET_DROP = 24 - // PR_GET_TSC will get the the value of the flag determining whether the + // PR_GET_TSC gets the value of the flag determining whether the // timestamp counter can be read. PR_GET_TSC = 25 - // PR_SET_TSC will set the the value of the flag determining whether the + // PR_SET_TSC sets the value of the flag determining whether the // timestamp counter can be read. PR_SET_TSC = 26 - // PR_SET_TIMERSLACK set the process's time slack. + // PR_SET_TIMERSLACK sets the process' time slack. PR_SET_TIMERSLACK = 29 - // PR_GET_TIMERSLACK get the process's time slack. + // PR_GET_TIMERSLACK gets the process' time slack. PR_GET_TIMERSLACK = 30 - // PR_TASK_PERF_EVENTS_DISABLE disable all performance counters attached to - // the calling process. + // PR_TASK_PERF_EVENTS_DISABLE disables all performance counters + // attached to the calling process. PR_TASK_PERF_EVENTS_DISABLE = 31 - // PR_TASK_PERF_EVENTS_ENABLE enable all performance counters attached to - // the calling process. + // PR_TASK_PERF_EVENTS_ENABLE enables all performance counters attached + // to the calling process. PR_TASK_PERF_EVENTS_ENABLE = 32 - // PR_MCE_KILL set the machine check memory corruption kill policy for the - // calling thread. + // PR_MCE_KILL sets the machine check memory corruption kill policy for + // the calling thread. PR_MCE_KILL = 33 - // PR_MCE_KILL_GET get the machine check memory corruption kill policy for the - // calling thread. + // PR_MCE_KILL_GET gets the machine check memory corruption kill policy + // for the calling thread. PR_MCE_KILL_GET = 34 - // PR_SET_MM will modify certain kernel memory map descriptor fields of the - // calling process. See prctl(2) for more information. + // PR_SET_MM modifies certain kernel memory map descriptor fields of + // the calling process. See prctl(2) for more information. PR_SET_MM = 35 PR_SET_MM_START_CODE = 1 @@ -104,44 +104,45 @@ const ( PR_SET_MM_ENV_START = 10 PR_SET_MM_ENV_END = 11 PR_SET_MM_AUXV = 12 - // PR_SET_MM_EXE_FILE will supersede the /proc/pid/exe symbolic link with a - // new one pointing to a new executable file identified by the file descriptor - // provided in arg3 argument. See prctl(2) for more information. + // PR_SET_MM_EXE_FILE supersedes the /proc/pid/exe symbolic link with a + // new one pointing to a new executable file identified by the file + // descriptor provided in arg3 argument. See prctl(2) for more + // information. PR_SET_MM_EXE_FILE = 13 PR_SET_MM_MAP = 14 PR_SET_MM_MAP_SIZE = 15 - // PR_SET_CHILD_SUBREAPER set the "child subreaper" attribute of the calling - // process. + // PR_SET_CHILD_SUBREAPER sets the "child subreaper" attribute of the + // calling process. PR_SET_CHILD_SUBREAPER = 36 - // PR_GET_CHILD_SUBREAPER get the "child subreaper" attribute of the calling - // process. + // PR_GET_CHILD_SUBREAPER gets the "child subreaper" attribute of the + // calling process. PR_GET_CHILD_SUBREAPER = 37 - // PR_SET_NO_NEW_PRIVS will set the calling thread's no_new_privs bit. + // PR_SET_NO_NEW_PRIVS sets the calling thread's no_new_privs bit. PR_SET_NO_NEW_PRIVS = 38 - // PR_GET_NO_NEW_PRIVS will get the calling thread's no_new_privs bit. + // PR_GET_NO_NEW_PRIVS gets the calling thread's no_new_privs bit. PR_GET_NO_NEW_PRIVS = 39 - // PR_GET_TID_ADDRESS retrieve the clear_child_tid address. + // PR_GET_TID_ADDRESS retrieves the clear_child_tid address. PR_GET_TID_ADDRESS = 40 - // PR_SET_THP_DISABLE set the state of the "THP disable" flag for the calling - // thread. + // PR_SET_THP_DISABLE sets the state of the "THP disable" flag for the + // calling thread. PR_SET_THP_DISABLE = 41 - // PR_GET_THP_DISABLE get the state of the "THP disable" flag for the calling - // thread. + // PR_GET_THP_DISABLE gets the state of the "THP disable" flag for the + // calling thread. PR_GET_THP_DISABLE = 42 - // PR_MPX_ENABLE_MANAGEMENT enable kernel management of Memory Protection - // eXtensions (MPX) bounds tables. + // PR_MPX_ENABLE_MANAGEMENT enables kernel management of Memory + // Protection eXtensions (MPX) bounds tables. PR_MPX_ENABLE_MANAGEMENT = 43 - // PR_MPX_DISABLE_MANAGEMENTdisable kernel management of Memory Protection - // eXtensions (MPX) bounds tables. + // PR_MPX_DISABLE_MANAGEMENT disables kernel management of Memory + // Protection eXtensions (MPX) bounds tables. PR_MPX_DISABLE_MANAGEMENT = 44 ) -- cgit v1.2.3