summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2020-01-29 13:21:12 -0800
committerKevin Krakauer <krakauer@google.com>2020-01-29 13:21:12 -0800
commitb615f94aeacb2c21bb59c8b44f303e7b7ca05ad6 (patch)
tree79907e842eeba2a1f01acb5b5661800dc6ef2174 /pkg/sentry
parentd6a2e01d3e57e0837c7e5cfda3b56c4dcfbb4627 (diff)
parent148fda60e8dee29f2df85e3104e3d5de1a225bcf (diff)
Merge branch 'master' into ipt-udp-matchers
Diffstat (limited to 'pkg/sentry')
-rw-r--r--pkg/sentry/BUILD2
-rw-r--r--pkg/sentry/arch/BUILD24
-rw-r--r--pkg/sentry/arch/arch.go2
-rw-r--r--pkg/sentry/arch/arch_aarch64.go2
-rw-r--r--pkg/sentry/arch/arch_amd64.go2
-rw-r--r--pkg/sentry/arch/arch_arm64.go6
-rw-r--r--pkg/sentry/arch/arch_state_x86.go2
-rw-r--r--pkg/sentry/arch/arch_x86.go2
-rw-r--r--pkg/sentry/arch/auxv.go2
-rw-r--r--pkg/sentry/arch/signal.go2
-rw-r--r--pkg/sentry/arch/signal_amd64.go2
-rw-r--r--pkg/sentry/arch/signal_arm64.go2
-rw-r--r--pkg/sentry/arch/signal_stack.go2
-rw-r--r--pkg/sentry/arch/stack.go4
-rw-r--r--pkg/sentry/context/BUILD14
-rw-r--r--pkg/sentry/context/context.go141
-rw-r--r--pkg/sentry/contexttest/BUILD (renamed from pkg/sentry/context/contexttest/BUILD)5
-rw-r--r--pkg/sentry/contexttest/contexttest.go (renamed from pkg/sentry/context/contexttest/contexttest.go)2
-rw-r--r--pkg/sentry/control/BUILD8
-rw-r--r--pkg/sentry/device/BUILD6
-rw-r--r--pkg/sentry/devices/memdev/BUILD28
-rw-r--r--pkg/sentry/devices/memdev/full.go75
-rw-r--r--pkg/sentry/devices/memdev/memdev.go59
-rw-r--r--pkg/sentry/devices/memdev/null.go76
-rw-r--r--pkg/sentry/devices/memdev/random.go92
-rw-r--r--pkg/sentry/devices/memdev/zero.go88
-rw-r--r--pkg/sentry/fs/BUILD18
-rw-r--r--pkg/sentry/fs/anon/BUILD7
-rw-r--r--pkg/sentry/fs/anon/anon.go4
-rw-r--r--pkg/sentry/fs/attr.go7
-rw-r--r--pkg/sentry/fs/context.go2
-rw-r--r--pkg/sentry/fs/copy_up.go4
-rw-r--r--pkg/sentry/fs/copy_up_test.go2
-rw-r--r--pkg/sentry/fs/dev/BUILD9
-rw-r--r--pkg/sentry/fs/dev/dev.go4
-rw-r--r--pkg/sentry/fs/dev/fs.go2
-rw-r--r--pkg/sentry/fs/dev/full.go4
-rw-r--r--pkg/sentry/fs/dev/null.go2
-rw-r--r--pkg/sentry/fs/dev/random.go6
-rw-r--r--pkg/sentry/fs/dev/tty.go2
-rw-r--r--pkg/sentry/fs/dirent.go2
-rw-r--r--pkg/sentry/fs/dirent_refs_test.go4
-rw-r--r--pkg/sentry/fs/fdpipe/BUILD18
-rw-r--r--pkg/sentry/fs/fdpipe/pipe.go6
-rw-r--r--pkg/sentry/fs/fdpipe/pipe_opener.go2
-rw-r--r--pkg/sentry/fs/fdpipe/pipe_opener_test.go6
-rw-r--r--pkg/sentry/fs/fdpipe/pipe_state.go2
-rw-r--r--pkg/sentry/fs/fdpipe/pipe_test.go4
-rw-r--r--pkg/sentry/fs/file.go11
-rw-r--r--pkg/sentry/fs/file_operations.go4
-rw-r--r--pkg/sentry/fs/file_overlay.go4
-rw-r--r--pkg/sentry/fs/file_overlay_test.go2
-rw-r--r--pkg/sentry/fs/filesystems.go2
-rw-r--r--pkg/sentry/fs/filetest/BUILD9
-rw-r--r--pkg/sentry/fs/filetest/filetest.go6
-rw-r--r--pkg/sentry/fs/fs.go2
-rw-r--r--pkg/sentry/fs/fsutil/BUILD20
-rw-r--r--pkg/sentry/fs/fsutil/dirty_set.go6
-rw-r--r--pkg/sentry/fs/fsutil/dirty_set_test.go2
-rw-r--r--pkg/sentry/fs/fsutil/file.go4
-rw-r--r--pkg/sentry/fs/fsutil/file_range_set.go6
-rw-r--r--pkg/sentry/fs/fsutil/host_file_mapper.go4
-rw-r--r--pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go2
-rw-r--r--pkg/sentry/fs/fsutil/host_mappable.go6
-rw-r--r--pkg/sentry/fs/fsutil/inode.go2
-rw-r--r--pkg/sentry/fs/fsutil/inode_cached.go6
-rw-r--r--pkg/sentry/fs/fsutil/inode_cached_test.go8
-rw-r--r--pkg/sentry/fs/gofer/BUILD16
-rw-r--r--pkg/sentry/fs/gofer/attr.go4
-rw-r--r--pkg/sentry/fs/gofer/cache_policy.go2
-rw-r--r--pkg/sentry/fs/gofer/context_file.go2
-rw-r--r--pkg/sentry/fs/gofer/file.go4
-rw-r--r--pkg/sentry/fs/gofer/file_state.go2
-rw-r--r--pkg/sentry/fs/gofer/fs.go2
-rw-r--r--pkg/sentry/fs/gofer/gofer_test.go4
-rw-r--r--pkg/sentry/fs/gofer/handles.go4
-rw-r--r--pkg/sentry/fs/gofer/inode.go4
-rw-r--r--pkg/sentry/fs/gofer/inode_state.go2
-rw-r--r--pkg/sentry/fs/gofer/path.go2
-rw-r--r--pkg/sentry/fs/gofer/session.go2
-rw-r--r--pkg/sentry/fs/gofer/session_state.go2
-rw-r--r--pkg/sentry/fs/gofer/socket.go2
-rw-r--r--pkg/sentry/fs/gofer/util.go2
-rw-r--r--pkg/sentry/fs/host/BUILD18
-rw-r--r--pkg/sentry/fs/host/control.go2
-rw-r--r--pkg/sentry/fs/host/file.go6
-rw-r--r--pkg/sentry/fs/host/fs.go2
-rw-r--r--pkg/sentry/fs/host/fs_test.go4
-rw-r--r--pkg/sentry/fs/host/inode.go4
-rw-r--r--pkg/sentry/fs/host/inode_state.go2
-rw-r--r--pkg/sentry/fs/host/inode_test.go2
-rw-r--r--pkg/sentry/fs/host/socket.go2
-rw-r--r--pkg/sentry/fs/host/socket_test.go4
-rw-r--r--pkg/sentry/fs/host/tty.go4
-rw-r--r--pkg/sentry/fs/host/wait_test.go2
-rw-r--r--pkg/sentry/fs/inode.go2
-rw-r--r--pkg/sentry/fs/inode_operations.go2
-rw-r--r--pkg/sentry/fs/inode_overlay.go2
-rw-r--r--pkg/sentry/fs/inode_overlay_test.go2
-rw-r--r--pkg/sentry/fs/inotify.go4
-rw-r--r--pkg/sentry/fs/inotify_event.go4
-rw-r--r--pkg/sentry/fs/lock/BUILD6
-rw-r--r--pkg/sentry/fs/mock.go2
-rw-r--r--pkg/sentry/fs/mount.go2
-rw-r--r--pkg/sentry/fs/mount_overlay.go2
-rw-r--r--pkg/sentry/fs/mount_test.go2
-rw-r--r--pkg/sentry/fs/mounts.go2
-rw-r--r--pkg/sentry/fs/mounts_test.go2
-rw-r--r--pkg/sentry/fs/offset.go2
-rw-r--r--pkg/sentry/fs/overlay.go4
-rw-r--r--pkg/sentry/fs/proc/BUILD14
-rw-r--r--pkg/sentry/fs/proc/cgroup.go2
-rw-r--r--pkg/sentry/fs/proc/cpuinfo.go2
-rw-r--r--pkg/sentry/fs/proc/device/BUILD3
-rw-r--r--pkg/sentry/fs/proc/exec_args.go4
-rw-r--r--pkg/sentry/fs/proc/fds.go2
-rw-r--r--pkg/sentry/fs/proc/filesystems.go2
-rw-r--r--pkg/sentry/fs/proc/fs.go2
-rw-r--r--pkg/sentry/fs/proc/inode.go4
-rw-r--r--pkg/sentry/fs/proc/loadavg.go2
-rw-r--r--pkg/sentry/fs/proc/meminfo.go4
-rw-r--r--pkg/sentry/fs/proc/mounts.go2
-rw-r--r--pkg/sentry/fs/proc/net.go4
-rw-r--r--pkg/sentry/fs/proc/proc.go2
-rw-r--r--pkg/sentry/fs/proc/seqfile/BUILD16
-rw-r--r--pkg/sentry/fs/proc/seqfile/seqfile.go4
-rw-r--r--pkg/sentry/fs/proc/seqfile/seqfile_test.go6
-rw-r--r--pkg/sentry/fs/proc/stat.go2
-rw-r--r--pkg/sentry/fs/proc/sys.go4
-rw-r--r--pkg/sentry/fs/proc/sys_net.go4
-rw-r--r--pkg/sentry/fs/proc/sys_net_test.go4
-rw-r--r--pkg/sentry/fs/proc/task.go4
-rw-r--r--pkg/sentry/fs/proc/uid_gid_map.go4
-rw-r--r--pkg/sentry/fs/proc/uptime.go4
-rw-r--r--pkg/sentry/fs/proc/version.go2
-rw-r--r--pkg/sentry/fs/ramfs/BUILD12
-rw-r--r--pkg/sentry/fs/ramfs/dir.go2
-rw-r--r--pkg/sentry/fs/ramfs/socket.go2
-rw-r--r--pkg/sentry/fs/ramfs/symlink.go2
-rw-r--r--pkg/sentry/fs/ramfs/tree.go4
-rw-r--r--pkg/sentry/fs/ramfs/tree_test.go2
-rw-r--r--pkg/sentry/fs/splice.go7
-rw-r--r--pkg/sentry/fs/sys/BUILD7
-rw-r--r--pkg/sentry/fs/sys/devices.go2
-rw-r--r--pkg/sentry/fs/sys/fs.go2
-rw-r--r--pkg/sentry/fs/sys/sys.go4
-rw-r--r--pkg/sentry/fs/timerfd/BUILD7
-rw-r--r--pkg/sentry/fs/timerfd/timerfd.go4
-rw-r--r--pkg/sentry/fs/tmpfs/BUILD16
-rw-r--r--pkg/sentry/fs/tmpfs/file_regular.go4
-rw-r--r--pkg/sentry/fs/tmpfs/file_test.go4
-rw-r--r--pkg/sentry/fs/tmpfs/fs.go2
-rw-r--r--pkg/sentry/fs/tmpfs/inode_file.go6
-rw-r--r--pkg/sentry/fs/tmpfs/tmpfs.go4
-rw-r--r--pkg/sentry/fs/tty/BUILD16
-rw-r--r--pkg/sentry/fs/tty/dir.go4
-rw-r--r--pkg/sentry/fs/tty/fs.go2
-rw-r--r--pkg/sentry/fs/tty/line_discipline.go4
-rw-r--r--pkg/sentry/fs/tty/master.go4
-rw-r--r--pkg/sentry/fs/tty/queue.go6
-rw-r--r--pkg/sentry/fs/tty/slave.go4
-rw-r--r--pkg/sentry/fs/tty/terminal.go4
-rw-r--r--pkg/sentry/fs/tty/tty_test.go4
-rw-r--r--pkg/sentry/fsimpl/devtmpfs/BUILD33
-rw-r--r--pkg/sentry/fsimpl/devtmpfs/devtmpfs.go187
-rw-r--r--pkg/sentry/fsimpl/devtmpfs/devtmpfs_test.go119
-rw-r--r--pkg/sentry/fsimpl/ext/BUILD18
-rw-r--r--pkg/sentry/fsimpl/ext/benchmark/BUILD6
-rw-r--r--pkg/sentry/fsimpl/ext/benchmark/benchmark_test.go4
-rw-r--r--pkg/sentry/fsimpl/ext/directory.go2
-rw-r--r--pkg/sentry/fsimpl/ext/disklayout/BUILD6
-rw-r--r--pkg/sentry/fsimpl/ext/ext.go2
-rw-r--r--pkg/sentry/fsimpl/ext/ext_test.go6
-rw-r--r--pkg/sentry/fsimpl/ext/file_description.go2
-rw-r--r--pkg/sentry/fsimpl/ext/filesystem.go2
-rw-r--r--pkg/sentry/fsimpl/ext/regular_file.go6
-rw-r--r--pkg/sentry/fsimpl/ext/symlink.go4
-rw-r--r--pkg/sentry/fsimpl/kernfs/BUILD16
-rw-r--r--pkg/sentry/fsimpl/kernfs/dynamic_bytes_file.go8
-rw-r--r--pkg/sentry/fsimpl/kernfs/fd_impl_util.go4
-rw-r--r--pkg/sentry/fsimpl/kernfs/filesystem.go2
-rw-r--r--pkg/sentry/fsimpl/kernfs/inode_impl_util.go2
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs.go2
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs_test.go6
-rw-r--r--pkg/sentry/fsimpl/kernfs/symlink.go2
-rw-r--r--pkg/sentry/fsimpl/proc/BUILD20
-rw-r--r--pkg/sentry/fsimpl/proc/filesystem.go2
-rw-r--r--pkg/sentry/fsimpl/proc/subtasks.go2
-rw-r--r--pkg/sentry/fsimpl/proc/task.go2
-rw-r--r--pkg/sentry/fsimpl/proc/task_files.go6
-rw-r--r--pkg/sentry/fsimpl/proc/tasks.go4
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_files.go4
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_net.go4
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_sys.go86
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_sys_test.go2
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_test.go4
-rw-r--r--pkg/sentry/fsimpl/sys/BUILD8
-rw-r--r--pkg/sentry/fsimpl/sys/sys.go2
-rw-r--r--pkg/sentry/fsimpl/testutil/BUILD9
-rw-r--r--pkg/sentry/fsimpl/testutil/kernel.go2
-rw-r--r--pkg/sentry/fsimpl/testutil/testutil.go4
-rw-r--r--pkg/sentry/fsimpl/tmpfs/BUILD25
-rw-r--r--pkg/sentry/fsimpl/tmpfs/benchmark_test.go4
-rw-r--r--pkg/sentry/fsimpl/tmpfs/directory.go2
-rw-r--r--pkg/sentry/fsimpl/tmpfs/filesystem.go2
-rw-r--r--pkg/sentry/fsimpl/tmpfs/named_pipe.go4
-rw-r--r--pkg/sentry/fsimpl/tmpfs/pipe_test.go6
-rw-r--r--pkg/sentry/fsimpl/tmpfs/regular_file.go6
-rw-r--r--pkg/sentry/fsimpl/tmpfs/regular_file_test.go4
-rw-r--r--pkg/sentry/fsimpl/tmpfs/tmpfs.go2
-rw-r--r--pkg/sentry/hostcpu/BUILD6
-rw-r--r--pkg/sentry/hostmm/BUILD5
-rw-r--r--pkg/sentry/hostmm/hostmm.go2
-rw-r--r--pkg/sentry/inet/BUILD5
-rw-r--r--pkg/sentry/inet/context.go2
-rw-r--r--pkg/sentry/kernel/BUILD37
-rw-r--r--pkg/sentry/kernel/auth/BUILD5
-rw-r--r--pkg/sentry/kernel/auth/context.go2
-rw-r--r--pkg/sentry/kernel/auth/id_map.go2
-rw-r--r--pkg/sentry/kernel/context.go2
-rw-r--r--pkg/sentry/kernel/contexttest/BUILD7
-rw-r--r--pkg/sentry/kernel/contexttest/contexttest.go4
-rw-r--r--pkg/sentry/kernel/epoll/BUILD12
-rw-r--r--pkg/sentry/kernel/epoll/epoll.go4
-rw-r--r--pkg/sentry/kernel/epoll/epoll_test.go2
-rw-r--r--pkg/sentry/kernel/eventfd/BUILD14
-rw-r--r--pkg/sentry/kernel/eventfd/eventfd.go4
-rw-r--r--pkg/sentry/kernel/eventfd/eventfd_test.go4
-rw-r--r--pkg/sentry/kernel/fasync/BUILD3
-rw-r--r--pkg/sentry/kernel/fd_table.go176
-rw-r--r--pkg/sentry/kernel/fd_table_test.go10
-rw-r--r--pkg/sentry/kernel/fd_table_unsafe.go100
-rw-r--r--pkg/sentry/kernel/futex/BUILD12
-rw-r--r--pkg/sentry/kernel/futex/futex.go2
-rw-r--r--pkg/sentry/kernel/futex/futex_test.go2
-rw-r--r--pkg/sentry/kernel/kernel.go33
-rw-r--r--pkg/sentry/kernel/memevent/BUILD20
-rw-r--r--pkg/sentry/kernel/pipe/BUILD18
-rw-r--r--pkg/sentry/kernel/pipe/buffer.go2
-rw-r--r--pkg/sentry/kernel/pipe/buffer_test.go2
-rw-r--r--pkg/sentry/kernel/pipe/node.go2
-rw-r--r--pkg/sentry/kernel/pipe/node_test.go6
-rw-r--r--pkg/sentry/kernel/pipe/pipe.go2
-rw-r--r--pkg/sentry/kernel/pipe/pipe_test.go4
-rw-r--r--pkg/sentry/kernel/pipe/pipe_util.go4
-rw-r--r--pkg/sentry/kernel/pipe/reader_writer.go4
-rw-r--r--pkg/sentry/kernel/pipe/vfs.go4
-rw-r--r--pkg/sentry/kernel/ptrace.go2
-rw-r--r--pkg/sentry/kernel/ptrace_amd64.go2
-rw-r--r--pkg/sentry/kernel/ptrace_arm64.go2
-rw-r--r--pkg/sentry/kernel/rseq.go2
-rw-r--r--pkg/sentry/kernel/sched/BUILD6
-rw-r--r--pkg/sentry/kernel/seccomp.go2
-rw-r--r--pkg/sentry/kernel/semaphore/BUILD12
-rw-r--r--pkg/sentry/kernel/semaphore/semaphore.go2
-rw-r--r--pkg/sentry/kernel/semaphore/semaphore_test.go4
-rw-r--r--pkg/sentry/kernel/shm/BUILD7
-rw-r--r--pkg/sentry/kernel/shm/shm.go4
-rw-r--r--pkg/sentry/kernel/signalfd/BUILD9
-rw-r--r--pkg/sentry/kernel/signalfd/signalfd.go4
-rw-r--r--pkg/sentry/kernel/syscalls.go2
-rw-r--r--pkg/sentry/kernel/task.go13
-rw-r--r--pkg/sentry/kernel/task_clone.go2
-rw-r--r--pkg/sentry/kernel/task_context.go4
-rw-r--r--pkg/sentry/kernel/task_exec.go3
-rw-r--r--pkg/sentry/kernel/task_futex.go2
-rw-r--r--pkg/sentry/kernel/task_log.go2
-rw-r--r--pkg/sentry/kernel/task_run.go2
-rw-r--r--pkg/sentry/kernel/task_signals.go2
-rw-r--r--pkg/sentry/kernel/task_start.go2
-rw-r--r--pkg/sentry/kernel/task_syscall.go2
-rw-r--r--pkg/sentry/kernel/task_usermem.go2
-rw-r--r--pkg/sentry/kernel/time/BUILD5
-rw-r--r--pkg/sentry/kernel/time/context.go2
-rw-r--r--pkg/sentry/kernel/timekeeper_test.go4
-rw-r--r--pkg/sentry/kernel/tty.go2
-rw-r--r--pkg/sentry/kernel/vdso.go4
-rw-r--r--pkg/sentry/limits/BUILD8
-rw-r--r--pkg/sentry/limits/context.go2
-rw-r--r--pkg/sentry/loader/BUILD10
-rw-r--r--pkg/sentry/loader/elf.go4
-rw-r--r--pkg/sentry/loader/interpreter.go4
-rw-r--r--pkg/sentry/loader/loader.go4
-rw-r--r--pkg/sentry/loader/vdso.go6
-rw-r--r--pkg/sentry/memmap/BUILD12
-rw-r--r--pkg/sentry/memmap/mapping_set.go2
-rw-r--r--pkg/sentry/memmap/mapping_set_test.go2
-rw-r--r--pkg/sentry/memmap/memmap.go4
-rw-r--r--pkg/sentry/mm/BUILD24
-rw-r--r--pkg/sentry/mm/address_space.go2
-rw-r--r--pkg/sentry/mm/aio_context.go4
-rw-r--r--pkg/sentry/mm/debug.go2
-rw-r--r--pkg/sentry/mm/io.go6
-rw-r--r--pkg/sentry/mm/lifecycle.go4
-rw-r--r--pkg/sentry/mm/metadata.go2
-rw-r--r--pkg/sentry/mm/mm.go4
-rw-r--r--pkg/sentry/mm/mm_test.go6
-rw-r--r--pkg/sentry/mm/pma.go8
-rw-r--r--pkg/sentry/mm/procfs.go4
-rw-r--r--pkg/sentry/mm/save_restore.go2
-rw-r--r--pkg/sentry/mm/shm.go4
-rw-r--r--pkg/sentry/mm/special_mappable.go4
-rw-r--r--pkg/sentry/mm/syscalls.go4
-rw-r--r--pkg/sentry/mm/vma.go4
-rw-r--r--pkg/sentry/pgalloc/BUILD14
-rw-r--r--pkg/sentry/pgalloc/context.go2
-rw-r--r--pkg/sentry/pgalloc/pgalloc.go6
-rw-r--r--pkg/sentry/pgalloc/pgalloc_test.go2
-rw-r--r--pkg/sentry/pgalloc/save_restore.go2
-rw-r--r--pkg/sentry/platform/BUILD11
-rw-r--r--pkg/sentry/platform/context.go2
-rw-r--r--pkg/sentry/platform/interrupt/BUILD6
-rw-r--r--pkg/sentry/platform/kvm/BUILD12
-rw-r--r--pkg/sentry/platform/kvm/address_space.go2
-rw-r--r--pkg/sentry/platform/kvm/bluepill.go2
-rw-r--r--pkg/sentry/platform/kvm/bluepill_fault.go2
-rw-r--r--pkg/sentry/platform/kvm/context.go2
-rw-r--r--pkg/sentry/platform/kvm/kvm.go2
-rw-r--r--pkg/sentry/platform/kvm/kvm_test.go2
-rw-r--r--pkg/sentry/platform/kvm/machine.go2
-rw-r--r--pkg/sentry/platform/kvm/machine_amd64.go2
-rw-r--r--pkg/sentry/platform/kvm/machine_arm64.go2
-rw-r--r--pkg/sentry/platform/kvm/machine_arm64_unsafe.go2
-rw-r--r--pkg/sentry/platform/kvm/physical_map.go2
-rw-r--r--pkg/sentry/platform/kvm/testutil/BUILD3
-rw-r--r--pkg/sentry/platform/kvm/virtual_map.go2
-rw-r--r--pkg/sentry/platform/kvm/virtual_map_test.go2
-rw-r--r--pkg/sentry/platform/mmap_min_addr.go2
-rw-r--r--pkg/sentry/platform/platform.go4
-rw-r--r--pkg/sentry/platform/ptrace/BUILD7
-rw-r--r--pkg/sentry/platform/ptrace/ptrace.go2
-rw-r--r--pkg/sentry/platform/ptrace/ptrace_unsafe.go2
-rw-r--r--pkg/sentry/platform/ptrace/stub_unsafe.go4
-rw-r--r--pkg/sentry/platform/ptrace/subprocess.go2
-rw-r--r--pkg/sentry/platform/ring0/BUILD5
-rw-r--r--pkg/sentry/platform/ring0/defs_amd64.go2
-rw-r--r--pkg/sentry/platform/ring0/defs_arm64.go2
-rw-r--r--pkg/sentry/platform/ring0/entry_arm64.go2
-rw-r--r--pkg/sentry/platform/ring0/gen_offsets/BUILD4
-rw-r--r--pkg/sentry/platform/ring0/kernel_arm64.go2
-rw-r--r--pkg/sentry/platform/ring0/lib_arm64.go2
-rw-r--r--pkg/sentry/platform/ring0/offsets_arm64.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/BUILD20
-rw-r--r--pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables_aarch64.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables_arm64_test.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables_test.go2
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables_x86.go2
-rw-r--r--pkg/sentry/platform/safecopy/BUILD31
-rw-r--r--pkg/sentry/platform/safecopy/LICENSE27
-rw-r--r--pkg/sentry/platform/safecopy/atomic_amd64.s136
-rw-r--r--pkg/sentry/platform/safecopy/atomic_arm64.s126
-rw-r--r--pkg/sentry/platform/safecopy/memclr_amd64.s147
-rw-r--r--pkg/sentry/platform/safecopy/memclr_arm64.s74
-rw-r--r--pkg/sentry/platform/safecopy/memcpy_amd64.s250
-rw-r--r--pkg/sentry/platform/safecopy/memcpy_arm64.s78
-rw-r--r--pkg/sentry/platform/safecopy/safecopy.go144
-rw-r--r--pkg/sentry/platform/safecopy/safecopy_test.go617
-rw-r--r--pkg/sentry/platform/safecopy/safecopy_unsafe.go335
-rw-r--r--pkg/sentry/platform/safecopy/sighandler_amd64.s133
-rw-r--r--pkg/sentry/platform/safecopy/sighandler_arm64.s143
-rw-r--r--pkg/sentry/safemem/BUILD29
-rw-r--r--pkg/sentry/safemem/block_unsafe.go279
-rw-r--r--pkg/sentry/safemem/io.go392
-rw-r--r--pkg/sentry/safemem/io_test.go199
-rw-r--r--pkg/sentry/safemem/seq_test.go196
-rw-r--r--pkg/sentry/safemem/seq_unsafe.go299
-rw-r--r--pkg/sentry/sighandling/BUILD3
-rw-r--r--pkg/sentry/socket/BUILD7
-rw-r--r--pkg/sentry/socket/control/BUILD7
-rw-r--r--pkg/sentry/socket/control/control.go4
-rw-r--r--pkg/sentry/socket/hostinet/BUILD9
-rw-r--r--pkg/sentry/socket/hostinet/socket.go6
-rw-r--r--pkg/sentry/socket/hostinet/socket_unsafe.go4
-rw-r--r--pkg/sentry/socket/hostinet/stack.go4
-rw-r--r--pkg/sentry/socket/netfilter/BUILD5
-rw-r--r--pkg/sentry/socket/netfilter/netfilter.go2
-rw-r--r--pkg/sentry/socket/netlink/BUILD7
-rw-r--r--pkg/sentry/socket/netlink/message.go2
-rw-r--r--pkg/sentry/socket/netlink/port/BUILD6
-rw-r--r--pkg/sentry/socket/netlink/provider.go2
-rw-r--r--pkg/sentry/socket/netlink/route/BUILD11
-rw-r--r--pkg/sentry/socket/netlink/route/protocol.go160
-rw-r--r--pkg/sentry/socket/netlink/socket.go4
-rw-r--r--pkg/sentry/socket/netlink/uevent/BUILD5
-rw-r--r--pkg/sentry/socket/netlink/uevent/protocol.go2
-rw-r--r--pkg/sentry/socket/netstack/BUILD9
-rw-r--r--pkg/sentry/socket/netstack/netstack.go6
-rw-r--r--pkg/sentry/socket/netstack/provider.go2
-rw-r--r--pkg/sentry/socket/socket.go4
-rw-r--r--pkg/sentry/socket/unix/BUILD9
-rw-r--r--pkg/sentry/socket/unix/io.go4
-rw-r--r--pkg/sentry/socket/unix/transport/BUILD5
-rw-r--r--pkg/sentry/socket/unix/transport/connectioned.go2
-rw-r--r--pkg/sentry/socket/unix/transport/connectionless.go2
-rw-r--r--pkg/sentry/socket/unix/transport/queue.go40
-rw-r--r--pkg/sentry/socket/unix/transport/unix.go31
-rw-r--r--pkg/sentry/socket/unix/unix.go4
-rw-r--r--pkg/sentry/state/BUILD3
-rw-r--r--pkg/sentry/strace/BUILD22
-rw-r--r--pkg/sentry/strace/linux64_amd64.go2
-rw-r--r--pkg/sentry/strace/linux64_arm64.go2
-rw-r--r--pkg/sentry/strace/poll.go2
-rw-r--r--pkg/sentry/strace/select.go2
-rw-r--r--pkg/sentry/strace/signal.go2
-rw-r--r--pkg/sentry/strace/socket.go2
-rw-r--r--pkg/sentry/strace/strace.go2
-rw-r--r--pkg/sentry/syscalls/BUILD3
-rw-r--r--pkg/sentry/syscalls/linux/BUILD10
-rw-r--r--pkg/sentry/syscalls/linux/error.go72
-rw-r--r--pkg/sentry/syscalls/linux/linux64_amd64.go2
-rw-r--r--pkg/sentry/syscalls/linux/linux64_arm64.go2
-rw-r--r--pkg/sentry/syscalls/linux/sigset.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_aio.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_epoll.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_file.go6
-rw-r--r--pkg/sentry/syscalls/linux/sys_futex.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_getdents.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_mempolicy.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_mmap.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_mount.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_pipe.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_poll.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_random.go4
-rw-r--r--pkg/sentry/syscalls/linux/sys_read.go4
-rw-r--r--pkg/sentry/syscalls/linux/sys_rlimit.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_seccomp.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_sem.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_signal.go7
-rw-r--r--pkg/sentry/syscalls/linux/sys_socket.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_splice.go19
-rw-r--r--pkg/sentry/syscalls/linux/sys_stat.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_stat_amd64.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_stat_arm64.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_thread.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_time.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_timer.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_write.go2
-rw-r--r--pkg/sentry/syscalls/linux/sys_xattr.go3
-rw-r--r--pkg/sentry/syscalls/linux/timespec.go2
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/BUILD24
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/linux64.go (renamed from pkg/sentry/safemem/safemem.go)6
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go (renamed from pkg/sentry/usermem/usermem_unsafe.go)16
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/linux64_override_arm64.go (renamed from pkg/sentry/usermem/usermem_x86.go)31
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/sys_read.go95
-rw-r--r--pkg/sentry/time/BUILD6
-rw-r--r--pkg/sentry/unimpl/BUILD23
-rw-r--r--pkg/sentry/unimpl/events.go2
-rw-r--r--pkg/sentry/uniqueid/BUILD5
-rw-r--r--pkg/sentry/uniqueid/context.go2
-rw-r--r--pkg/sentry/usage/BUILD5
-rw-r--r--pkg/sentry/usermem/BUILD58
-rw-r--r--pkg/sentry/usermem/README.md31
-rw-r--r--pkg/sentry/usermem/access_type.go128
-rw-r--r--pkg/sentry/usermem/addr.go108
-rw-r--r--pkg/sentry/usermem/addr_range_seq_test.go197
-rw-r--r--pkg/sentry/usermem/addr_range_seq_unsafe.go277
-rw-r--r--pkg/sentry/usermem/bytes_io.go141
-rw-r--r--pkg/sentry/usermem/bytes_io_unsafe.go47
-rw-r--r--pkg/sentry/usermem/usermem.go597
-rw-r--r--pkg/sentry/usermem/usermem_arm64.go53
-rw-r--r--pkg/sentry/usermem/usermem_test.go424
-rw-r--r--pkg/sentry/vfs/BUILD37
-rw-r--r--pkg/sentry/vfs/anonfs.go259
-rw-r--r--pkg/sentry/vfs/context.go2
-rw-r--r--pkg/sentry/vfs/device.go2
-rw-r--r--pkg/sentry/vfs/epoll.go377
-rw-r--r--pkg/sentry/vfs/file_description.go63
-rw-r--r--pkg/sentry/vfs/file_description_impl_util.go101
-rw-r--r--pkg/sentry/vfs/file_description_impl_util_test.go156
-rw-r--r--pkg/sentry/vfs/filesystem.go2
-rw-r--r--pkg/sentry/vfs/filesystem_type.go2
-rw-r--r--pkg/sentry/vfs/mount.go2
-rw-r--r--pkg/sentry/vfs/pathname.go2
-rw-r--r--pkg/sentry/vfs/testutil.go173
-rw-r--r--pkg/sentry/vfs/vfs.go42
-rw-r--r--pkg/sentry/watchdog/BUILD3
479 files changed, 3269 insertions, 7312 deletions
diff --git a/pkg/sentry/BUILD b/pkg/sentry/BUILD
index 2d6379c86..e8b794179 100644
--- a/pkg/sentry/BUILD
+++ b/pkg/sentry/BUILD
@@ -6,6 +6,8 @@ package(licenses = ["notice"])
package_group(
name = "internal",
packages = [
+ "//cloud/gvisor/gopkg/sentry/...",
+ "//cloud/gvisor/sentry/...",
"//pkg/sentry/...",
"//runsc/...",
# Code generated by go_marshal relies on go_marshal libraries.
diff --git a/pkg/sentry/arch/BUILD b/pkg/sentry/arch/BUILD
index 65f22af2b..34c0a867d 100644
--- a/pkg/sentry/arch/BUILD
+++ b/pkg/sentry/arch/BUILD
@@ -1,6 +1,4 @@
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "proto_library")
package(licenses = ["notice"])
@@ -27,37 +25,23 @@ go_library(
"syscalls_amd64.go",
"syscalls_arm64.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/arch",
visibility = ["//:sandbox"],
deps = [
":registers_go_proto",
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/cpuid",
"//pkg/log",
- "//pkg/sentry/context",
"//pkg/sentry/limits",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
proto_library(
- name = "registers_proto",
+ name = "registers",
srcs = ["registers.proto"],
visibility = ["//visibility:public"],
)
-
-cc_proto_library(
- name = "registers_cc_proto",
- visibility = ["//visibility:public"],
- deps = [":registers_proto"],
-)
-
-go_proto_library(
- name = "registers_go_proto",
- importpath = "gvisor.dev/gvisor/pkg/sentry/arch/registers_go_proto",
- proto = ":registers_proto",
- visibility = ["//visibility:public"],
-)
diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go
index 81ec98a77..1d11cc472 100644
--- a/pkg/sentry/arch/arch.go
+++ b/pkg/sentry/arch/arch.go
@@ -24,7 +24,7 @@ import (
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/limits"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Arch describes an architecture.
diff --git a/pkg/sentry/arch/arch_aarch64.go b/pkg/sentry/arch/arch_aarch64.go
index ea4dedbdf..3b6987665 100644
--- a/pkg/sentry/arch/arch_aarch64.go
+++ b/pkg/sentry/arch/arch_aarch64.go
@@ -25,8 +25,8 @@ import (
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/log"
rpb "gvisor.dev/gvisor/pkg/sentry/arch/registers_go_proto"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/arch/arch_amd64.go b/pkg/sentry/arch/arch_amd64.go
index 2aa08b1a9..85d6acc0f 100644
--- a/pkg/sentry/arch/arch_amd64.go
+++ b/pkg/sentry/arch/arch_amd64.go
@@ -25,7 +25,7 @@ import (
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/sentry/limits"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Host specifies the host architecture.
diff --git a/pkg/sentry/arch/arch_arm64.go b/pkg/sentry/arch/arch_arm64.go
index 0d5b7d317..ac98897b5 100644
--- a/pkg/sentry/arch/arch_arm64.go
+++ b/pkg/sentry/arch/arch_arm64.go
@@ -21,7 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/sentry/limits"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Host specifies the host architecture.
@@ -137,8 +137,8 @@ func (c *context64) SetTLS(value uintptr) bool {
return false
}
-// SetRSEQInterruptedIP implements Context.SetRSEQInterruptedIP.
-func (c *context64) SetRSEQInterruptedIP(value uintptr) {
+// SetOldRSeqInterruptedIP implements Context.SetOldRSeqInterruptedIP.
+func (c *context64) SetOldRSeqInterruptedIP(value uintptr) {
c.Regs.Regs[3] = uint64(value)
}
diff --git a/pkg/sentry/arch/arch_state_x86.go b/pkg/sentry/arch/arch_state_x86.go
index 84f11b0d1..d388ee9cf 100644
--- a/pkg/sentry/arch/arch_state_x86.go
+++ b/pkg/sentry/arch/arch_state_x86.go
@@ -21,7 +21,7 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/cpuid"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ErrFloatingPoint indicates a failed restore due to unusable floating point
diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go
index 9f41e566f..a18093155 100644
--- a/pkg/sentry/arch/arch_x86.go
+++ b/pkg/sentry/arch/arch_x86.go
@@ -25,9 +25,9 @@ import (
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/log"
rpb "gvisor.dev/gvisor/pkg/sentry/arch/registers_go_proto"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// System-related constants for x86.
diff --git a/pkg/sentry/arch/auxv.go b/pkg/sentry/arch/auxv.go
index 4546b2ef9..2b4c8f3fc 100644
--- a/pkg/sentry/arch/auxv.go
+++ b/pkg/sentry/arch/auxv.go
@@ -15,7 +15,7 @@
package arch
import (
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// An AuxEntry represents an entry in an ELF auxiliary vector.
diff --git a/pkg/sentry/arch/signal.go b/pkg/sentry/arch/signal.go
index 402e46025..8b03d0187 100644
--- a/pkg/sentry/arch/signal.go
+++ b/pkg/sentry/arch/signal.go
@@ -16,7 +16,7 @@ package arch
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SignalAct represents the action that should be taken when a signal is
diff --git a/pkg/sentry/arch/signal_amd64.go b/pkg/sentry/arch/signal_amd64.go
index 1e4f9c3c2..81b92bb43 100644
--- a/pkg/sentry/arch/signal_amd64.go
+++ b/pkg/sentry/arch/signal_amd64.go
@@ -23,7 +23,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SignalContext64 is equivalent to struct sigcontext, the type passed as the
diff --git a/pkg/sentry/arch/signal_arm64.go b/pkg/sentry/arch/signal_arm64.go
index 7d0e98935..4f4cc46a8 100644
--- a/pkg/sentry/arch/signal_arm64.go
+++ b/pkg/sentry/arch/signal_arm64.go
@@ -19,7 +19,7 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SignalContext64 is equivalent to struct sigcontext, the type passed as the
diff --git a/pkg/sentry/arch/signal_stack.go b/pkg/sentry/arch/signal_stack.go
index d324da705..1a6056171 100644
--- a/pkg/sentry/arch/signal_stack.go
+++ b/pkg/sentry/arch/signal_stack.go
@@ -17,7 +17,7 @@
package arch
import (
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/arch/stack.go b/pkg/sentry/arch/stack.go
index 7472c3c61..09bceabc9 100644
--- a/pkg/sentry/arch/stack.go
+++ b/pkg/sentry/arch/stack.go
@@ -18,8 +18,8 @@ import (
"encoding/binary"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Stack is a simple wrapper around a usermem.IO and an address.
diff --git a/pkg/sentry/context/BUILD b/pkg/sentry/context/BUILD
deleted file mode 100644
index 8dc1a77b1..000000000
--- a/pkg/sentry/context/BUILD
+++ /dev/null
@@ -1,14 +0,0 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "context",
- srcs = ["context.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/context",
- visibility = ["//pkg/sentry:internal"],
- deps = [
- "//pkg/amutex",
- "//pkg/log",
- ],
-)
diff --git a/pkg/sentry/context/context.go b/pkg/sentry/context/context.go
deleted file mode 100644
index 23e009ef3..000000000
--- a/pkg/sentry/context/context.go
+++ /dev/null
@@ -1,141 +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 context defines an internal context type.
-//
-// The given Context conforms to the standard Go context, but mandates
-// additional methods that are specific to the kernel internals. Note however,
-// that the Context described by this package carries additional constraints
-// regarding concurrent access and retaining beyond the scope of a call.
-//
-// See the Context type for complete details.
-package context
-
-import (
- "context"
- "time"
-
- "gvisor.dev/gvisor/pkg/amutex"
- "gvisor.dev/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.
-//
-// While Context exists for essentially the same reasons as Go's standard
-// context.Context, the standard type represents the state of an operation
-// rather than that of a goroutine. This is a critical distinction:
-//
-// - Unlike context.Context, which "may be passed to functions running in
-// different goroutines", it is *not safe* to use the same Context in multiple
-// concurrent goroutines.
-//
-// - It is *not safe* to retain a Context passed to a function beyond the scope
-// of that function call.
-//
-// In both cases, values extracted from the Context should be used instead.
-type Context interface {
- log.Logger
- amutex.Sleeper
- context.Context
-
- // UninterruptibleSleepStart indicates the beginning of an uninterruptible
- // sleep state (equivalent to Linux's TASK_UNINTERRUPTIBLE). If deactivate
- // is true and the Context represents a Task, the Task's AddressSpace is
- // deactivated.
- UninterruptibleSleepStart(deactivate bool)
-
- // UninterruptibleSleepFinish indicates the end of an uninterruptible sleep
- // state that was begun by a previous call to UninterruptibleSleepStart. If
- // activate is true and the Context represents a Task, the Task's
- // AddressSpace is activated. Normally activate is the same value as the
- // deactivate parameter passed to UninterruptibleSleepStart.
- UninterruptibleSleepFinish(activate bool)
-}
-
-// NoopSleeper is a noop implementation of amutex.Sleeper and UninterruptibleSleep
-// methods for anonymous embedding in other types that do not implement sleeps.
-type NoopSleeper struct {
- amutex.NoopSleeper
-}
-
-// UninterruptibleSleepStart does nothing.
-func (NoopSleeper) UninterruptibleSleepStart(bool) {}
-
-// UninterruptibleSleepFinish does nothing.
-func (NoopSleeper) UninterruptibleSleepFinish(bool) {}
-
-// Deadline returns zero values, meaning no deadline.
-func (NoopSleeper) Deadline() (time.Time, bool) {
- return time.Time{}, false
-}
-
-// Done returns nil.
-func (NoopSleeper) Done() <-chan struct{} {
- return nil
-}
-
-// Err returns nil.
-func (NoopSleeper) Err() error {
- return nil
-}
-
-// logContext implements basic logging.
-type logContext struct {
- log.Logger
- NoopSleeper
-}
-
-// Value implements Context.Value.
-func (logContext) Value(key interface{}) interface{} {
- return nil
-}
-
-// bgContext is the context returned by context.Background.
-var bgContext = &logContext{Logger: log.Log()}
-
-// Background returns an empty context using the default logger.
-//
-// Users should be wary of using a Background context. Please tag any use with
-// FIXME(b/38173783) and a note to remove this use.
-//
-// Generally, one should use the Task as their context when available, or avoid
-// having to use a context in places where a Task is unavailable.
-//
-// Using a Background context for tests is fine, as long as no values are
-// needed from the context in the tested code paths.
-func Background() Context {
- return bgContext
-}
diff --git a/pkg/sentry/context/contexttest/BUILD b/pkg/sentry/contexttest/BUILD
index 581e7aa96..6f4c86684 100644
--- a/pkg/sentry/context/contexttest/BUILD
+++ b/pkg/sentry/contexttest/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -6,11 +6,10 @@ go_library(
name = "contexttest",
testonly = 1,
srcs = ["contexttest.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/context/contexttest",
visibility = ["//pkg/sentry:internal"],
deps = [
+ "//pkg/context",
"//pkg/memutil",
- "//pkg/sentry/context",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
"//pkg/sentry/limits",
diff --git a/pkg/sentry/context/contexttest/contexttest.go b/pkg/sentry/contexttest/contexttest.go
index 15cf086a9..031fc64ec 100644
--- a/pkg/sentry/context/contexttest/contexttest.go
+++ b/pkg/sentry/contexttest/contexttest.go
@@ -21,8 +21,8 @@ import (
"testing"
"time"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/memutil"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/limits"
diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD
index 2561a6109..e69496477 100644
--- a/pkg/sentry/control/BUILD
+++ b/pkg/sentry/control/BUILD
@@ -1,5 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -12,9 +11,8 @@ go_library(
"proc.go",
"state.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/control",
visibility = [
- "//pkg/sentry:internal",
+ "//:sandbox",
],
deps = [
"//pkg/abi/linux",
@@ -40,7 +38,7 @@ go_test(
name = "control_test",
size = "small",
srcs = ["proc_test.go"],
- embed = [":control"],
+ library = ":control",
deps = [
"//pkg/log",
"//pkg/sentry/kernel/time",
diff --git a/pkg/sentry/device/BUILD b/pkg/sentry/device/BUILD
index 97fa1512c..e403cbd8b 100644
--- a/pkg/sentry/device/BUILD
+++ b/pkg/sentry/device/BUILD
@@ -1,12 +1,10 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
go_library(
name = "device",
srcs = ["device.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/device",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
@@ -18,5 +16,5 @@ go_test(
name = "device_test",
size = "small",
srcs = ["device_test.go"],
- embed = [":device"],
+ library = ":device",
)
diff --git a/pkg/sentry/devices/memdev/BUILD b/pkg/sentry/devices/memdev/BUILD
new file mode 100644
index 000000000..abe58f818
--- /dev/null
+++ b/pkg/sentry/devices/memdev/BUILD
@@ -0,0 +1,28 @@
+load("//tools:defs.bzl", "go_library")
+
+licenses(["notice"])
+
+go_library(
+ name = "memdev",
+ srcs = [
+ "full.go",
+ "memdev.go",
+ "null.go",
+ "random.go",
+ "zero.go",
+ ],
+ visibility = ["//pkg/sentry:internal"],
+ deps = [
+ "//pkg/abi/linux",
+ "//pkg/context",
+ "//pkg/rand",
+ "//pkg/safemem",
+ "//pkg/sentry/fsimpl/devtmpfs",
+ "//pkg/sentry/memmap",
+ "//pkg/sentry/mm",
+ "//pkg/sentry/pgalloc",
+ "//pkg/sentry/vfs",
+ "//pkg/syserror",
+ "//pkg/usermem",
+ ],
+)
diff --git a/pkg/sentry/devices/memdev/full.go b/pkg/sentry/devices/memdev/full.go
new file mode 100644
index 000000000..c7e197691
--- /dev/null
+++ b/pkg/sentry/devices/memdev/full.go
@@ -0,0 +1,75 @@
+// Copyright 2020 The 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 memdev
+
+import (
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
+)
+
+const fullDevMinor = 7
+
+// fullDevice implements vfs.Device for /dev/full.
+type fullDevice struct{}
+
+// Open implements vfs.Device.Open.
+func (fullDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
+ fd := &fullFD{}
+ if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
+ UseDentryMetadata: true,
+ }); err != nil {
+ return nil, err
+ }
+ return &fd.vfsfd, nil
+}
+
+// fullFD implements vfs.FileDescriptionImpl for /dev/full.
+type fullFD struct {
+ vfsfd vfs.FileDescription
+ vfs.FileDescriptionDefaultImpl
+ vfs.DentryMetadataFileDescriptionImpl
+}
+
+// Release implements vfs.FileDescriptionImpl.Release.
+func (fd *fullFD) Release() {
+ // noop
+}
+
+// PRead implements vfs.FileDescriptionImpl.PRead.
+func (fd *fullFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts vfs.ReadOptions) (int64, error) {
+ return dst.ZeroOut(ctx, dst.NumBytes())
+}
+
+// Read implements vfs.FileDescriptionImpl.Read.
+func (fd *fullFD) Read(ctx context.Context, dst usermem.IOSequence, opts vfs.ReadOptions) (int64, error) {
+ return dst.ZeroOut(ctx, dst.NumBytes())
+}
+
+// PWrite implements vfs.FileDescriptionImpl.PWrite.
+func (fd *fullFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error) {
+ return 0, syserror.ENOSPC
+}
+
+// Write implements vfs.FileDescriptionImpl.Write.
+func (fd *fullFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) {
+ return 0, syserror.ENOSPC
+}
+
+// Seek implements vfs.FileDescriptionImpl.Seek.
+func (fd *fullFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error) {
+ return 0, nil
+}
diff --git a/pkg/sentry/devices/memdev/memdev.go b/pkg/sentry/devices/memdev/memdev.go
new file mode 100644
index 000000000..5759900c4
--- /dev/null
+++ b/pkg/sentry/devices/memdev/memdev.go
@@ -0,0 +1,59 @@
+// Copyright 2020 The 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 memdev implements "mem" character devices, as implemented in Linux
+// by drivers/char/mem.c and drivers/char/random.c.
+package memdev
+
+import (
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/fsimpl/devtmpfs"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+)
+
+// Register registers all devices implemented by this package in vfsObj.
+func Register(vfsObj *vfs.VirtualFilesystem) error {
+ for minor, dev := range map[uint32]vfs.Device{
+ nullDevMinor: nullDevice{},
+ zeroDevMinor: zeroDevice{},
+ fullDevMinor: fullDevice{},
+ randomDevMinor: randomDevice{},
+ urandomDevMinor: randomDevice{},
+ } {
+ if err := vfsObj.RegisterDevice(vfs.CharDevice, linux.MEM_MAJOR, minor, dev, &vfs.RegisterDeviceOptions{
+ GroupName: "mem",
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// CreateDevtmpfsFiles creates device special files in dev representing all
+// devices implemented by this package.
+func CreateDevtmpfsFiles(ctx context.Context, dev *devtmpfs.Accessor) error {
+ for minor, name := range map[uint32]string{
+ nullDevMinor: "null",
+ zeroDevMinor: "zero",
+ fullDevMinor: "full",
+ randomDevMinor: "random",
+ urandomDevMinor: "urandom",
+ } {
+ if err := dev.CreateDeviceFile(ctx, name, vfs.CharDevice, linux.MEM_MAJOR, minor, 0666 /* mode */); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/pkg/sentry/devices/memdev/null.go b/pkg/sentry/devices/memdev/null.go
new file mode 100644
index 000000000..33d060d02
--- /dev/null
+++ b/pkg/sentry/devices/memdev/null.go
@@ -0,0 +1,76 @@
+// Copyright 2020 The 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 memdev
+
+import (
+ "io"
+
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/usermem"
+)
+
+const nullDevMinor = 3
+
+// nullDevice implements vfs.Device for /dev/null.
+type nullDevice struct{}
+
+// Open implements vfs.Device.Open.
+func (nullDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
+ fd := &nullFD{}
+ if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
+ UseDentryMetadata: true,
+ }); err != nil {
+ return nil, err
+ }
+ return &fd.vfsfd, nil
+}
+
+// nullFD implements vfs.FileDescriptionImpl for /dev/null.
+type nullFD struct {
+ vfsfd vfs.FileDescription
+ vfs.FileDescriptionDefaultImpl
+ vfs.DentryMetadataFileDescriptionImpl
+}
+
+// Release implements vfs.FileDescriptionImpl.Release.
+func (fd *nullFD) Release() {
+ // noop
+}
+
+// PRead implements vfs.FileDescriptionImpl.PRead.
+func (fd *nullFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts vfs.ReadOptions) (int64, error) {
+ return 0, io.EOF
+}
+
+// Read implements vfs.FileDescriptionImpl.Read.
+func (fd *nullFD) Read(ctx context.Context, dst usermem.IOSequence, opts vfs.ReadOptions) (int64, error) {
+ return 0, io.EOF
+}
+
+// PWrite implements vfs.FileDescriptionImpl.PWrite.
+func (fd *nullFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error) {
+ return src.NumBytes(), nil
+}
+
+// Write implements vfs.FileDescriptionImpl.Write.
+func (fd *nullFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) {
+ return src.NumBytes(), nil
+}
+
+// Seek implements vfs.FileDescriptionImpl.Seek.
+func (fd *nullFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error) {
+ return 0, nil
+}
diff --git a/pkg/sentry/devices/memdev/random.go b/pkg/sentry/devices/memdev/random.go
new file mode 100644
index 000000000..acfa23149
--- /dev/null
+++ b/pkg/sentry/devices/memdev/random.go
@@ -0,0 +1,92 @@
+// Copyright 2020 The 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 memdev
+
+import (
+ "sync/atomic"
+
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/rand"
+ "gvisor.dev/gvisor/pkg/safemem"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/usermem"
+)
+
+const (
+ randomDevMinor = 8
+ urandomDevMinor = 9
+)
+
+// randomDevice implements vfs.Device for /dev/random and /dev/urandom.
+type randomDevice struct{}
+
+// Open implements vfs.Device.Open.
+func (randomDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
+ fd := &randomFD{}
+ if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
+ UseDentryMetadata: true,
+ }); err != nil {
+ return nil, err
+ }
+ return &fd.vfsfd, nil
+}
+
+// randomFD implements vfs.FileDescriptionImpl for /dev/random.
+type randomFD struct {
+ vfsfd vfs.FileDescription
+ vfs.FileDescriptionDefaultImpl
+ vfs.DentryMetadataFileDescriptionImpl
+
+ // off is the "file offset". off is accessed using atomic memory
+ // operations.
+ off int64
+}
+
+// Release implements vfs.FileDescriptionImpl.Release.
+func (fd *randomFD) Release() {
+ // noop
+}
+
+// PRead implements vfs.FileDescriptionImpl.PRead.
+func (fd *randomFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts vfs.ReadOptions) (int64, error) {
+ return dst.CopyOutFrom(ctx, safemem.FromIOReader{rand.Reader})
+}
+
+// Read implements vfs.FileDescriptionImpl.Read.
+func (fd *randomFD) Read(ctx context.Context, dst usermem.IOSequence, opts vfs.ReadOptions) (int64, error) {
+ n, err := dst.CopyOutFrom(ctx, safemem.FromIOReader{rand.Reader})
+ atomic.AddInt64(&fd.off, n)
+ return n, err
+}
+
+// PWrite implements vfs.FileDescriptionImpl.PWrite.
+func (fd *randomFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error) {
+ // In Linux, this mixes the written bytes into the entropy pool; we just
+ // throw them away.
+ return src.NumBytes(), nil
+}
+
+// Write implements vfs.FileDescriptionImpl.Write.
+func (fd *randomFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) {
+ atomic.AddInt64(&fd.off, src.NumBytes())
+ return src.NumBytes(), nil
+}
+
+// Seek implements vfs.FileDescriptionImpl.Seek.
+func (fd *randomFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error) {
+ // Linux: drivers/char/random.c:random_fops.llseek == urandom_fops.llseek
+ // == noop_llseek
+ return atomic.LoadInt64(&fd.off), nil
+}
diff --git a/pkg/sentry/devices/memdev/zero.go b/pkg/sentry/devices/memdev/zero.go
new file mode 100644
index 000000000..3b1372b9e
--- /dev/null
+++ b/pkg/sentry/devices/memdev/zero.go
@@ -0,0 +1,88 @@
+// Copyright 2020 The 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 memdev
+
+import (
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/memmap"
+ "gvisor.dev/gvisor/pkg/sentry/mm"
+ "gvisor.dev/gvisor/pkg/sentry/pgalloc"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/usermem"
+)
+
+const zeroDevMinor = 5
+
+// zeroDevice implements vfs.Device for /dev/zero.
+type zeroDevice struct{}
+
+// Open implements vfs.Device.Open.
+func (zeroDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
+ fd := &zeroFD{}
+ if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{
+ UseDentryMetadata: true,
+ }); err != nil {
+ return nil, err
+ }
+ return &fd.vfsfd, nil
+}
+
+// zeroFD implements vfs.FileDescriptionImpl for /dev/zero.
+type zeroFD struct {
+ vfsfd vfs.FileDescription
+ vfs.FileDescriptionDefaultImpl
+ vfs.DentryMetadataFileDescriptionImpl
+}
+
+// Release implements vfs.FileDescriptionImpl.Release.
+func (fd *zeroFD) Release() {
+ // noop
+}
+
+// PRead implements vfs.FileDescriptionImpl.PRead.
+func (fd *zeroFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts vfs.ReadOptions) (int64, error) {
+ return dst.ZeroOut(ctx, dst.NumBytes())
+}
+
+// Read implements vfs.FileDescriptionImpl.Read.
+func (fd *zeroFD) Read(ctx context.Context, dst usermem.IOSequence, opts vfs.ReadOptions) (int64, error) {
+ return dst.ZeroOut(ctx, dst.NumBytes())
+}
+
+// PWrite implements vfs.FileDescriptionImpl.PWrite.
+func (fd *zeroFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error) {
+ return src.NumBytes(), nil
+}
+
+// Write implements vfs.FileDescriptionImpl.Write.
+func (fd *zeroFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) {
+ return src.NumBytes(), nil
+}
+
+// Seek implements vfs.FileDescriptionImpl.Seek.
+func (fd *zeroFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error) {
+ return 0, nil
+}
+
+// ConfigureMMap implements vfs.FileDescriptionImpl.ConfigureMMap.
+func (fd *zeroFD) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) error {
+ m, err := mm.NewSharedAnonMappable(opts.Length, pgalloc.MemoryFileProviderFromContext(ctx))
+ if err != nil {
+ return err
+ }
+ opts.MappingIdentity = m
+ opts.Mappable = m
+ return nil
+}
diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD
index 7d5d72d5a..ea85ab33c 100644
--- a/pkg/sentry/fs/BUILD
+++ b/pkg/sentry/fs/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -44,18 +43,17 @@ go_library(
"splice.go",
"sync.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/amutex",
+ "//pkg/context",
"//pkg/log",
"//pkg/metric",
"//pkg/p9",
"//pkg/refs",
"//pkg/secio",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs/lock",
"//pkg/sentry/kernel/auth",
@@ -66,10 +64,10 @@ go_library(
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/uniqueid",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/state",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -109,14 +107,14 @@ go_test(
],
deps = [
":fs",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/fs/ramfs",
"//pkg/sentry/fs/tmpfs",
"//pkg/sentry/kernel/contexttest",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
@@ -129,9 +127,9 @@ go_test(
"mount_test.go",
"path_test.go",
],
- embed = [":fs"],
+ library = ":fs",
deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
],
)
diff --git a/pkg/sentry/fs/anon/BUILD b/pkg/sentry/fs/anon/BUILD
index ae1c9cf76..aedcecfa1 100644
--- a/pkg/sentry/fs/anon/BUILD
+++ b/pkg/sentry/fs/anon/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -8,14 +8,13 @@ go_library(
"anon.go",
"device.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/anon",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/anon/anon.go b/pkg/sentry/fs/anon/anon.go
index 7323c7222..5c421f5fb 100644
--- a/pkg/sentry/fs/anon/anon.go
+++ b/pkg/sentry/fs/anon/anon.go
@@ -18,10 +18,10 @@ package anon
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// NewInode constructs an anonymous Inode that is not associated
diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go
index 4f3d6410e..f60bd423d 100644
--- a/pkg/sentry/fs/attr.go
+++ b/pkg/sentry/fs/attr.go
@@ -20,8 +20,8 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
)
@@ -206,6 +206,11 @@ func IsPipe(s StableAttr) bool {
return s.Type == Pipe
}
+// IsAnonymous returns true if StableAttr.Type matches any type of anonymous.
+func IsAnonymous(s StableAttr) bool {
+ return s.Type == Anonymous
+}
+
// IsSocket returns true if StableAttr.Type matches any type of socket.
func IsSocket(s StableAttr) bool {
return s.Type == Socket
diff --git a/pkg/sentry/fs/context.go b/pkg/sentry/fs/context.go
index dd427de5d..0fbd60056 100644
--- a/pkg/sentry/fs/context.go
+++ b/pkg/sentry/fs/context.go
@@ -16,7 +16,7 @@ package fs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
diff --git a/pkg/sentry/fs/copy_up.go b/pkg/sentry/fs/copy_up.go
index e03e3e417..f6c79e51b 100644
--- a/pkg/sentry/fs/copy_up.go
+++ b/pkg/sentry/fs/copy_up.go
@@ -19,12 +19,12 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// copyUp copies a file in an overlay from a lower filesystem to an
diff --git a/pkg/sentry/fs/copy_up_test.go b/pkg/sentry/fs/copy_up_test.go
index 738580c5f..91792d9fe 100644
--- a/pkg/sentry/fs/copy_up_test.go
+++ b/pkg/sentry/fs/copy_up_test.go
@@ -24,8 +24,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/fs"
_ "gvisor.dev/gvisor/pkg/sentry/fs/tmpfs"
"gvisor.dev/gvisor/pkg/sentry/kernel/contexttest"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/fs/dev/BUILD b/pkg/sentry/fs/dev/BUILD
index a0d9e8496..4c4b7d5cc 100644
--- a/pkg/sentry/fs/dev/BUILD
+++ b/pkg/sentry/fs/dev/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -13,12 +13,12 @@ go_library(
"random.go",
"tty.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/dev",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/rand",
- "//pkg/sentry/context",
+ "//pkg/safemem",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
@@ -27,9 +27,8 @@ go_library(
"//pkg/sentry/memmap",
"//pkg/sentry/mm",
"//pkg/sentry/pgalloc",
- "//pkg/sentry/safemem",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go
index f739c476c..35bd23991 100644
--- a/pkg/sentry/fs/dev/dev.go
+++ b/pkg/sentry/fs/dev/dev.go
@@ -18,11 +18,11 @@ package dev
import (
"math"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
"gvisor.dev/gvisor/pkg/sentry/fs/tmpfs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Memory device numbers are from Linux's drivers/char/mem.c
diff --git a/pkg/sentry/fs/dev/fs.go b/pkg/sentry/fs/dev/fs.go
index 55f8af704..5e518fb63 100644
--- a/pkg/sentry/fs/dev/fs.go
+++ b/pkg/sentry/fs/dev/fs.go
@@ -15,7 +15,7 @@
package dev
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/dev/full.go b/pkg/sentry/fs/dev/full.go
index 07e0ea010..deb9c6ad8 100644
--- a/pkg/sentry/fs/dev/full.go
+++ b/pkg/sentry/fs/dev/full.go
@@ -16,11 +16,11 @@ package dev
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/dev/null.go b/pkg/sentry/fs/dev/null.go
index 4404b97ef..aec33d0d9 100644
--- a/pkg/sentry/fs/dev/null.go
+++ b/pkg/sentry/fs/dev/null.go
@@ -16,7 +16,7 @@ package dev
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/memmap"
diff --git a/pkg/sentry/fs/dev/random.go b/pkg/sentry/fs/dev/random.go
index 49cb92f6e..2a9bbeb18 100644
--- a/pkg/sentry/fs/dev/random.go
+++ b/pkg/sentry/fs/dev/random.go
@@ -16,12 +16,12 @@ package dev
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/rand"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/dev/tty.go b/pkg/sentry/fs/dev/tty.go
index 87d80e292..760ca563d 100644
--- a/pkg/sentry/fs/dev/tty.go
+++ b/pkg/sentry/fs/dev/tty.go
@@ -16,7 +16,7 @@ package dev
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/waiter"
diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go
index 31fc4d87b..acab0411a 100644
--- a/pkg/sentry/fs/dirent.go
+++ b/pkg/sentry/fs/dirent.go
@@ -22,8 +22,8 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go
index 47bc72a88..98d69c6f2 100644
--- a/pkg/sentry/fs/dirent_refs_test.go
+++ b/pkg/sentry/fs/dirent_refs_test.go
@@ -18,8 +18,8 @@ import (
"syscall"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
)
func newMockDirInode(ctx context.Context, cache *DirentCache) *Inode {
diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD
index cc43de69d..1d09e983c 100644
--- a/pkg/sentry/fs/fdpipe/BUILD
+++ b/pkg/sentry/fs/fdpipe/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -10,21 +9,20 @@ go_library(
"pipe_opener.go",
"pipe_state.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/fdpipe",
imports = ["gvisor.dev/gvisor/pkg/sentry/fs"],
visibility = ["//pkg/sentry:internal"],
deps = [
+ "//pkg/context",
"//pkg/fd",
"//pkg/fdnotifier",
"//pkg/log",
+ "//pkg/safemem",
"//pkg/secio",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
- "//pkg/sentry/safemem",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -36,15 +34,15 @@ go_test(
"pipe_opener_test.go",
"pipe_test.go",
],
- embed = [":fdpipe"],
+ library = ":fdpipe",
deps = [
+ "//pkg/context",
"//pkg/fd",
"//pkg/fdnotifier",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
"@com_github_google_uuid//:go_default_library",
],
)
diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go
index 5b6cfeb0a..9fce177ad 100644
--- a/pkg/sentry/fs/fdpipe/pipe.go
+++ b/pkg/sentry/fs/fdpipe/pipe.go
@@ -19,17 +19,17 @@ import (
"os"
"syscall"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/secio"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go
index 64b558975..0c3595998 100644
--- a/pkg/sentry/fs/fdpipe/pipe_opener.go
+++ b/pkg/sentry/fs/fdpipe/pipe_opener.go
@@ -20,8 +20,8 @@ import (
"syscall"
"time"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go
index 577445148..e556da48a 100644
--- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go
+++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go
@@ -26,12 +26,12 @@ import (
"github.com/google/uuid"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type hostOpener struct {
diff --git a/pkg/sentry/fs/fdpipe/pipe_state.go b/pkg/sentry/fs/fdpipe/pipe_state.go
index cee87f726..af8230a7d 100644
--- a/pkg/sentry/fs/fdpipe/pipe_state.go
+++ b/pkg/sentry/fs/fdpipe/pipe_state.go
@@ -18,7 +18,7 @@ import (
"fmt"
"io/ioutil"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sync"
)
diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go
index 69abc1e71..5aff0cc95 100644
--- a/pkg/sentry/fs/fdpipe/pipe_test.go
+++ b/pkg/sentry/fs/fdpipe/pipe_test.go
@@ -23,10 +23,10 @@ import (
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/fdnotifier"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func singlePipeFD() (int, error) {
diff --git a/pkg/sentry/fs/file.go b/pkg/sentry/fs/file.go
index 7c4586296..78100e448 100644
--- a/pkg/sentry/fs/file.go
+++ b/pkg/sentry/fs/file.go
@@ -20,16 +20,16 @@ import (
"time"
"gvisor.dev/gvisor/pkg/amutex"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/metric"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs/lock"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -555,10 +555,6 @@ type lockedWriter struct {
//
// This applies only to Write, not WriteAt.
Offset int64
-
- // Err contains the first error encountered while copying. This is
- // useful to determine whether Writer or Reader failed during io.Copy.
- Err error
}
// Write implements io.Writer.Write.
@@ -594,8 +590,5 @@ func (w *lockedWriter) WriteAt(buf []byte, offset int64) (int, error) {
break
}
}
- if w.Err == nil {
- w.Err = err
- }
return written, err
}
diff --git a/pkg/sentry/fs/file_operations.go b/pkg/sentry/fs/file_operations.go
index b88303f17..beba0f771 100644
--- a/pkg/sentry/fs/file_operations.go
+++ b/pkg/sentry/fs/file_operations.go
@@ -17,10 +17,10 @@ package fs
import (
"io"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/file_overlay.go b/pkg/sentry/fs/file_overlay.go
index 8991207b4..dcc1df38f 100644
--- a/pkg/sentry/fs/file_overlay.go
+++ b/pkg/sentry/fs/file_overlay.go
@@ -17,13 +17,13 @@ package fs
import (
"io"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/file_overlay_test.go b/pkg/sentry/fs/file_overlay_test.go
index 2fb824d5c..02538bb4f 100644
--- a/pkg/sentry/fs/file_overlay_test.go
+++ b/pkg/sentry/fs/file_overlay_test.go
@@ -18,7 +18,7 @@ import (
"reflect"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
diff --git a/pkg/sentry/fs/filesystems.go b/pkg/sentry/fs/filesystems.go
index c5b51620a..084da2a8d 100644
--- a/pkg/sentry/fs/filesystems.go
+++ b/pkg/sentry/fs/filesystems.go
@@ -19,7 +19,7 @@ import (
"sort"
"strings"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sync"
)
diff --git a/pkg/sentry/fs/filetest/BUILD b/pkg/sentry/fs/filetest/BUILD
index 358dc2be3..a8000e010 100644
--- a/pkg/sentry/fs/filetest/BUILD
+++ b/pkg/sentry/fs/filetest/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -6,15 +6,14 @@ go_library(
name = "filetest",
testonly = 1,
srcs = ["filetest.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/filetest",
visibility = ["//pkg/sentry:internal"],
deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/fs/filetest/filetest.go b/pkg/sentry/fs/filetest/filetest.go
index 22270a494..8049538f2 100644
--- a/pkg/sentry/fs/filetest/filetest.go
+++ b/pkg/sentry/fs/filetest/filetest.go
@@ -19,12 +19,12 @@ import (
"fmt"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/fs.go b/pkg/sentry/fs/fs.go
index 26abf49e2..bdba6efe5 100644
--- a/pkg/sentry/fs/fs.go
+++ b/pkg/sentry/fs/fs.go
@@ -54,8 +54,8 @@
package fs
import (
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sync"
)
diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD
index 945b6270d..4ab2a384f 100644
--- a/pkg/sentry/fs/fsutil/BUILD
+++ b/pkg/sentry/fs/fsutil/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -75,26 +74,25 @@ go_library(
"inode.go",
"inode_cached.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/fsutil",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/log",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/kernel/time",
"//pkg/sentry/memmap",
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/state",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -106,15 +104,15 @@ go_test(
"dirty_set_test.go",
"inode_cached_test.go",
],
- embed = [":fsutil"],
+ library = ":fsutil",
deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/safemem",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
"//pkg/sentry/kernel/time",
"//pkg/sentry/memmap",
- "//pkg/sentry/safemem",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/fsutil/dirty_set.go b/pkg/sentry/fs/fsutil/dirty_set.go
index 12132680b..c6cd45087 100644
--- a/pkg/sentry/fs/fsutil/dirty_set.go
+++ b/pkg/sentry/fs/fsutil/dirty_set.go
@@ -17,11 +17,11 @@ package fsutil
import (
"math"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// DirtySet maps offsets into a memmap.Mappable to DirtyInfo. It is used to
diff --git a/pkg/sentry/fs/fsutil/dirty_set_test.go b/pkg/sentry/fs/fsutil/dirty_set_test.go
index 75575d994..e3579c23c 100644
--- a/pkg/sentry/fs/fsutil/dirty_set_test.go
+++ b/pkg/sentry/fs/fsutil/dirty_set_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func TestDirtySet(t *testing.T) {
diff --git a/pkg/sentry/fs/fsutil/file.go b/pkg/sentry/fs/fsutil/file.go
index fc5b3b1a1..08695391c 100644
--- a/pkg/sentry/fs/fsutil/file.go
+++ b/pkg/sentry/fs/fsutil/file.go
@@ -17,12 +17,12 @@ package fsutil
import (
"io"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/fsutil/file_range_set.go b/pkg/sentry/fs/fsutil/file_range_set.go
index f52d712e3..5643cdac9 100644
--- a/pkg/sentry/fs/fsutil/file_range_set.go
+++ b/pkg/sentry/fs/fsutil/file_range_set.go
@@ -19,13 +19,13 @@ import (
"io"
"math"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// FileRangeSet maps offsets into a memmap.Mappable to offsets into a
diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go
index 837fc70b5..67278aa86 100644
--- a/pkg/sentry/fs/fsutil/host_file_mapper.go
+++ b/pkg/sentry/fs/fsutil/host_file_mapper.go
@@ -19,11 +19,11 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// HostFileMapper caches mappings of an arbitrary host file descriptor. It is
diff --git a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go
index ad11a0573..2d4778d64 100644
--- a/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go
+++ b/pkg/sentry/fs/fsutil/host_file_mapper_unsafe.go
@@ -17,7 +17,7 @@ package fsutil
import (
"unsafe"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
+ "gvisor.dev/gvisor/pkg/safemem"
)
func (*HostFileMapper) unsafeBlockFromChunkMapping(addr uintptr) safemem.Block {
diff --git a/pkg/sentry/fs/fsutil/host_mappable.go b/pkg/sentry/fs/fsutil/host_mappable.go
index a625f0e26..78fec553e 100644
--- a/pkg/sentry/fs/fsutil/host_mappable.go
+++ b/pkg/sentry/fs/fsutil/host_mappable.go
@@ -17,13 +17,13 @@ package fsutil
import (
"math"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// HostMappable implements memmap.Mappable and platform.File over a
diff --git a/pkg/sentry/fs/fsutil/inode.go b/pkg/sentry/fs/fsutil/inode.go
index df7b74855..252830572 100644
--- a/pkg/sentry/fs/fsutil/inode.go
+++ b/pkg/sentry/fs/fsutil/inode.go
@@ -16,7 +16,7 @@ package fsutil
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/memmap"
diff --git a/pkg/sentry/fs/fsutil/inode_cached.go b/pkg/sentry/fs/fsutil/inode_cached.go
index 20a014402..573b8586e 100644
--- a/pkg/sentry/fs/fsutil/inode_cached.go
+++ b/pkg/sentry/fs/fsutil/inode_cached.go
@@ -18,18 +18,18 @@ import (
"fmt"
"io"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/time"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Lock order (compare the lock order model in mm/mm.go):
diff --git a/pkg/sentry/fs/fsutil/inode_cached_test.go b/pkg/sentry/fs/fsutil/inode_cached_test.go
index 129f314c8..1547584c5 100644
--- a/pkg/sentry/fs/fsutil/inode_cached_test.go
+++ b/pkg/sentry/fs/fsutil/inode_cached_test.go
@@ -19,14 +19,14 @@ import (
"io"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type noopBackingFile struct{}
diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD
index fd870e8e1..971d3718e 100644
--- a/pkg/sentry/fs/gofer/BUILD
+++ b/pkg/sentry/fs/gofer/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -22,17 +21,17 @@ go_library(
"socket.go",
"util.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/gofer",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fd",
"//pkg/log",
"//pkg/metric",
"//pkg/p9",
"//pkg/refs",
+ "//pkg/safemem",
"//pkg/secio",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fdpipe",
@@ -41,13 +40,12 @@ go_library(
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
"//pkg/sentry/memmap",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserr",
"//pkg/syserror",
"//pkg/unet",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -56,12 +54,12 @@ go_test(
name = "gofer_test",
size = "small",
srcs = ["gofer_test.go"],
- embed = [":gofer"],
+ library = ":gofer",
deps = [
+ "//pkg/context",
"//pkg/p9",
"//pkg/p9/p9test",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
],
)
diff --git a/pkg/sentry/fs/gofer/attr.go b/pkg/sentry/fs/gofer/attr.go
index 4848e2374..71cccdc34 100644
--- a/pkg/sentry/fs/gofer/attr.go
+++ b/pkg/sentry/fs/gofer/attr.go
@@ -17,12 +17,12 @@ package gofer
import (
"syscall"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// getattr returns the 9p attributes of the p9.File. On success, Mode, Size, and RDev
diff --git a/pkg/sentry/fs/gofer/cache_policy.go b/pkg/sentry/fs/gofer/cache_policy.go
index cc11c6339..ebea03c42 100644
--- a/pkg/sentry/fs/gofer/cache_policy.go
+++ b/pkg/sentry/fs/gofer/cache_policy.go
@@ -17,7 +17,7 @@ package gofer
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/gofer/context_file.go b/pkg/sentry/fs/gofer/context_file.go
index 2125dafef..3da818aed 100644
--- a/pkg/sentry/fs/gofer/context_file.go
+++ b/pkg/sentry/fs/gofer/context_file.go
@@ -15,9 +15,9 @@
package gofer
import (
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
)
// contextFile is a wrapper around p9.File that notifies the context that
diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go
index 7960b9c7b..23296f246 100644
--- a/pkg/sentry/fs/gofer/file.go
+++ b/pkg/sentry/fs/gofer/file.go
@@ -19,16 +19,16 @@ import (
"syscall"
"time"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/metric"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go
index bb8312849..ff96b28ba 100644
--- a/pkg/sentry/fs/gofer/file_state.go
+++ b/pkg/sentry/fs/gofer/file_state.go
@@ -17,7 +17,7 @@ package gofer
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/gofer/fs.go b/pkg/sentry/fs/gofer/fs.go
index cf96dd9fa..9d41fcbdb 100644
--- a/pkg/sentry/fs/gofer/fs.go
+++ b/pkg/sentry/fs/gofer/fs.go
@@ -20,8 +20,8 @@ import (
"fmt"
"strconv"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/gofer/gofer_test.go b/pkg/sentry/fs/gofer/gofer_test.go
index 7fc3c32ae..0c2f89ae8 100644
--- a/pkg/sentry/fs/gofer/gofer_test.go
+++ b/pkg/sentry/fs/gofer/gofer_test.go
@@ -20,10 +20,10 @@ import (
"testing"
"time"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
"gvisor.dev/gvisor/pkg/p9/p9test"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/gofer/handles.go b/pkg/sentry/fs/gofer/handles.go
index b86c49b39..9f7c3e89f 100644
--- a/pkg/sentry/fs/gofer/handles.go
+++ b/pkg/sentry/fs/gofer/handles.go
@@ -17,14 +17,14 @@ package gofer
import (
"io"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/p9"
"gvisor.dev/gvisor/pkg/refs"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/secio"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
)
// handles are the open handles of a gofer file. They are reference counted to
diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go
index 98d1a8a48..ac28174d2 100644
--- a/pkg/sentry/fs/gofer/inode.go
+++ b/pkg/sentry/fs/gofer/inode.go
@@ -19,17 +19,17 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fdpipe"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/host"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go
index 0b2eedb7c..238f7804c 100644
--- a/pkg/sentry/fs/gofer/inode_state.go
+++ b/pkg/sentry/fs/gofer/inode_state.go
@@ -20,8 +20,8 @@ import (
"path/filepath"
"strings"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/time"
diff --git a/pkg/sentry/fs/gofer/path.go b/pkg/sentry/fs/gofer/path.go
index c09f3b71c..0c1be05ef 100644
--- a/pkg/sentry/fs/gofer/path.go
+++ b/pkg/sentry/fs/gofer/path.go
@@ -18,9 +18,9 @@ import (
"fmt"
"syscall"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
diff --git a/pkg/sentry/fs/gofer/session.go b/pkg/sentry/fs/gofer/session.go
index edc796ce0..498c4645a 100644
--- a/pkg/sentry/fs/gofer/session.go
+++ b/pkg/sentry/fs/gofer/session.go
@@ -17,9 +17,9 @@ package gofer
import (
"fmt"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
diff --git a/pkg/sentry/fs/gofer/session_state.go b/pkg/sentry/fs/gofer/session_state.go
index d045e04ff..0285c5361 100644
--- a/pkg/sentry/fs/gofer/session_state.go
+++ b/pkg/sentry/fs/gofer/session_state.go
@@ -17,8 +17,8 @@ package gofer
import (
"fmt"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/unet"
)
diff --git a/pkg/sentry/fs/gofer/socket.go b/pkg/sentry/fs/gofer/socket.go
index a45a8f36c..376cfce2c 100644
--- a/pkg/sentry/fs/gofer/socket.go
+++ b/pkg/sentry/fs/gofer/socket.go
@@ -16,9 +16,9 @@ package gofer
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/host"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
diff --git a/pkg/sentry/fs/gofer/util.go b/pkg/sentry/fs/gofer/util.go
index 848e6812b..2d8d3a2ea 100644
--- a/pkg/sentry/fs/gofer/util.go
+++ b/pkg/sentry/fs/gofer/util.go
@@ -17,8 +17,8 @@ package gofer
import (
"syscall"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/p9"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD
index 2b581aa69..21003ea45 100644
--- a/pkg/sentry/fs/host/BUILD
+++ b/pkg/sentry/fs/host/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -25,17 +24,17 @@ go_library(
"util_arm64_unsafe.go",
"util_unsafe.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/host",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fd",
"//pkg/fdnotifier",
"//pkg/log",
"//pkg/refs",
+ "//pkg/safemem",
"//pkg/secio",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
@@ -43,18 +42,17 @@ go_library(
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
"//pkg/sentry/memmap",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket/control",
"//pkg/sentry/socket/unix",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/unimpl",
"//pkg/sentry/uniqueid",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserr",
"//pkg/syserror",
"//pkg/tcpip",
"//pkg/unet",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -69,19 +67,19 @@ go_test(
"socket_test.go",
"wait_test.go",
],
- embed = [":host"],
+ library = ":host",
deps = [
+ "//pkg/context",
"//pkg/fd",
"//pkg/fdnotifier",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
"//pkg/sentry/kernel/time",
"//pkg/sentry/socket",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/syserr",
"//pkg/tcpip",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/fs/host/control.go b/pkg/sentry/fs/host/control.go
index 5532ff5a0..1658979fc 100644
--- a/pkg/sentry/fs/host/control.go
+++ b/pkg/sentry/fs/host/control.go
@@ -17,7 +17,7 @@ package host
import (
"syscall"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/socket/control"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go
index f6c626f2c..e08f56d04 100644
--- a/pkg/sentry/fs/host/file.go
+++ b/pkg/sentry/fs/host/file.go
@@ -18,17 +18,17 @@ import (
"fmt"
"syscall"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/secio"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/host/fs.go b/pkg/sentry/fs/host/fs.go
index 68d2697c0..d3e8e3a36 100644
--- a/pkg/sentry/fs/host/fs.go
+++ b/pkg/sentry/fs/host/fs.go
@@ -23,8 +23,8 @@ import (
"strconv"
"strings"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/host/fs_test.go b/pkg/sentry/fs/host/fs_test.go
index c6852ee30..3111d2df9 100644
--- a/pkg/sentry/fs/host/fs_test.go
+++ b/pkg/sentry/fs/host/fs_test.go
@@ -23,8 +23,8 @@ import (
"sort"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go
index 873a1c52d..6fa39caab 100644
--- a/pkg/sentry/fs/host/inode.go
+++ b/pkg/sentry/fs/host/inode.go
@@ -18,14 +18,14 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/secio"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
diff --git a/pkg/sentry/fs/host/inode_state.go b/pkg/sentry/fs/host/inode_state.go
index b267ec305..299e0e0b0 100644
--- a/pkg/sentry/fs/host/inode_state.go
+++ b/pkg/sentry/fs/host/inode_state.go
@@ -18,7 +18,7 @@ import (
"fmt"
"syscall"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go
index 2d959f10d..7221bc825 100644
--- a/pkg/sentry/fs/host/inode_test.go
+++ b/pkg/sentry/fs/host/inode_test.go
@@ -21,7 +21,7 @@ import (
"syscall"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go
index c076d5bdd..06fc2d80a 100644
--- a/pkg/sentry/fs/host/socket.go
+++ b/pkg/sentry/fs/host/socket.go
@@ -19,11 +19,11 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/socket/control"
unixsocket "gvisor.dev/gvisor/pkg/sentry/socket/unix"
diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go
index 68b38fd1c..eb4afe520 100644
--- a/pkg/sentry/fs/host/socket_test.go
+++ b/pkg/sentry/fs/host/socket_test.go
@@ -21,13 +21,13 @@ import (
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/fdnotifier"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go
index 753ef8cd6..3f218b4a7 100644
--- a/pkg/sentry/fs/host/tty.go
+++ b/pkg/sentry/fs/host/tty.go
@@ -16,14 +16,14 @@ package host
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/unimpl"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// TTYFileOperations implements fs.FileOperations for a host file descriptor
diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go
index 88d24d693..d49c3a635 100644
--- a/pkg/sentry/fs/host/wait_test.go
+++ b/pkg/sentry/fs/host/wait_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"time"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/inode.go b/pkg/sentry/fs/inode.go
index e4cf5a570..b66c091ab 100644
--- a/pkg/sentry/fs/inode.go
+++ b/pkg/sentry/fs/inode.go
@@ -16,10 +16,10 @@ package fs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/metric"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs/lock"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/memmap"
diff --git a/pkg/sentry/fs/inode_operations.go b/pkg/sentry/fs/inode_operations.go
index 13261cb81..70f2eae96 100644
--- a/pkg/sentry/fs/inode_operations.go
+++ b/pkg/sentry/fs/inode_operations.go
@@ -17,7 +17,7 @@ package fs
import (
"errors"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
diff --git a/pkg/sentry/fs/inode_overlay.go b/pkg/sentry/fs/inode_overlay.go
index c477de837..4729b4aac 100644
--- a/pkg/sentry/fs/inode_overlay.go
+++ b/pkg/sentry/fs/inode_overlay.go
@@ -19,8 +19,8 @@ import (
"strings"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fs/inode_overlay_test.go b/pkg/sentry/fs/inode_overlay_test.go
index 493d98c36..389c219d6 100644
--- a/pkg/sentry/fs/inode_overlay_test.go
+++ b/pkg/sentry/fs/inode_overlay_test.go
@@ -17,7 +17,7 @@ package fs_test
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go
index cc7dd1c92..928c90aa0 100644
--- a/pkg/sentry/fs/inotify.go
+++ b/pkg/sentry/fs/inotify.go
@@ -19,13 +19,13 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go
index 9f70a3e82..686e1b1cd 100644
--- a/pkg/sentry/fs/inotify_event.go
+++ b/pkg/sentry/fs/inotify_event.go
@@ -18,8 +18,8 @@ import (
"bytes"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// inotifyEventBaseSize is the base size of linux's struct inotify_event. This
diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD
index 2c332a82a..ae3331737 100644
--- a/pkg/sentry/fs/lock/BUILD
+++ b/pkg/sentry/fs/lock/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -40,7 +39,6 @@ go_library(
"lock_set.go",
"lock_set_functions.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/lock",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/log",
@@ -56,5 +54,5 @@ go_test(
"lock_range_test.go",
"lock_test.go",
],
- embed = [":lock"],
+ library = ":lock",
)
diff --git a/pkg/sentry/fs/mock.go b/pkg/sentry/fs/mock.go
index 7a24c6f1b..1d6ea5736 100644
--- a/pkg/sentry/fs/mock.go
+++ b/pkg/sentry/fs/mock.go
@@ -15,7 +15,7 @@
package fs
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fs/mount.go b/pkg/sentry/fs/mount.go
index 7a9692800..37bae6810 100644
--- a/pkg/sentry/fs/mount.go
+++ b/pkg/sentry/fs/mount.go
@@ -19,8 +19,8 @@ import (
"fmt"
"sync/atomic"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
)
// DirentOperations provide file systems greater control over how long a Dirent
diff --git a/pkg/sentry/fs/mount_overlay.go b/pkg/sentry/fs/mount_overlay.go
index 299712cd7..78e35b1e6 100644
--- a/pkg/sentry/fs/mount_overlay.go
+++ b/pkg/sentry/fs/mount_overlay.go
@@ -15,7 +15,7 @@
package fs
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// overlayMountSourceOperations implements MountSourceOperations for an overlay
diff --git a/pkg/sentry/fs/mount_test.go b/pkg/sentry/fs/mount_test.go
index 0b84732aa..e672a438c 100644
--- a/pkg/sentry/fs/mount_test.go
+++ b/pkg/sentry/fs/mount_test.go
@@ -18,7 +18,7 @@ import (
"fmt"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
)
// cacheReallyContains iterates through the dirent cache to determine whether
diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go
index a9627a9d1..574a2cc91 100644
--- a/pkg/sentry/fs/mounts.go
+++ b/pkg/sentry/fs/mounts.go
@@ -22,9 +22,9 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
diff --git a/pkg/sentry/fs/mounts_test.go b/pkg/sentry/fs/mounts_test.go
index c4c771f2c..a69b41468 100644
--- a/pkg/sentry/fs/mounts_test.go
+++ b/pkg/sentry/fs/mounts_test.go
@@ -17,7 +17,7 @@ package fs_test
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
diff --git a/pkg/sentry/fs/offset.go b/pkg/sentry/fs/offset.go
index f7d844ce7..53b5df175 100644
--- a/pkg/sentry/fs/offset.go
+++ b/pkg/sentry/fs/offset.go
@@ -17,7 +17,7 @@ package fs
import (
"math"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// OffsetPageEnd returns the file offset rounded up to the nearest
diff --git a/pkg/sentry/fs/overlay.go b/pkg/sentry/fs/overlay.go
index f7702f8f4..a8ae7d81d 100644
--- a/pkg/sentry/fs/overlay.go
+++ b/pkg/sentry/fs/overlay.go
@@ -18,12 +18,12 @@ import (
"fmt"
"strings"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// The virtual filesystem implements an overlay configuration. For a high-level
diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD
index cb37c6c6b..280093c5e 100644
--- a/pkg/sentry/fs/proc/BUILD
+++ b/pkg/sentry/fs/proc/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -27,12 +26,11 @@ go_library(
"uptime.go",
"version.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/proc",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/fs/proc/device",
@@ -48,10 +46,10 @@ go_library(
"//pkg/sentry/socket/unix",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
"//pkg/tcpip/header",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -63,11 +61,11 @@ go_test(
"net_test.go",
"sys_net_test.go",
],
- embed = [":proc"],
+ library = ":proc",
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/inet",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/proc/cgroup.go b/pkg/sentry/fs/proc/cgroup.go
index c4abe319d..7c1d9e7e9 100644
--- a/pkg/sentry/fs/proc/cgroup.go
+++ b/pkg/sentry/fs/proc/cgroup.go
@@ -17,7 +17,7 @@ package proc
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/proc/cpuinfo.go b/pkg/sentry/fs/proc/cpuinfo.go
index df0c4e3a7..c96533401 100644
--- a/pkg/sentry/fs/proc/cpuinfo.go
+++ b/pkg/sentry/fs/proc/cpuinfo.go
@@ -17,7 +17,7 @@ package proc
import (
"bytes"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
)
diff --git a/pkg/sentry/fs/proc/device/BUILD b/pkg/sentry/fs/proc/device/BUILD
index 0394451d4..52c9aa93d 100644
--- a/pkg/sentry/fs/proc/device/BUILD
+++ b/pkg/sentry/fs/proc/device/BUILD
@@ -1,11 +1,10 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "device",
srcs = ["device.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/proc/device",
visibility = ["//pkg/sentry:internal"],
deps = ["//pkg/sentry/device"],
)
diff --git a/pkg/sentry/fs/proc/exec_args.go b/pkg/sentry/fs/proc/exec_args.go
index 9aaeb780b..8fe626e1c 100644
--- a/pkg/sentry/fs/proc/exec_args.go
+++ b/pkg/sentry/fs/proc/exec_args.go
@@ -20,12 +20,12 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go
index 2fa3cfa7d..35972e23c 100644
--- a/pkg/sentry/fs/proc/fds.go
+++ b/pkg/sentry/fs/proc/fds.go
@@ -19,7 +19,7 @@ import (
"sort"
"strconv"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/device"
diff --git a/pkg/sentry/fs/proc/filesystems.go b/pkg/sentry/fs/proc/filesystems.go
index 7b3b974ab..0a58ac34c 100644
--- a/pkg/sentry/fs/proc/filesystems.go
+++ b/pkg/sentry/fs/proc/filesystems.go
@@ -18,7 +18,7 @@ import (
"bytes"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
)
diff --git a/pkg/sentry/fs/proc/fs.go b/pkg/sentry/fs/proc/fs.go
index 761d24462..daf1ba781 100644
--- a/pkg/sentry/fs/proc/fs.go
+++ b/pkg/sentry/fs/proc/fs.go
@@ -17,7 +17,7 @@ package proc
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/proc/inode.go b/pkg/sentry/fs/proc/inode.go
index 723f6b661..d2859a4c2 100644
--- a/pkg/sentry/fs/proc/inode.go
+++ b/pkg/sentry/fs/proc/inode.go
@@ -16,14 +16,14 @@ package proc
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/device"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// LINT.IfChange
diff --git a/pkg/sentry/fs/proc/loadavg.go b/pkg/sentry/fs/proc/loadavg.go
index d7d2afcb7..139d49c34 100644
--- a/pkg/sentry/fs/proc/loadavg.go
+++ b/pkg/sentry/fs/proc/loadavg.go
@@ -18,7 +18,7 @@ import (
"bytes"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
)
diff --git a/pkg/sentry/fs/proc/meminfo.go b/pkg/sentry/fs/proc/meminfo.go
index 313c6a32b..465b47da9 100644
--- a/pkg/sentry/fs/proc/meminfo.go
+++ b/pkg/sentry/fs/proc/meminfo.go
@@ -18,11 +18,11 @@ import (
"bytes"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// LINT.IfChange
diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go
index d4efc86e0..c10888100 100644
--- a/pkg/sentry/fs/proc/mounts.go
+++ b/pkg/sentry/fs/proc/mounts.go
@@ -20,7 +20,7 @@ import (
"sort"
"strings"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/kernel"
diff --git a/pkg/sentry/fs/proc/net.go b/pkg/sentry/fs/proc/net.go
index bad445f3f..6f2775344 100644
--- a/pkg/sentry/fs/proc/net.go
+++ b/pkg/sentry/fs/proc/net.go
@@ -22,8 +22,8 @@ import (
"time"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
@@ -33,9 +33,9 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/unix"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
"gvisor.dev/gvisor/pkg/tcpip/header"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// LINT.IfChange
diff --git a/pkg/sentry/fs/proc/proc.go b/pkg/sentry/fs/proc/proc.go
index 29867dc3a..c8abb5052 100644
--- a/pkg/sentry/fs/proc/proc.go
+++ b/pkg/sentry/fs/proc/proc.go
@@ -20,7 +20,7 @@ import (
"sort"
"strconv"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/device"
diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD
index 38b246dff..21338d912 100644
--- a/pkg/sentry/fs/proc/seqfile/BUILD
+++ b/pkg/sentry/fs/proc/seqfile/BUILD
@@ -1,23 +1,21 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
go_library(
name = "seqfile",
srcs = ["seqfile.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/fs/proc/device",
"//pkg/sentry/kernel/time",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -26,12 +24,12 @@ go_test(
name = "seqfile_test",
size = "small",
srcs = ["seqfile_test.go"],
- embed = [":seqfile"],
+ library = ":seqfile",
deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
"//pkg/sentry/fs/ramfs",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/proc/seqfile/seqfile.go b/pkg/sentry/fs/proc/seqfile/seqfile.go
index f9af191d5..6121f0e95 100644
--- a/pkg/sentry/fs/proc/seqfile/seqfile.go
+++ b/pkg/sentry/fs/proc/seqfile/seqfile.go
@@ -19,14 +19,14 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/device"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go
index ebfeee835..98e394569 100644
--- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go
+++ b/pkg/sentry/fs/proc/seqfile/seqfile_test.go
@@ -20,11 +20,11 @@ import (
"io"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type seqTest struct {
diff --git a/pkg/sentry/fs/proc/stat.go b/pkg/sentry/fs/proc/stat.go
index bc5b2bc7b..d4fbd76ac 100644
--- a/pkg/sentry/fs/proc/stat.go
+++ b/pkg/sentry/fs/proc/stat.go
@@ -19,7 +19,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/kernel"
)
diff --git a/pkg/sentry/fs/proc/sys.go b/pkg/sentry/fs/proc/sys.go
index 2bdcf5f70..f8aad2dbd 100644
--- a/pkg/sentry/fs/proc/sys.go
+++ b/pkg/sentry/fs/proc/sys.go
@@ -20,13 +20,13 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/sys_net.go b/pkg/sentry/fs/proc/sys_net.go
index b9e8ef35f..0772d4ae4 100644
--- a/pkg/sentry/fs/proc/sys_net.go
+++ b/pkg/sentry/fs/proc/sys_net.go
@@ -19,14 +19,14 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/device"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
"gvisor.dev/gvisor/pkg/sentry/inet"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go
index 6abae7a60..355e83d47 100644
--- a/pkg/sentry/fs/proc/sys_net_test.go
+++ b/pkg/sentry/fs/proc/sys_net_test.go
@@ -17,9 +17,9 @@ package proc
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/inet"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func TestQuerySendBufferSize(t *testing.T) {
diff --git a/pkg/sentry/fs/proc/task.go b/pkg/sentry/fs/proc/task.go
index 7358d6ef9..ca020e11e 100644
--- a/pkg/sentry/fs/proc/task.go
+++ b/pkg/sentry/fs/proc/task.go
@@ -22,7 +22,7 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/device"
@@ -32,8 +32,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/mm"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/uid_gid_map.go b/pkg/sentry/fs/proc/uid_gid_map.go
index 3eacc9265..8d9517b95 100644
--- a/pkg/sentry/fs/proc/uid_gid_map.go
+++ b/pkg/sentry/fs/proc/uid_gid_map.go
@@ -20,13 +20,13 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/uptime.go b/pkg/sentry/fs/proc/uptime.go
index adfe58adb..c0f6fb802 100644
--- a/pkg/sentry/fs/proc/uptime.go
+++ b/pkg/sentry/fs/proc/uptime.go
@@ -19,12 +19,12 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/proc/version.go b/pkg/sentry/fs/proc/version.go
index 27fd5b1cb..35e258ff6 100644
--- a/pkg/sentry/fs/proc/version.go
+++ b/pkg/sentry/fs/proc/version.go
@@ -17,7 +17,7 @@ package proc
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/kernel"
)
diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD
index 3fb7b0633..8ca823fb3 100644
--- a/pkg/sentry/fs/ramfs/BUILD
+++ b/pkg/sentry/fs/ramfs/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -11,18 +10,17 @@ go_library(
"symlink.go",
"tree.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/ramfs",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -31,9 +29,9 @@ go_test(
name = "ramfs_test",
size = "small",
srcs = ["tree_test.go"],
- embed = [":ramfs"],
+ library = ":ramfs",
deps = [
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
],
)
diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go
index dcbb8eb2e..bfa304552 100644
--- a/pkg/sentry/fs/ramfs/dir.go
+++ b/pkg/sentry/fs/ramfs/dir.go
@@ -20,7 +20,7 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
diff --git a/pkg/sentry/fs/ramfs/socket.go b/pkg/sentry/fs/ramfs/socket.go
index a24fe2ea2..29ff004f2 100644
--- a/pkg/sentry/fs/ramfs/socket.go
+++ b/pkg/sentry/fs/ramfs/socket.go
@@ -16,7 +16,7 @@ package ramfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
diff --git a/pkg/sentry/fs/ramfs/symlink.go b/pkg/sentry/fs/ramfs/symlink.go
index fcfaa29aa..d988349aa 100644
--- a/pkg/sentry/fs/ramfs/symlink.go
+++ b/pkg/sentry/fs/ramfs/symlink.go
@@ -16,7 +16,7 @@ package ramfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/waiter"
diff --git a/pkg/sentry/fs/ramfs/tree.go b/pkg/sentry/fs/ramfs/tree.go
index 702cc4a1e..dfc9d3453 100644
--- a/pkg/sentry/fs/ramfs/tree.go
+++ b/pkg/sentry/fs/ramfs/tree.go
@@ -19,10 +19,10 @@ import (
"path"
"strings"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// MakeDirectoryTree constructs a ramfs tree of all directories containing
diff --git a/pkg/sentry/fs/ramfs/tree_test.go b/pkg/sentry/fs/ramfs/tree_test.go
index 61a7e2900..a6ed8b2c5 100644
--- a/pkg/sentry/fs/ramfs/tree_test.go
+++ b/pkg/sentry/fs/ramfs/tree_test.go
@@ -17,7 +17,7 @@ package ramfs
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/splice.go b/pkg/sentry/fs/splice.go
index 389c330a0..33da82868 100644
--- a/pkg/sentry/fs/splice.go
+++ b/pkg/sentry/fs/splice.go
@@ -18,7 +18,7 @@ import (
"io"
"sync/atomic"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserror"
)
@@ -167,11 +167,6 @@ func Splice(ctx context.Context, dst *File, src *File, opts SpliceOpts) (int64,
if !srcPipe && !opts.SrcOffset {
atomic.StoreInt64(&src.offset, src.offset+n)
}
-
- // Don't report any errors if we have some progress without data loss.
- if w.Err == nil {
- err = nil
- }
}
// Drop locks.
diff --git a/pkg/sentry/fs/sys/BUILD b/pkg/sentry/fs/sys/BUILD
index 25f0f124e..f2e8b9932 100644
--- a/pkg/sentry/fs/sys/BUILD
+++ b/pkg/sentry/fs/sys/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -10,16 +10,15 @@ go_library(
"fs.go",
"sys.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/sys",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/fs/ramfs",
"//pkg/sentry/kernel",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/sys/devices.go b/pkg/sentry/fs/sys/devices.go
index 4f78ca8d2..b67065956 100644
--- a/pkg/sentry/fs/sys/devices.go
+++ b/pkg/sentry/fs/sys/devices.go
@@ -18,7 +18,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
diff --git a/pkg/sentry/fs/sys/fs.go b/pkg/sentry/fs/sys/fs.go
index e60b63e75..fd03a4e38 100644
--- a/pkg/sentry/fs/sys/fs.go
+++ b/pkg/sentry/fs/sys/fs.go
@@ -15,7 +15,7 @@
package sys
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
)
diff --git a/pkg/sentry/fs/sys/sys.go b/pkg/sentry/fs/sys/sys.go
index b14bf3f55..0891645e4 100644
--- a/pkg/sentry/fs/sys/sys.go
+++ b/pkg/sentry/fs/sys/sys.go
@@ -16,10 +16,10 @@
package sys
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func newFile(ctx context.Context, node fs.InodeOperations, msrc *fs.MountSource) *fs.Inode {
diff --git a/pkg/sentry/fs/timerfd/BUILD b/pkg/sentry/fs/timerfd/BUILD
index a215c1b95..d16cdb4df 100644
--- a/pkg/sentry/fs/timerfd/BUILD
+++ b/pkg/sentry/fs/timerfd/BUILD
@@ -1,20 +1,19 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "timerfd",
srcs = ["timerfd.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/timerfd",
visibility = ["//pkg/sentry:internal"],
deps = [
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel/time",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go
index f8bf663bb..88c344089 100644
--- a/pkg/sentry/fs/timerfd/timerfd.go
+++ b/pkg/sentry/fs/timerfd/timerfd.go
@@ -19,13 +19,13 @@ package timerfd
import (
"sync/atomic"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tmpfs/BUILD b/pkg/sentry/fs/tmpfs/BUILD
index 3400b940c..aa7199014 100644
--- a/pkg/sentry/fs/tmpfs/BUILD
+++ b/pkg/sentry/fs/tmpfs/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -12,12 +11,12 @@ go_library(
"inode_file.go",
"tmpfs.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/tmpfs",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/metric",
- "//pkg/sentry/context",
+ "//pkg/safemem",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
@@ -27,12 +26,11 @@ go_library(
"//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/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -41,12 +39,12 @@ go_test(
name = "tmpfs_test",
size = "small",
srcs = ["file_test.go"],
- embed = [":tmpfs"],
+ library = ":tmpfs",
deps = [
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs",
"//pkg/sentry/kernel/contexttest",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/tmpfs/file_regular.go b/pkg/sentry/fs/tmpfs/file_regular.go
index 9a6943fe4..614f8f8a1 100644
--- a/pkg/sentry/fs/tmpfs/file_regular.go
+++ b/pkg/sentry/fs/tmpfs/file_regular.go
@@ -15,11 +15,11 @@
package tmpfs
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tmpfs/file_test.go b/pkg/sentry/fs/tmpfs/file_test.go
index 0075ef023..aaba35502 100644
--- a/pkg/sentry/fs/tmpfs/file_test.go
+++ b/pkg/sentry/fs/tmpfs/file_test.go
@@ -18,11 +18,11 @@ import (
"bytes"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/contexttest"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func newFileInode(ctx context.Context) *fs.Inode {
diff --git a/pkg/sentry/fs/tmpfs/fs.go b/pkg/sentry/fs/tmpfs/fs.go
index be98ad751..d5be56c3f 100644
--- a/pkg/sentry/fs/tmpfs/fs.go
+++ b/pkg/sentry/fs/tmpfs/fs.go
@@ -19,7 +19,7 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
diff --git a/pkg/sentry/fs/tmpfs/inode_file.go b/pkg/sentry/fs/tmpfs/inode_file.go
index f1c87fe41..dabc10662 100644
--- a/pkg/sentry/fs/tmpfs/inode_file.go
+++ b/pkg/sentry/fs/tmpfs/inode_file.go
@@ -20,18 +20,18 @@ import (
"time"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/metric"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var (
diff --git a/pkg/sentry/fs/tmpfs/tmpfs.go b/pkg/sentry/fs/tmpfs/tmpfs.go
index 0f718e236..c00cef0a5 100644
--- a/pkg/sentry/fs/tmpfs/tmpfs.go
+++ b/pkg/sentry/fs/tmpfs/tmpfs.go
@@ -17,7 +17,7 @@ package tmpfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/fs/ramfs"
@@ -25,8 +25,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/pipe"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var fsInfo = fs.Info{
diff --git a/pkg/sentry/fs/tty/BUILD b/pkg/sentry/fs/tty/BUILD
index f6f60d0cf..5cb0e0417 100644
--- a/pkg/sentry/fs/tty/BUILD
+++ b/pkg/sentry/fs/tty/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -14,24 +13,23 @@ go_library(
"slave.go",
"terminal.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fs/tty",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/refs",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/unimpl",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -40,10 +38,10 @@ go_test(
name = "tty_test",
size = "small",
srcs = ["tty_test.go"],
- embed = [":tty"],
+ library = ":tty",
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context/contexttest",
- "//pkg/sentry/usermem",
+ "//pkg/sentry/contexttest",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fs/tty/dir.go b/pkg/sentry/fs/tty/dir.go
index 88aa66b24..108654827 100644
--- a/pkg/sentry/fs/tty/dir.go
+++ b/pkg/sentry/fs/tty/dir.go
@@ -21,14 +21,14 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tty/fs.go b/pkg/sentry/fs/tty/fs.go
index edee56c12..8fe05ebe5 100644
--- a/pkg/sentry/fs/tty/fs.go
+++ b/pkg/sentry/fs/tty/fs.go
@@ -15,7 +15,7 @@
package tty
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/syserror"
diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go
index 9fe02657e..12b1c6097 100644
--- a/pkg/sentry/fs/tty/line_discipline.go
+++ b/pkg/sentry/fs/tty/line_discipline.go
@@ -19,11 +19,11 @@ import (
"unicode/utf8"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tty/master.go b/pkg/sentry/fs/tty/master.go
index 6b07f6bf2..f62da49bd 100644
--- a/pkg/sentry/fs/tty/master.go
+++ b/pkg/sentry/fs/tty/master.go
@@ -16,13 +16,13 @@ package tty
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/unimpl"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tty/queue.go b/pkg/sentry/fs/tty/queue.go
index 21ccc6f32..1ca79c0b2 100644
--- a/pkg/sentry/fs/tty/queue.go
+++ b/pkg/sentry/fs/tty/queue.go
@@ -16,12 +16,12 @@ package tty
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tty/slave.go b/pkg/sentry/fs/tty/slave.go
index 2a51e6bab..db55cdc48 100644
--- a/pkg/sentry/fs/tty/slave.go
+++ b/pkg/sentry/fs/tty/slave.go
@@ -16,12 +16,12 @@ package tty
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/fs/tty/terminal.go b/pkg/sentry/fs/tty/terminal.go
index 917f90cc0..5883f26db 100644
--- a/pkg/sentry/fs/tty/terminal.go
+++ b/pkg/sentry/fs/tty/terminal.go
@@ -16,11 +16,11 @@ package tty
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Terminal is a pseudoterminal.
diff --git a/pkg/sentry/fs/tty/tty_test.go b/pkg/sentry/fs/tty/tty_test.go
index 59f07ff8e..2cbc05678 100644
--- a/pkg/sentry/fs/tty/tty_test.go
+++ b/pkg/sentry/fs/tty/tty_test.go
@@ -18,8 +18,8 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func TestSimpleMasterToSlave(t *testing.T) {
diff --git a/pkg/sentry/fsimpl/devtmpfs/BUILD b/pkg/sentry/fsimpl/devtmpfs/BUILD
new file mode 100644
index 000000000..aa0c2ad8c
--- /dev/null
+++ b/pkg/sentry/fsimpl/devtmpfs/BUILD
@@ -0,0 +1,33 @@
+load("//tools:defs.bzl", "go_library", "go_test")
+
+licenses(["notice"])
+
+go_library(
+ name = "devtmpfs",
+ srcs = ["devtmpfs.go"],
+ visibility = ["//pkg/sentry:internal"],
+ deps = [
+ "//pkg/abi/linux",
+ "//pkg/context",
+ "//pkg/fspath",
+ "//pkg/sentry/fsimpl/tmpfs",
+ "//pkg/sentry/kernel/auth",
+ "//pkg/sentry/vfs",
+ "//pkg/sync",
+ ],
+)
+
+go_test(
+ name = "devtmpfs_test",
+ size = "small",
+ srcs = ["devtmpfs_test.go"],
+ library = ":devtmpfs",
+ deps = [
+ "//pkg/abi/linux",
+ "//pkg/fspath",
+ "//pkg/sentry/contexttest",
+ "//pkg/sentry/fsimpl/tmpfs",
+ "//pkg/sentry/kernel/auth",
+ "//pkg/sentry/vfs",
+ ],
+)
diff --git a/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go b/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go
new file mode 100644
index 000000000..d36fa74fb
--- /dev/null
+++ b/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go
@@ -0,0 +1,187 @@
+// Copyright 2020 The 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 devtmpfs provides an implementation of /dev based on tmpfs,
+// analogous to Linux's devtmpfs.
+package devtmpfs
+
+import (
+ "fmt"
+
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/fspath"
+ "gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/sync"
+)
+
+// FilesystemType implements vfs.FilesystemType.
+type FilesystemType struct {
+ initOnce sync.Once
+ initErr error
+
+ // fs is the tmpfs filesystem that backs all mounts of this FilesystemType.
+ // root is fs' root. fs and root are immutable.
+ fs *vfs.Filesystem
+ root *vfs.Dentry
+}
+
+// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
+func (fst *FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
+ fst.initOnce.Do(func() {
+ fs, root, err := tmpfs.FilesystemType{}.GetFilesystem(ctx, vfsObj, creds, "" /* source */, vfs.GetFilesystemOptions{
+ Data: "mode=0755", // opts from drivers/base/devtmpfs.c:devtmpfs_init()
+ })
+ if err != nil {
+ fst.initErr = err
+ return
+ }
+ fst.fs = fs
+ fst.root = root
+ })
+ if fst.initErr != nil {
+ return nil, nil, fst.initErr
+ }
+ fst.fs.IncRef()
+ fst.root.IncRef()
+ return fst.fs, fst.root, nil
+}
+
+// Accessor allows devices to create device special files in devtmpfs.
+type Accessor struct {
+ vfsObj *vfs.VirtualFilesystem
+ mntns *vfs.MountNamespace
+ root vfs.VirtualDentry
+ creds *auth.Credentials
+}
+
+// NewAccessor returns an Accessor that supports creation of device special
+// files in the devtmpfs instance registered with name fsTypeName in vfsObj.
+func NewAccessor(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, fsTypeName string) (*Accessor, error) {
+ mntns, err := vfsObj.NewMountNamespace(ctx, creds, "devtmpfs" /* source */, fsTypeName, &vfs.GetFilesystemOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return &Accessor{
+ vfsObj: vfsObj,
+ mntns: mntns,
+ root: mntns.Root(),
+ creds: creds,
+ }, nil
+}
+
+// Release must be called when a is no longer in use.
+func (a *Accessor) Release() {
+ a.root.DecRef()
+ a.mntns.DecRef(a.vfsObj)
+}
+
+// accessorContext implements context.Context by extending an existing
+// context.Context with an Accessor's values for VFS-relevant state.
+type accessorContext struct {
+ context.Context
+ a *Accessor
+}
+
+func (a *Accessor) wrapContext(ctx context.Context) *accessorContext {
+ return &accessorContext{
+ Context: ctx,
+ a: a,
+ }
+}
+
+// Value implements context.Context.Value.
+func (ac *accessorContext) Value(key interface{}) interface{} {
+ switch key {
+ case vfs.CtxMountNamespace:
+ return ac.a.mntns
+ case vfs.CtxRoot:
+ ac.a.root.IncRef()
+ return ac.a.root
+ default:
+ return ac.Context.Value(key)
+ }
+}
+
+func (a *Accessor) pathOperationAt(pathname string) *vfs.PathOperation {
+ return &vfs.PathOperation{
+ Root: a.root,
+ Start: a.root,
+ Path: fspath.Parse(pathname),
+ }
+}
+
+// CreateDeviceFile creates a device special file at the given pathname in the
+// devtmpfs instance accessed by the Accessor.
+func (a *Accessor) CreateDeviceFile(ctx context.Context, pathname string, kind vfs.DeviceKind, major, minor uint32, perms uint16) error {
+ mode := (linux.FileMode)(perms)
+ switch kind {
+ case vfs.BlockDevice:
+ mode |= linux.S_IFBLK
+ case vfs.CharDevice:
+ mode |= linux.S_IFCHR
+ default:
+ panic(fmt.Sprintf("invalid vfs.DeviceKind: %v", kind))
+ }
+ // NOTE: Linux's devtmpfs refuses to automatically delete files it didn't
+ // create, which it recognizes by storing a pointer to the kdevtmpfs struct
+ // thread in struct inode::i_private. Accessor doesn't yet support deletion
+ // of files at all, and probably won't as long as we don't need to support
+ // kernel modules, so this is moot for now.
+ return a.vfsObj.MknodAt(a.wrapContext(ctx), a.creds, a.pathOperationAt(pathname), &vfs.MknodOptions{
+ Mode: mode,
+ DevMajor: major,
+ DevMinor: minor,
+ })
+}
+
+// UserspaceInit creates symbolic links and mount points in the devtmpfs
+// instance accessed by the Accessor that are created by userspace in Linux. It
+// does not create mounts.
+func (a *Accessor) UserspaceInit(ctx context.Context) error {
+ actx := a.wrapContext(ctx)
+
+ // systemd: src/shared/dev-setup.c:dev_setup()
+ for _, symlink := range []struct {
+ source string
+ target string
+ }{
+ // /proc/kcore is not implemented.
+ {source: "fd", target: "/proc/self/fd"},
+ {source: "stdin", target: "/proc/self/fd/0"},
+ {source: "stdout", target: "/proc/self/fd/1"},
+ {source: "stderr", target: "/proc/self/fd/2"},
+ } {
+ if err := a.vfsObj.SymlinkAt(actx, a.creds, a.pathOperationAt(symlink.source), symlink.target); err != nil {
+ return fmt.Errorf("failed to create symlink %q => %q: %v", symlink.source, symlink.target, err)
+ }
+ }
+
+ // systemd: src/core/mount-setup.c:mount_table
+ for _, dir := range []string{
+ "shm",
+ "pts",
+ } {
+ if err := a.vfsObj.MkdirAt(actx, a.creds, a.pathOperationAt(dir), &vfs.MkdirOptions{
+ // systemd: src/core/mount-setup.c:mount_one()
+ Mode: 0755,
+ }); err != nil {
+ return fmt.Errorf("failed to create directory %q: %v", dir, err)
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/sentry/fsimpl/devtmpfs/devtmpfs_test.go b/pkg/sentry/fsimpl/devtmpfs/devtmpfs_test.go
new file mode 100644
index 000000000..82c58c900
--- /dev/null
+++ b/pkg/sentry/fsimpl/devtmpfs/devtmpfs_test.go
@@ -0,0 +1,119 @@
+// Copyright 2020 The 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 devtmpfs
+
+import (
+ "testing"
+
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/fspath"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+)
+
+func TestDevtmpfs(t *testing.T) {
+ ctx := contexttest.Context(t)
+ creds := auth.CredentialsFromContext(ctx)
+
+ vfsObj := vfs.New()
+ // Register tmpfs just so that we can have a root filesystem that isn't
+ // devtmpfs.
+ vfsObj.MustRegisterFilesystemType("tmpfs", tmpfs.FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
+ AllowUserMount: true,
+ })
+ vfsObj.MustRegisterFilesystemType("devtmpfs", &FilesystemType{}, &vfs.RegisterFilesystemTypeOptions{
+ AllowUserMount: true,
+ })
+
+ // Create a test mount namespace with devtmpfs mounted at "/dev".
+ const devPath = "/dev"
+ mntns, err := vfsObj.NewMountNamespace(ctx, creds, "tmpfs" /* source */, "tmpfs" /* fsTypeName */, &vfs.GetFilesystemOptions{})
+ if err != nil {
+ t.Fatalf("failed to create tmpfs root mount: %v", err)
+ }
+ defer mntns.DecRef(vfsObj)
+ root := mntns.Root()
+ defer root.DecRef()
+ devpop := vfs.PathOperation{
+ Root: root,
+ Start: root,
+ Path: fspath.Parse(devPath),
+ }
+ if err := vfsObj.MkdirAt(ctx, creds, &devpop, &vfs.MkdirOptions{
+ Mode: 0755,
+ }); err != nil {
+ t.Fatalf("failed to create mount point: %v", err)
+ }
+ if err := vfsObj.MountAt(ctx, creds, "devtmpfs" /* source */, &devpop, "devtmpfs" /* fsTypeName */, &vfs.MountOptions{}); err != nil {
+ t.Fatalf("failed to mount devtmpfs: %v", err)
+ }
+
+ a, err := NewAccessor(ctx, vfsObj, creds, "devtmpfs")
+ if err != nil {
+ t.Fatalf("failed to create devtmpfs.Accessor: %v", err)
+ }
+ defer a.Release()
+
+ // Create "userspace-initialized" files using a devtmpfs.Accessor.
+ if err := a.UserspaceInit(ctx); err != nil {
+ t.Fatalf("failed to userspace-initialize devtmpfs: %v", err)
+ }
+ // Created files should be visible in the test mount namespace.
+ abspath := devPath + "/fd"
+ target, err := vfsObj.ReadlinkAt(ctx, creds, &vfs.PathOperation{
+ Root: root,
+ Start: root,
+ Path: fspath.Parse(abspath),
+ })
+ if want := "/proc/self/fd"; err != nil || target != want {
+ t.Fatalf("readlink(%q): got (%q, %v), wanted (%q, nil)", abspath, target, err, want)
+ }
+
+ // Create a dummy device special file using a devtmpfs.Accessor.
+ const (
+ pathInDev = "dummy"
+ kind = vfs.CharDevice
+ major = 12
+ minor = 34
+ perms = 0600
+ wantMode = linux.S_IFCHR | perms
+ )
+ if err := a.CreateDeviceFile(ctx, pathInDev, kind, major, minor, perms); err != nil {
+ t.Fatalf("failed to create device file: %v", err)
+ }
+ // The device special file should be visible in the test mount namespace.
+ abspath = devPath + "/" + pathInDev
+ stat, err := vfsObj.StatAt(ctx, creds, &vfs.PathOperation{
+ Root: root,
+ Start: root,
+ Path: fspath.Parse(abspath),
+ }, &vfs.StatOptions{
+ Mask: linux.STATX_TYPE | linux.STATX_MODE,
+ })
+ if err != nil {
+ t.Fatalf("failed to stat device file at %q: %v", abspath, err)
+ }
+ if stat.Mode != wantMode {
+ t.Errorf("device file mode: got %v, wanted %v", stat.Mode, wantMode)
+ }
+ if stat.RdevMajor != major {
+ t.Errorf("major device number: got %v, wanted %v", stat.RdevMajor, major)
+ }
+ if stat.RdevMinor != minor {
+ t.Errorf("minor device number: got %v, wanted %v", stat.RdevMinor, minor)
+ }
+}
diff --git a/pkg/sentry/fsimpl/ext/BUILD b/pkg/sentry/fsimpl/ext/BUILD
index 903874141..6f78f478f 100644
--- a/pkg/sentry/fsimpl/ext/BUILD
+++ b/pkg/sentry/fsimpl/ext/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
package(licenses = ["notice"])
@@ -32,26 +31,25 @@ go_library(
"symlink.go",
"utils.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/ext",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/fd",
"//pkg/fspath",
"//pkg/log",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fsimpl/ext/disklayout",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/memmap",
- "//pkg/sentry/safemem",
"//pkg/sentry/syscalls/linux",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -71,18 +69,18 @@ go_test(
"//pkg/sentry/fsimpl/ext:assets/tiny.ext3",
"//pkg/sentry/fsimpl/ext:assets/tiny.ext4",
],
- embed = [":ext"],
+ library = ":ext",
deps = [
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/fspath",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fsimpl/ext/disklayout",
"//pkg/sentry/kernel/auth",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/syserror",
+ "//pkg/usermem",
"//runsc/testutil",
"@com_github_google_go-cmp//cmp:go_default_library",
"@com_github_google_go-cmp//cmp/cmpopts:go_default_library",
diff --git a/pkg/sentry/fsimpl/ext/benchmark/BUILD b/pkg/sentry/fsimpl/ext/benchmark/BUILD
index 4fc8296ef..6c5a559fd 100644
--- a/pkg/sentry/fsimpl/ext/benchmark/BUILD
+++ b/pkg/sentry/fsimpl/ext/benchmark/BUILD
@@ -1,4 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_test")
package(licenses = ["notice"])
@@ -7,9 +7,9 @@ go_test(
size = "small",
srcs = ["benchmark_test.go"],
deps = [
+ "//pkg/context",
"//pkg/fspath",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fsimpl/ext",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/vfs",
diff --git a/pkg/sentry/fsimpl/ext/benchmark/benchmark_test.go b/pkg/sentry/fsimpl/ext/benchmark/benchmark_test.go
index a56b03711..d1436b943 100644
--- a/pkg/sentry/fsimpl/ext/benchmark/benchmark_test.go
+++ b/pkg/sentry/fsimpl/ext/benchmark/benchmark_test.go
@@ -24,9 +24,9 @@ import (
"strings"
"testing"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/ext"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
diff --git a/pkg/sentry/fsimpl/ext/directory.go b/pkg/sentry/fsimpl/ext/directory.go
index 8944171c8..ebb72b75e 100644
--- a/pkg/sentry/fsimpl/ext/directory.go
+++ b/pkg/sentry/fsimpl/ext/directory.go
@@ -17,8 +17,8 @@ package ext
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/ext/disklayout"
"gvisor.dev/gvisor/pkg/sentry/memmap"
diff --git a/pkg/sentry/fsimpl/ext/disklayout/BUILD b/pkg/sentry/fsimpl/ext/disklayout/BUILD
index fcfaf5c3e..9bd9c76c0 100644
--- a/pkg/sentry/fsimpl/ext/disklayout/BUILD
+++ b/pkg/sentry/fsimpl/ext/disklayout/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -23,7 +22,6 @@ go_library(
"superblock_old.go",
"test_utils.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/ext/disklayout",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
@@ -44,6 +42,6 @@ go_test(
"inode_test.go",
"superblock_test.go",
],
- embed = [":disklayout"],
+ library = ":disklayout",
deps = ["//pkg/sentry/kernel/time"],
)
diff --git a/pkg/sentry/fsimpl/ext/ext.go b/pkg/sentry/fsimpl/ext/ext.go
index 4b7d17dc6..373d23b74 100644
--- a/pkg/sentry/fsimpl/ext/ext.go
+++ b/pkg/sentry/fsimpl/ext/ext.go
@@ -21,9 +21,9 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/ext/disklayout"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
diff --git a/pkg/sentry/fsimpl/ext/ext_test.go b/pkg/sentry/fsimpl/ext/ext_test.go
index 6c14a1e2d..05f992826 100644
--- a/pkg/sentry/fsimpl/ext/ext_test.go
+++ b/pkg/sentry/fsimpl/ext/ext_test.go
@@ -25,14 +25,14 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/ext/disklayout"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/runsc/testutil"
)
diff --git a/pkg/sentry/fsimpl/ext/file_description.go b/pkg/sentry/fsimpl/ext/file_description.go
index 841274daf..92f7da40d 100644
--- a/pkg/sentry/fsimpl/ext/file_description.go
+++ b/pkg/sentry/fsimpl/ext/file_description.go
@@ -16,7 +16,7 @@ package ext
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fsimpl/ext/filesystem.go b/pkg/sentry/fsimpl/ext/filesystem.go
index 9afb1a84c..07bf58953 100644
--- a/pkg/sentry/fsimpl/ext/filesystem.go
+++ b/pkg/sentry/fsimpl/ext/filesystem.go
@@ -19,8 +19,8 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/ext/disklayout"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
diff --git a/pkg/sentry/fsimpl/ext/regular_file.go b/pkg/sentry/fsimpl/ext/regular_file.go
index d11153c90..30135ddb0 100644
--- a/pkg/sentry/fsimpl/ext/regular_file.go
+++ b/pkg/sentry/fsimpl/ext/regular_file.go
@@ -18,13 +18,13 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// regularFile represents a regular file's inode. This too follows the
diff --git a/pkg/sentry/fsimpl/ext/symlink.go b/pkg/sentry/fsimpl/ext/symlink.go
index bdf8705c1..1447a4dc1 100644
--- a/pkg/sentry/fsimpl/ext/symlink.go
+++ b/pkg/sentry/fsimpl/ext/symlink.go
@@ -15,11 +15,11 @@
package ext
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// symlink represents a symlink inode.
diff --git a/pkg/sentry/fsimpl/kernfs/BUILD b/pkg/sentry/fsimpl/kernfs/BUILD
index 66d409785..e73f1f857 100644
--- a/pkg/sentry/fsimpl/kernfs/BUILD
+++ b/pkg/sentry/fsimpl/kernfs/BUILD
@@ -1,8 +1,7 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-package(licenses = ["notice"])
+licenses(["notice"])
go_template_instance(
name = "slot_list",
@@ -27,20 +26,19 @@ go_library(
"slot_list.go",
"symlink.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fspath",
"//pkg/log",
"//pkg/refs",
- "//pkg/sentry/context",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/memmap",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
@@ -51,13 +49,13 @@ go_test(
deps = [
":kernfs",
"//pkg/abi/linux",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fsimpl/testutil",
"//pkg/sentry/kernel/auth",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/syserror",
+ "//pkg/usermem",
"@com_github_google_go-cmp//cmp:go_default_library",
],
)
diff --git a/pkg/sentry/fsimpl/kernfs/dynamic_bytes_file.go b/pkg/sentry/fsimpl/kernfs/dynamic_bytes_file.go
index 75624e0b1..733792c78 100644
--- a/pkg/sentry/fsimpl/kernfs/dynamic_bytes_file.go
+++ b/pkg/sentry/fsimpl/kernfs/dynamic_bytes_file.go
@@ -18,11 +18,11 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// DynamicBytesFile implements kernfs.Inode and represents a read-only
@@ -108,12 +108,12 @@ func (fd *DynamicBytesFD) PRead(ctx context.Context, dst usermem.IOSequence, off
// Write implements vfs.FileDescriptionImpl.Write.
func (fd *DynamicBytesFD) Write(ctx context.Context, src usermem.IOSequence, opts vfs.WriteOptions) (int64, error) {
- return fd.FileDescriptionDefaultImpl.Write(ctx, src, opts)
+ return fd.DynamicBytesFileDescriptionImpl.Write(ctx, src, opts)
}
// PWrite implements vfs.FileDescriptionImpl.PWrite.
func (fd *DynamicBytesFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error) {
- return fd.FileDescriptionDefaultImpl.PWrite(ctx, src, offset, opts)
+ return fd.DynamicBytesFileDescriptionImpl.PWrite(ctx, src, offset, opts)
}
// Release implements vfs.FileDescriptionImpl.Release.
diff --git a/pkg/sentry/fsimpl/kernfs/fd_impl_util.go b/pkg/sentry/fsimpl/kernfs/fd_impl_util.go
index 5fa1fa67b..6104751c8 100644
--- a/pkg/sentry/fsimpl/kernfs/fd_impl_util.go
+++ b/pkg/sentry/fsimpl/kernfs/fd_impl_util.go
@@ -16,11 +16,11 @@ package kernfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// GenericDirectoryFD implements vfs.FileDescriptionImpl for a generic directory
diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go
index a4600ad47..9d65d0179 100644
--- a/pkg/sentry/fsimpl/kernfs/filesystem.go
+++ b/pkg/sentry/fsimpl/kernfs/filesystem.go
@@ -20,8 +20,8 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go
index 1700fffd9..adca2313f 100644
--- a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go
+++ b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go
@@ -19,8 +19,8 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
diff --git a/pkg/sentry/fsimpl/kernfs/kernfs.go b/pkg/sentry/fsimpl/kernfs/kernfs.go
index 85bcdcc57..79ebea8a5 100644
--- a/pkg/sentry/fsimpl/kernfs/kernfs.go
+++ b/pkg/sentry/fsimpl/kernfs/kernfs.go
@@ -56,8 +56,8 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
diff --git a/pkg/sentry/fsimpl/kernfs/kernfs_test.go b/pkg/sentry/fsimpl/kernfs/kernfs_test.go
index fade59491..ee65cf491 100644
--- a/pkg/sentry/fsimpl/kernfs/kernfs_test.go
+++ b/pkg/sentry/fsimpl/kernfs/kernfs_test.go
@@ -21,14 +21,14 @@ import (
"github.com/google/go-cmp/cmp"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/testutil"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const defaultMode linux.FileMode = 01777
diff --git a/pkg/sentry/fsimpl/kernfs/symlink.go b/pkg/sentry/fsimpl/kernfs/symlink.go
index f19f12854..0ee7eb9b7 100644
--- a/pkg/sentry/fsimpl/kernfs/symlink.go
+++ b/pkg/sentry/fsimpl/kernfs/symlink.go
@@ -16,7 +16,7 @@ package kernfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
diff --git a/pkg/sentry/fsimpl/proc/BUILD b/pkg/sentry/fsimpl/proc/BUILD
index c5b79fb38..12aac2e6a 100644
--- a/pkg/sentry/fsimpl/proc/BUILD
+++ b/pkg/sentry/fsimpl/proc/BUILD
@@ -1,7 +1,6 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
-package(licenses = ["notice"])
+licenses(["notice"])
go_library(
name = "proc",
@@ -15,11 +14,11 @@ go_library(
"tasks_net.go",
"tasks_sys.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/proc",
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
+ "//pkg/safemem",
"//pkg/sentry/fs",
"//pkg/sentry/fsimpl/kernfs",
"//pkg/sentry/inet",
@@ -28,15 +27,14 @@ go_library(
"//pkg/sentry/kernel/time",
"//pkg/sentry/limits",
"//pkg/sentry/mm",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket",
"//pkg/sentry/socket/unix",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/syserror",
"//pkg/tcpip/header",
+ "//pkg/usermem",
],
)
@@ -47,18 +45,18 @@ go_test(
"tasks_sys_test.go",
"tasks_test.go",
],
- embed = [":proc"],
+ library = ":proc",
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fspath",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fsimpl/testutil",
"//pkg/sentry/inet",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fsimpl/proc/filesystem.go b/pkg/sentry/fsimpl/proc/filesystem.go
index f49819187..11477b6a9 100644
--- a/pkg/sentry/fsimpl/proc/filesystem.go
+++ b/pkg/sentry/fsimpl/proc/filesystem.go
@@ -19,7 +19,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
diff --git a/pkg/sentry/fsimpl/proc/subtasks.go b/pkg/sentry/fsimpl/proc/subtasks.go
index 91eded415..353e37195 100644
--- a/pkg/sentry/fsimpl/proc/subtasks.go
+++ b/pkg/sentry/fsimpl/proc/subtasks.go
@@ -19,7 +19,7 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/vfs"
diff --git a/pkg/sentry/fsimpl/proc/task.go b/pkg/sentry/fsimpl/proc/task.go
index a0580f20d..eb5bc62c0 100644
--- a/pkg/sentry/fsimpl/proc/task.go
+++ b/pkg/sentry/fsimpl/proc/task.go
@@ -19,7 +19,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
diff --git a/pkg/sentry/fsimpl/proc/task_files.go b/pkg/sentry/fsimpl/proc/task_files.go
index 7bc352ae9..efd3b3453 100644
--- a/pkg/sentry/fsimpl/proc/task_files.go
+++ b/pkg/sentry/fsimpl/proc/task_files.go
@@ -20,17 +20,17 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// mm gets the kernel task's MemoryManager. No additional reference is taken on
diff --git a/pkg/sentry/fsimpl/proc/tasks.go b/pkg/sentry/fsimpl/proc/tasks.go
index 51f634716..14bd334e8 100644
--- a/pkg/sentry/fsimpl/proc/tasks.go
+++ b/pkg/sentry/fsimpl/proc/tasks.go
@@ -20,7 +20,7 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
@@ -69,7 +69,7 @@ func newTasksInode(inoGen InoGenerator, k *kernel.Kernel, pidns *kernel.PIDNames
"cpuinfo": newDentry(root, inoGen.NextIno(), 0444, newStaticFile(cpuInfoData(k))),
//"filesystems": newDentry(root, inoGen.NextIno(), 0444, &filesystemsData{}),
"loadavg": newDentry(root, inoGen.NextIno(), 0444, &loadavgData{}),
- "sys": newSysDir(root, inoGen),
+ "sys": newSysDir(root, inoGen, k),
"meminfo": newDentry(root, inoGen.NextIno(), 0444, &meminfoData{}),
"mounts": kernfs.NewStaticSymlink(root, inoGen.NextIno(), "self/mounts"),
"net": newNetDir(root, inoGen, k),
diff --git a/pkg/sentry/fsimpl/proc/tasks_files.go b/pkg/sentry/fsimpl/proc/tasks_files.go
index ad3760e39..434998910 100644
--- a/pkg/sentry/fsimpl/proc/tasks_files.go
+++ b/pkg/sentry/fsimpl/proc/tasks_files.go
@@ -20,14 +20,14 @@ import (
"strconv"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type selfSymlink struct {
diff --git a/pkg/sentry/fsimpl/proc/tasks_net.go b/pkg/sentry/fsimpl/proc/tasks_net.go
index 4aaf23e97..608fec017 100644
--- a/pkg/sentry/fsimpl/proc/tasks_net.go
+++ b/pkg/sentry/fsimpl/proc/tasks_net.go
@@ -22,8 +22,8 @@ import (
"time"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/inet"
@@ -32,9 +32,9 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/unix"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
"gvisor.dev/gvisor/pkg/tcpip/header"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func newNetDir(root *auth.Credentials, inoGen InoGenerator, k *kernel.Kernel) *kernfs.Dentry {
diff --git a/pkg/sentry/fsimpl/proc/tasks_sys.go b/pkg/sentry/fsimpl/proc/tasks_sys.go
index aabf2bf0c..c7ce74883 100644
--- a/pkg/sentry/fsimpl/proc/tasks_sys.go
+++ b/pkg/sentry/fsimpl/proc/tasks_sys.go
@@ -19,14 +19,18 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
+ "gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// newSysDir returns the dentry corresponding to /proc/sys directory.
-func newSysDir(root *auth.Credentials, inoGen InoGenerator) *kernfs.Dentry {
+func newSysDir(root *auth.Credentials, inoGen InoGenerator, k *kernel.Kernel) *kernfs.Dentry {
return kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
"kernel": kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
"hostname": newDentry(root, inoGen.NextIno(), 0444, &hostnameData{}),
@@ -38,18 +42,18 @@ func newSysDir(root *auth.Credentials, inoGen InoGenerator) *kernfs.Dentry {
"mmap_min_addr": newDentry(root, inoGen.NextIno(), 0444, &mmapMinAddrData{}),
"overcommit_memory": newDentry(root, inoGen.NextIno(), 0444, newStaticFile("0\n")),
}),
- "net": newSysNetDir(root, inoGen),
+ "net": newSysNetDir(root, inoGen, k),
})
}
// newSysNetDir returns the dentry corresponding to /proc/sys/net directory.
-func newSysNetDir(root *auth.Credentials, inoGen InoGenerator) *kernfs.Dentry {
- return kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
- "net": kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
+func newSysNetDir(root *auth.Credentials, inoGen InoGenerator, k *kernel.Kernel) *kernfs.Dentry {
+ var contents map[string]*kernfs.Dentry
+
+ if stack := k.NetworkStack(); stack != nil {
+ contents = map[string]*kernfs.Dentry{
"ipv4": kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
- // Add tcp_sack.
- // TODO(gvisor.dev/issue/1195): tcp_sack allows write(2)
- // "tcp_sack": newTCPSackInode(ctx, msrc, s),
+ "tcp_sack": newDentry(root, inoGen.NextIno(), 0644, &tcpSackData{stack: stack}),
// The following files are simple stubs until they are implemented in
// netstack, most of these files are configuration related. We use the
@@ -103,7 +107,11 @@ func newSysNetDir(root *auth.Credentials, inoGen InoGenerator) *kernfs.Dentry {
"wmem_default": newDentry(root, inoGen.NextIno(), 0444, newStaticFile("212992")),
"wmem_max": newDentry(root, inoGen.NextIno(), 0444, newStaticFile("212992")),
}),
- }),
+ }
+ }
+
+ return kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, map[string]*kernfs.Dentry{
+ "net": kernfs.NewStaticDir(root, inoGen.NextIno(), 0555, contents),
})
}
@@ -141,3 +149,61 @@ func (*hostnameData) Generate(ctx context.Context, buf *bytes.Buffer) error {
buf.WriteString("\n")
return nil
}
+
+// tcpSackData implements vfs.WritableDynamicBytesSource for
+// /proc/sys/net/tcp_sack.
+//
+// +stateify savable
+type tcpSackData struct {
+ kernfs.DynamicBytesFile
+
+ stack inet.Stack `state:"wait"`
+ enabled *bool
+}
+
+var _ vfs.WritableDynamicBytesSource = (*tcpSackData)(nil)
+
+// Generate implements vfs.DynamicBytesSource.
+func (d *tcpSackData) Generate(ctx context.Context, buf *bytes.Buffer) error {
+ if d.enabled == nil {
+ sack, err := d.stack.TCPSACKEnabled()
+ if err != nil {
+ return err
+ }
+ d.enabled = &sack
+ }
+
+ val := "0\n"
+ if *d.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.
+ val = "1\n"
+ }
+ buf.WriteString(val)
+ return nil
+}
+
+func (d *tcpSackData) Write(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) {
+ if offset != 0 {
+ // No need to handle partial writes thus far.
+ return 0, syserror.EINVAL
+ }
+ if src.NumBytes() == 0 {
+ return 0, nil
+ }
+
+ // Limit the amount of memory allocated.
+ src = src.TakeFirst(usermem.PageSize - 1)
+
+ var v int32
+ n, err := usermem.CopyInt32StringInVec(ctx, src.IO, src.Addrs, &v, src.Opts)
+ if err != nil {
+ return n, err
+ }
+ if d.enabled == nil {
+ d.enabled = new(bool)
+ }
+ *d.enabled = v != 0
+ return n, d.stack.SetTCPSACKEnabled(*d.enabled)
+}
diff --git a/pkg/sentry/fsimpl/proc/tasks_sys_test.go b/pkg/sentry/fsimpl/proc/tasks_sys_test.go
index 0a1d3f34b..be54897bb 100644
--- a/pkg/sentry/fsimpl/proc/tasks_sys_test.go
+++ b/pkg/sentry/fsimpl/proc/tasks_sys_test.go
@@ -20,7 +20,7 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/inet"
)
diff --git a/pkg/sentry/fsimpl/proc/tasks_test.go b/pkg/sentry/fsimpl/proc/tasks_test.go
index 2c1635f33..6fc3524db 100644
--- a/pkg/sentry/fsimpl/proc/tasks_test.go
+++ b/pkg/sentry/fsimpl/proc/tasks_test.go
@@ -22,14 +22,14 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/testutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var (
diff --git a/pkg/sentry/fsimpl/sys/BUILD b/pkg/sentry/fsimpl/sys/BUILD
index ee3c842bd..66c0d8bc8 100644
--- a/pkg/sentry/fsimpl/sys/BUILD
+++ b/pkg/sentry/fsimpl/sys/BUILD
@@ -1,17 +1,15 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
-package(licenses = ["notice"])
+licenses(["notice"])
go_library(
name = "sys",
srcs = [
"sys.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/sys",
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fsimpl/kernfs",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
diff --git a/pkg/sentry/fsimpl/sys/sys.go b/pkg/sentry/fsimpl/sys/sys.go
index 1305ad01d..e35d52d17 100644
--- a/pkg/sentry/fsimpl/sys/sys.go
+++ b/pkg/sentry/fsimpl/sys/sys.go
@@ -20,7 +20,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
diff --git a/pkg/sentry/fsimpl/testutil/BUILD b/pkg/sentry/fsimpl/testutil/BUILD
index 4e70d84a7..efd5974c4 100644
--- a/pkg/sentry/fsimpl/testutil/BUILD
+++ b/pkg/sentry/fsimpl/testutil/BUILD
@@ -1,6 +1,6 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
-package(licenses = ["notice"])
+licenses(["notice"])
go_library(
name = "testutil",
@@ -9,14 +9,13 @@ go_library(
"kernel.go",
"testutil.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/testutil",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/cpuid",
"//pkg/fspath",
"//pkg/memutil",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
@@ -28,9 +27,9 @@ go_library(
"//pkg/sentry/platform/kvm",
"//pkg/sentry/platform/ptrace",
"//pkg/sentry/time",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/sync",
+ "//pkg/usermem",
"@com_github_google_go-cmp//cmp:go_default_library",
],
)
diff --git a/pkg/sentry/fsimpl/testutil/kernel.go b/pkg/sentry/fsimpl/testutil/kernel.go
index 295da2d52..89f8c4915 100644
--- a/pkg/sentry/fsimpl/testutil/kernel.go
+++ b/pkg/sentry/fsimpl/testutil/kernel.go
@@ -21,9 +21,9 @@ import (
"runtime"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/memutil"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
diff --git a/pkg/sentry/fsimpl/testutil/testutil.go b/pkg/sentry/fsimpl/testutil/testutil.go
index 2a723a89f..1c98335c1 100644
--- a/pkg/sentry/fsimpl/testutil/testutil.go
+++ b/pkg/sentry/fsimpl/testutil/testutil.go
@@ -24,12 +24,12 @@ import (
"github.com/google/go-cmp/cmp"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// System represents the context for a single test.
diff --git a/pkg/sentry/fsimpl/tmpfs/BUILD b/pkg/sentry/fsimpl/tmpfs/BUILD
index 691476b4f..c61366224 100644
--- a/pkg/sentry/fsimpl/tmpfs/BUILD
+++ b/pkg/sentry/fsimpl/tmpfs/BUILD
@@ -1,8 +1,7 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-package(licenses = ["notice"])
+licenses(["notice"])
go_template_instance(
name = "dentry_list",
@@ -28,14 +27,15 @@ go_library(
"symlink.go",
"tmpfs.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs",
+ visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/amutex",
+ "//pkg/context",
"//pkg/fspath",
"//pkg/log",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel",
@@ -45,12 +45,11 @@ go_library(
"//pkg/sentry/memmap",
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
- "//pkg/sentry/safemem",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
@@ -61,10 +60,10 @@ go_test(
deps = [
":tmpfs",
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fspath",
"//pkg/refs",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
"//pkg/sentry/fs/tmpfs",
"//pkg/sentry/kernel/auth",
@@ -81,16 +80,16 @@ go_test(
"regular_file_test.go",
"stat_test.go",
],
- embed = [":tmpfs"],
+ library = ":tmpfs",
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fspath",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/contexttest",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/fsimpl/tmpfs/benchmark_test.go b/pkg/sentry/fsimpl/tmpfs/benchmark_test.go
index d88c83499..54241c8e8 100644
--- a/pkg/sentry/fsimpl/tmpfs/benchmark_test.go
+++ b/pkg/sentry/fsimpl/tmpfs/benchmark_test.go
@@ -21,10 +21,10 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
_ "gvisor.dev/gvisor/pkg/sentry/fs/tmpfs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/tmpfs"
diff --git a/pkg/sentry/fsimpl/tmpfs/directory.go b/pkg/sentry/fsimpl/tmpfs/directory.go
index 887ca2619..dc0d27cf9 100644
--- a/pkg/sentry/fsimpl/tmpfs/directory.go
+++ b/pkg/sentry/fsimpl/tmpfs/directory.go
@@ -16,7 +16,7 @@ package tmpfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
diff --git a/pkg/sentry/fsimpl/tmpfs/filesystem.go b/pkg/sentry/fsimpl/tmpfs/filesystem.go
index d726f03c5..5ee9cf1e9 100644
--- a/pkg/sentry/fsimpl/tmpfs/filesystem.go
+++ b/pkg/sentry/fsimpl/tmpfs/filesystem.go
@@ -19,8 +19,8 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/fsimpl/tmpfs/named_pipe.go b/pkg/sentry/fsimpl/tmpfs/named_pipe.go
index 482aabd52..0c57fdca3 100644
--- a/pkg/sentry/fsimpl/tmpfs/named_pipe.go
+++ b/pkg/sentry/fsimpl/tmpfs/named_pipe.go
@@ -16,11 +16,11 @@ package tmpfs
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/kernel/pipe"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type namedPipe struct {
diff --git a/pkg/sentry/fsimpl/tmpfs/pipe_test.go b/pkg/sentry/fsimpl/tmpfs/pipe_test.go
index 70b42a6ec..5ee7f2a72 100644
--- a/pkg/sentry/fsimpl/tmpfs/pipe_test.go
+++ b/pkg/sentry/fsimpl/tmpfs/pipe_test.go
@@ -19,13 +19,13 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const fileName = "mypipe"
diff --git a/pkg/sentry/fsimpl/tmpfs/regular_file.go b/pkg/sentry/fsimpl/tmpfs/regular_file.go
index 7c633c1b0..e9e6faf67 100644
--- a/pkg/sentry/fsimpl/tmpfs/regular_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/regular_file.go
@@ -20,17 +20,17 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type regularFile struct {
diff --git a/pkg/sentry/fsimpl/tmpfs/regular_file_test.go b/pkg/sentry/fsimpl/tmpfs/regular_file_test.go
index 034a29fdb..32552e261 100644
--- a/pkg/sentry/fsimpl/tmpfs/regular_file_test.go
+++ b/pkg/sentry/fsimpl/tmpfs/regular_file_test.go
@@ -22,12 +22,12 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/kernel/contexttest"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// nextFileID is used to generate unique file names.
diff --git a/pkg/sentry/fsimpl/tmpfs/tmpfs.go b/pkg/sentry/fsimpl/tmpfs/tmpfs.go
index 515f033f2..88dbd6e35 100644
--- a/pkg/sentry/fsimpl/tmpfs/tmpfs.go
+++ b/pkg/sentry/fsimpl/tmpfs/tmpfs.go
@@ -29,7 +29,7 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
diff --git a/pkg/sentry/hostcpu/BUILD b/pkg/sentry/hostcpu/BUILD
index 359468ccc..e6933aa70 100644
--- a/pkg/sentry/hostcpu/BUILD
+++ b/pkg/sentry/hostcpu/BUILD
@@ -1,5 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -10,7 +9,6 @@ go_library(
"getcpu_arm64.s",
"hostcpu.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/hostcpu",
visibility = ["//:sandbox"],
)
@@ -18,5 +16,5 @@ go_test(
name = "hostcpu_test",
size = "small",
srcs = ["hostcpu_test.go"],
- embed = [":hostcpu"],
+ library = ":hostcpu",
)
diff --git a/pkg/sentry/hostmm/BUILD b/pkg/sentry/hostmm/BUILD
index 67831d5a1..61c78569d 100644
--- a/pkg/sentry/hostmm/BUILD
+++ b/pkg/sentry/hostmm/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -8,11 +8,10 @@ go_library(
"cgroup.go",
"hostmm.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/hostmm",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/fd",
"//pkg/log",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/hostmm/hostmm.go b/pkg/sentry/hostmm/hostmm.go
index 19335ca73..506c7864a 100644
--- a/pkg/sentry/hostmm/hostmm.go
+++ b/pkg/sentry/hostmm/hostmm.go
@@ -24,7 +24,7 @@ import (
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// NotifyCurrentMemcgPressureCallback requests that f is called whenever the
diff --git a/pkg/sentry/inet/BUILD b/pkg/sentry/inet/BUILD
index 8d60ad4ad..334432abf 100644
--- a/pkg/sentry/inet/BUILD
+++ b/pkg/sentry/inet/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(
default_visibility = ["//:sandbox"],
@@ -12,9 +12,8 @@ go_library(
"inet.go",
"test_stack.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/inet",
deps = [
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/tcpip/stack",
],
)
diff --git a/pkg/sentry/inet/context.go b/pkg/sentry/inet/context.go
index 4eda7dd1f..e8cc1bffd 100644
--- a/pkg/sentry/inet/context.go
+++ b/pkg/sentry/inet/context.go
@@ -15,7 +15,7 @@
package inet
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is the inet package's type for context.Context.Value keys.
diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD
index ac85ba0c8..a27628c0a 100644
--- a/pkg/sentry/kernel/BUILD
+++ b/pkg/sentry/kernel/BUILD
@@ -1,8 +1,5 @@
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("//tools:defs.bzl", "go_library", "go_test", "proto_library")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -78,26 +75,12 @@ go_template_instance(
)
proto_library(
- name = "uncaught_signal_proto",
+ name = "uncaught_signal",
srcs = ["uncaught_signal.proto"],
visibility = ["//visibility:public"],
deps = ["//pkg/sentry/arch:registers_proto"],
)
-cc_proto_library(
- name = "uncaught_signal_cc_proto",
- visibility = ["//visibility:public"],
- deps = [":uncaught_signal_proto"],
-)
-
-go_proto_library(
- name = "uncaught_signal_go_proto",
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/uncaught_signal_go_proto",
- proto = ":uncaught_signal_proto",
- visibility = ["//visibility:public"],
- deps = ["//pkg/sentry/arch:registers_go_proto"],
-)
-
go_library(
name = "kernel",
srcs = [
@@ -156,7 +139,6 @@ go_library(
"vdso.go",
"version.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel",
imports = [
"gvisor.dev/gvisor/pkg/bpf",
"gvisor.dev/gvisor/pkg/sentry/device",
@@ -171,14 +153,15 @@ go_library(
"//pkg/binary",
"//pkg/bits",
"//pkg/bpf",
+ "//pkg/context",
"//pkg/cpuid",
"//pkg/eventchannel",
"//pkg/log",
"//pkg/metric",
"//pkg/refs",
+ "//pkg/safemem",
"//pkg/secio",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/lock",
@@ -198,7 +181,6 @@ go_library(
"//pkg/sentry/mm",
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket/netlink/port",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/time",
@@ -206,7 +188,7 @@ go_library(
"//pkg/sentry/unimpl:unimplemented_syscall_go_proto",
"//pkg/sentry/uniqueid",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
+ "//pkg/sentry/vfs",
"//pkg/state",
"//pkg/state/statefile",
"//pkg/sync",
@@ -214,6 +196,7 @@ go_library(
"//pkg/syserror",
"//pkg/tcpip",
"//pkg/tcpip/stack",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -227,12 +210,12 @@ go_test(
"task_test.go",
"timekeeper_test.go",
],
- embed = [":kernel"],
+ library = ":kernel",
deps = [
"//pkg/abi",
+ "//pkg/context",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
"//pkg/sentry/fs/filetest",
"//pkg/sentry/kernel/sched",
@@ -240,8 +223,8 @@ go_test(
"//pkg/sentry/pgalloc",
"//pkg/sentry/time",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD
index 1aa72fa47..2bc49483a 100644
--- a/pkg/sentry/kernel/auth/BUILD
+++ b/pkg/sentry/kernel/auth/BUILD
@@ -1,5 +1,5 @@
+load("//tools:defs.bzl", "go_library")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -57,13 +57,12 @@ go_library(
"id_map_set.go",
"user_namespace.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/auth",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/bits",
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
"//pkg/sync",
"//pkg/syserror",
],
diff --git a/pkg/sentry/kernel/auth/context.go b/pkg/sentry/kernel/auth/context.go
index 5c0e7d6b6..ef5723127 100644
--- a/pkg/sentry/kernel/auth/context.go
+++ b/pkg/sentry/kernel/auth/context.go
@@ -15,7 +15,7 @@
package auth
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is the auth package's type for context.Context.Value keys.
diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go
index 3d74bc610..28cbe159d 100644
--- a/pkg/sentry/kernel/auth/id_map.go
+++ b/pkg/sentry/kernel/auth/id_map.go
@@ -16,7 +16,7 @@ package auth
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/kernel/context.go b/pkg/sentry/kernel/context.go
index 3c9dceaba..0c40bf315 100644
--- a/pkg/sentry/kernel/context.go
+++ b/pkg/sentry/kernel/context.go
@@ -17,8 +17,8 @@ package kernel
import (
"time"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
)
// contextID is the kernel package's type for context.Context.Value keys.
diff --git a/pkg/sentry/kernel/contexttest/BUILD b/pkg/sentry/kernel/contexttest/BUILD
index 3a88a585c..9d26392c0 100644
--- a/pkg/sentry/kernel/contexttest/BUILD
+++ b/pkg/sentry/kernel/contexttest/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -6,11 +6,10 @@ go_library(
name = "contexttest",
testonly = 1,
srcs = ["contexttest.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/contexttest",
visibility = ["//pkg/sentry:internal"],
deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/kernel",
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
diff --git a/pkg/sentry/kernel/contexttest/contexttest.go b/pkg/sentry/kernel/contexttest/contexttest.go
index 82f9d8922..22c340e56 100644
--- a/pkg/sentry/kernel/contexttest/contexttest.go
+++ b/pkg/sentry/kernel/contexttest/contexttest.go
@@ -19,8 +19,8 @@ package contexttest
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD
index c47f6b6fc..dedf0fa15 100644
--- a/pkg/sentry/kernel/epoll/BUILD
+++ b/pkg/sentry/kernel/epoll/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -23,16 +22,15 @@ go_library(
"epoll_list.go",
"epoll_state.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/epoll",
visibility = ["//pkg/sentry:internal"],
deps = [
+ "//pkg/context",
"//pkg/refs",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
- "//pkg/sentry/usermem",
"//pkg/sync",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -43,9 +41,9 @@ go_test(
srcs = [
"epoll_test.go",
],
- embed = [":epoll"],
+ library = ":epoll",
deps = [
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs/filetest",
"//pkg/waiter",
],
diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go
index e84742993..8bffb78fc 100644
--- a/pkg/sentry/kernel/epoll/epoll.go
+++ b/pkg/sentry/kernel/epoll/epoll.go
@@ -20,13 +20,13 @@ import (
"fmt"
"syscall"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/epoll/epoll_test.go b/pkg/sentry/kernel/epoll/epoll_test.go
index 4a20d4c82..22630e9c5 100644
--- a/pkg/sentry/kernel/epoll/epoll_test.go
+++ b/pkg/sentry/kernel/epoll/epoll_test.go
@@ -17,7 +17,7 @@ package epoll
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs/filetest"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD
index c831fbab2..9983a32e5 100644
--- a/pkg/sentry/kernel/eventfd/BUILD
+++ b/pkg/sentry/kernel/eventfd/BUILD
@@ -1,23 +1,21 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
go_library(
name = "eventfd",
srcs = ["eventfd.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/eventfd",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fdnotifier",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -26,10 +24,10 @@ go_test(
name = "eventfd_test",
size = "small",
srcs = ["eventfd_test.go"],
- embed = [":eventfd"],
+ library = ":eventfd",
deps = [
- "//pkg/sentry/context/contexttest",
- "//pkg/sentry/usermem",
+ "//pkg/sentry/contexttest",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go
index 687690679..87951adeb 100644
--- a/pkg/sentry/kernel/eventfd/eventfd.go
+++ b/pkg/sentry/kernel/eventfd/eventfd.go
@@ -21,14 +21,14 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fdnotifier"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/eventfd/eventfd_test.go b/pkg/sentry/kernel/eventfd/eventfd_test.go
index 018c7f3ef..9b4892f74 100644
--- a/pkg/sentry/kernel/eventfd/eventfd_test.go
+++ b/pkg/sentry/kernel/eventfd/eventfd_test.go
@@ -17,8 +17,8 @@ package eventfd
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD
index 6b36bc63e..b9126e946 100644
--- a/pkg/sentry/kernel/fasync/BUILD
+++ b/pkg/sentry/kernel/fasync/BUILD
@@ -1,11 +1,10 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "fasync",
srcs = ["fasync.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/fasync",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi/linux",
diff --git a/pkg/sentry/kernel/fd_table.go b/pkg/sentry/kernel/fd_table.go
index cd1501f85..23b88f7a6 100644
--- a/pkg/sentry/kernel/fd_table.go
+++ b/pkg/sentry/kernel/fd_table.go
@@ -1,4 +1,4 @@
-// Copyright 2018 Google LLC
+// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,18 +15,19 @@
package kernel
import (
- "bytes"
"fmt"
"math"
+ "strings"
"sync/atomic"
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/lock"
"gvisor.dev/gvisor/pkg/sentry/limits"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
)
@@ -62,10 +63,14 @@ func (f FDFlags) ToLinuxFDFlags() (mask uint) {
// Note that this is immutable and can only be changed via operations on the
// descriptorTable.
//
+// It contains both VFS1 and VFS2 file types, but only one of them can be set.
+//
// +stateify savable
type descriptor struct {
- file *fs.File
- flags FDFlags
+ // TODO(gvisor.dev/issue/1624): Remove fs.File.
+ file *fs.File
+ fileVFS2 *vfs.FileDescription
+ flags FDFlags
}
// FDTable is used to manage File references and flags.
@@ -95,10 +100,11 @@ type FDTable struct {
func (f *FDTable) saveDescriptorTable() map[int32]descriptor {
m := make(map[int32]descriptor)
- f.forEach(func(fd int32, file *fs.File, flags FDFlags) {
+ f.forEach(func(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags) {
m[fd] = descriptor{
- file: file,
- flags: flags,
+ file: file,
+ fileVFS2: fileVFS2,
+ flags: flags,
}
})
return m
@@ -107,13 +113,17 @@ func (f *FDTable) saveDescriptorTable() map[int32]descriptor {
func (f *FDTable) loadDescriptorTable(m map[int32]descriptor) {
f.init() // Initialize table.
for fd, d := range m {
- f.set(fd, d.file, d.flags)
-
- // Note that we do _not_ need to acquire a extra table
- // reference here. The table reference will already be
- // accounted for in the file, so we drop the reference taken by
- // set above.
- d.file.DecRef()
+ f.setAll(fd, d.file, d.fileVFS2, d.flags)
+
+ // Note that we do _not_ need to acquire a extra table reference here. The
+ // table reference will already be accounted for in the file, so we drop the
+ // reference taken by set above.
+ switch {
+ case d.file != nil:
+ d.file.DecRef()
+ case d.fileVFS2 != nil:
+ d.fileVFS2.DecRef()
+ }
}
}
@@ -139,6 +149,15 @@ func (f *FDTable) drop(file *fs.File) {
file.DecRef()
}
+// dropVFS2 drops the table reference.
+func (f *FDTable) dropVFS2(file *vfs.FileDescription) {
+ // TODO(gvisor.dev/issue/1480): Release locks.
+ // TODO(gvisor.dev/issue/1479): Send inotify events.
+
+ // Drop the table reference.
+ file.DecRef()
+}
+
// ID returns a unique identifier for this FDTable.
func (f *FDTable) ID() uint64 {
return f.uid
@@ -156,7 +175,7 @@ func (k *Kernel) NewFDTable() *FDTable {
// destroy removes all of the file descriptors from the map.
func (f *FDTable) destroy() {
- f.RemoveIf(func(*fs.File, FDFlags) bool {
+ f.RemoveIf(func(*fs.File, *vfs.FileDescription, FDFlags) bool {
return true
})
}
@@ -175,19 +194,26 @@ func (f *FDTable) Size() int {
// forEach iterates over all non-nil files.
//
// It is the caller's responsibility to acquire an appropriate lock.
-func (f *FDTable) forEach(fn func(fd int32, file *fs.File, flags FDFlags)) {
+func (f *FDTable) forEach(fn func(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags)) {
fd := int32(0)
for {
- file, flags, ok := f.get(fd)
+ file, fileVFS2, flags, ok := f.getAll(fd)
if !ok {
break
}
- if file != nil {
+ switch {
+ case file != nil:
if !file.TryIncRef() {
continue // Race caught.
}
- fn(int32(fd), file, flags)
+ fn(fd, file, nil, flags)
file.DecRef()
+ case fileVFS2 != nil:
+ if !fileVFS2.TryIncRef() {
+ continue // Race caught.
+ }
+ fn(fd, nil, fileVFS2, flags)
+ fileVFS2.DecRef()
}
fd++
}
@@ -195,12 +221,24 @@ func (f *FDTable) forEach(fn func(fd int32, file *fs.File, flags FDFlags)) {
// String is a stringer for FDTable.
func (f *FDTable) String() string {
- var b bytes.Buffer
- f.forEach(func(fd int32, file *fs.File, flags FDFlags) {
- n, _ := file.Dirent.FullName(nil /* root */)
- b.WriteString(fmt.Sprintf("\tfd:%d => name %s\n", fd, n))
+ var buf strings.Builder
+ f.forEach(func(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags) {
+ switch {
+ case file != nil:
+ n, _ := file.Dirent.FullName(nil /* root */)
+ fmt.Fprintf(&buf, "\tfd:%d => name %s\n", fd, n)
+
+ case fileVFS2 != nil:
+ vfsObj := fileVFS2.Mount().Filesystem().VirtualFilesystem()
+ name, err := vfsObj.PathnameWithDeleted(context.Background(), vfs.VirtualDentry{}, fileVFS2.VirtualDentry())
+ if err != nil {
+ fmt.Fprintf(&buf, "<err: %v>\n", err)
+ return
+ }
+ fmt.Fprintf(&buf, "\tfd:%d => name %s\n", fd, name)
+ }
})
- return b.String()
+ return buf.String()
}
// NewFDs allocates new FDs guaranteed to be the lowest number available
@@ -262,6 +300,17 @@ func (f *FDTable) NewFDs(ctx context.Context, fd int32, files []*fs.File, flags
// reference for that FD, the ref count for that existing reference is
// decremented.
func (f *FDTable) NewFDAt(ctx context.Context, fd int32, file *fs.File, flags FDFlags) error {
+ return f.newFDAt(ctx, fd, file, nil, flags)
+}
+
+// NewFDAtVFS2 sets the file reference for the given FD. If there is an active
+// reference for that FD, the ref count for that existing reference is
+// decremented.
+func (f *FDTable) NewFDAtVFS2(ctx context.Context, fd int32, file *vfs.FileDescription, flags FDFlags) error {
+ return f.newFDAt(ctx, fd, nil, file, flags)
+}
+
+func (f *FDTable) newFDAt(ctx context.Context, fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags) error {
if fd < 0 {
// Don't accept negative FDs.
return syscall.EBADF
@@ -278,7 +327,7 @@ func (f *FDTable) NewFDAt(ctx context.Context, fd int32, file *fs.File, flags FD
}
// Install the entry.
- f.set(fd, file, flags)
+ f.setAll(fd, file, fileVFS2, flags)
return nil
}
@@ -330,10 +379,35 @@ func (f *FDTable) Get(fd int32) (*fs.File, FDFlags) {
}
}
+// GetVFS2 returns a reference to the file and the flags for the FD or nil if no
+// file is defined for the given fd.
+//
+// N.B. Callers are required to use DecRef when they are done.
+//
+//go:nosplit
+func (f *FDTable) GetVFS2(fd int32) (*vfs.FileDescription, FDFlags) {
+ if fd < 0 {
+ return nil, FDFlags{}
+ }
+
+ for {
+ file, flags, _ := f.getVFS2(fd)
+ if file != nil {
+ if !file.TryIncRef() {
+ continue // Race caught.
+ }
+ // Reference acquired.
+ return file, flags
+ }
+ // No file available.
+ return nil, FDFlags{}
+ }
+}
+
// GetFDs returns a list of valid fds.
func (f *FDTable) GetFDs() []int32 {
fds := make([]int32, 0, int(atomic.LoadInt32(&f.used)))
- f.forEach(func(fd int32, file *fs.File, flags FDFlags) {
+ f.forEach(func(fd int32, _ *fs.File, _ *vfs.FileDescription, _ FDFlags) {
fds = append(fds, fd)
})
return fds
@@ -344,7 +418,19 @@ func (f *FDTable) GetFDs() []int32 {
// they're done using the slice.
func (f *FDTable) GetRefs() []*fs.File {
files := make([]*fs.File, 0, f.Size())
- f.forEach(func(_ int32, file *fs.File, flags FDFlags) {
+ f.forEach(func(_ int32, file *fs.File, _ *vfs.FileDescription, _ FDFlags) {
+ file.IncRef() // Acquire a reference for caller.
+ files = append(files, file)
+ })
+ return files
+}
+
+// GetRefsVFS2 returns a stable slice of references to all files and bumps the
+// reference count on each. The caller must use DecRef on each reference when
+// they're done using the slice.
+func (f *FDTable) GetRefsVFS2() []*vfs.FileDescription {
+ files := make([]*vfs.FileDescription, 0, f.Size())
+ f.forEach(func(_ int32, _ *fs.File, file *vfs.FileDescription, _ FDFlags) {
file.IncRef() // Acquire a reference for caller.
files = append(files, file)
})
@@ -355,10 +441,15 @@ func (f *FDTable) GetRefs() []*fs.File {
func (f *FDTable) Fork() *FDTable {
clone := f.k.NewFDTable()
- f.forEach(func(fd int32, file *fs.File, flags FDFlags) {
+ f.forEach(func(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags) {
// The set function here will acquire an appropriate table
// reference for the clone. We don't need anything else.
- clone.set(fd, file, flags)
+ switch {
+ case file != nil:
+ clone.set(fd, file, flags)
+ case fileVFS2 != nil:
+ clone.setVFS2(fd, fileVFS2, flags)
+ }
})
return clone
}
@@ -366,9 +457,9 @@ func (f *FDTable) Fork() *FDTable {
// Remove removes an FD from and returns a non-file iff successful.
//
// N.B. Callers are required to use DecRef when they are done.
-func (f *FDTable) Remove(fd int32) *fs.File {
+func (f *FDTable) Remove(fd int32) (*fs.File, *vfs.FileDescription) {
if fd < 0 {
- return nil
+ return nil, nil
}
f.mu.Lock()
@@ -379,21 +470,26 @@ func (f *FDTable) Remove(fd int32) *fs.File {
f.next = fd
}
- orig, _, _ := f.get(fd)
- if orig != nil {
- orig.IncRef() // Reference for caller.
- f.set(fd, nil, FDFlags{}) // Zap entry.
+ orig, orig2, _, _ := f.getAll(fd)
+
+ // Add reference for caller.
+ switch {
+ case orig != nil:
+ orig.IncRef()
+ case orig2 != nil:
+ orig2.IncRef()
}
- return orig
+ f.setAll(fd, nil, nil, FDFlags{}) // Zap entry.
+ return orig, orig2
}
// RemoveIf removes all FDs where cond is true.
-func (f *FDTable) RemoveIf(cond func(*fs.File, FDFlags) bool) {
+func (f *FDTable) RemoveIf(cond func(*fs.File, *vfs.FileDescription, FDFlags) bool) {
f.mu.Lock()
defer f.mu.Unlock()
- f.forEach(func(fd int32, file *fs.File, flags FDFlags) {
- if cond(file, flags) {
+ f.forEach(func(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags) {
+ if cond(file, fileVFS2, flags) {
f.set(fd, nil, FDFlags{}) // Clear from table.
// Update current available position.
if fd < f.next {
diff --git a/pkg/sentry/kernel/fd_table_test.go b/pkg/sentry/kernel/fd_table_test.go
index eccb7d1e7..29f95a2c4 100644
--- a/pkg/sentry/kernel/fd_table_test.go
+++ b/pkg/sentry/kernel/fd_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.
@@ -18,8 +18,8 @@ import (
"runtime"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/filetest"
"gvisor.dev/gvisor/pkg/sentry/limits"
@@ -150,13 +150,13 @@ func TestFDTable(t *testing.T) {
t.Fatalf("fdTable.Get(2): got a %v, wanted nil", ref)
}
- ref := fdTable.Remove(1)
+ ref, _ := fdTable.Remove(1)
if ref == nil {
t.Fatalf("fdTable.Remove(1) for an existing FD: failed, want success")
}
ref.DecRef()
- if ref := fdTable.Remove(1); ref != nil {
+ if ref, _ := fdTable.Remove(1); ref != nil {
t.Fatalf("r.Remove(1) for a removed FD: got success, want failure")
}
})
diff --git a/pkg/sentry/kernel/fd_table_unsafe.go b/pkg/sentry/kernel/fd_table_unsafe.go
index e009df974..7fd97dc53 100644
--- a/pkg/sentry/kernel/fd_table_unsafe.go
+++ b/pkg/sentry/kernel/fd_table_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.
@@ -19,6 +19,7 @@ import (
"unsafe"
"gvisor.dev/gvisor/pkg/sentry/fs"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
)
type descriptorTable struct {
@@ -41,15 +42,38 @@ func (f *FDTable) init() {
//
//go:nosplit
func (f *FDTable) get(fd int32) (*fs.File, FDFlags, bool) {
+ file, _, flags, ok := f.getAll(fd)
+ return file, flags, ok
+}
+
+// getVFS2 gets a file entry.
+//
+// The boolean indicates whether this was in range.
+//
+//go:nosplit
+func (f *FDTable) getVFS2(fd int32) (*vfs.FileDescription, FDFlags, bool) {
+ _, file, flags, ok := f.getAll(fd)
+ return file, flags, ok
+}
+
+// getAll gets a file entry.
+//
+// The boolean indicates whether this was in range.
+//
+//go:nosplit
+func (f *FDTable) getAll(fd int32) (*fs.File, *vfs.FileDescription, FDFlags, bool) {
slice := *(*[]unsafe.Pointer)(atomic.LoadPointer(&f.slice))
if fd >= int32(len(slice)) {
- return nil, FDFlags{}, false
+ return nil, nil, FDFlags{}, false
}
d := (*descriptor)(atomic.LoadPointer(&slice[fd]))
if d == nil {
- return nil, FDFlags{}, true
+ return nil, nil, FDFlags{}, true
}
- return d.file, d.flags, true
+ if d.file != nil && d.fileVFS2 != nil {
+ panic("VFS1 and VFS2 files set")
+ }
+ return d.file, d.fileVFS2, d.flags, true
}
// set sets an entry.
@@ -59,6 +83,30 @@ func (f *FDTable) get(fd int32) (*fs.File, FDFlags, bool) {
//
// Precondition: mu must be held.
func (f *FDTable) set(fd int32, file *fs.File, flags FDFlags) {
+ f.setAll(fd, file, nil, flags)
+}
+
+// setVFS2 sets an entry.
+//
+// This handles accounting changes, as well as acquiring and releasing the
+// reference needed by the table iff the file is different.
+//
+// Precondition: mu must be held.
+func (f *FDTable) setVFS2(fd int32, file *vfs.FileDescription, flags FDFlags) {
+ f.setAll(fd, nil, file, flags)
+}
+
+// setAll sets an entry.
+//
+// This handles accounting changes, as well as acquiring and releasing the
+// reference needed by the table iff the file is different.
+//
+// Precondition: mu must be held.
+func (f *FDTable) setAll(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags) {
+ if file != nil && fileVFS2 != nil {
+ panic("VFS1 and VFS2 files set")
+ }
+
slice := *(*[]unsafe.Pointer)(atomic.LoadPointer(&f.slice))
// Grow the table as required.
@@ -71,33 +119,51 @@ func (f *FDTable) set(fd int32, file *fs.File, flags FDFlags) {
atomic.StorePointer(&f.slice, unsafe.Pointer(&slice))
}
- // Create the new element.
- var d *descriptor
- if file != nil {
- d = &descriptor{
- file: file,
- flags: flags,
+ var desc *descriptor
+ if file != nil || fileVFS2 != nil {
+ desc = &descriptor{
+ file: file,
+ fileVFS2: fileVFS2,
+ flags: flags,
}
}
// Update the single element.
- orig := (*descriptor)(atomic.SwapPointer(&slice[fd], unsafe.Pointer(d)))
+ orig := (*descriptor)(atomic.SwapPointer(&slice[fd], unsafe.Pointer(desc)))
// Acquire a table reference.
- if file != nil && (orig == nil || file != orig.file) {
- file.IncRef()
+ if desc != nil {
+ switch {
+ case desc.file != nil:
+ if orig == nil || desc.file != orig.file {
+ desc.file.IncRef()
+ }
+ case desc.fileVFS2 != nil:
+ if orig == nil || desc.fileVFS2 != orig.fileVFS2 {
+ desc.fileVFS2.IncRef()
+ }
+ }
}
// Drop the table reference.
- if orig != nil && file != orig.file {
- f.drop(orig.file)
+ if orig != nil {
+ switch {
+ case orig.file != nil:
+ if desc == nil || desc.file != orig.file {
+ f.drop(orig.file)
+ }
+ case orig.fileVFS2 != nil:
+ if desc == nil || desc.fileVFS2 != orig.fileVFS2 {
+ f.dropVFS2(orig.fileVFS2)
+ }
+ }
}
// Adjust used.
switch {
- case orig == nil && file != nil:
+ case orig == nil && desc != nil:
atomic.AddInt32(&f.used, 1)
- case orig != nil && file == nil:
+ case orig != nil && desc == nil:
atomic.AddInt32(&f.used, -1)
}
}
diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD
index 50db443ce..c5021f2db 100644
--- a/pkg/sentry/kernel/futex/BUILD
+++ b/pkg/sentry/kernel/futex/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -34,16 +33,15 @@ go_library(
"futex.go",
"waiter_list.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/futex",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
"//pkg/sentry/memmap",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
@@ -51,9 +49,9 @@ go_test(
name = "futex_test",
size = "small",
srcs = ["futex_test.go"],
- embed = [":futex"],
+ library = ":futex",
deps = [
- "//pkg/sentry/usermem",
"//pkg/sync",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go
index d1931c8f4..732e66da4 100644
--- a/pkg/sentry/kernel/futex/futex.go
+++ b/pkg/sentry/kernel/futex/futex.go
@@ -20,9 +20,9 @@ package futex
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// KeyKind indicates the type of a Key.
diff --git a/pkg/sentry/kernel/futex/futex_test.go b/pkg/sentry/kernel/futex/futex_test.go
index c23126ca5..7c5c7665b 100644
--- a/pkg/sentry/kernel/futex/futex_test.go
+++ b/pkg/sentry/kernel/futex/futex_test.go
@@ -22,8 +22,8 @@ import (
"testing"
"unsafe"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// testData implements the Target interface, and allows us to
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go
index c85e97fef..dcd6e91c4 100644
--- a/pkg/sentry/kernel/kernel.go
+++ b/pkg/sentry/kernel/kernel.go
@@ -40,12 +40,12 @@ import (
"time"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/eventchannel"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/timerfd"
"gvisor.dev/gvisor/pkg/sentry/hostcpu"
@@ -65,6 +65,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/unimpl"
uspb "gvisor.dev/gvisor/pkg/sentry/unimpl/unimplemented_syscall_go_proto"
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/state"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/tcpip"
@@ -435,17 +436,17 @@ func (k *Kernel) flushMountSourceRefs() error {
// There may be some open FDs whose filesystems have been unmounted. We
// must flush those as well.
- return k.tasks.forEachFDPaused(func(file *fs.File) error {
+ return k.tasks.forEachFDPaused(func(file *fs.File, _ *vfs.FileDescription) error {
file.Dirent.Inode.MountSource.FlushDirentRefs()
return nil
})
}
-// forEachFDPaused applies the given function to each open file descriptor in each
-// task.
+// forEachFDPaused applies the given function to each open file descriptor in
+// each task.
//
// Precondition: Must be called with the kernel paused.
-func (ts *TaskSet) forEachFDPaused(f func(*fs.File) error) (err error) {
+func (ts *TaskSet) forEachFDPaused(f func(*fs.File, *vfs.FileDescription) error) (err error) {
ts.mu.RLock()
defer ts.mu.RUnlock()
for t := range ts.Root.tids {
@@ -453,8 +454,8 @@ func (ts *TaskSet) forEachFDPaused(f func(*fs.File) error) (err error) {
if t.fdTable == nil {
continue
}
- t.fdTable.forEach(func(_ int32, file *fs.File, _ FDFlags) {
- if lastErr := f(file); lastErr != nil && err == nil {
+ t.fdTable.forEach(func(_ int32, file *fs.File, fileVFS2 *vfs.FileDescription, _ FDFlags) {
+ if lastErr := f(file, fileVFS2); lastErr != nil && err == nil {
err = lastErr
}
})
@@ -463,7 +464,8 @@ func (ts *TaskSet) forEachFDPaused(f func(*fs.File) error) (err error) {
}
func (ts *TaskSet) flushWritesToFiles(ctx context.Context) error {
- return ts.forEachFDPaused(func(file *fs.File) error {
+ // TODO(gvisor.dev/issues/1663): Add save support for VFS2.
+ return ts.forEachFDPaused(func(file *fs.File, _ *vfs.FileDescription) error {
if flags := file.Flags(); !flags.Write {
return nil
}
@@ -474,12 +476,9 @@ func (ts *TaskSet) flushWritesToFiles(ctx context.Context) error {
syncErr := file.Fsync(ctx, 0, fs.FileMaxOffset, fs.SyncAll)
if err := fs.SaveFileFsyncError(syncErr); err != nil {
name, _ := file.Dirent.FullName(nil /* root */)
- // Wrap this error in ErrSaveRejection
- // so that it will trigger a save
- // error, rather than a panic. This
- // also allows us to distinguish Fsync
- // errors from state file errors in
- // state.Save.
+ // Wrap this error in ErrSaveRejection so that it will trigger a save
+ // error, rather than a panic. This also allows us to distinguish Fsync
+ // errors from state file errors in state.Save.
return fs.ErrSaveRejection{
Err: fmt.Errorf("%q was not sufficiently synced: %v", name, err),
}
@@ -519,7 +518,7 @@ func (ts *TaskSet) unregisterEpollWaiters() {
for t := range ts.Root.tids {
// We can skip locking Task.mu here since the kernel is paused.
if t.fdTable != nil {
- t.fdTable.forEach(func(_ int32, file *fs.File, _ FDFlags) {
+ t.fdTable.forEach(func(_ int32, file *fs.File, _ *vfs.FileDescription, _ FDFlags) {
if e, ok := file.FileOperations.(*epoll.EventPoll); ok {
e.UnregisterEpollWaiters()
}
@@ -921,7 +920,7 @@ func (k *Kernel) pauseTimeLocked() {
// This means we'll iterate FDTables shared by multiple tasks repeatedly,
// but ktime.Timer.Pause is idempotent so this is harmless.
if t.fdTable != nil {
- t.fdTable.forEach(func(_ int32, file *fs.File, _ FDFlags) {
+ t.fdTable.forEach(func(_ int32, file *fs.File, _ *vfs.FileDescription, _ FDFlags) {
if tfd, ok := file.FileOperations.(*timerfd.TimerOperations); ok {
tfd.PauseTimer()
}
@@ -951,7 +950,7 @@ func (k *Kernel) resumeTimeLocked() {
}
}
if t.fdTable != nil {
- t.fdTable.forEach(func(_ int32, file *fs.File, _ FDFlags) {
+ t.fdTable.forEach(func(_ int32, file *fs.File, _ *vfs.FileDescription, _ FDFlags) {
if tfd, ok := file.FileOperations.(*timerfd.TimerOperations); ok {
tfd.ResumeTimer()
}
diff --git a/pkg/sentry/kernel/memevent/BUILD b/pkg/sentry/kernel/memevent/BUILD
index 7f36252a9..4486848d2 100644
--- a/pkg/sentry/kernel/memevent/BUILD
+++ b/pkg/sentry/kernel/memevent/BUILD
@@ -1,13 +1,10 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("//tools:defs.bzl", "go_library", "proto_library")
package(licenses = ["notice"])
go_library(
name = "memevent",
srcs = ["memory_events.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/memevent",
visibility = ["//:sandbox"],
deps = [
":memory_events_go_proto",
@@ -21,20 +18,7 @@ go_library(
)
proto_library(
- name = "memory_events_proto",
+ name = "memory_events",
srcs = ["memory_events.proto"],
visibility = ["//visibility:public"],
)
-
-cc_proto_library(
- name = "memory_events_cc_proto",
- visibility = ["//visibility:public"],
- deps = [":memory_events_proto"],
-)
-
-go_proto_library(
- name = "memory_events_go_proto",
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/memevent/memory_events_go_proto",
- proto = ":memory_events_proto",
- visibility = ["//visibility:public"],
-)
diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD
index 5eeaeff66..4c049d5b4 100644
--- a/pkg/sentry/kernel/pipe/BUILD
+++ b/pkg/sentry/kernel/pipe/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -30,21 +29,20 @@ go_library(
"vfs.go",
"writer.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/pipe",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/amutex",
+ "//pkg/context",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
- "//pkg/sentry/safemem",
- "//pkg/sentry/usermem",
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -57,13 +55,13 @@ go_test(
"node_test.go",
"pipe_test.go",
],
- embed = [":pipe"],
+ library = ":pipe",
deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/fs",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/kernel/pipe/buffer.go b/pkg/sentry/kernel/pipe/buffer.go
index 1c0f34269..fe3be5dbd 100644
--- a/pkg/sentry/kernel/pipe/buffer.go
+++ b/pkg/sentry/kernel/pipe/buffer.go
@@ -17,7 +17,7 @@ package pipe
import (
"io"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sync"
)
diff --git a/pkg/sentry/kernel/pipe/buffer_test.go b/pkg/sentry/kernel/pipe/buffer_test.go
index ee1b90115..4d54b8b8f 100644
--- a/pkg/sentry/kernel/pipe/buffer_test.go
+++ b/pkg/sentry/kernel/pipe/buffer_test.go
@@ -18,7 +18,7 @@ import (
"testing"
"unsafe"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func TestBufferSize(t *testing.T) {
diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go
index 716f589af..4b688c627 100644
--- a/pkg/sentry/kernel/pipe/node.go
+++ b/pkg/sentry/kernel/pipe/node.go
@@ -16,7 +16,7 @@ package pipe
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sync"
diff --git a/pkg/sentry/kernel/pipe/node_test.go b/pkg/sentry/kernel/pipe/node_test.go
index 16fa80abe..ab75a87ff 100644
--- a/pkg/sentry/kernel/pipe/node_test.go
+++ b/pkg/sentry/kernel/pipe/node_test.go
@@ -18,11 +18,11 @@ import (
"testing"
"time"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type sleeper struct {
diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go
index e4fd7d420..08410283f 100644
--- a/pkg/sentry/kernel/pipe/pipe.go
+++ b/pkg/sentry/kernel/pipe/pipe.go
@@ -20,7 +20,7 @@ import (
"sync/atomic"
"syscall"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
diff --git a/pkg/sentry/kernel/pipe/pipe_test.go b/pkg/sentry/kernel/pipe/pipe_test.go
index e3a14b665..bda739dbe 100644
--- a/pkg/sentry/kernel/pipe/pipe_test.go
+++ b/pkg/sentry/kernel/pipe/pipe_test.go
@@ -18,9 +18,9 @@ import (
"bytes"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/pipe/pipe_util.go b/pkg/sentry/kernel/pipe/pipe_util.go
index 8394eb78b..80158239e 100644
--- a/pkg/sentry/kernel/pipe/pipe_util.go
+++ b/pkg/sentry/kernel/pipe/pipe_util.go
@@ -21,10 +21,10 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/amutex"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go
index b4d29fc77..b2b5691ee 100644
--- a/pkg/sentry/kernel/pipe/reader_writer.go
+++ b/pkg/sentry/kernel/pipe/reader_writer.go
@@ -17,11 +17,11 @@ package pipe
import (
"io"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ReaderWriter satisfies the FileOperations interface and services both
diff --git a/pkg/sentry/kernel/pipe/vfs.go b/pkg/sentry/kernel/pipe/vfs.go
index 6f83e3cee..a5675bd70 100644
--- a/pkg/sentry/kernel/pipe/vfs.go
+++ b/pkg/sentry/kernel/pipe/vfs.go
@@ -16,12 +16,12 @@ package pipe
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go
index 3be171cdc..35ad97d5d 100644
--- a/pkg/sentry/kernel/ptrace.go
+++ b/pkg/sentry/kernel/ptrace.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ptraceOptions are the subset of options controlling a task's ptrace behavior
diff --git a/pkg/sentry/kernel/ptrace_amd64.go b/pkg/sentry/kernel/ptrace_amd64.go
index 5514cf432..cef1276ec 100644
--- a/pkg/sentry/kernel/ptrace_amd64.go
+++ b/pkg/sentry/kernel/ptrace_amd64.go
@@ -18,8 +18,8 @@ package kernel
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ptraceArch implements arch-specific ptrace commands.
diff --git a/pkg/sentry/kernel/ptrace_arm64.go b/pkg/sentry/kernel/ptrace_arm64.go
index 61e412911..d971b96b3 100644
--- a/pkg/sentry/kernel/ptrace_arm64.go
+++ b/pkg/sentry/kernel/ptrace_arm64.go
@@ -17,8 +17,8 @@
package kernel
import (
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ptraceArch implements arch-specific ptrace commands.
diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go
index b14429854..efebfd872 100644
--- a/pkg/sentry/kernel/rseq.go
+++ b/pkg/sentry/kernel/rseq.go
@@ -19,8 +19,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/hostcpu"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Restartable sequences.
diff --git a/pkg/sentry/kernel/sched/BUILD b/pkg/sentry/kernel/sched/BUILD
index 98ea7a0d8..1b82e087b 100644
--- a/pkg/sentry/kernel/sched/BUILD
+++ b/pkg/sentry/kernel/sched/BUILD
@@ -1,5 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -9,7 +8,6 @@ go_library(
"cpuset.go",
"sched.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/sched",
visibility = ["//pkg/sentry:internal"],
)
@@ -17,5 +15,5 @@ go_test(
name = "sched_test",
size = "small",
srcs = ["cpuset_test.go"],
- embed = [":sched"],
+ library = ":sched",
)
diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go
index 2347dcf36..c38c5a40c 100644
--- a/pkg/sentry/kernel/seccomp.go
+++ b/pkg/sentry/kernel/seccomp.go
@@ -21,8 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/bpf"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const maxSyscallFilterInstructions = 1 << 15
diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD
index 13a961594..65e5427c1 100644
--- a/pkg/sentry/kernel/semaphore/BUILD
+++ b/pkg/sentry/kernel/semaphore/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -22,12 +21,11 @@ go_library(
"semaphore.go",
"waiter_list.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/semaphore",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
@@ -40,11 +38,11 @@ go_test(
name = "semaphore_test",
size = "small",
srcs = ["semaphore_test.go"],
- embed = [":semaphore"],
+ library = ":semaphore",
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/kernel/auth",
"//pkg/syserror",
],
diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go
index 18299814e..1000f3287 100644
--- a/pkg/sentry/kernel/semaphore/semaphore.go
+++ b/pkg/sentry/kernel/semaphore/semaphore.go
@@ -19,8 +19,8 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go
index c235f6ca4..e47acefdf 100644
--- a/pkg/sentry/kernel/semaphore/semaphore_test.go
+++ b/pkg/sentry/kernel/semaphore/semaphore_test.go
@@ -18,8 +18,8 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD
index 7321b22ed..bfd779837 100644
--- a/pkg/sentry/kernel/shm/BUILD
+++ b/pkg/sentry/kernel/shm/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -8,13 +8,12 @@ go_library(
"device.go",
"shm.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/shm",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/log",
"//pkg/refs",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/kernel/auth",
@@ -23,8 +22,8 @@ go_library(
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go
index 8ddef7eb8..208569057 100644
--- a/pkg/sentry/kernel/shm/shm.go
+++ b/pkg/sentry/kernel/shm/shm.go
@@ -37,9 +37,9 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
@@ -47,9 +47,9 @@ import (
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Key represents a shm segment key. Analogous to a file name.
diff --git a/pkg/sentry/kernel/signalfd/BUILD b/pkg/sentry/kernel/signalfd/BUILD
index 89e4d84b1..3eb78e91b 100644
--- a/pkg/sentry/kernel/signalfd/BUILD
+++ b/pkg/sentry/kernel/signalfd/BUILD
@@ -1,23 +1,22 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
-package(licenses = ["notice"])
+licenses(["notice"])
go_library(
name = "signalfd",
srcs = ["signalfd.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/signalfd",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/kernel/signalfd/signalfd.go b/pkg/sentry/kernel/signalfd/signalfd.go
index 28be4a939..8243bb93e 100644
--- a/pkg/sentry/kernel/signalfd/signalfd.go
+++ b/pkg/sentry/kernel/signalfd/signalfd.go
@@ -18,14 +18,14 @@ package signalfd
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go
index d2d01add4..93c4fe969 100644
--- a/pkg/sentry/kernel/syscalls.go
+++ b/pkg/sentry/kernel/syscalls.go
@@ -21,8 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/bits"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// maxSyscallNum is the highest supported syscall number.
diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go
index 978d66da8..981e8c7fe 100644
--- a/pkg/sentry/kernel/task.go
+++ b/pkg/sentry/kernel/task.go
@@ -21,8 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/bpf"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
@@ -35,8 +35,9 @@ import (
"gvisor.dev/gvisor/pkg/sentry/unimpl"
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -743,6 +744,14 @@ func (t *Task) GetFile(fd int32) *fs.File {
return f
}
+// GetFileVFS2 is a convenience wrapper for t.FDTable().GetVFS2.
+//
+// Precondition: same as FDTable.Get.
+func (t *Task) GetFileVFS2(fd int32) *vfs.FileDescription {
+ f, _ := t.fdTable.GetVFS2(fd)
+ return f
+}
+
// NewFDs is a convenience wrapper for t.FDTable().NewFDs.
//
// This automatically passes the task as the context.
diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go
index 247bd4aba..53d4d211b 100644
--- a/pkg/sentry/kernel/task_clone.go
+++ b/pkg/sentry/kernel/task_clone.go
@@ -17,8 +17,8 @@ package kernel
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/bpf"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SharingOptions controls what resources are shared by a new task created by
diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go
index bb5560acf..2d6e7733c 100644
--- a/pkg/sentry/kernel/task_context.go
+++ b/pkg/sentry/kernel/task_context.go
@@ -18,13 +18,13 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/futex"
"gvisor.dev/gvisor/pkg/sentry/loader"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var errNoSyscalls = syserr.New("no syscall table found", linux.ENOEXEC)
diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go
index fa6528386..8f57a34a6 100644
--- a/pkg/sentry/kernel/task_exec.go
+++ b/pkg/sentry/kernel/task_exec.go
@@ -69,6 +69,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/mm"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserror"
)
@@ -198,7 +199,7 @@ func (r *runSyscallAfterExecStop) execute(t *Task) taskRunState {
t.tg.pidns.owner.mu.Unlock()
// Remove FDs with the CloseOnExec flag set.
- t.fdTable.RemoveIf(func(file *fs.File, flags FDFlags) bool {
+ t.fdTable.RemoveIf(func(_ *fs.File, _ *vfs.FileDescription, flags FDFlags) bool {
return flags.CloseOnExec
})
diff --git a/pkg/sentry/kernel/task_futex.go b/pkg/sentry/kernel/task_futex.go
index c211b5b74..a53e77c9f 100644
--- a/pkg/sentry/kernel/task_futex.go
+++ b/pkg/sentry/kernel/task_futex.go
@@ -16,7 +16,7 @@ package kernel
import (
"gvisor.dev/gvisor/pkg/sentry/kernel/futex"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Futex returns t's futex manager.
diff --git a/pkg/sentry/kernel/task_log.go b/pkg/sentry/kernel/task_log.go
index 0fb3661de..41259210c 100644
--- a/pkg/sentry/kernel/task_log.go
+++ b/pkg/sentry/kernel/task_log.go
@@ -20,7 +20,7 @@ import (
"sort"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go
index 6357273d3..5568c91bc 100644
--- a/pkg/sentry/kernel/task_run.go
+++ b/pkg/sentry/kernel/task_run.go
@@ -26,7 +26,7 @@ import (
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// A taskRunState is a reified state in the task state machine. See README.md
diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go
index 39cd1340d..8802db142 100644
--- a/pkg/sentry/kernel/task_signals.go
+++ b/pkg/sentry/kernel/task_signals.go
@@ -26,8 +26,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ucspb "gvisor.dev/gvisor/pkg/sentry/kernel/uncaught_signal_go_proto"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go
index 58af16ee2..de838beef 100644
--- a/pkg/sentry/kernel/task_start.go
+++ b/pkg/sentry/kernel/task_start.go
@@ -21,8 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/futex"
"gvisor.dev/gvisor/pkg/sentry/kernel/sched"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// TaskConfig defines the configuration of a new Task (see below).
diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go
index 3180f5560..d555d69a8 100644
--- a/pkg/sentry/kernel/task_syscall.go
+++ b/pkg/sentry/kernel/task_syscall.go
@@ -25,8 +25,8 @@ import (
"gvisor.dev/gvisor/pkg/metric"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SyscallRestartErrno represents a ERESTART* errno defined in the Linux's kernel
diff --git a/pkg/sentry/kernel/task_usermem.go b/pkg/sentry/kernel/task_usermem.go
index 518bfe1bd..2bf3ce8a8 100644
--- a/pkg/sentry/kernel/task_usermem.go
+++ b/pkg/sentry/kernel/task_usermem.go
@@ -18,8 +18,8 @@ import (
"math"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// MAX_RW_COUNT is the maximum size in bytes of a single read or write.
diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD
index 4e4de0512..7ba7dc50c 100644
--- a/pkg/sentry/kernel/time/BUILD
+++ b/pkg/sentry/kernel/time/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -8,11 +8,10 @@ go_library(
"context.go",
"time.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/kernel/time",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sync",
"//pkg/syserror",
"//pkg/waiter",
diff --git a/pkg/sentry/kernel/time/context.go b/pkg/sentry/kernel/time/context.go
index 8ef483dd3..00b729d88 100644
--- a/pkg/sentry/kernel/time/context.go
+++ b/pkg/sentry/kernel/time/context.go
@@ -15,7 +15,7 @@
package time
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is the time package's type for context.Context.Value keys.
diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go
index 849c5b646..cf2f7ca72 100644
--- a/pkg/sentry/kernel/timekeeper_test.go
+++ b/pkg/sentry/kernel/timekeeper_test.go
@@ -17,12 +17,12 @@ package kernel
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
sentrytime "gvisor.dev/gvisor/pkg/sentry/time"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// mockClocks is a sentrytime.Clocks that simply returns the times in the
diff --git a/pkg/sentry/kernel/tty.go b/pkg/sentry/kernel/tty.go
index 464d2306a..d0e0810e8 100644
--- a/pkg/sentry/kernel/tty.go
+++ b/pkg/sentry/kernel/tty.go
@@ -33,6 +33,8 @@ type TTY struct {
// TTY returns the thread group's controlling terminal. If nil, there is no
// controlling terminal.
func (tg *ThreadGroup) TTY() *TTY {
+ tg.pidns.owner.mu.RLock()
+ defer tg.pidns.owner.mu.RUnlock()
tg.signalHandlers.mu.Lock()
defer tg.signalHandlers.mu.Unlock()
return tg.tty
diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go
index fdd10c56c..f1b3c212c 100644
--- a/pkg/sentry/kernel/vdso.go
+++ b/pkg/sentry/kernel/vdso.go
@@ -18,10 +18,10 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// vdsoParams are the parameters exposed to the VDSO.
diff --git a/pkg/sentry/limits/BUILD b/pkg/sentry/limits/BUILD
index 9fa841e8b..cf591c4c1 100644
--- a/pkg/sentry/limits/BUILD
+++ b/pkg/sentry/limits/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -10,11 +9,10 @@ go_library(
"limits.go",
"linux.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/limits",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sync",
],
)
@@ -25,5 +23,5 @@ go_test(
srcs = [
"limits_test.go",
],
- embed = [":limits"],
+ library = ":limits",
)
diff --git a/pkg/sentry/limits/context.go b/pkg/sentry/limits/context.go
index 6972749ed..77e1fe217 100644
--- a/pkg/sentry/limits/context.go
+++ b/pkg/sentry/limits/context.go
@@ -15,7 +15,7 @@
package limits
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is the limit package's type for context.Context.Value keys.
diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD
index 2890393bd..23790378a 100644
--- a/pkg/sentry/loader/BUILD
+++ b/pkg/sentry/loader/BUILD
@@ -1,5 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_embed_data")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_embed_data", "go_library")
package(licenses = ["notice"])
@@ -20,17 +19,17 @@ go_library(
"vdso_state.go",
":vdso_bin",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/loader",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi",
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/cpuid",
"//pkg/log",
"//pkg/rand",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
@@ -39,12 +38,11 @@ go_library(
"//pkg/sentry/memmap",
"//pkg/sentry/mm",
"//pkg/sentry/pgalloc",
- "//pkg/sentry/safemem",
"//pkg/sentry/uniqueid",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/syserr",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/loader/elf.go b/pkg/sentry/loader/elf.go
index 6299a3e2f..122ed05c2 100644
--- a/pkg/sentry/loader/elf.go
+++ b/pkg/sentry/loader/elf.go
@@ -23,16 +23,16 @@ import (
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/loader/interpreter.go b/pkg/sentry/loader/interpreter.go
index ccf909cac..098a45d36 100644
--- a/pkg/sentry/loader/interpreter.go
+++ b/pkg/sentry/loader/interpreter.go
@@ -18,10 +18,10 @@ import (
"bytes"
"io"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go
index b03eeb005..9a613d6b7 100644
--- a/pkg/sentry/loader/loader.go
+++ b/pkg/sentry/loader/loader.go
@@ -24,16 +24,16 @@ import (
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/rand"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// LoadArgs holds specifications for an executable file to be loaded.
diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go
index df8a81907..52f446ed7 100644
--- a/pkg/sentry/loader/vdso.go
+++ b/pkg/sentry/loader/vdso.go
@@ -20,20 +20,20 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/anon"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/mm"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/uniqueid"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/memmap/BUILD b/pkg/sentry/memmap/BUILD
index 112794e9c..a98b66de1 100644
--- a/pkg/sentry/memmap/BUILD
+++ b/pkg/sentry/memmap/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -37,14 +36,13 @@ go_library(
"mapping_set_impl.go",
"memmap.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/memmap",
visibility = ["//pkg/sentry:internal"],
deps = [
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
"//pkg/sentry/platform",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
@@ -52,6 +50,6 @@ go_test(
name = "memmap_test",
size = "small",
srcs = ["mapping_set_test.go"],
- embed = [":memmap"],
- deps = ["//pkg/sentry/usermem"],
+ library = ":memmap",
+ deps = ["//pkg/usermem"],
)
diff --git a/pkg/sentry/memmap/mapping_set.go b/pkg/sentry/memmap/mapping_set.go
index 0a5b7ce45..d609c1ae0 100644
--- a/pkg/sentry/memmap/mapping_set.go
+++ b/pkg/sentry/memmap/mapping_set.go
@@ -18,7 +18,7 @@ import (
"fmt"
"math"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// MappingSet maps offsets into a Mappable to mappings of those offsets. It is
diff --git a/pkg/sentry/memmap/mapping_set_test.go b/pkg/sentry/memmap/mapping_set_test.go
index f9b11a59c..d39efe38f 100644
--- a/pkg/sentry/memmap/mapping_set_test.go
+++ b/pkg/sentry/memmap/mapping_set_test.go
@@ -18,7 +18,7 @@ import (
"reflect"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type testMappingSpace struct {
diff --git a/pkg/sentry/memmap/memmap.go b/pkg/sentry/memmap/memmap.go
index 16a722a13..c6db9fc8f 100644
--- a/pkg/sentry/memmap/memmap.go
+++ b/pkg/sentry/memmap/memmap.go
@@ -18,9 +18,9 @@ package memmap
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Mappable represents a memory-mappable object, a mutable mapping from uint64
diff --git a/pkg/sentry/mm/BUILD b/pkg/sentry/mm/BUILD
index 83e248431..e5729ced5 100644
--- a/pkg/sentry/mm/BUILD
+++ b/pkg/sentry/mm/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -28,7 +27,7 @@ go_template_instance(
"minDegree": "8",
},
imports = {
- "usermem": "gvisor.dev/gvisor/pkg/sentry/usermem",
+ "usermem": "gvisor.dev/gvisor/pkg/usermem",
},
package = "mm",
prefix = "vma",
@@ -48,7 +47,7 @@ go_template_instance(
"minDegree": "8",
},
imports = {
- "usermem": "gvisor.dev/gvisor/pkg/sentry/usermem",
+ "usermem": "gvisor.dev/gvisor/pkg/usermem",
},
package = "mm",
prefix = "pma",
@@ -96,15 +95,16 @@ go_library(
"vma.go",
"vma_set.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/mm",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/atomicbitops",
+ "//pkg/context",
"//pkg/log",
"//pkg/refs",
+ "//pkg/safecopy",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/proc/seqfile",
"//pkg/sentry/kernel/auth",
@@ -114,13 +114,11 @@ go_library(
"//pkg/sentry/memmap",
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
- "//pkg/sentry/platform/safecopy",
- "//pkg/sentry/safemem",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
"//pkg/tcpip/buffer",
+ "//pkg/usermem",
],
)
@@ -128,16 +126,16 @@ go_test(
name = "mm_test",
size = "small",
srcs = ["mm_test.go"],
- embed = [":mm"],
+ library = ":mm",
deps = [
+ "//pkg/context",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
+ "//pkg/sentry/contexttest",
"//pkg/sentry/limits",
"//pkg/sentry/memmap",
"//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/mm/address_space.go b/pkg/sentry/mm/address_space.go
index cfebcfd42..e58a63deb 100644
--- a/pkg/sentry/mm/address_space.go
+++ b/pkg/sentry/mm/address_space.go
@@ -20,7 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// AddressSpace returns the platform.AddressSpace bound to mm.
diff --git a/pkg/sentry/mm/aio_context.go b/pkg/sentry/mm/aio_context.go
index 4b48866ad..cb29d94b0 100644
--- a/pkg/sentry/mm/aio_context.go
+++ b/pkg/sentry/mm/aio_context.go
@@ -16,15 +16,15 @@ package mm
import (
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// aioManager creates and manages asynchronous I/O contexts.
diff --git a/pkg/sentry/mm/debug.go b/pkg/sentry/mm/debug.go
index df9adf708..c273c982e 100644
--- a/pkg/sentry/mm/debug.go
+++ b/pkg/sentry/mm/debug.go
@@ -18,7 +18,7 @@ import (
"bytes"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
const (
diff --git a/pkg/sentry/mm/io.go b/pkg/sentry/mm/io.go
index b03e7d020..fa776f9c6 100644
--- a/pkg/sentry/mm/io.go
+++ b/pkg/sentry/mm/io.go
@@ -15,11 +15,11 @@
package mm
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// There are two supported ways to copy data to/from application virtual
diff --git a/pkg/sentry/mm/lifecycle.go b/pkg/sentry/mm/lifecycle.go
index 4e9ca1de6..47b8fbf43 100644
--- a/pkg/sentry/mm/lifecycle.go
+++ b/pkg/sentry/mm/lifecycle.go
@@ -19,13 +19,13 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/atomicbitops"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// NewMemoryManager returns a new MemoryManager with no mappings and 1 user.
diff --git a/pkg/sentry/mm/metadata.go b/pkg/sentry/mm/metadata.go
index d2a01d48a..f550acae0 100644
--- a/pkg/sentry/mm/metadata.go
+++ b/pkg/sentry/mm/metadata.go
@@ -17,7 +17,7 @@ package mm
import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Dumpability describes if and how core dumps should be created.
diff --git a/pkg/sentry/mm/mm.go b/pkg/sentry/mm/mm.go
index 78cc9e6e4..09e582dd3 100644
--- a/pkg/sentry/mm/mm.go
+++ b/pkg/sentry/mm/mm.go
@@ -35,14 +35,14 @@
package mm
import (
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// MemoryManager implements a virtual address space.
diff --git a/pkg/sentry/mm/mm_test.go b/pkg/sentry/mm/mm_test.go
index 4d2bfaaed..edacca741 100644
--- a/pkg/sentry/mm/mm_test.go
+++ b/pkg/sentry/mm/mm_test.go
@@ -17,15 +17,15 @@ package mm
import (
"testing"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func testMemoryManager(ctx context.Context) *MemoryManager {
diff --git a/pkg/sentry/mm/pma.go b/pkg/sentry/mm/pma.go
index c976c6f45..62e4c20af 100644
--- a/pkg/sentry/mm/pma.go
+++ b/pkg/sentry/mm/pma.go
@@ -17,14 +17,14 @@ package mm
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safecopy"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/platform/safecopy"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// existingPMAsLocked checks that pmas exist for all addresses in ar, and
diff --git a/pkg/sentry/mm/procfs.go b/pkg/sentry/mm/procfs.go
index 79610acb7..1ab92f046 100644
--- a/pkg/sentry/mm/procfs.go
+++ b/pkg/sentry/mm/procfs.go
@@ -19,10 +19,10 @@ import (
"fmt"
"strings"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs/proc/seqfile"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/mm/save_restore.go b/pkg/sentry/mm/save_restore.go
index 93259c5a3..f56215d9a 100644
--- a/pkg/sentry/mm/save_restore.go
+++ b/pkg/sentry/mm/save_restore.go
@@ -17,7 +17,7 @@ package mm
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// InvalidateUnsavable invokes memmap.Mappable.InvalidateUnsavable on all
diff --git a/pkg/sentry/mm/shm.go b/pkg/sentry/mm/shm.go
index b9f2d23e5..6432731d4 100644
--- a/pkg/sentry/mm/shm.go
+++ b/pkg/sentry/mm/shm.go
@@ -15,10 +15,10 @@
package mm
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/shm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// DetachShm unmaps a sysv shared memory segment.
diff --git a/pkg/sentry/mm/special_mappable.go b/pkg/sentry/mm/special_mappable.go
index ea2d7af74..9ad52082d 100644
--- a/pkg/sentry/mm/special_mappable.go
+++ b/pkg/sentry/mm/special_mappable.go
@@ -15,14 +15,14 @@
package mm
import (
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SpecialMappable implements memmap.MappingIdentity and memmap.Mappable with
diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go
index c2466c988..c5dfa5972 100644
--- a/pkg/sentry/mm/syscalls.go
+++ b/pkg/sentry/mm/syscalls.go
@@ -19,14 +19,14 @@ import (
mrand "math/rand"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/kernel/futex"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/pgalloc"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// HandleUserFault handles an application page fault. sp is the faulting
diff --git a/pkg/sentry/mm/vma.go b/pkg/sentry/mm/vma.go
index f2fd70799..9a14e69e6 100644
--- a/pkg/sentry/mm/vma.go
+++ b/pkg/sentry/mm/vma.go
@@ -18,13 +18,13 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Preconditions: mm.mappingMu must be locked for writing. opts must be valid
diff --git a/pkg/sentry/pgalloc/BUILD b/pkg/sentry/pgalloc/BUILD
index a9a2642c5..1eeb9f317 100644
--- a/pkg/sentry/pgalloc/BUILD
+++ b/pkg/sentry/pgalloc/BUILD
@@ -1,6 +1,5 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -60,21 +59,20 @@ go_library(
"save_restore.go",
"usage_set.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/pgalloc",
visibility = ["//pkg/sentry:internal"],
deps = [
+ "//pkg/context",
"//pkg/log",
"//pkg/memutil",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/hostmm",
"//pkg/sentry/platform",
- "//pkg/sentry/safemem",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/state",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
@@ -82,6 +80,6 @@ go_test(
name = "pgalloc_test",
size = "small",
srcs = ["pgalloc_test.go"],
- embed = [":pgalloc"],
- deps = ["//pkg/sentry/usermem"],
+ library = ":pgalloc",
+ deps = ["//pkg/usermem"],
)
diff --git a/pkg/sentry/pgalloc/context.go b/pkg/sentry/pgalloc/context.go
index 11ccf897b..d25215418 100644
--- a/pkg/sentry/pgalloc/context.go
+++ b/pkg/sentry/pgalloc/context.go
@@ -15,7 +15,7 @@
package pgalloc
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is this package's type for context.Context.Value keys.
diff --git a/pkg/sentry/pgalloc/pgalloc.go b/pkg/sentry/pgalloc/pgalloc.go
index c99e023d9..577e9306a 100644
--- a/pkg/sentry/pgalloc/pgalloc.go
+++ b/pkg/sentry/pgalloc/pgalloc.go
@@ -29,15 +29,15 @@ import (
"syscall"
"time"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/hostmm"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// MemoryFile is a platform.File whose pages may be allocated to arbitrary
diff --git a/pkg/sentry/pgalloc/pgalloc_test.go b/pkg/sentry/pgalloc/pgalloc_test.go
index 428e6a859..293f22c6b 100644
--- a/pkg/sentry/pgalloc/pgalloc_test.go
+++ b/pkg/sentry/pgalloc/pgalloc_test.go
@@ -17,7 +17,7 @@ package pgalloc
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/pgalloc/save_restore.go b/pkg/sentry/pgalloc/save_restore.go
index aafce1d00..f8385c146 100644
--- a/pkg/sentry/pgalloc/save_restore.go
+++ b/pkg/sentry/pgalloc/save_restore.go
@@ -25,8 +25,8 @@ import (
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/state"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SaveTo writes f's state to the given stream.
diff --git a/pkg/sentry/platform/BUILD b/pkg/sentry/platform/BUILD
index 157bffa81..453241eca 100644
--- a/pkg/sentry/platform/BUILD
+++ b/pkg/sentry/platform/BUILD
@@ -1,5 +1,5 @@
+load("//tools:defs.bzl", "go_library")
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -22,19 +22,18 @@ go_library(
"mmap_min_addr.go",
"platform.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/atomicbitops",
+ "//pkg/context",
"//pkg/log",
+ "//pkg/safecopy",
+ "//pkg/safemem",
"//pkg/seccomp",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
- "//pkg/sentry/platform/safecopy",
- "//pkg/sentry/safemem",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/platform/context.go b/pkg/sentry/platform/context.go
index e29bc4485..6759cda65 100644
--- a/pkg/sentry/platform/context.go
+++ b/pkg/sentry/platform/context.go
@@ -15,7 +15,7 @@
package platform
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is the auth package's type for context.Context.Value keys.
diff --git a/pkg/sentry/platform/interrupt/BUILD b/pkg/sentry/platform/interrupt/BUILD
index 85e882df9..83b385f14 100644
--- a/pkg/sentry/platform/interrupt/BUILD
+++ b/pkg/sentry/platform/interrupt/BUILD
@@ -1,5 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -8,7 +7,6 @@ go_library(
srcs = [
"interrupt.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/interrupt",
visibility = ["//pkg/sentry:internal"],
deps = ["//pkg/sync"],
)
@@ -17,5 +15,5 @@ go_test(
name = "interrupt_test",
size = "small",
srcs = ["interrupt_test.go"],
- embed = [":interrupt"],
+ library = ":interrupt",
)
diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD
index 6a358d1d4..159f7eafd 100644
--- a/pkg/sentry/platform/kvm/BUILD
+++ b/pkg/sentry/platform/kvm/BUILD
@@ -1,5 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
@@ -38,7 +37,6 @@ go_library(
"physical_map_arm64.go",
"virtual_map.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/kvm",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
@@ -46,16 +44,16 @@ go_library(
"//pkg/cpuid",
"//pkg/log",
"//pkg/procid",
+ "//pkg/safecopy",
"//pkg/seccomp",
"//pkg/sentry/arch",
"//pkg/sentry/platform",
"//pkg/sentry/platform/interrupt",
"//pkg/sentry/platform/ring0",
"//pkg/sentry/platform/ring0/pagetables",
- "//pkg/sentry/platform/safecopy",
"//pkg/sentry/time",
- "//pkg/sentry/usermem",
"//pkg/sync",
+ "//pkg/usermem",
],
)
@@ -65,7 +63,7 @@ go_test(
"kvm_test.go",
"virtual_map_test.go",
],
- embed = [":kvm"],
+ library = ":kvm",
tags = [
"manual",
"nogotsan",
@@ -77,6 +75,6 @@ go_test(
"//pkg/sentry/platform/kvm/testutil",
"//pkg/sentry/platform/ring0",
"//pkg/sentry/platform/ring0/pagetables",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/platform/kvm/address_space.go b/pkg/sentry/platform/kvm/address_space.go
index a25f3c449..be213bfe8 100644
--- a/pkg/sentry/platform/kvm/address_space.go
+++ b/pkg/sentry/platform/kvm/address_space.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/atomicbitops"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// dirtySet tracks vCPUs for invalidation.
diff --git a/pkg/sentry/platform/kvm/bluepill.go b/pkg/sentry/platform/kvm/bluepill.go
index 30dbb74d6..35cd55fef 100644
--- a/pkg/sentry/platform/kvm/bluepill.go
+++ b/pkg/sentry/platform/kvm/bluepill.go
@@ -19,9 +19,9 @@ import (
"reflect"
"syscall"
+ "gvisor.dev/gvisor/pkg/safecopy"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
- "gvisor.dev/gvisor/pkg/sentry/platform/safecopy"
)
// bluepill enters guest mode.
diff --git a/pkg/sentry/platform/kvm/bluepill_fault.go b/pkg/sentry/platform/kvm/bluepill_fault.go
index f6459cda9..e34f46aeb 100644
--- a/pkg/sentry/platform/kvm/bluepill_fault.go
+++ b/pkg/sentry/platform/kvm/bluepill_fault.go
@@ -18,7 +18,7 @@ import (
"sync/atomic"
"syscall"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/platform/kvm/context.go b/pkg/sentry/platform/kvm/context.go
index 99450d22d..c769ac7b4 100644
--- a/pkg/sentry/platform/kvm/context.go
+++ b/pkg/sentry/platform/kvm/context.go
@@ -19,7 +19,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/interrupt"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// context is an implementation of the platform context.
diff --git a/pkg/sentry/platform/kvm/kvm.go b/pkg/sentry/platform/kvm/kvm.go
index d337c5c7c..972ba85c3 100644
--- a/pkg/sentry/platform/kvm/kvm.go
+++ b/pkg/sentry/platform/kvm/kvm.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// KVM represents a lightweight VM context.
diff --git a/pkg/sentry/platform/kvm/kvm_test.go b/pkg/sentry/platform/kvm/kvm_test.go
index 30df725d4..c42752d50 100644
--- a/pkg/sentry/platform/kvm/kvm_test.go
+++ b/pkg/sentry/platform/kvm/kvm_test.go
@@ -27,7 +27,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/platform/kvm/testutil"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var dummyFPState = (*byte)(arch.NewFloatingPointData())
diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go
index e6d912168..8076c7529 100644
--- a/pkg/sentry/platform/kvm/machine.go
+++ b/pkg/sentry/platform/kvm/machine.go
@@ -25,8 +25,8 @@ import (
"gvisor.dev/gvisor/pkg/procid"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// machine contains state associated with the VM as a whole.
diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go
index 873e39dc7..923ce3909 100644
--- a/pkg/sentry/platform/kvm/machine_amd64.go
+++ b/pkg/sentry/platform/kvm/machine_amd64.go
@@ -26,7 +26,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// initArchState initializes architecture-specific state.
diff --git a/pkg/sentry/platform/kvm/machine_arm64.go b/pkg/sentry/platform/kvm/machine_arm64.go
index 3b1f20219..09552837a 100644
--- a/pkg/sentry/platform/kvm/machine_arm64.go
+++ b/pkg/sentry/platform/kvm/machine_arm64.go
@@ -20,7 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type vCPUArchState struct {
diff --git a/pkg/sentry/platform/kvm/machine_arm64_unsafe.go b/pkg/sentry/platform/kvm/machine_arm64_unsafe.go
index 3f2f97a6b..1c8384e6b 100644
--- a/pkg/sentry/platform/kvm/machine_arm64_unsafe.go
+++ b/pkg/sentry/platform/kvm/machine_arm64_unsafe.go
@@ -26,7 +26,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// setMemoryRegion initializes a region.
diff --git a/pkg/sentry/platform/kvm/physical_map.go b/pkg/sentry/platform/kvm/physical_map.go
index 91de5dab1..f7fa2f98d 100644
--- a/pkg/sentry/platform/kvm/physical_map.go
+++ b/pkg/sentry/platform/kvm/physical_map.go
@@ -21,7 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/platform/ring0"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type region struct {
diff --git a/pkg/sentry/platform/kvm/testutil/BUILD b/pkg/sentry/platform/kvm/testutil/BUILD
index b0e45f159..f7605df8a 100644
--- a/pkg/sentry/platform/kvm/testutil/BUILD
+++ b/pkg/sentry/platform/kvm/testutil/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -12,6 +12,5 @@ go_library(
"testutil_arm64.go",
"testutil_arm64.s",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/kvm/testutil",
visibility = ["//pkg/sentry/platform/kvm:__pkg__"],
)
diff --git a/pkg/sentry/platform/kvm/virtual_map.go b/pkg/sentry/platform/kvm/virtual_map.go
index 2d68855ef..c8897d34f 100644
--- a/pkg/sentry/platform/kvm/virtual_map.go
+++ b/pkg/sentry/platform/kvm/virtual_map.go
@@ -22,7 +22,7 @@ import (
"regexp"
"strconv"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type virtualRegion struct {
diff --git a/pkg/sentry/platform/kvm/virtual_map_test.go b/pkg/sentry/platform/kvm/virtual_map_test.go
index 6a2f145be..327e2be4f 100644
--- a/pkg/sentry/platform/kvm/virtual_map_test.go
+++ b/pkg/sentry/platform/kvm/virtual_map_test.go
@@ -18,7 +18,7 @@ import (
"syscall"
"testing"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type checker struct {
diff --git a/pkg/sentry/platform/mmap_min_addr.go b/pkg/sentry/platform/mmap_min_addr.go
index 999787462..091c2e365 100644
--- a/pkg/sentry/platform/mmap_min_addr.go
+++ b/pkg/sentry/platform/mmap_min_addr.go
@@ -20,7 +20,7 @@ import (
"strconv"
"strings"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// systemMMapMinAddrSource is the source file.
diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go
index ec22dbf87..2ca696382 100644
--- a/pkg/sentry/platform/platform.go
+++ b/pkg/sentry/platform/platform.go
@@ -22,10 +22,10 @@ import (
"os"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/seccomp"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Platform provides abstractions for execution contexts (Context,
diff --git a/pkg/sentry/platform/ptrace/BUILD b/pkg/sentry/platform/ptrace/BUILD
index cd13390c3..95abd321e 100644
--- a/pkg/sentry/platform/ptrace/BUILD
+++ b/pkg/sentry/platform/ptrace/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -20,20 +20,19 @@ go_library(
"subprocess_linux_unsafe.go",
"subprocess_unsafe.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/ptrace",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi/linux",
"//pkg/log",
"//pkg/procid",
+ "//pkg/safecopy",
"//pkg/seccomp",
"//pkg/sentry/arch",
"//pkg/sentry/hostcpu",
"//pkg/sentry/platform",
"//pkg/sentry/platform/interrupt",
- "//pkg/sentry/platform/safecopy",
- "//pkg/sentry/usermem",
"//pkg/sync",
+ "//pkg/usermem",
"@org_golang_x_sys//unix:go_default_library",
],
)
diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go
index bb0e03880..03adb624b 100644
--- a/pkg/sentry/platform/ptrace/ptrace.go
+++ b/pkg/sentry/platform/ptrace/ptrace.go
@@ -51,8 +51,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/platform"
"gvisor.dev/gvisor/pkg/sentry/platform/interrupt"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var (
diff --git a/pkg/sentry/platform/ptrace/ptrace_unsafe.go b/pkg/sentry/platform/ptrace/ptrace_unsafe.go
index 72c7ec564..6c0ed7b3e 100644
--- a/pkg/sentry/platform/ptrace/ptrace_unsafe.go
+++ b/pkg/sentry/platform/ptrace/ptrace_unsafe.go
@@ -20,7 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// getRegs gets the general purpose register set.
diff --git a/pkg/sentry/platform/ptrace/stub_unsafe.go b/pkg/sentry/platform/ptrace/stub_unsafe.go
index aa1b87237..341dde143 100644
--- a/pkg/sentry/platform/ptrace/stub_unsafe.go
+++ b/pkg/sentry/platform/ptrace/stub_unsafe.go
@@ -19,8 +19,8 @@ import (
"syscall"
"unsafe"
- "gvisor.dev/gvisor/pkg/sentry/platform/safecopy"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/safecopy"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// stub is defined in arch-specific assembly.
diff --git a/pkg/sentry/platform/ptrace/subprocess.go b/pkg/sentry/platform/ptrace/subprocess.go
index 15dc46a5b..31b7cec53 100644
--- a/pkg/sentry/platform/ptrace/subprocess.go
+++ b/pkg/sentry/platform/ptrace/subprocess.go
@@ -25,8 +25,8 @@ import (
"gvisor.dev/gvisor/pkg/procid"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/platform"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Linux kernel errnos which "should never be seen by user programs", but will
diff --git a/pkg/sentry/platform/ring0/BUILD b/pkg/sentry/platform/ring0/BUILD
index 87f4552b5..934b6fbcd 100644
--- a/pkg/sentry/platform/ring0/BUILD
+++ b/pkg/sentry/platform/ring0/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance")
package(licenses = ["notice"])
@@ -74,11 +74,10 @@ go_library(
"lib_arm64.s",
"ring0.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/ring0",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/cpuid",
"//pkg/sentry/platform/ring0/pagetables",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/platform/ring0/defs_amd64.go b/pkg/sentry/platform/ring0/defs_amd64.go
index 9dae0dccb..9c6c2cf5c 100644
--- a/pkg/sentry/platform/ring0/defs_amd64.go
+++ b/pkg/sentry/platform/ring0/defs_amd64.go
@@ -18,7 +18,7 @@ package ring0
import (
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var (
diff --git a/pkg/sentry/platform/ring0/defs_arm64.go b/pkg/sentry/platform/ring0/defs_arm64.go
index a850ce6cf..1583dda12 100644
--- a/pkg/sentry/platform/ring0/defs_arm64.go
+++ b/pkg/sentry/platform/ring0/defs_arm64.go
@@ -18,7 +18,7 @@ package ring0
import (
"gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var (
diff --git a/pkg/sentry/platform/ring0/entry_arm64.go b/pkg/sentry/platform/ring0/entry_arm64.go
index 0dfa42c36..62a93f3d6 100644
--- a/pkg/sentry/platform/ring0/entry_arm64.go
+++ b/pkg/sentry/platform/ring0/entry_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/platform/ring0/gen_offsets/BUILD b/pkg/sentry/platform/ring0/gen_offsets/BUILD
index 42076fb04..4cae10459 100644
--- a/pkg/sentry/platform/ring0/gen_offsets/BUILD
+++ b/pkg/sentry/platform/ring0/gen_offsets/BUILD
@@ -1,4 +1,4 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary")
+load("//tools:defs.bzl", "go_binary")
load("//tools/go_generics:defs.bzl", "go_template_instance")
package(licenses = ["notice"])
@@ -28,6 +28,6 @@ go_binary(
deps = [
"//pkg/cpuid",
"//pkg/sentry/platform/ring0/pagetables",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/platform/ring0/kernel_arm64.go b/pkg/sentry/platform/ring0/kernel_arm64.go
index ed82a131e..c3d341998 100644
--- a/pkg/sentry/platform/ring0/kernel_arm64.go
+++ b/pkg/sentry/platform/ring0/kernel_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/platform/ring0/lib_arm64.go b/pkg/sentry/platform/ring0/lib_arm64.go
index 8bcfe1032..af075aae4 100644
--- a/pkg/sentry/platform/ring0/lib_arm64.go
+++ b/pkg/sentry/platform/ring0/lib_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/platform/ring0/offsets_arm64.go b/pkg/sentry/platform/ring0/offsets_arm64.go
index cd2a65f97..8c960c749 100644
--- a/pkg/sentry/platform/ring0/offsets_arm64.go
+++ b/pkg/sentry/platform/ring0/offsets_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/platform/ring0/pagetables/BUILD b/pkg/sentry/platform/ring0/pagetables/BUILD
index 387a7f6c3..971eed7fa 100644
--- a/pkg/sentry/platform/ring0/pagetables/BUILD
+++ b/pkg/sentry/platform/ring0/pagetables/BUILD
@@ -1,17 +1,14 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test", "select_arch")
load("//tools/go_generics:defs.bzl", "go_template", "go_template_instance")
package(licenses = ["notice"])
-config_setting(
- name = "aarch64",
- constraint_values = ["@bazel_tools//platforms:aarch64"],
-)
-
go_template(
name = "generic_walker",
- srcs = ["walker_amd64.go"],
+ srcs = select_arch(
+ amd64 = ["walker_amd64.go"],
+ arm64 = ["walker_amd64.go"],
+ ),
opt_types = [
"Visitor",
],
@@ -91,14 +88,13 @@ go_library(
"walker_map.go",
"walker_unmap.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables",
visibility = [
"//pkg/sentry/platform/kvm:__subpackages__",
"//pkg/sentry/platform/ring0:__subpackages__",
],
deps = [
- "//pkg/sentry/usermem",
"//pkg/sync",
+ "//pkg/usermem",
],
)
@@ -111,6 +107,6 @@ go_test(
"pagetables_test.go",
"walker_check.go",
],
- embed = [":pagetables"],
- deps = ["//pkg/sentry/usermem"],
+ library = ":pagetables",
+ deps = ["//pkg/usermem"],
)
diff --git a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go
index a90394a33..d08bfdeb3 100644
--- a/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go
+++ b/pkg/sentry/platform/ring0/pagetables/allocator_unsafe.go
@@ -17,7 +17,7 @@ package pagetables
import (
"unsafe"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// newAlignedPTEs returns a set of aligned PTEs.
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables.go b/pkg/sentry/platform/ring0/pagetables/pagetables.go
index 30c64a372..87e88e97d 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables.go
@@ -21,7 +21,7 @@
package pagetables
import (
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// PageTables is a set of page tables.
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_aarch64.go b/pkg/sentry/platform/ring0/pagetables/pagetables_aarch64.go
index e78424766..78510ebed 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables_aarch64.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables_aarch64.go
@@ -19,7 +19,7 @@ package pagetables
import (
"sync/atomic"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// archPageTables is architecture-specific data.
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go
index 35e917526..54e8e554f 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables_amd64_test.go
@@ -19,7 +19,7 @@ package pagetables
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func Test2MAnd4K(t *testing.T) {
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_arm64_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_arm64_test.go
index 254116233..2f73d424f 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables_arm64_test.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables_arm64_test.go
@@ -19,7 +19,7 @@ package pagetables
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func Test2MAnd4K(t *testing.T) {
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go
index 6e95ad2b9..5c88d087d 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables_test.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables_test.go
@@ -17,7 +17,7 @@ package pagetables
import (
"testing"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
type mapping struct {
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
index 3e2383c5e..dcf061df9 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
@@ -19,7 +19,7 @@ package pagetables
import (
"sync/atomic"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// archPageTables is architecture-specific data.
diff --git a/pkg/sentry/platform/safecopy/BUILD b/pkg/sentry/platform/safecopy/BUILD
deleted file mode 100644
index 6769cd0a5..000000000
--- a/pkg/sentry/platform/safecopy/BUILD
+++ /dev/null
@@ -1,31 +0,0 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "safecopy",
- srcs = [
- "atomic_amd64.s",
- "atomic_arm64.s",
- "memclr_amd64.s",
- "memclr_arm64.s",
- "memcpy_amd64.s",
- "memcpy_arm64.s",
- "safecopy.go",
- "safecopy_unsafe.go",
- "sighandler_amd64.s",
- "sighandler_arm64.s",
- ],
- importpath = "gvisor.dev/gvisor/pkg/sentry/platform/safecopy",
- visibility = ["//pkg/sentry:internal"],
- deps = ["//pkg/syserror"],
-)
-
-go_test(
- name = "safecopy_test",
- srcs = [
- "safecopy_test.go",
- ],
- embed = [":safecopy"],
-)
diff --git a/pkg/sentry/platform/safecopy/LICENSE b/pkg/sentry/platform/safecopy/LICENSE
deleted file mode 100644
index 6a66aea5e..000000000
--- a/pkg/sentry/platform/safecopy/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/sentry/platform/safecopy/atomic_amd64.s b/pkg/sentry/platform/safecopy/atomic_amd64.s
deleted file mode 100644
index a0cd78f33..000000000
--- a/pkg/sentry/platform/safecopy/atomic_amd64.s
+++ /dev/null
@@ -1,136 +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.
-
-#include "textflag.h"
-
-// handleSwapUint32Fault returns the value stored in DI. Control is transferred
-// to it when swapUint32 below receives SIGSEGV or SIGBUS, with the signal
-// number stored in DI.
-//
-// It must have the same frame configuration as swapUint32 so that it can undo
-// any potential call frame set up by the assembler.
-TEXT handleSwapUint32Fault(SB), NOSPLIT, $0-24
- MOVL DI, sig+20(FP)
- RET
-
-// swapUint32 atomically stores new into *addr and returns (the previous *addr
-// value, 0). If a SIGSEGV or SIGBUS signal is received during the swap, the
-// value of old is unspecified, and sig is the number of the signal that was
-// received.
-//
-// Preconditions: addr must be aligned to a 4-byte boundary.
-//
-//func swapUint32(ptr unsafe.Pointer, new uint32) (old uint32, sig int32)
-TEXT ·swapUint32(SB), NOSPLIT, $0-24
- // 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,
- // handleSwapUint32Fault will store a different value in this address.
- MOVL $0, sig+20(FP)
-
- MOVQ addr+0(FP), DI
- MOVL new+8(FP), AX
- XCHGL AX, 0(DI)
- MOVL AX, old+16(FP)
- RET
-
-// handleSwapUint64Fault returns the value stored in DI. Control is transferred
-// to it when swapUint64 below receives SIGSEGV or SIGBUS, with the signal
-// number stored in DI.
-//
-// It must have the same frame configuration as swapUint64 so that it can undo
-// any potential call frame set up by the assembler.
-TEXT handleSwapUint64Fault(SB), NOSPLIT, $0-28
- MOVL DI, sig+24(FP)
- RET
-
-// swapUint64 atomically stores new into *addr and returns (the previous *addr
-// value, 0). If a SIGSEGV or SIGBUS signal is received during the swap, the
-// value of old is unspecified, and sig is the number of the signal that was
-// received.
-//
-// Preconditions: addr must be aligned to a 8-byte boundary.
-//
-//func swapUint64(ptr unsafe.Pointer, new uint64) (old uint64, sig int32)
-TEXT ·swapUint64(SB), NOSPLIT, $0-28
- // 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,
- // handleSwapUint64Fault will store a different value in this address.
- MOVL $0, sig+24(FP)
-
- MOVQ addr+0(FP), DI
- MOVQ new+8(FP), AX
- XCHGQ AX, 0(DI)
- MOVQ AX, old+16(FP)
- RET
-
-// handleCompareAndSwapUint32Fault returns the value stored in DI. Control is
-// transferred to it when swapUint64 below receives SIGSEGV or SIGBUS, with the
-// signal number stored in DI.
-//
-// It must have the same frame configuration as compareAndSwapUint32 so that it
-// can undo any potential call frame set up by the assembler.
-TEXT handleCompareAndSwapUint32Fault(SB), NOSPLIT, $0-24
- MOVL DI, sig+20(FP)
- RET
-
-// compareAndSwapUint32 is like sync/atomic.CompareAndSwapUint32, but returns
-// (the value previously stored at addr, 0). If a SIGSEGV or SIGBUS signal is
-// received during the operation, the value of prev is unspecified, and sig is
-// the number of the signal that was received.
-//
-// Preconditions: addr must be aligned to a 4-byte boundary.
-//
-//func compareAndSwapUint32(ptr unsafe.Pointer, old, new uint32) (prev uint32, sig int32)
-TEXT ·compareAndSwapUint32(SB), NOSPLIT, $0-24
- // 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,
- // handleCompareAndSwapUint32Fault will store a different value in this
- // address.
- MOVL $0, sig+20(FP)
-
- MOVQ addr+0(FP), DI
- MOVL old+8(FP), AX
- MOVL new+12(FP), DX
- LOCK
- 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
deleted file mode 100644
index d58ed71f7..000000000
--- a/pkg/sentry/platform/safecopy/atomic_arm64.s
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// handleSwapUint32Fault returns the value stored in R1. Control is transferred
-// to it when swapUint32 below receives SIGSEGV or SIGBUS, with the signal
-// number stored in R1.
-//
-// It must have the same frame configuration as swapUint32 so that it can undo
-// any potential call frame set up by the assembler.
-TEXT handleSwapUint32Fault(SB), NOSPLIT, $0-24
- MOVW R1, sig+20(FP)
- RET
-
-// See the corresponding doc in safecopy_unsafe.go
-//
-// The code is derived from Go source runtime/internal/atomic.Xchg.
-//
-//func swapUint32(ptr unsafe.Pointer, new uint32) (old uint32, sig int32)
-TEXT ·swapUint32(SB), NOSPLIT, $0-24
- // 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,
- // handleSwapUint32Fault will store a different value in this address.
- MOVW $0, sig+20(FP)
-again:
- MOVD addr+0(FP), R0
- MOVW new+8(FP), R1
- LDAXRW (R0), R2
- STLXRW R1, (R0), R3
- CBNZ R3, again
- MOVW R2, old+16(FP)
- RET
-
-// handleSwapUint64Fault returns the value stored in R1. Control is transferred
-// to it when swapUint64 below receives SIGSEGV or SIGBUS, with the signal
-// number stored in R1.
-//
-// It must have the same frame configuration as swapUint64 so that it can undo
-// any potential call frame set up by the assembler.
-TEXT handleSwapUint64Fault(SB), NOSPLIT, $0-28
- MOVW R1, sig+24(FP)
- RET
-
-// See the corresponding doc in safecopy_unsafe.go
-//
-// The code is derived from Go source runtime/internal/atomic.Xchg64.
-//
-//func swapUint64(ptr unsafe.Pointer, new uint64) (old uint64, sig int32)
-TEXT ·swapUint64(SB), NOSPLIT, $0-28
- // 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,
- // handleSwapUint64Fault will store a different value in this address.
- MOVW $0, sig+24(FP)
-again:
- MOVD addr+0(FP), R0
- MOVD new+8(FP), R1
- LDAXR (R0), R2
- STLXR R1, (R0), R3
- CBNZ R3, again
- MOVD R2, old+16(FP)
- RET
-
-// handleCompareAndSwapUint32Fault returns the value stored in R1. Control is
-// transferred to it when compareAndSwapUint32 below receives SIGSEGV or SIGBUS,
-// with the signal number stored in R1.
-//
-// It must have the same frame configuration as compareAndSwapUint32 so that it
-// can undo any potential call frame set up by the assembler.
-TEXT handleCompareAndSwapUint32Fault(SB), NOSPLIT, $0-24
- MOVW R1, sig+20(FP)
- RET
-
-// See the corresponding doc in safecopy_unsafe.go
-//
-// The code is derived from Go source runtime/internal/atomic.Cas.
-//
-//func compareAndSwapUint32(ptr unsafe.Pointer, old, new uint32) (prev uint32, sig int32)
-TEXT ·compareAndSwapUint32(SB), NOSPLIT, $0-24
- // 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,
- // handleCompareAndSwapUint32Fault will store a different value in this
- // address.
- MOVW $0, sig+20(FP)
-
- MOVD addr+0(FP), R0
- MOVW old+8(FP), R1
- MOVW new+12(FP), R2
-again:
- LDAXRW (R0), R3
- CMPW R1, R3
- BNE done
- STLXRW R2, (R0), R4
- CBNZ R4, 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/memclr_amd64.s b/pkg/sentry/platform/safecopy/memclr_amd64.s
deleted file mode 100644
index 64cf32f05..000000000
--- a/pkg/sentry/platform/safecopy/memclr_amd64.s
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// handleMemclrFault returns (the value stored in AX, the value stored in DI).
-// Control is transferred to it when memclr below receives SIGSEGV or SIGBUS,
-// with the faulting address stored in AX and the signal number stored in DI.
-//
-// It must have the same frame configuration as memclr so that it can undo any
-// potential call frame set up by the assembler.
-TEXT handleMemclrFault(SB), NOSPLIT, $0-28
- MOVQ AX, addr+16(FP)
- MOVL DI, sig+24(FP)
- RET
-
-// memclr sets the n bytes following ptr to zeroes. If a SIGSEGV or SIGBUS
-// signal is received during the write, it returns the address that caused the
-// fault and the number of the signal that was received. Otherwise, it returns
-// an unspecified address and a signal number of 0.
-//
-// Data is written in order, such that if a fault happens at address p, it is
-// safe to assume that all data before p-maxRegisterSize has already been
-// successfully written.
-//
-// The code is derived from runtime.memclrNoHeapPointers.
-//
-// func memclr(ptr unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
-TEXT ·memclr(SB), NOSPLIT, $0-28
- // 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,
- // handleMemclrFault will store a different value in this address.
- MOVL $0, sig+24(FP)
-
- MOVQ ptr+0(FP), DI
- MOVQ n+8(FP), BX
- XORQ AX, AX
-
- // MOVOU seems always faster than REP STOSQ.
-tail:
- TESTQ BX, BX
- JEQ _0
- CMPQ BX, $2
- JBE _1or2
- CMPQ BX, $4
- JBE _3or4
- CMPQ BX, $8
- JB _5through7
- JE _8
- CMPQ BX, $16
- JBE _9through16
- PXOR X0, X0
- CMPQ BX, $32
- JBE _17through32
- CMPQ BX, $64
- JBE _33through64
- CMPQ BX, $128
- JBE _65through128
- CMPQ BX, $256
- JBE _129through256
- // TODO: use branch table and BSR to make this just a single dispatch
- // TODO: for really big clears, use MOVNTDQ, even without AVX2.
-
-loop:
- MOVOU X0, 0(DI)
- MOVOU X0, 16(DI)
- MOVOU X0, 32(DI)
- MOVOU X0, 48(DI)
- MOVOU X0, 64(DI)
- MOVOU X0, 80(DI)
- MOVOU X0, 96(DI)
- MOVOU X0, 112(DI)
- MOVOU X0, 128(DI)
- MOVOU X0, 144(DI)
- MOVOU X0, 160(DI)
- MOVOU X0, 176(DI)
- MOVOU X0, 192(DI)
- MOVOU X0, 208(DI)
- MOVOU X0, 224(DI)
- MOVOU X0, 240(DI)
- SUBQ $256, BX
- ADDQ $256, DI
- CMPQ BX, $256
- JAE loop
- JMP tail
-
-_1or2:
- MOVB AX, (DI)
- MOVB AX, -1(DI)(BX*1)
- RET
-_0:
- RET
-_3or4:
- MOVW AX, (DI)
- MOVW AX, -2(DI)(BX*1)
- RET
-_5through7:
- MOVL AX, (DI)
- MOVL AX, -4(DI)(BX*1)
- RET
-_8:
- // We need a separate case for 8 to make sure we clear pointers atomically.
- MOVQ AX, (DI)
- RET
-_9through16:
- MOVQ AX, (DI)
- MOVQ AX, -8(DI)(BX*1)
- RET
-_17through32:
- MOVOU X0, (DI)
- MOVOU X0, -16(DI)(BX*1)
- RET
-_33through64:
- MOVOU X0, (DI)
- MOVOU X0, 16(DI)
- MOVOU X0, -32(DI)(BX*1)
- MOVOU X0, -16(DI)(BX*1)
- RET
-_65through128:
- MOVOU X0, (DI)
- MOVOU X0, 16(DI)
- MOVOU X0, 32(DI)
- MOVOU X0, 48(DI)
- MOVOU X0, -64(DI)(BX*1)
- MOVOU X0, -48(DI)(BX*1)
- MOVOU X0, -32(DI)(BX*1)
- MOVOU X0, -16(DI)(BX*1)
- RET
-_129through256:
- MOVOU X0, (DI)
- MOVOU X0, 16(DI)
- MOVOU X0, 32(DI)
- MOVOU X0, 48(DI)
- MOVOU X0, 64(DI)
- MOVOU X0, 80(DI)
- MOVOU X0, 96(DI)
- MOVOU X0, 112(DI)
- MOVOU X0, -128(DI)(BX*1)
- MOVOU X0, -112(DI)(BX*1)
- MOVOU X0, -96(DI)(BX*1)
- MOVOU X0, -80(DI)(BX*1)
- MOVOU X0, -64(DI)(BX*1)
- MOVOU X0, -48(DI)(BX*1)
- MOVOU X0, -32(DI)(BX*1)
- MOVOU X0, -16(DI)(BX*1)
- RET
diff --git a/pkg/sentry/platform/safecopy/memclr_arm64.s b/pkg/sentry/platform/safecopy/memclr_arm64.s
deleted file mode 100644
index 7361b9067..000000000
--- a/pkg/sentry/platform/safecopy/memclr_arm64.s
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// handleMemclrFault returns (the value stored in R0, the value stored in R1).
-// Control is transferred to it when memclr below receives SIGSEGV or SIGBUS,
-// with the faulting address stored in R0 and the signal number stored in R1.
-//
-// It must have the same frame configuration as memclr so that it can undo any
-// potential call frame set up by the assembler.
-TEXT handleMemclrFault(SB), NOSPLIT, $0-28
- MOVD R0, addr+16(FP)
- MOVW R1, sig+24(FP)
- RET
-
-// See the corresponding doc in safecopy_unsafe.go
-//
-// The code is derived from runtime.memclrNoHeapPointers.
-//
-// func memclr(ptr unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
-TEXT ·memclr(SB), NOSPLIT, $0-28
- // 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,
- // handleMemclrFault will store a different value in this address.
- MOVW $0, sig+24(FP)
- MOVD ptr+0(FP), R0
- MOVD n+8(FP), R1
-
- // If size is less than 16 bytes, use tail_zero to zero what remains
- CMP $16, R1
- BLT tail_zero
- // Get buffer offset into 16 byte aligned address for better performance
- ANDS $15, R0, ZR
- BNE unaligned_to_16
-aligned_to_16:
- LSR $4, R1, R2
-zero_by_16:
- STP.P (ZR, ZR), 16(R0) // Store pair with post index.
- SUBS $1, R2, R2
- BNE zero_by_16
- ANDS $15, R1, R1
- BEQ end
-
- // Zero buffer with size=R1 < 16
-tail_zero:
- TBZ $3, R1, tail_zero_4
- MOVD.P ZR, 8(R0)
-tail_zero_4:
- TBZ $2, R1, tail_zero_2
- MOVW.P ZR, 4(R0)
-tail_zero_2:
- TBZ $1, R1, tail_zero_1
- MOVH.P ZR, 2(R0)
-tail_zero_1:
- TBZ $0, R1, end
- MOVB ZR, (R0)
-end:
- RET
-
-unaligned_to_16:
- MOVD R0, R2
-head_loop:
- MOVBU.P ZR, 1(R0)
- ANDS $15, R0, ZR
- BNE head_loop
- // Adjust length for what remains
- SUB R2, R0, R3
- SUB R3, R1
- // If size is less than 16 bytes, use tail_zero to zero what remains
- CMP $16, R1
- BLT tail_zero
- B aligned_to_16
diff --git a/pkg/sentry/platform/safecopy/memcpy_amd64.s b/pkg/sentry/platform/safecopy/memcpy_amd64.s
deleted file mode 100644
index 129691d68..000000000
--- a/pkg/sentry/platform/safecopy/memcpy_amd64.s
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
-// Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
-// Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "textflag.h"
-
-// handleMemcpyFault returns (the value stored in AX, the value stored in DI).
-// Control is transferred to it when memcpy below receives SIGSEGV or SIGBUS,
-// with the faulting address stored in AX and the signal number stored in DI.
-//
-// It must have the same frame configuration as memcpy so that it can undo any
-// potential call frame set up by the assembler.
-TEXT handleMemcpyFault(SB), NOSPLIT, $0-36
- MOVQ AX, addr+24(FP)
- MOVL DI, sig+32(FP)
- RET
-
-// memcpy copies data from src to dst. If a SIGSEGV or SIGBUS signal is received
-// during the copy, it returns the address that caused the fault and the number
-// of the signal that was received. Otherwise, it returns an unspecified address
-// and a signal number of 0.
-//
-// Data is copied in order, such that if a fault happens at address p, it is
-// safe to assume that all data before p-maxRegisterSize has already been
-// successfully copied.
-//
-// The code is derived from the forward copying part of runtime.memmove.
-//
-// func memcpy(dst, src unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
-TEXT ·memcpy(SB), NOSPLIT, $0-36
- // 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,
- // handleMemcpyFault will store a different value in this address.
- MOVL $0, sig+32(FP)
-
- MOVQ to+0(FP), DI
- MOVQ from+8(FP), SI
- MOVQ n+16(FP), BX
-
- // REP instructions have a high startup cost, so we handle small sizes
- // with some straightline code. The REP MOVSQ instruction is really fast
- // for large sizes. The cutover is approximately 2K.
-tail:
- // move_129through256 or smaller work whether or not the source and the
- // destination memory regions overlap because they load all data into
- // registers before writing it back. move_256through2048 on the other
- // hand can be used only when the memory regions don't overlap or the copy
- // direction is forward.
- TESTQ BX, BX
- JEQ move_0
- CMPQ BX, $2
- JBE move_1or2
- CMPQ BX, $4
- JBE move_3or4
- CMPQ BX, $8
- JB move_5through7
- JE move_8
- CMPQ BX, $16
- JBE move_9through16
- CMPQ BX, $32
- JBE move_17through32
- CMPQ BX, $64
- JBE move_33through64
- CMPQ BX, $128
- JBE move_65through128
- CMPQ BX, $256
- JBE move_129through256
- // TODO: use branch table and BSR to make this just a single dispatch
-
-/*
- * forward copy loop
- */
- CMPQ BX, $2048
- JLS move_256through2048
-
- // Check alignment
- MOVL SI, AX
- ORL DI, AX
- TESTL $7, AX
- JEQ fwdBy8
-
- // Do 1 byte at a time
- MOVQ BX, CX
- REP; MOVSB
- RET
-
-fwdBy8:
- // Do 8 bytes at a time
- MOVQ BX, CX
- SHRQ $3, CX
- ANDQ $7, BX
- REP; MOVSQ
- JMP tail
-
-move_1or2:
- MOVB (SI), AX
- MOVB AX, (DI)
- MOVB -1(SI)(BX*1), CX
- MOVB CX, -1(DI)(BX*1)
- RET
-move_0:
- RET
-move_3or4:
- MOVW (SI), AX
- MOVW AX, (DI)
- MOVW -2(SI)(BX*1), CX
- MOVW CX, -2(DI)(BX*1)
- RET
-move_5through7:
- MOVL (SI), AX
- MOVL AX, (DI)
- MOVL -4(SI)(BX*1), CX
- MOVL CX, -4(DI)(BX*1)
- RET
-move_8:
- // We need a separate case for 8 to make sure we write pointers atomically.
- MOVQ (SI), AX
- MOVQ AX, (DI)
- RET
-move_9through16:
- MOVQ (SI), AX
- MOVQ AX, (DI)
- MOVQ -8(SI)(BX*1), CX
- MOVQ CX, -8(DI)(BX*1)
- RET
-move_17through32:
- MOVOU (SI), X0
- MOVOU X0, (DI)
- MOVOU -16(SI)(BX*1), X1
- MOVOU X1, -16(DI)(BX*1)
- RET
-move_33through64:
- MOVOU (SI), X0
- MOVOU X0, (DI)
- MOVOU 16(SI), X1
- MOVOU X1, 16(DI)
- MOVOU -32(SI)(BX*1), X2
- MOVOU X2, -32(DI)(BX*1)
- MOVOU -16(SI)(BX*1), X3
- MOVOU X3, -16(DI)(BX*1)
- RET
-move_65through128:
- MOVOU (SI), X0
- MOVOU X0, (DI)
- MOVOU 16(SI), X1
- MOVOU X1, 16(DI)
- MOVOU 32(SI), X2
- MOVOU X2, 32(DI)
- MOVOU 48(SI), X3
- MOVOU X3, 48(DI)
- MOVOU -64(SI)(BX*1), X4
- MOVOU X4, -64(DI)(BX*1)
- MOVOU -48(SI)(BX*1), X5
- MOVOU X5, -48(DI)(BX*1)
- MOVOU -32(SI)(BX*1), X6
- MOVOU X6, -32(DI)(BX*1)
- MOVOU -16(SI)(BX*1), X7
- MOVOU X7, -16(DI)(BX*1)
- RET
-move_129through256:
- MOVOU (SI), X0
- MOVOU X0, (DI)
- MOVOU 16(SI), X1
- MOVOU X1, 16(DI)
- MOVOU 32(SI), X2
- MOVOU X2, 32(DI)
- MOVOU 48(SI), X3
- MOVOU X3, 48(DI)
- MOVOU 64(SI), X4
- MOVOU X4, 64(DI)
- MOVOU 80(SI), X5
- MOVOU X5, 80(DI)
- MOVOU 96(SI), X6
- MOVOU X6, 96(DI)
- MOVOU 112(SI), X7
- MOVOU X7, 112(DI)
- MOVOU -128(SI)(BX*1), X8
- MOVOU X8, -128(DI)(BX*1)
- MOVOU -112(SI)(BX*1), X9
- MOVOU X9, -112(DI)(BX*1)
- MOVOU -96(SI)(BX*1), X10
- MOVOU X10, -96(DI)(BX*1)
- MOVOU -80(SI)(BX*1), X11
- MOVOU X11, -80(DI)(BX*1)
- MOVOU -64(SI)(BX*1), X12
- MOVOU X12, -64(DI)(BX*1)
- MOVOU -48(SI)(BX*1), X13
- MOVOU X13, -48(DI)(BX*1)
- MOVOU -32(SI)(BX*1), X14
- MOVOU X14, -32(DI)(BX*1)
- MOVOU -16(SI)(BX*1), X15
- MOVOU X15, -16(DI)(BX*1)
- RET
-move_256through2048:
- SUBQ $256, BX
- MOVOU (SI), X0
- MOVOU X0, (DI)
- MOVOU 16(SI), X1
- MOVOU X1, 16(DI)
- MOVOU 32(SI), X2
- MOVOU X2, 32(DI)
- MOVOU 48(SI), X3
- MOVOU X3, 48(DI)
- MOVOU 64(SI), X4
- MOVOU X4, 64(DI)
- MOVOU 80(SI), X5
- MOVOU X5, 80(DI)
- MOVOU 96(SI), X6
- MOVOU X6, 96(DI)
- MOVOU 112(SI), X7
- MOVOU X7, 112(DI)
- MOVOU 128(SI), X8
- MOVOU X8, 128(DI)
- MOVOU 144(SI), X9
- MOVOU X9, 144(DI)
- MOVOU 160(SI), X10
- MOVOU X10, 160(DI)
- MOVOU 176(SI), X11
- MOVOU X11, 176(DI)
- MOVOU 192(SI), X12
- MOVOU X12, 192(DI)
- MOVOU 208(SI), X13
- MOVOU X13, 208(DI)
- MOVOU 224(SI), X14
- MOVOU X14, 224(DI)
- MOVOU 240(SI), X15
- MOVOU X15, 240(DI)
- CMPQ BX, $256
- LEAQ 256(SI), SI
- LEAQ 256(DI), DI
- JGE move_256through2048
- JMP tail
diff --git a/pkg/sentry/platform/safecopy/memcpy_arm64.s b/pkg/sentry/platform/safecopy/memcpy_arm64.s
deleted file mode 100644
index e7e541565..000000000
--- a/pkg/sentry/platform/safecopy/memcpy_arm64.s
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// handleMemcpyFault returns (the value stored in R0, the value stored in R1).
-// Control is transferred to it when memcpy below receives SIGSEGV or SIGBUS,
-// with the faulting address stored in R0 and the signal number stored in R1.
-//
-// It must have the same frame configuration as memcpy so that it can undo any
-// potential call frame set up by the assembler.
-TEXT handleMemcpyFault(SB), NOSPLIT, $0-36
- MOVD R0, addr+24(FP)
- MOVW R1, sig+32(FP)
- RET
-
-// memcpy copies data from src to dst. If a SIGSEGV or SIGBUS signal is received
-// during the copy, it returns the address that caused the fault and the number
-// of the signal that was received. Otherwise, it returns an unspecified address
-// and a signal number of 0.
-//
-// Data is copied in order, such that if a fault happens at address p, it is
-// safe to assume that all data before p-maxRegisterSize has already been
-// successfully copied.
-//
-// The code is derived from the Go source runtime.memmove.
-//
-// func memcpy(dst, src unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
-TEXT ·memcpy(SB), NOSPLIT, $-8-36
- // 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,
- // handleMemcpyFault will store a different value in this address.
- MOVW $0, sig+32(FP)
-
- MOVD to+0(FP), R3
- MOVD from+8(FP), R4
- MOVD n+16(FP), R5
- CMP $0, R5
- BNE check
- RET
-
-check:
- AND $~7, R5, R7 // R7 is N&~7.
- SUB R7, R5, R6 // R6 is N&7.
-
- // Copying forward proceeds by copying R7/8 words then copying R6 bytes.
- // R3 and R4 are advanced as we copy.
-
- // (There may be implementations of armv8 where copying by bytes until
- // at least one of source or dest is word aligned is a worthwhile
- // optimization, but the on the one tested so far (xgene) it did not
- // make a significance difference.)
-
- CMP $0, R7 // Do we need to do any word-by-word copying?
- BEQ noforwardlarge
- ADD R3, R7, R9 // R9 points just past where we copy by word.
-
-forwardlargeloop:
- MOVD.P 8(R4), R8 // R8 is just a scratch register.
- MOVD.P R8, 8(R3)
- CMP R3, R9
- BNE forwardlargeloop
-
-noforwardlarge:
- CMP $0, R6 // Do we need to do any byte-by-byte copying?
- BNE forwardtail
- RET
-
-forwardtail:
- ADD R3, R6, R9 // R9 points just past the destination memory.
-
-forwardtailloop:
- MOVBU.P 1(R4), R8
- MOVBU.P R8, 1(R3)
- CMP R3, R9
- BNE forwardtailloop
- RET
diff --git a/pkg/sentry/platform/safecopy/safecopy.go b/pkg/sentry/platform/safecopy/safecopy.go
deleted file mode 100644
index 2fb7e5809..000000000
--- a/pkg/sentry/platform/safecopy/safecopy.go
+++ /dev/null
@@ -1,144 +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 safecopy provides an efficient implementation of functions to access
-// memory that may result in SIGSEGV or SIGBUS being sent to the accessor.
-package safecopy
-
-import (
- "fmt"
- "reflect"
- "runtime"
- "syscall"
-
- "gvisor.dev/gvisor/pkg/syserror"
-)
-
-// SegvError is returned when a safecopy function receives SIGSEGV.
-type SegvError struct {
- // Addr is the address at which the SIGSEGV occurred.
- Addr uintptr
-}
-
-// Error implements error.Error.
-func (e SegvError) Error() string {
- return fmt.Sprintf("SIGSEGV at %#x", e.Addr)
-}
-
-// BusError is returned when a safecopy function receives SIGBUS.
-type BusError struct {
- // Addr is the address at which the SIGBUS occurred.
- Addr uintptr
-}
-
-// Error implements error.Error.
-func (e BusError) Error() string {
- return fmt.Sprintf("SIGBUS at %#x", e.Addr)
-}
-
-// AlignmentError is returned when a safecopy function is passed an address
-// that does not meet alignment requirements.
-type AlignmentError struct {
- // Addr is the invalid address.
- Addr uintptr
-
- // Alignment is the required alignment.
- Alignment uintptr
-}
-
-// Error implements error.Error.
-func (e AlignmentError) Error() string {
- return fmt.Sprintf("address %#x is not aligned to a %d-byte boundary", e.Addr, e.Alignment)
-}
-
-var (
- // The begin and end addresses below are for the functions that are
- // checked by the signal handler.
- memcpyBegin uintptr
- memcpyEnd uintptr
- memclrBegin uintptr
- memclrEnd uintptr
- swapUint32Begin uintptr
- swapUint32End uintptr
- swapUint64Begin uintptr
- 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
- // when we get a SIGSEGV that is not interesting to us.
- savedSigSegVHandler uintptr
-
- // same a above, but for SIGBUS signals.
- savedSigBusHandler uintptr
-)
-
-// signalHandler is our replacement signal handler for SIGSEGV and SIGBUS
-// signals.
-func signalHandler()
-
-// FindEndAddress returns the end address (one byte beyond the last) of the
-// function that contains the specified address (begin).
-func FindEndAddress(begin uintptr) uintptr {
- f := runtime.FuncForPC(begin)
- if f != nil {
- for p := begin; ; p++ {
- g := runtime.FuncForPC(p)
- if f != g {
- return p
- }
- }
- }
- return begin
-}
-
-// initializeAddresses initializes the addresses used by the signal handler.
-func initializeAddresses() {
- // The following functions are written in assembly language, so they won't
- // be inlined by the existing compiler/linker. Tests will fail if this
- // assumption is violated.
- memcpyBegin = reflect.ValueOf(memcpy).Pointer()
- memcpyEnd = FindEndAddress(memcpyBegin)
- memclrBegin = reflect.ValueOf(memclr).Pointer()
- memclrEnd = FindEndAddress(memclrBegin)
- swapUint32Begin = reflect.ValueOf(swapUint32).Pointer()
- swapUint32End = FindEndAddress(swapUint32Begin)
- swapUint64Begin = reflect.ValueOf(swapUint64).Pointer()
- swapUint64End = FindEndAddress(swapUint64Begin)
- compareAndSwapUint32Begin = reflect.ValueOf(compareAndSwapUint32).Pointer()
- compareAndSwapUint32End = FindEndAddress(compareAndSwapUint32Begin)
- loadUint32Begin = reflect.ValueOf(loadUint32).Pointer()
- loadUint32End = FindEndAddress(loadUint32Begin)
-}
-
-func init() {
- initializeAddresses()
- if err := ReplaceSignalHandler(syscall.SIGSEGV, reflect.ValueOf(signalHandler).Pointer(), &savedSigSegVHandler); err != nil {
- panic(fmt.Sprintf("Unable to set handler for SIGSEGV: %v", err))
- }
- if err := ReplaceSignalHandler(syscall.SIGBUS, reflect.ValueOf(signalHandler).Pointer(), &savedSigBusHandler); err != nil {
- panic(fmt.Sprintf("Unable to set handler for SIGBUS: %v", err))
- }
- syserror.AddErrorUnwrapper(func(e error) (syscall.Errno, bool) {
- switch e.(type) {
- case SegvError, BusError, AlignmentError:
- return syscall.EFAULT, true
- default:
- return 0, false
- }
- })
-}
diff --git a/pkg/sentry/platform/safecopy/safecopy_test.go b/pkg/sentry/platform/safecopy/safecopy_test.go
deleted file mode 100644
index 5818f7f9b..000000000
--- a/pkg/sentry/platform/safecopy/safecopy_test.go
+++ /dev/null
@@ -1,617 +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 safecopy
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "math/rand"
- "os"
- "runtime/debug"
- "syscall"
- "testing"
- "unsafe"
-)
-
-// Size of a page in bytes. Cloned from usermem.PageSize to avoid a circular
-// dependency.
-const pageSize = 4096
-
-func initRandom(b []byte) {
- for i := range b {
- b[i] = byte(rand.Intn(256))
- }
-}
-
-func randBuf(size int) []byte {
- b := make([]byte, size)
- initRandom(b)
- return b
-}
-
-func TestCopyInSuccess(t *testing.T) {
- // Test that CopyIn does not return an error when all pages are accessible.
- const bufLen = 8192
- a := randBuf(bufLen)
- b := make([]byte, bufLen)
-
- n, err := CopyIn(b, unsafe.Pointer(&a[0]))
- if n != bufLen {
- t.Errorf("Unexpected copy length, got %v, want %v", n, bufLen)
- }
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if !bytes.Equal(a, b) {
- t.Errorf("Buffers are not equal when they should be: %v %v", a, b)
- }
-}
-
-func TestCopyOutSuccess(t *testing.T) {
- // Test that CopyOut does not return an error when all pages are
- // accessible.
- const bufLen = 8192
- a := randBuf(bufLen)
- b := make([]byte, bufLen)
-
- n, err := CopyOut(unsafe.Pointer(&b[0]), a)
- if n != bufLen {
- t.Errorf("Unexpected copy length, got %v, want %v", n, bufLen)
- }
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if !bytes.Equal(a, b) {
- t.Errorf("Buffers are not equal when they should be: %v %v", a, b)
- }
-}
-
-func TestCopySuccess(t *testing.T) {
- // Test that Copy does not return an error when all pages are accessible.
- const bufLen = 8192
- a := randBuf(bufLen)
- b := make([]byte, bufLen)
-
- n, err := Copy(unsafe.Pointer(&b[0]), unsafe.Pointer(&a[0]), bufLen)
- if n != bufLen {
- t.Errorf("Unexpected copy length, got %v, want %v", n, bufLen)
- }
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if !bytes.Equal(a, b) {
- t.Errorf("Buffers are not equal when they should be: %v %v", a, b)
- }
-}
-
-func TestZeroOutSuccess(t *testing.T) {
- // Test that ZeroOut does not return an error when all pages are
- // accessible.
- const bufLen = 8192
- a := make([]byte, bufLen)
- b := randBuf(bufLen)
-
- n, err := ZeroOut(unsafe.Pointer(&b[0]), bufLen)
- if n != bufLen {
- t.Errorf("Unexpected copy length, got %v, want %v", n, bufLen)
- }
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if !bytes.Equal(a, b) {
- t.Errorf("Buffers are not equal when they should be: %v %v", a, b)
- }
-}
-
-func TestSwapUint32Success(t *testing.T) {
- // Test that SwapUint32 does not return an error when the page is
- // accessible.
- before := uint32(rand.Int31())
- after := uint32(rand.Int31())
- val := before
-
- old, err := SwapUint32(unsafe.Pointer(&val), after)
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if old != before {
- t.Errorf("Unexpected old value: got %v, want %v", old, before)
- }
- if val != after {
- t.Errorf("Unexpected new value: got %v, want %v", val, after)
- }
-}
-
-func TestSwapUint32AlignmentError(t *testing.T) {
- // Test that SwapUint32 returns an AlignmentError when passed an unaligned
- // address.
- data := new(struct{ val uint64 })
- addr := uintptr(unsafe.Pointer(&data.val)) + 1
- want := AlignmentError{Addr: addr, Alignment: 4}
- if _, err := SwapUint32(unsafe.Pointer(addr), 1); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
-}
-
-func TestSwapUint64Success(t *testing.T) {
- // Test that SwapUint64 does not return an error when the page is
- // accessible.
- before := uint64(rand.Int63())
- after := uint64(rand.Int63())
- // "The first word in ... an allocated struct or slice can be relied upon
- // to be 64-bit aligned." - sync/atomic docs
- data := new(struct{ val uint64 })
- data.val = before
-
- old, err := SwapUint64(unsafe.Pointer(&data.val), after)
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if old != before {
- t.Errorf("Unexpected old value: got %v, want %v", old, before)
- }
- if data.val != after {
- t.Errorf("Unexpected new value: got %v, want %v", data.val, after)
- }
-}
-
-func TestSwapUint64AlignmentError(t *testing.T) {
- // Test that SwapUint64 returns an AlignmentError when passed an unaligned
- // address.
- data := new(struct{ val1, val2 uint64 })
- addr := uintptr(unsafe.Pointer(&data.val1)) + 1
- want := AlignmentError{Addr: addr, Alignment: 8}
- if _, err := SwapUint64(unsafe.Pointer(addr), 1); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
-}
-
-func TestCompareAndSwapUint32Success(t *testing.T) {
- // Test that CompareAndSwapUint32 does not return an error when the page is
- // accessible.
- before := uint32(rand.Int31())
- after := uint32(rand.Int31())
- val := before
-
- old, err := CompareAndSwapUint32(unsafe.Pointer(&val), before, after)
- if err != nil {
- t.Errorf("Unexpected error: %v", err)
- }
- if old != before {
- t.Errorf("Unexpected old value: got %v, want %v", old, before)
- }
- if val != after {
- t.Errorf("Unexpected new value: got %v, want %v", val, after)
- }
-}
-
-func TestCompareAndSwapUint32AlignmentError(t *testing.T) {
- // Test that CompareAndSwapUint32 returns an AlignmentError when passed an
- // unaligned address.
- data := new(struct{ val uint64 })
- addr := uintptr(unsafe.Pointer(&data.val)) + 1
- want := AlignmentError{Addr: addr, Alignment: 4}
- if _, err := CompareAndSwapUint32(unsafe.Pointer(addr), 0, 1); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
-}
-
-// withSegvErrorTestMapping calls fn with a two-page mapping. The first page
-// contains random data, and the second page generates SIGSEGV when accessed.
-func withSegvErrorTestMapping(t *testing.T, fn func(m []byte)) {
- mapping, err := syscall.Mmap(-1, 0, 2*pageSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANONYMOUS|syscall.MAP_PRIVATE)
- if err != nil {
- t.Fatalf("Mmap failed: %v", err)
- }
- defer syscall.Munmap(mapping)
- if err := syscall.Mprotect(mapping[pageSize:], syscall.PROT_NONE); err != nil {
- t.Fatalf("Mprotect failed: %v", err)
- }
- initRandom(mapping[:pageSize])
-
- fn(mapping)
-}
-
-// withBusErrorTestMapping calls fn with a two-page mapping. The first page
-// contains random data, and the second page generates SIGBUS when accessed.
-func withBusErrorTestMapping(t *testing.T, fn func(m []byte)) {
- f, err := ioutil.TempFile("", "sigbus_test")
- if err != nil {
- t.Fatalf("TempFile failed: %v", err)
- }
- defer f.Close()
- if err := f.Truncate(pageSize); err != nil {
- t.Fatalf("Truncate failed: %v", err)
- }
- mapping, err := syscall.Mmap(int(f.Fd()), 0, 2*pageSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
- if err != nil {
- t.Fatalf("Mmap failed: %v", err)
- }
- defer syscall.Munmap(mapping)
- initRandom(mapping[:pageSize])
-
- fn(mapping)
-}
-
-func TestCopyInSegvError(t *testing.T) {
- // Test that CopyIn returns a SegvError when reaching a page that signals
- // SIGSEGV.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGSEGV", bytesBeforeFault), func(t *testing.T) {
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- src := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- dst := randBuf(pageSize)
- n, err := CopyIn(dst, src)
- if n != bytesBeforeFault {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := dst[:bytesBeforeFault], mapping[pageSize-bytesBeforeFault:pageSize]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopyInBusError(t *testing.T) {
- // Test that CopyIn returns a BusError when reaching a page that signals
- // SIGBUS.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGBUS", bytesBeforeFault), func(t *testing.T) {
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- src := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- dst := randBuf(pageSize)
- n, err := CopyIn(dst, src)
- if n != bytesBeforeFault {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := dst[:bytesBeforeFault], mapping[pageSize-bytesBeforeFault:pageSize]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopyOutSegvError(t *testing.T) {
- // Test that CopyOut returns a SegvError when reaching a page that signals
- // SIGSEGV.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGSEGV", bytesBeforeFault), func(t *testing.T) {
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- dst := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- src := randBuf(pageSize)
- n, err := CopyOut(dst, src)
- if n != bytesBeforeFault {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := mapping[pageSize-bytesBeforeFault:pageSize], src[:bytesBeforeFault]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopyOutBusError(t *testing.T) {
- // Test that CopyOut returns a BusError when reaching a page that signals
- // SIGBUS.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGSEGV", bytesBeforeFault), func(t *testing.T) {
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- dst := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- src := randBuf(pageSize)
- n, err := CopyOut(dst, src)
- if n != bytesBeforeFault {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := mapping[pageSize-bytesBeforeFault:pageSize], src[:bytesBeforeFault]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopySourceSegvError(t *testing.T) {
- // Test that Copy returns a SegvError when copying from a page that signals
- // SIGSEGV.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGSEGV", bytesBeforeFault), func(t *testing.T) {
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- src := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- dst := randBuf(pageSize)
- n, err := Copy(unsafe.Pointer(&dst[0]), src, pageSize)
- if n != uintptr(bytesBeforeFault) {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := dst[:bytesBeforeFault], mapping[pageSize-bytesBeforeFault:pageSize]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopySourceBusError(t *testing.T) {
- // Test that Copy returns a BusError when copying from a page that signals
- // SIGBUS.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGBUS", bytesBeforeFault), func(t *testing.T) {
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- src := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- dst := randBuf(pageSize)
- n, err := Copy(unsafe.Pointer(&dst[0]), src, pageSize)
- if n != uintptr(bytesBeforeFault) {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := dst[:bytesBeforeFault], mapping[pageSize-bytesBeforeFault:pageSize]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopyDestinationSegvError(t *testing.T) {
- // Test that Copy returns a SegvError when copying to a page that signals
- // SIGSEGV.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGSEGV", bytesBeforeFault), func(t *testing.T) {
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- dst := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- src := randBuf(pageSize)
- n, err := Copy(dst, unsafe.Pointer(&src[0]), pageSize)
- if n != uintptr(bytesBeforeFault) {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := mapping[pageSize-bytesBeforeFault:pageSize], src[:bytesBeforeFault]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestCopyDestinationBusError(t *testing.T) {
- // Test that Copy returns a BusError when copying to a page that signals
- // SIGBUS.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting copy %d bytes before SIGBUS", bytesBeforeFault), func(t *testing.T) {
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- dst := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- src := randBuf(pageSize)
- n, err := Copy(dst, unsafe.Pointer(&src[0]), pageSize)
- if n != uintptr(bytesBeforeFault) {
- t.Errorf("Unexpected copy length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := mapping[pageSize-bytesBeforeFault:pageSize], src[:bytesBeforeFault]; !bytes.Equal(got, want) {
- t.Errorf("Buffers are not equal when they should be: %v %v", got, want)
- }
- })
- })
- }
-}
-
-func TestZeroOutSegvError(t *testing.T) {
- // Test that ZeroOut returns a SegvError when reaching a page that signals
- // SIGSEGV.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting write %d bytes before SIGSEGV", bytesBeforeFault), func(t *testing.T) {
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- dst := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- n, err := ZeroOut(dst, pageSize)
- if n != uintptr(bytesBeforeFault) {
- t.Errorf("Unexpected write length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := mapping[pageSize-bytesBeforeFault:pageSize], make([]byte, bytesBeforeFault); !bytes.Equal(got, want) {
- t.Errorf("Non-zero bytes in written part of mapping: %v", got)
- }
- })
- })
- }
-}
-
-func TestZeroOutBusError(t *testing.T) {
- // Test that ZeroOut returns a BusError when reaching a page that signals
- // SIGBUS.
- for bytesBeforeFault := 0; bytesBeforeFault <= 2*maxRegisterSize; bytesBeforeFault++ {
- t.Run(fmt.Sprintf("starting write %d bytes before SIGBUS", bytesBeforeFault), func(t *testing.T) {
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- dst := unsafe.Pointer(secondPage - uintptr(bytesBeforeFault))
- n, err := ZeroOut(dst, pageSize)
- if n != uintptr(bytesBeforeFault) {
- t.Errorf("Unexpected write length: got %v, want %v", n, bytesBeforeFault)
- }
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- if got, want := mapping[pageSize-bytesBeforeFault:pageSize], make([]byte, bytesBeforeFault); !bytes.Equal(got, want) {
- t.Errorf("Non-zero bytes in written part of mapping: %v", got)
- }
- })
- })
- }
-}
-
-func TestSwapUint32SegvError(t *testing.T) {
- // Test that SwapUint32 returns a SegvError when reaching a page that
- // signals SIGSEGV.
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- _, err := SwapUint32(unsafe.Pointer(secondPage), 1)
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- })
-}
-
-func TestSwapUint32BusError(t *testing.T) {
- // Test that SwapUint32 returns a BusError when reaching a page that
- // signals SIGBUS.
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- _, err := SwapUint32(unsafe.Pointer(secondPage), 1)
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- })
-}
-
-func TestSwapUint64SegvError(t *testing.T) {
- // Test that SwapUint64 returns a SegvError when reaching a page that
- // signals SIGSEGV.
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- _, err := SwapUint64(unsafe.Pointer(secondPage), 1)
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- })
-}
-
-func TestSwapUint64BusError(t *testing.T) {
- // Test that SwapUint64 returns a BusError when reaching a page that
- // signals SIGBUS.
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- _, err := SwapUint64(unsafe.Pointer(secondPage), 1)
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- })
-}
-
-func TestCompareAndSwapUint32SegvError(t *testing.T) {
- // Test that CompareAndSwapUint32 returns a SegvError when reaching a page
- // that signals SIGSEGV.
- withSegvErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- _, err := CompareAndSwapUint32(unsafe.Pointer(secondPage), 0, 1)
- if want := (SegvError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- })
-}
-
-func TestCompareAndSwapUint32BusError(t *testing.T) {
- // Test that CompareAndSwapUint32 returns a BusError when reaching a page
- // that signals SIGBUS.
- withBusErrorTestMapping(t, func(mapping []byte) {
- secondPage := uintptr(unsafe.Pointer(&mapping[0])) + pageSize
- _, err := CompareAndSwapUint32(unsafe.Pointer(secondPage), 0, 1)
- if want := (BusError{secondPage}); err != want {
- t.Errorf("Unexpected error: got %v, want %v", err, want)
- }
- })
-}
-
-func testCopy(dst, src []byte) (panicked bool) {
- defer func() {
- if r := recover(); r != nil {
- panicked = true
- }
- }()
- debug.SetPanicOnFault(true)
- copy(dst, src)
- return
-}
-
-func TestSegVOnMemmove(t *testing.T) {
- // Test that SIGSEGVs received by runtime.memmove when *not* doing
- // CopyIn or CopyOut work gets propagated to the runtime.
- const bufLen = pageSize
- a, err := syscall.Mmap(-1, 0, bufLen, syscall.PROT_NONE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
- if err != nil {
- t.Fatalf("Mmap failed: %v", err)
-
- }
- defer syscall.Munmap(a)
- b := randBuf(bufLen)
-
- if !testCopy(b, a) {
- t.Fatalf("testCopy didn't panic when it should have")
- }
-
- if !testCopy(a, b) {
- t.Fatalf("testCopy didn't panic when it should have")
- }
-}
-
-func TestSigbusOnMemmove(t *testing.T) {
- // Test that SIGBUS received by runtime.memmove when *not* doing
- // CopyIn or CopyOut work gets propagated to the runtime.
- const bufLen = pageSize
- f, err := ioutil.TempFile("", "sigbus_test")
- if err != nil {
- t.Fatalf("TempFile failed: %v", err)
- }
- os.Remove(f.Name())
- defer f.Close()
-
- a, err := syscall.Mmap(int(f.Fd()), 0, bufLen, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
- if err != nil {
- t.Fatalf("Mmap failed: %v", err)
-
- }
- defer syscall.Munmap(a)
- b := randBuf(bufLen)
-
- if !testCopy(b, a) {
- t.Fatalf("testCopy didn't panic when it should have")
- }
-
- if !testCopy(a, b) {
- t.Fatalf("testCopy didn't panic when it should have")
- }
-}
diff --git a/pkg/sentry/platform/safecopy/safecopy_unsafe.go b/pkg/sentry/platform/safecopy/safecopy_unsafe.go
deleted file mode 100644
index eef028e68..000000000
--- a/pkg/sentry/platform/safecopy/safecopy_unsafe.go
+++ /dev/null
@@ -1,335 +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 safecopy
-
-import (
- "fmt"
- "syscall"
- "unsafe"
-)
-
-// maxRegisterSize is the maximum register size used in memcpy and memclr. It
-// is used to decide by how much to rewind the copy (for memcpy) or zeroing
-// (for memclr) before proceeding.
-const maxRegisterSize = 16
-
-// memcpy copies data from src to dst. If a SIGSEGV or SIGBUS signal is received
-// during the copy, it returns the address that caused the fault and the number
-// of the signal that was received. Otherwise, it returns an unspecified address
-// and a signal number of 0.
-//
-// Data is copied in order, such that if a fault happens at address p, it is
-// safe to assume that all data before p-maxRegisterSize has already been
-// successfully copied.
-//
-//go:noescape
-func memcpy(dst, src unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
-
-// memclr sets the n bytes following ptr to zeroes. If a SIGSEGV or SIGBUS
-// signal is received during the write, it returns the address that caused the
-// fault and the number of the signal that was received. Otherwise, it returns
-// an unspecified address and a signal number of 0.
-//
-// Data is written in order, such that if a fault happens at address p, it is
-// safe to assume that all data before p-maxRegisterSize has already been
-// successfully written.
-//
-//go:noescape
-func memclr(ptr unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
-
-// swapUint32 atomically stores new into *ptr and returns (the previous *ptr
-// value, 0). If a SIGSEGV or SIGBUS signal is received during the swap, the
-// value of old is unspecified, and sig is the number of the signal that was
-// received.
-//
-// Preconditions: ptr must be aligned to a 4-byte boundary.
-//
-//go:noescape
-func swapUint32(ptr unsafe.Pointer, new uint32) (old uint32, sig int32)
-
-// swapUint64 atomically stores new into *ptr and returns (the previous *ptr
-// value, 0). If a SIGSEGV or SIGBUS signal is received during the swap, the
-// value of old is unspecified, and sig is the number of the signal that was
-// received.
-//
-// Preconditions: ptr must be aligned to a 8-byte boundary.
-//
-//go:noescape
-func swapUint64(ptr unsafe.Pointer, new uint64) (old uint64, sig int32)
-
-// compareAndSwapUint32 is like sync/atomic.CompareAndSwapUint32, but returns
-// (the value previously stored at ptr, 0). If a SIGSEGV or SIGBUS signal is
-// received during the operation, the value of prev is unspecified, and sig is
-// the number of the signal that was received.
-//
-// Preconditions: ptr must be aligned to a 4-byte boundary.
-//
-//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) {
- toCopy := uintptr(len(dst))
- if len(dst) == 0 {
- return 0, nil
- }
-
- fault, sig := memcpy(unsafe.Pointer(&dst[0]), src, toCopy)
- if sig == 0 {
- return len(dst), nil
- }
-
- faultN, srcN := uintptr(fault), uintptr(src)
- if faultN < srcN || faultN >= srcN+toCopy {
- panic(fmt.Sprintf("CopyIn raised signal %d at %#x, which is outside source [%#x, %#x)", sig, faultN, srcN, srcN+toCopy))
- }
-
- // memcpy might have ended the copy up to maxRegisterSize bytes before
- // fault, if an instruction caused a memory access that straddled two
- // pages, and the second one faulted. Try to copy up to the fault.
- var done int
- if faultN-srcN > maxRegisterSize {
- done = int(faultN - srcN - maxRegisterSize)
- }
- n, err := CopyIn(dst[done:int(faultN-srcN)], unsafe.Pointer(srcN+uintptr(done)))
- done += n
- if err != nil {
- return done, err
- }
- return done, errorFromFaultSignal(fault, sig)
-}
-
-// CopyOut copies len(src) bytes from src to dst. If returns the number of
-// bytes done and an error if SIGSEGV or SIGBUS is received while writing to
-// dst.
-func CopyOut(dst unsafe.Pointer, src []byte) (int, error) {
- toCopy := uintptr(len(src))
- if toCopy == 0 {
- return 0, nil
- }
-
- fault, sig := memcpy(dst, unsafe.Pointer(&src[0]), toCopy)
- if sig == 0 {
- return len(src), nil
- }
-
- faultN, dstN := uintptr(fault), uintptr(dst)
- if faultN < dstN || faultN >= dstN+toCopy {
- panic(fmt.Sprintf("CopyOut raised signal %d at %#x, which is outside destination [%#x, %#x)", sig, faultN, dstN, dstN+toCopy))
- }
-
- // memcpy might have ended the copy up to maxRegisterSize bytes before
- // fault, if an instruction caused a memory access that straddled two
- // pages, and the second one faulted. Try to copy up to the fault.
- var done int
- if faultN-dstN > maxRegisterSize {
- done = int(faultN - dstN - maxRegisterSize)
- }
- n, err := CopyOut(unsafe.Pointer(dstN+uintptr(done)), src[done:int(faultN-dstN)])
- done += n
- if err != nil {
- return done, err
- }
- return done, errorFromFaultSignal(fault, sig)
-}
-
-// Copy copies toCopy 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
-// or writing to dst.
-//
-// Data is copied in order; if [src, src+toCopy) and [dst, dst+toCopy) overlap,
-// the resulting contents of dst are unspecified.
-func Copy(dst, src unsafe.Pointer, toCopy uintptr) (uintptr, error) {
- if toCopy == 0 {
- return 0, nil
- }
-
- fault, sig := memcpy(dst, src, toCopy)
- if sig == 0 {
- return toCopy, nil
- }
-
- // Did the fault occur while reading from src or writing to dst?
- faultN, srcN, dstN := uintptr(fault), uintptr(src), uintptr(dst)
- faultAfterSrc := ^uintptr(0)
- if faultN >= srcN {
- faultAfterSrc = faultN - srcN
- }
- faultAfterDst := ^uintptr(0)
- if faultN >= dstN {
- faultAfterDst = faultN - dstN
- }
- if faultAfterSrc >= toCopy && faultAfterDst >= toCopy {
- panic(fmt.Sprintf("Copy raised signal %d at %#x, which is outside source [%#x, %#x) and destination [%#x, %#x)", sig, faultN, srcN, srcN+toCopy, dstN, dstN+toCopy))
- }
- faultedAfter := faultAfterSrc
- if faultedAfter > faultAfterDst {
- faultedAfter = faultAfterDst
- }
-
- // memcpy might have ended the copy up to maxRegisterSize bytes before
- // fault, if an instruction caused a memory access that straddled two
- // pages, and the second one faulted. Try to copy up to the fault.
- var done uintptr
- if faultedAfter > maxRegisterSize {
- done = faultedAfter - maxRegisterSize
- }
- n, err := Copy(unsafe.Pointer(dstN+done), unsafe.Pointer(srcN+done), faultedAfter-done)
- done += n
- if err != nil {
- return done, err
- }
- return done, errorFromFaultSignal(fault, sig)
-}
-
-// ZeroOut writes toZero zero bytes to dst. It returns the number of bytes
-// written and an error if SIGSEGV or SIGBUS is received while writing to dst.
-func ZeroOut(dst unsafe.Pointer, toZero uintptr) (uintptr, error) {
- if toZero == 0 {
- return 0, nil
- }
-
- fault, sig := memclr(dst, toZero)
- if sig == 0 {
- return toZero, nil
- }
-
- faultN, dstN := uintptr(fault), uintptr(dst)
- if faultN < dstN || faultN >= dstN+toZero {
- panic(fmt.Sprintf("ZeroOut raised signal %d at %#x, which is outside destination [%#x, %#x)", sig, faultN, dstN, dstN+toZero))
- }
-
- // memclr might have ended the write up to maxRegisterSize bytes before
- // fault, if an instruction caused a memory access that straddled two
- // pages, and the second one faulted. Try to write up to the fault.
- var done uintptr
- if faultN-dstN > maxRegisterSize {
- done = faultN - dstN - maxRegisterSize
- }
- n, err := ZeroOut(unsafe.Pointer(dstN+done), faultN-dstN-done)
- done += n
- if err != nil {
- return done, err
- }
- return done, errorFromFaultSignal(fault, sig)
-}
-
-// SwapUint32 is equivalent to sync/atomic.SwapUint32, except that it returns
-// an error if SIGSEGV or SIGBUS is received while accessing ptr, or if ptr is
-// not aligned to a 4-byte boundary.
-func SwapUint32(ptr unsafe.Pointer, new uint32) (uint32, error) {
- if addr := uintptr(ptr); addr&3 != 0 {
- return 0, AlignmentError{addr, 4}
- }
- old, sig := swapUint32(ptr, new)
- return old, errorFromFaultSignal(ptr, sig)
-}
-
-// SwapUint64 is equivalent to sync/atomic.SwapUint64, except that it returns
-// an error if SIGSEGV or SIGBUS is received while accessing ptr, or if ptr is
-// not aligned to an 8-byte boundary.
-func SwapUint64(ptr unsafe.Pointer, new uint64) (uint64, error) {
- if addr := uintptr(ptr); addr&7 != 0 {
- return 0, AlignmentError{addr, 8}
- }
- old, sig := swapUint64(ptr, new)
- return old, errorFromFaultSignal(ptr, sig)
-}
-
-// CompareAndSwapUint32 is equivalent to atomicbitops.CompareAndSwapUint32,
-// except that it returns an error if SIGSEGV or SIGBUS is received while
-// accessing ptr, or if ptr is not aligned to a 4-byte boundary.
-func CompareAndSwapUint32(ptr unsafe.Pointer, old, new uint32) (uint32, error) {
- if addr := uintptr(ptr); addr&3 != 0 {
- return 0, AlignmentError{addr, 4}
- }
- prev, sig := compareAndSwapUint32(ptr, old, new)
- 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:
- return nil
- case int32(syscall.SIGSEGV):
- return SegvError{uintptr(addr)}
- case int32(syscall.SIGBUS):
- return BusError{uintptr(addr)}
- default:
- panic(fmt.Sprintf("safecopy got unexpected signal %d at address %#x", sig, addr))
- }
-}
-
-// ReplaceSignalHandler replaces the existing signal handler for the provided
-// signal with the one that handles faults in safecopy-protected functions.
-//
-// It stores the value of the previously set handler in previous.
-//
-// This function will be called on initialization in order to install safecopy
-// handlers for appropriate signals. These handlers will call the previous
-// handler however, and if this is function is being used externally then the
-// same courtesy is expected.
-func ReplaceSignalHandler(sig syscall.Signal, handler uintptr, previous *uintptr) error {
- var sa struct {
- handler uintptr
- flags uint64
- restorer uintptr
- mask uint64
- }
- const maskLen = 8
-
- // Get the existing signal handler information, and save the current
- // handler. Once we replace it, we will use this pointer to fall back to
- // it when we receive other signals.
- if _, _, e := syscall.RawSyscall6(syscall.SYS_RT_SIGACTION, uintptr(sig), 0, uintptr(unsafe.Pointer(&sa)), maskLen, 0, 0); e != 0 {
- return e
- }
-
- // Fail if there isn't a previous handler.
- if sa.handler == 0 {
- return fmt.Errorf("previous handler for signal %x isn't set", sig)
- }
-
- *previous = sa.handler
-
- // Install our own handler.
- sa.handler = handler
- if _, _, e := syscall.RawSyscall6(syscall.SYS_RT_SIGACTION, uintptr(sig), uintptr(unsafe.Pointer(&sa)), 0, maskLen, 0, 0); e != 0 {
- return e
- }
-
- return nil
-}
diff --git a/pkg/sentry/platform/safecopy/sighandler_amd64.s b/pkg/sentry/platform/safecopy/sighandler_amd64.s
deleted file mode 100644
index 475ae48e9..000000000
--- a/pkg/sentry/platform/safecopy/sighandler_amd64.s
+++ /dev/null
@@ -1,133 +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.
-
-#include "textflag.h"
-
-// The signals handled by sigHandler.
-#define SIGBUS 7
-#define SIGSEGV 11
-
-// Offsets to the registers in context->uc_mcontext.gregs[].
-#define REG_RDI 0x68
-#define REG_RAX 0x90
-#define REG_IP 0xa8
-
-// Offset to the si_addr field of siginfo.
-#define SI_CODE 0x08
-#define SI_ADDR 0x10
-
-// signalHandler is the signal handler for SIGSEGV and SIGBUS signals. It must
-// not be set up as a handler to any other signals.
-//
-// If the instruction causing the signal is within a safecopy-protected
-// function, the signal is handled such that execution resumes in the
-// appropriate fault handling stub with AX containing the faulting address and
-// DI containing the signal number. Otherwise control is transferred to the
-// previously configured signal handler (savedSigSegvHandler or
-// savedSigBusHandler).
-//
-// This function cannot be written in go because it runs whenever a signal is
-// received by the thread (preempting whatever was running), which includes when
-// garbage collector has stopped or isn't expecting any interactions (like
-// barriers).
-//
-// The arguments are the following:
-// DI - The signal number.
-// SI - Pointer to siginfo_t structure.
-// DX - Pointer to ucontext structure.
-TEXT ·signalHandler(SB),NOSPLIT,$0
- // Check if the signal is from the kernel.
- MOVQ $0x0, CX
- CMPL CX, SI_CODE(SI)
- JGE original_handler
-
- // Check if RIP is within the area we care about.
- MOVQ REG_IP(DX), CX
- CMPQ CX, ·memcpyBegin(SB)
- JB not_memcpy
- CMPQ CX, ·memcpyEnd(SB)
- JAE not_memcpy
-
- // Modify the context such that execution will resume in the fault
- // handler.
- LEAQ handleMemcpyFault(SB), CX
- JMP handle_fault
-
-not_memcpy:
- CMPQ CX, ·memclrBegin(SB)
- JB not_memclr
- CMPQ CX, ·memclrEnd(SB)
- JAE not_memclr
-
- LEAQ handleMemclrFault(SB), CX
- JMP handle_fault
-
-not_memclr:
- CMPQ CX, ·swapUint32Begin(SB)
- JB not_swapuint32
- CMPQ CX, ·swapUint32End(SB)
- JAE not_swapuint32
-
- LEAQ handleSwapUint32Fault(SB), CX
- JMP handle_fault
-
-not_swapuint32:
- CMPQ CX, ·swapUint64Begin(SB)
- JB not_swapuint64
- CMPQ CX, ·swapUint64End(SB)
- JAE not_swapuint64
-
- LEAQ handleSwapUint64Fault(SB), CX
- JMP handle_fault
-
-not_swapuint64:
- CMPQ CX, ·compareAndSwapUint32Begin(SB)
- JB not_casuint32
- CMPQ CX, ·compareAndSwapUint32End(SB)
- JAE not_casuint32
-
- LEAQ handleCompareAndSwapUint32Fault(SB), CX
- 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
- MOVQ ·savedSigBusHandler(SB), AX
- CMPL DI, $SIGSEGV
- CMOVQEQ ·savedSigSegVHandler(SB), AX
- JMP AX
-
-handle_fault:
- // Entered with the address of the fault handler in RCX; store it in
- // RIP.
- MOVQ CX, REG_IP(DX)
-
- // Store the faulting address in RAX.
- MOVQ SI_ADDR(SI), CX
- MOVQ CX, REG_RAX(DX)
-
- // Store the signal number in EDI.
- MOVL DI, REG_RDI(DX)
-
- RET
diff --git a/pkg/sentry/platform/safecopy/sighandler_arm64.s b/pkg/sentry/platform/safecopy/sighandler_arm64.s
deleted file mode 100644
index 53e4ac2c1..000000000
--- a/pkg/sentry/platform/safecopy/sighandler_arm64.s
+++ /dev/null
@@ -1,143 +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.
-
-#include "textflag.h"
-
-// The signals handled by sigHandler.
-#define SIGBUS 7
-#define SIGSEGV 11
-
-// Offsets to the registers in context->uc_mcontext.gregs[].
-#define REG_R0 0xB8
-#define REG_R1 0xC0
-#define REG_PC 0x1B8
-
-// Offset to the si_addr field of siginfo.
-#define SI_CODE 0x08
-#define SI_ADDR 0x10
-
-// signalHandler is the signal handler for SIGSEGV and SIGBUS signals. It must
-// not be set up as a handler to any other signals.
-//
-// If the instruction causing the signal is within a safecopy-protected
-// function, the signal is handled such that execution resumes in the
-// appropriate fault handling stub with R0 containing the faulting address and
-// R1 containing the signal number. Otherwise control is transferred to the
-// previously configured signal handler (savedSigSegvHandler or
-// savedSigBusHandler).
-//
-// This function cannot be written in go because it runs whenever a signal is
-// received by the thread (preempting whatever was running), which includes when
-// garbage collector has stopped or isn't expecting any interactions (like
-// barriers).
-//
-// The arguments are the following:
-// R0 - The signal number.
-// R1 - Pointer to siginfo_t structure.
-// R2 - Pointer to ucontext structure.
-TEXT ·signalHandler(SB),NOSPLIT,$0
- // Check if the signal is from the kernel, si_code > 0 means a kernel signal.
- MOVD SI_CODE(R1), R7
- CMPW $0x0, R7
- BLE original_handler
-
- // Check if PC is within the area we care about.
- MOVD REG_PC(R2), R7
- MOVD ·memcpyBegin(SB), R8
- CMP R8, R7
- BLO not_memcpy
- MOVD ·memcpyEnd(SB), R8
- CMP R8, R7
- BHS not_memcpy
-
- // Modify the context such that execution will resume in the fault handler.
- MOVD $handleMemcpyFault(SB), R7
- B handle_fault
-
-not_memcpy:
- MOVD ·memclrBegin(SB), R8
- CMP R8, R7
- BLO not_memclr
- MOVD ·memclrEnd(SB), R8
- CMP R8, R7
- BHS not_memclr
-
- MOVD $handleMemclrFault(SB), R7
- B handle_fault
-
-not_memclr:
- MOVD ·swapUint32Begin(SB), R8
- CMP R8, R7
- BLO not_swapuint32
- MOVD ·swapUint32End(SB), R8
- CMP R8, R7
- BHS not_swapuint32
-
- MOVD $handleSwapUint32Fault(SB), R7
- B handle_fault
-
-not_swapuint32:
- MOVD ·swapUint64Begin(SB), R8
- CMP R8, R7
- BLO not_swapuint64
- MOVD ·swapUint64End(SB), R8
- CMP R8, R7
- BHS not_swapuint64
-
- MOVD $handleSwapUint64Fault(SB), R7
- B handle_fault
-
-not_swapuint64:
- MOVD ·compareAndSwapUint32Begin(SB), R8
- CMP R8, R7
- BLO not_casuint32
- MOVD ·compareAndSwapUint32End(SB), R8
- CMP R8, R7
- BHS not_casuint32
-
- MOVD $handleCompareAndSwapUint32Fault(SB), R7
- 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
- MOVD ·savedSigSegVHandler(SB), R8
- CMPW $SIGSEGV, R0
- CSEL EQ, R8, R7, R7
- B (R7)
-
-handle_fault:
- // Entered with the address of the fault handler in R7; store it in PC.
- MOVD R7, REG_PC(R2)
-
- // Store the faulting address in R0.
- MOVD SI_ADDR(R1), R7
- MOVD R7, REG_R0(R2)
-
- // Store the signal number in R1.
- MOVW R0, REG_R1(R2)
-
- RET
diff --git a/pkg/sentry/safemem/BUILD b/pkg/sentry/safemem/BUILD
deleted file mode 100644
index 884020f7b..000000000
--- a/pkg/sentry/safemem/BUILD
+++ /dev/null
@@ -1,29 +0,0 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "safemem",
- srcs = [
- "block_unsafe.go",
- "io.go",
- "safemem.go",
- "seq_unsafe.go",
- ],
- importpath = "gvisor.dev/gvisor/pkg/sentry/safemem",
- visibility = ["//pkg/sentry:internal"],
- deps = [
- "//pkg/sentry/platform/safecopy",
- ],
-)
-
-go_test(
- name = "safemem_test",
- size = "small",
- srcs = [
- "io_test.go",
- "seq_test.go",
- ],
- embed = [":safemem"],
-)
diff --git a/pkg/sentry/safemem/block_unsafe.go b/pkg/sentry/safemem/block_unsafe.go
deleted file mode 100644
index 6f03c94bf..000000000
--- a/pkg/sentry/safemem/block_unsafe.go
+++ /dev/null
@@ -1,279 +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 safemem
-
-import (
- "fmt"
- "reflect"
- "unsafe"
-
- "gvisor.dev/gvisor/pkg/sentry/platform/safecopy"
-)
-
-// A Block is a range of contiguous bytes, similar to []byte but with the
-// following differences:
-//
-// - The memory represented by a Block may require the use of safecopy to
-// access.
-//
-// - Block does not carry a capacity and cannot be expanded.
-//
-// Blocks are immutable and may be copied by value. The zero value of Block
-// represents an empty range, analogous to a nil []byte.
-type Block struct {
- // [start, start+length) is the represented memory.
- //
- // start is an unsafe.Pointer to ensure that Block prevents the represented
- // memory from being garbage-collected.
- start unsafe.Pointer
- length int
-
- // needSafecopy is true if accessing the represented memory requires the
- // use of safecopy.
- needSafecopy bool
-}
-
-// BlockFromSafeSlice returns a Block equivalent to slice, which is safe to
-// access without safecopy.
-func BlockFromSafeSlice(slice []byte) Block {
- return blockFromSlice(slice, false)
-}
-
-// BlockFromUnsafeSlice returns a Block equivalent to bs, which is not safe to
-// access without safecopy.
-func BlockFromUnsafeSlice(slice []byte) Block {
- return blockFromSlice(slice, true)
-}
-
-func blockFromSlice(slice []byte, needSafecopy bool) Block {
- if len(slice) == 0 {
- return Block{}
- }
- return Block{
- start: unsafe.Pointer(&slice[0]),
- length: len(slice),
- needSafecopy: needSafecopy,
- }
-}
-
-// BlockFromSafePointer returns a Block equivalent to [ptr, ptr+len), which is
-// safe to access without safecopy.
-//
-// Preconditions: ptr+len does not overflow.
-func BlockFromSafePointer(ptr unsafe.Pointer, len int) Block {
- return blockFromPointer(ptr, len, false)
-}
-
-// BlockFromUnsafePointer returns a Block equivalent to [ptr, ptr+len), which
-// is not safe to access without safecopy.
-//
-// Preconditions: ptr+len does not overflow.
-func BlockFromUnsafePointer(ptr unsafe.Pointer, len int) Block {
- return blockFromPointer(ptr, len, true)
-}
-
-func blockFromPointer(ptr unsafe.Pointer, len int, needSafecopy bool) Block {
- if uptr := uintptr(ptr); uptr+uintptr(len) < uptr {
- panic(fmt.Sprintf("ptr %#x + len %#x overflows", ptr, len))
- }
- return Block{
- start: ptr,
- length: len,
- needSafecopy: needSafecopy,
- }
-}
-
-// DropFirst returns a Block equivalent to b, but with the first n bytes
-// omitted. It is analogous to the [n:] operation on a slice, except that if n
-// > b.Len(), DropFirst returns an empty Block instead of panicking.
-//
-// Preconditions: n >= 0.
-func (b Block) DropFirst(n int) Block {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- return b.DropFirst64(uint64(n))
-}
-
-// DropFirst64 is equivalent to DropFirst but takes a uint64.
-func (b Block) DropFirst64(n uint64) Block {
- if n >= uint64(b.length) {
- return Block{}
- }
- return Block{
- start: unsafe.Pointer(uintptr(b.start) + uintptr(n)),
- length: b.length - int(n),
- needSafecopy: b.needSafecopy,
- }
-}
-
-// TakeFirst returns a Block equivalent to the first n bytes of b. It is
-// analogous to the [:n] operation on a slice, except that if n > b.Len(),
-// TakeFirst returns a copy of b instead of panicking.
-//
-// Preconditions: n >= 0.
-func (b Block) TakeFirst(n int) Block {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- return b.TakeFirst64(uint64(n))
-}
-
-// TakeFirst64 is equivalent to TakeFirst but takes a uint64.
-func (b Block) TakeFirst64(n uint64) Block {
- if n == 0 {
- return Block{}
- }
- if n >= uint64(b.length) {
- return b
- }
- return Block{
- start: b.start,
- length: int(n),
- needSafecopy: b.needSafecopy,
- }
-}
-
-// ToSlice returns a []byte equivalent to b.
-func (b Block) ToSlice() []byte {
- var bs []byte
- hdr := (*reflect.SliceHeader)(unsafe.Pointer(&bs))
- hdr.Data = uintptr(b.start)
- hdr.Len = b.length
- hdr.Cap = b.length
- return bs
-}
-
-// Addr returns b's start address as a uintptr. It returns uintptr instead of
-// unsafe.Pointer so that code using safemem cannot obtain unsafe.Pointers
-// without importing the unsafe package explicitly.
-//
-// Note that a uintptr is not recognized as a pointer by the garbage collector,
-// such that if there are no uses of b after a call to b.Addr() and the address
-// is to Go-managed memory, the returned uintptr does not prevent garbage
-// collection of the pointee.
-func (b Block) Addr() uintptr {
- return uintptr(b.start)
-}
-
-// Len returns b's length in bytes.
-func (b Block) Len() int {
- return b.length
-}
-
-// NeedSafecopy returns true if accessing b.ToSlice() requires the use of safecopy.
-func (b Block) NeedSafecopy() bool {
- return b.needSafecopy
-}
-
-// String implements fmt.Stringer.String.
-func (b Block) String() string {
- if uintptr(b.start) == 0 && b.length == 0 {
- return "<nil>"
- }
- var suffix string
- if b.needSafecopy {
- suffix = "*"
- }
- return fmt.Sprintf("[%#x-%#x)%s", uintptr(b.start), uintptr(b.start)+uintptr(b.length), suffix)
-}
-
-// Copy copies src.Len() or dst.Len() bytes, whichever is less, from src
-// to dst and returns the number of bytes copied.
-//
-// If src and dst overlap, the data stored in dst is unspecified.
-func Copy(dst, src Block) (int, error) {
- if !dst.needSafecopy && !src.needSafecopy {
- return copy(dst.ToSlice(), src.ToSlice()), nil
- }
-
- n := dst.length
- if n > src.length {
- n = src.length
- }
- if n == 0 {
- return 0, nil
- }
-
- switch {
- case dst.needSafecopy && !src.needSafecopy:
- return safecopy.CopyOut(dst.start, src.TakeFirst(n).ToSlice())
- case !dst.needSafecopy && src.needSafecopy:
- return safecopy.CopyIn(dst.TakeFirst(n).ToSlice(), src.start)
- case dst.needSafecopy && src.needSafecopy:
- n64, err := safecopy.Copy(dst.start, src.start, uintptr(n))
- return int(n64), err
- default:
- panic("unreachable")
- }
-}
-
-// Zero sets all bytes in dst to 0 and returns the number of bytes zeroed.
-func Zero(dst Block) (int, error) {
- if !dst.needSafecopy {
- bs := dst.ToSlice()
- for i := range bs {
- bs[i] = 0
- }
- return len(bs), nil
- }
-
- n64, err := safecopy.ZeroOut(dst.start, uintptr(dst.length))
- return int(n64), err
-}
-
-// Safecopy atomics are no slower than non-safecopy atomics, so use the former
-// even when !b.needSafecopy to get consistent alignment checking.
-
-// SwapUint32 invokes safecopy.SwapUint32 on the first 4 bytes of b.
-//
-// Preconditions: b.Len() >= 4.
-func SwapUint32(b Block, new uint32) (uint32, error) {
- if b.length < 4 {
- panic(fmt.Sprintf("insufficient length: %d", b.length))
- }
- return safecopy.SwapUint32(b.start, new)
-}
-
-// SwapUint64 invokes safecopy.SwapUint64 on the first 8 bytes of b.
-//
-// Preconditions: b.Len() >= 8.
-func SwapUint64(b Block, new uint64) (uint64, error) {
- if b.length < 8 {
- panic(fmt.Sprintf("insufficient length: %d", b.length))
- }
- return safecopy.SwapUint64(b.start, new)
-}
-
-// CompareAndSwapUint32 invokes safecopy.CompareAndSwapUint32 on the first 4
-// bytes of b.
-//
-// Preconditions: b.Len() >= 4.
-func CompareAndSwapUint32(b Block, old, new uint32) (uint32, error) {
- if b.length < 4 {
- panic(fmt.Sprintf("insufficient length: %d", b.length))
- }
- 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/safemem/io.go b/pkg/sentry/safemem/io.go
deleted file mode 100644
index f039a5c34..000000000
--- a/pkg/sentry/safemem/io.go
+++ /dev/null
@@ -1,392 +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 safemem
-
-import (
- "errors"
- "io"
- "math"
-)
-
-// ErrEndOfBlockSeq is returned by BlockSeqWriter when attempting to write
-// beyond the end of the BlockSeq.
-var ErrEndOfBlockSeq = errors.New("write beyond end of BlockSeq")
-
-// Reader represents a streaming byte source like io.Reader.
-type Reader interface {
- // ReadToBlocks reads up to dsts.NumBytes() bytes into dsts and returns the
- // number of bytes read. It may return a partial read without an error
- // (i.e. (n, nil) where 0 < n < dsts.NumBytes()). It should not return a
- // full read with an error (i.e. (dsts.NumBytes(), err) where err != nil);
- // note that this differs from io.Reader.Read (in particular, io.EOF should
- // not be returned if ReadToBlocks successfully reads dsts.NumBytes()
- // bytes.)
- ReadToBlocks(dsts BlockSeq) (uint64, error)
-}
-
-// Writer represents a streaming byte sink like io.Writer.
-type Writer interface {
- // WriteFromBlocks writes up to srcs.NumBytes() bytes from srcs and returns
- // the number of bytes written. It may return a partial write without an
- // error (i.e. (n, nil) where 0 < n < srcs.NumBytes()). It should not
- // return a full write with an error (i.e. srcs.NumBytes(), err) where err
- // != nil).
- WriteFromBlocks(srcs BlockSeq) (uint64, error)
-}
-
-// ReadFullToBlocks repeatedly invokes r.ReadToBlocks until dsts.NumBytes()
-// bytes have been read or ReadToBlocks returns an error.
-func ReadFullToBlocks(r Reader, dsts BlockSeq) (uint64, error) {
- var done uint64
- for !dsts.IsEmpty() {
- n, err := r.ReadToBlocks(dsts)
- done += n
- if err != nil {
- return done, err
- }
- dsts = dsts.DropFirst64(n)
- }
- return done, nil
-}
-
-// WriteFullFromBlocks repeatedly invokes w.WriteFromBlocks until
-// srcs.NumBytes() bytes have been written or WriteFromBlocks returns an error.
-func WriteFullFromBlocks(w Writer, srcs BlockSeq) (uint64, error) {
- var done uint64
- for !srcs.IsEmpty() {
- n, err := w.WriteFromBlocks(srcs)
- done += n
- if err != nil {
- return done, err
- }
- srcs = srcs.DropFirst64(n)
- }
- return done, nil
-}
-
-// BlockSeqReader implements Reader by reading from a BlockSeq.
-type BlockSeqReader struct {
- Blocks BlockSeq
-}
-
-// ReadToBlocks implements Reader.ReadToBlocks.
-func (r *BlockSeqReader) ReadToBlocks(dsts BlockSeq) (uint64, error) {
- n, err := CopySeq(dsts, r.Blocks)
- r.Blocks = r.Blocks.DropFirst64(n)
- if err != nil {
- return n, err
- }
- if n < dsts.NumBytes() {
- return n, io.EOF
- }
- return n, nil
-}
-
-// BlockSeqWriter implements Writer by writing to a BlockSeq.
-type BlockSeqWriter struct {
- Blocks BlockSeq
-}
-
-// WriteFromBlocks implements Writer.WriteFromBlocks.
-func (w *BlockSeqWriter) WriteFromBlocks(srcs BlockSeq) (uint64, error) {
- n, err := CopySeq(w.Blocks, srcs)
- w.Blocks = w.Blocks.DropFirst64(n)
- if err != nil {
- return n, err
- }
- if n < srcs.NumBytes() {
- return n, ErrEndOfBlockSeq
- }
- return n, nil
-}
-
-// ReaderFunc implements Reader for a function with the semantics of
-// Reader.ReadToBlocks.
-type ReaderFunc func(dsts BlockSeq) (uint64, error)
-
-// ReadToBlocks implements Reader.ReadToBlocks.
-func (f ReaderFunc) ReadToBlocks(dsts BlockSeq) (uint64, error) {
- return f(dsts)
-}
-
-// WriterFunc implements Writer for a function with the semantics of
-// Writer.WriteFromBlocks.
-type WriterFunc func(srcs BlockSeq) (uint64, error)
-
-// WriteFromBlocks implements Writer.WriteFromBlocks.
-func (f WriterFunc) WriteFromBlocks(srcs BlockSeq) (uint64, error) {
- return f(srcs)
-}
-
-// ToIOReader implements io.Reader for a (safemem.)Reader.
-//
-// ToIOReader will return a successful partial read iff Reader.ReadToBlocks does
-// so.
-type ToIOReader struct {
- Reader Reader
-}
-
-// Read implements io.Reader.Read.
-func (r ToIOReader) Read(dst []byte) (int, error) {
- n, err := r.Reader.ReadToBlocks(BlockSeqOf(BlockFromSafeSlice(dst)))
- return int(n), err
-}
-
-// ToIOWriter implements io.Writer for a (safemem.)Writer.
-type ToIOWriter struct {
- Writer Writer
-}
-
-// Write implements io.Writer.Write.
-func (w ToIOWriter) Write(src []byte) (int, error) {
- // io.Writer does not permit partial writes.
- n, err := WriteFullFromBlocks(w.Writer, BlockSeqOf(BlockFromSafeSlice(src)))
- return int(n), err
-}
-
-// FromIOReader implements Reader for an io.Reader by repeatedly invoking
-// io.Reader.Read until it returns an error or partial read. This is not
-// thread-safe.
-//
-// FromIOReader will return a successful partial read iff Reader.Read does so.
-type FromIOReader struct {
- Reader io.Reader
-}
-
-// ReadToBlocks implements Reader.ReadToBlocks.
-func (r FromIOReader) ReadToBlocks(dsts BlockSeq) (uint64, error) {
- var buf []byte
- var done uint64
- for !dsts.IsEmpty() {
- dst := dsts.Head()
- var n int
- var err error
- n, buf, err = r.readToBlock(dst, buf)
- done += uint64(n)
- if n != dst.Len() {
- return done, err
- }
- dsts = dsts.Tail()
- if err != nil {
- if dsts.IsEmpty() && err == io.EOF {
- return done, nil
- }
- return done, err
- }
- }
- return done, nil
-}
-
-func (r FromIOReader) readToBlock(dst Block, buf []byte) (int, []byte, error) {
- // io.Reader isn't safecopy-aware, so we have to buffer Blocks that require
- // safecopy.
- if !dst.NeedSafecopy() {
- n, err := r.Reader.Read(dst.ToSlice())
- return n, buf, err
- }
- if len(buf) < dst.Len() {
- buf = make([]byte, dst.Len())
- }
- rn, rerr := r.Reader.Read(buf[:dst.Len()])
- wbn, wberr := Copy(dst, BlockFromSafeSlice(buf[:rn]))
- if wberr != nil {
- return wbn, buf, wberr
- }
- return wbn, buf, rerr
-}
-
-// FromIOReaderAt implements Reader for an io.ReaderAt. Does not repeatedly
-// invoke io.ReaderAt.ReadAt because ReadAt is more strict than Read. A partial
-// read indicates an error. This is not thread-safe.
-type FromIOReaderAt struct {
- ReaderAt io.ReaderAt
- Offset int64
-}
-
-// ReadToBlocks implements Reader.ReadToBlocks.
-func (r FromIOReaderAt) ReadToBlocks(dsts BlockSeq) (uint64, error) {
- var buf []byte
- var done uint64
- for !dsts.IsEmpty() {
- dst := dsts.Head()
- var n int
- var err error
- n, buf, err = r.readToBlock(dst, buf)
- done += uint64(n)
- if n != dst.Len() {
- return done, err
- }
- dsts = dsts.Tail()
- if err != nil {
- if dsts.IsEmpty() && err == io.EOF {
- return done, nil
- }
- return done, err
- }
- }
- return done, nil
-}
-
-func (r FromIOReaderAt) readToBlock(dst Block, buf []byte) (int, []byte, error) {
- // io.Reader isn't safecopy-aware, so we have to buffer Blocks that require
- // safecopy.
- if !dst.NeedSafecopy() {
- n, err := r.ReaderAt.ReadAt(dst.ToSlice(), r.Offset)
- r.Offset += int64(n)
- return n, buf, err
- }
- if len(buf) < dst.Len() {
- buf = make([]byte, dst.Len())
- }
- rn, rerr := r.ReaderAt.ReadAt(buf[:dst.Len()], r.Offset)
- r.Offset += int64(rn)
- wbn, wberr := Copy(dst, BlockFromSafeSlice(buf[:rn]))
- if wberr != nil {
- return wbn, buf, wberr
- }
- return wbn, buf, rerr
-}
-
-// FromIOWriter implements Writer for an io.Writer by repeatedly invoking
-// io.Writer.Write until it returns an error or partial write.
-//
-// FromIOWriter will tolerate implementations of io.Writer.Write that return
-// partial writes with a nil error in contravention of io.Writer's
-// requirements, since Writer is permitted to do so. FromIOWriter will return a
-// successful partial write iff Writer.Write does so.
-type FromIOWriter struct {
- Writer io.Writer
-}
-
-// WriteFromBlocks implements Writer.WriteFromBlocks.
-func (w FromIOWriter) WriteFromBlocks(srcs BlockSeq) (uint64, error) {
- var buf []byte
- var done uint64
- for !srcs.IsEmpty() {
- src := srcs.Head()
- var n int
- var err error
- n, buf, err = w.writeFromBlock(src, buf)
- done += uint64(n)
- if n != src.Len() || err != nil {
- return done, err
- }
- srcs = srcs.Tail()
- }
- return done, nil
-}
-
-func (w FromIOWriter) writeFromBlock(src Block, buf []byte) (int, []byte, error) {
- // io.Writer isn't safecopy-aware, so we have to buffer Blocks that require
- // safecopy.
- if !src.NeedSafecopy() {
- n, err := w.Writer.Write(src.ToSlice())
- return n, buf, err
- }
- if len(buf) < src.Len() {
- buf = make([]byte, src.Len())
- }
- bufn, buferr := Copy(BlockFromSafeSlice(buf[:src.Len()]), src)
- wn, werr := w.Writer.Write(buf[:bufn])
- if werr != nil {
- return wn, buf, werr
- }
- return wn, buf, buferr
-}
-
-// FromVecReaderFunc implements Reader for a function that reads data into a
-// [][]byte and returns the number of bytes read as an int64.
-type FromVecReaderFunc struct {
- ReadVec func(dsts [][]byte) (int64, error)
-}
-
-// ReadToBlocks implements Reader.ReadToBlocks.
-//
-// ReadToBlocks calls r.ReadVec at most once.
-func (r FromVecReaderFunc) ReadToBlocks(dsts BlockSeq) (uint64, error) {
- if dsts.IsEmpty() {
- return 0, nil
- }
- // Ensure that we don't pass a [][]byte with a total length > MaxInt64.
- dsts = dsts.TakeFirst64(uint64(math.MaxInt64))
- dstSlices := make([][]byte, 0, dsts.NumBlocks())
- // Buffer Blocks that require safecopy.
- for tmp := dsts; !tmp.IsEmpty(); tmp = tmp.Tail() {
- dst := tmp.Head()
- if dst.NeedSafecopy() {
- dstSlices = append(dstSlices, make([]byte, dst.Len()))
- } else {
- dstSlices = append(dstSlices, dst.ToSlice())
- }
- }
- rn, rerr := r.ReadVec(dstSlices)
- dsts = dsts.TakeFirst64(uint64(rn))
- var done uint64
- var i int
- for !dsts.IsEmpty() {
- dst := dsts.Head()
- if dst.NeedSafecopy() {
- n, err := Copy(dst, BlockFromSafeSlice(dstSlices[i]))
- done += uint64(n)
- if err != nil {
- return done, err
- }
- } else {
- done += uint64(dst.Len())
- }
- dsts = dsts.Tail()
- i++
- }
- return done, rerr
-}
-
-// FromVecWriterFunc implements Writer for a function that writes data from a
-// [][]byte and returns the number of bytes written.
-type FromVecWriterFunc struct {
- WriteVec func(srcs [][]byte) (int64, error)
-}
-
-// WriteFromBlocks implements Writer.WriteFromBlocks.
-//
-// WriteFromBlocks calls w.WriteVec at most once.
-func (w FromVecWriterFunc) WriteFromBlocks(srcs BlockSeq) (uint64, error) {
- if srcs.IsEmpty() {
- return 0, nil
- }
- // Ensure that we don't pass a [][]byte with a total length > MaxInt64.
- srcs = srcs.TakeFirst64(uint64(math.MaxInt64))
- srcSlices := make([][]byte, 0, srcs.NumBlocks())
- // Buffer Blocks that require safecopy.
- var buferr error
- for tmp := srcs; !tmp.IsEmpty(); tmp = tmp.Tail() {
- src := tmp.Head()
- if src.NeedSafecopy() {
- slice := make([]byte, src.Len())
- n, err := Copy(BlockFromSafeSlice(slice), src)
- srcSlices = append(srcSlices, slice[:n])
- if err != nil {
- buferr = err
- break
- }
- } else {
- srcSlices = append(srcSlices, src.ToSlice())
- }
- }
- n, err := w.WriteVec(srcSlices)
- if err != nil {
- return uint64(n), err
- }
- return uint64(n), buferr
-}
diff --git a/pkg/sentry/safemem/io_test.go b/pkg/sentry/safemem/io_test.go
deleted file mode 100644
index 629741bee..000000000
--- a/pkg/sentry/safemem/io_test.go
+++ /dev/null
@@ -1,199 +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 safemem
-
-import (
- "bytes"
- "io"
- "testing"
-)
-
-func makeBlocks(slices ...[]byte) []Block {
- blocks := make([]Block, 0, len(slices))
- for _, s := range slices {
- blocks = append(blocks, BlockFromSafeSlice(s))
- }
- return blocks
-}
-
-func TestFromIOReaderFullRead(t *testing.T) {
- r := FromIOReader{bytes.NewBufferString("foobar")}
- dsts := makeBlocks(make([]byte, 3), make([]byte, 3))
- n, err := r.ReadToBlocks(BlockSeqFromSlice(dsts))
- if wantN := uint64(6); n != wantN || err != nil {
- t.Errorf("ReadToBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- for i, want := range [][]byte{[]byte("foo"), []byte("bar")} {
- if got := dsts[i].ToSlice(); !bytes.Equal(got, want) {
- t.Errorf("dsts[%d]: got %q, wanted %q", i, got, want)
- }
- }
-}
-
-type eofHidingReader struct {
- Reader io.Reader
-}
-
-func (r eofHidingReader) Read(dst []byte) (int, error) {
- n, err := r.Reader.Read(dst)
- if err == io.EOF {
- return n, nil
- }
- return n, err
-}
-
-func TestFromIOReaderPartialRead(t *testing.T) {
- r := FromIOReader{eofHidingReader{bytes.NewBufferString("foob")}}
- dsts := makeBlocks(make([]byte, 3), make([]byte, 3))
- n, err := r.ReadToBlocks(BlockSeqFromSlice(dsts))
- // FromIOReader should stop after the eofHidingReader returns (1, nil)
- // for a 3-byte read.
- if wantN := uint64(4); n != wantN || err != nil {
- t.Errorf("ReadToBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- for i, want := range [][]byte{[]byte("foo"), []byte("b\x00\x00")} {
- if got := dsts[i].ToSlice(); !bytes.Equal(got, want) {
- t.Errorf("dsts[%d]: got %q, wanted %q", i, got, want)
- }
- }
-}
-
-type singleByteReader struct {
- Reader io.Reader
-}
-
-func (r singleByteReader) Read(dst []byte) (int, error) {
- if len(dst) == 0 {
- return r.Reader.Read(dst)
- }
- return r.Reader.Read(dst[:1])
-}
-
-func TestSingleByteReader(t *testing.T) {
- r := FromIOReader{singleByteReader{bytes.NewBufferString("foobar")}}
- dsts := makeBlocks(make([]byte, 3), make([]byte, 3))
- n, err := r.ReadToBlocks(BlockSeqFromSlice(dsts))
- // FromIOReader should stop after the singleByteReader returns (1, nil)
- // for a 3-byte read.
- if wantN := uint64(1); n != wantN || err != nil {
- t.Errorf("ReadToBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- for i, want := range [][]byte{[]byte("f\x00\x00"), []byte("\x00\x00\x00")} {
- if got := dsts[i].ToSlice(); !bytes.Equal(got, want) {
- t.Errorf("dsts[%d]: got %q, wanted %q", i, got, want)
- }
- }
-}
-
-func TestReadFullToBlocks(t *testing.T) {
- r := FromIOReader{singleByteReader{bytes.NewBufferString("foobar")}}
- dsts := makeBlocks(make([]byte, 3), make([]byte, 3))
- n, err := ReadFullToBlocks(r, BlockSeqFromSlice(dsts))
- // ReadFullToBlocks should call into FromIOReader => singleByteReader
- // repeatedly until dsts is exhausted.
- if wantN := uint64(6); n != wantN || err != nil {
- t.Errorf("ReadFullToBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- for i, want := range [][]byte{[]byte("foo"), []byte("bar")} {
- if got := dsts[i].ToSlice(); !bytes.Equal(got, want) {
- t.Errorf("dsts[%d]: got %q, wanted %q", i, got, want)
- }
- }
-}
-
-func TestFromIOWriterFullWrite(t *testing.T) {
- srcs := makeBlocks([]byte("foo"), []byte("bar"))
- var dst bytes.Buffer
- w := FromIOWriter{&dst}
- n, err := w.WriteFromBlocks(BlockSeqFromSlice(srcs))
- if wantN := uint64(6); n != wantN || err != nil {
- t.Errorf("WriteFromBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst.Bytes(), []byte("foobar"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
-}
-
-type limitedWriter struct {
- Writer io.Writer
- Done int
- Limit int
-}
-
-func (w *limitedWriter) Write(src []byte) (int, error) {
- count := len(src)
- if count > (w.Limit - w.Done) {
- count = w.Limit - w.Done
- }
- n, err := w.Writer.Write(src[:count])
- w.Done += n
- return n, err
-}
-
-func TestFromIOWriterPartialWrite(t *testing.T) {
- srcs := makeBlocks([]byte("foo"), []byte("bar"))
- var dst bytes.Buffer
- w := FromIOWriter{&limitedWriter{&dst, 0, 4}}
- n, err := w.WriteFromBlocks(BlockSeqFromSlice(srcs))
- // FromIOWriter should stop after the limitedWriter returns (1, nil) for a
- // 3-byte write.
- if wantN := uint64(4); n != wantN || err != nil {
- t.Errorf("WriteFromBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst.Bytes(), []byte("foob"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
-}
-
-type singleByteWriter struct {
- Writer io.Writer
-}
-
-func (w singleByteWriter) Write(src []byte) (int, error) {
- if len(src) == 0 {
- return w.Writer.Write(src)
- }
- return w.Writer.Write(src[:1])
-}
-
-func TestSingleByteWriter(t *testing.T) {
- srcs := makeBlocks([]byte("foo"), []byte("bar"))
- var dst bytes.Buffer
- w := FromIOWriter{singleByteWriter{&dst}}
- n, err := w.WriteFromBlocks(BlockSeqFromSlice(srcs))
- // FromIOWriter should stop after the singleByteWriter returns (1, nil)
- // for a 3-byte write.
- if wantN := uint64(1); n != wantN || err != nil {
- t.Errorf("WriteFromBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst.Bytes(), []byte("f"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
-}
-
-func TestWriteFullToBlocks(t *testing.T) {
- srcs := makeBlocks([]byte("foo"), []byte("bar"))
- var dst bytes.Buffer
- w := FromIOWriter{singleByteWriter{&dst}}
- n, err := WriteFullFromBlocks(w, BlockSeqFromSlice(srcs))
- // WriteFullToBlocks should call into FromIOWriter => singleByteWriter
- // repeatedly until srcs is exhausted.
- if wantN := uint64(6); n != wantN || err != nil {
- t.Errorf("WriteFullFromBlocks: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst.Bytes(), []byte("foobar"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
-}
diff --git a/pkg/sentry/safemem/seq_test.go b/pkg/sentry/safemem/seq_test.go
deleted file mode 100644
index eba4bb535..000000000
--- a/pkg/sentry/safemem/seq_test.go
+++ /dev/null
@@ -1,196 +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 safemem
-
-import (
- "bytes"
- "reflect"
- "testing"
-)
-
-type blockSeqTest struct {
- desc string
-
- pieces []string
- haveOffset bool
- offset uint64
- haveLimit bool
- limit uint64
-
- want string
-}
-
-func (t blockSeqTest) NonEmptyByteSlices() [][]byte {
- // t is a value, so we can mutate it freely.
- slices := make([][]byte, 0, len(t.pieces))
- for _, str := range t.pieces {
- if t.haveOffset {
- strOff := t.offset
- if strOff > uint64(len(str)) {
- strOff = uint64(len(str))
- }
- str = str[strOff:]
- t.offset -= strOff
- }
- if t.haveLimit {
- strLim := t.limit
- if strLim > uint64(len(str)) {
- strLim = uint64(len(str))
- }
- str = str[:strLim]
- t.limit -= strLim
- }
- if len(str) != 0 {
- slices = append(slices, []byte(str))
- }
- }
- return slices
-}
-
-func (t blockSeqTest) BlockSeq() BlockSeq {
- blocks := make([]Block, 0, len(t.pieces))
- for _, str := range t.pieces {
- blocks = append(blocks, BlockFromSafeSlice([]byte(str)))
- }
- bs := BlockSeqFromSlice(blocks)
- if t.haveOffset {
- bs = bs.DropFirst64(t.offset)
- }
- if t.haveLimit {
- bs = bs.TakeFirst64(t.limit)
- }
- return bs
-}
-
-var blockSeqTests = []blockSeqTest{
- {
- desc: "Empty sequence",
- },
- {
- desc: "Sequence of length 1",
- pieces: []string{"foobar"},
- want: "foobar",
- },
- {
- desc: "Sequence of length 2",
- pieces: []string{"foo", "bar"},
- want: "foobar",
- },
- {
- desc: "Empty Blocks",
- pieces: []string{"", "foo", "", "", "bar", ""},
- want: "foobar",
- },
- {
- desc: "Sequence with non-zero offset",
- pieces: []string{"foo", "bar"},
- haveOffset: true,
- offset: 2,
- want: "obar",
- },
- {
- desc: "Sequence with non-maximal limit",
- pieces: []string{"foo", "bar"},
- haveLimit: true,
- limit: 5,
- want: "fooba",
- },
- {
- desc: "Sequence with offset and limit",
- pieces: []string{"foo", "bar"},
- haveOffset: true,
- offset: 2,
- haveLimit: true,
- limit: 3,
- want: "oba",
- },
-}
-
-func TestBlockSeqNumBytes(t *testing.T) {
- for _, test := range blockSeqTests {
- t.Run(test.desc, func(t *testing.T) {
- if got, want := test.BlockSeq().NumBytes(), uint64(len(test.want)); got != want {
- t.Errorf("NumBytes: got %d, wanted %d", got, want)
- }
- })
- }
-}
-
-func TestBlockSeqIterBlocks(t *testing.T) {
- // Tests BlockSeq iteration using Head/Tail.
- for _, test := range blockSeqTests {
- t.Run(test.desc, func(t *testing.T) {
- srcs := test.BlockSeq()
- // "Note that a non-nil empty slice and a nil slice ... are not
- // deeply equal." - reflect
- slices := make([][]byte, 0, 0)
- for !srcs.IsEmpty() {
- src := srcs.Head()
- slices = append(slices, src.ToSlice())
- nextSrcs := srcs.Tail()
- if got, want := nextSrcs.NumBytes(), srcs.NumBytes()-uint64(src.Len()); got != want {
- t.Fatalf("%v.Tail(): got %v (%d bytes), wanted %d bytes", srcs, nextSrcs, got, want)
- }
- srcs = nextSrcs
- }
- if wantSlices := test.NonEmptyByteSlices(); !reflect.DeepEqual(slices, wantSlices) {
- t.Errorf("Accumulated slices: got %v, wanted %v", slices, wantSlices)
- }
- })
- }
-}
-
-func TestBlockSeqIterBytes(t *testing.T) {
- // Tests BlockSeq iteration using Head/DropFirst.
- for _, test := range blockSeqTests {
- t.Run(test.desc, func(t *testing.T) {
- srcs := test.BlockSeq()
- var dst bytes.Buffer
- for !srcs.IsEmpty() {
- src := srcs.Head()
- var b [1]byte
- n, err := Copy(BlockFromSafeSlice(b[:]), src)
- if n != 1 || err != nil {
- t.Fatalf("Copy: got (%v, %v), wanted (1, nil)", n, err)
- }
- dst.WriteByte(b[0])
- nextSrcs := srcs.DropFirst(1)
- if got, want := nextSrcs.NumBytes(), srcs.NumBytes()-1; got != want {
- t.Fatalf("%v.DropFirst(1): got %v (%d bytes), wanted %d bytes", srcs, nextSrcs, got, want)
- }
- srcs = nextSrcs
- }
- if got := string(dst.Bytes()); got != test.want {
- t.Errorf("Copied string: got %q, wanted %q", got, test.want)
- }
- })
- }
-}
-
-func TestBlockSeqDropBeyondLimit(t *testing.T) {
- blocks := []Block{BlockFromSafeSlice([]byte("123")), BlockFromSafeSlice([]byte("4"))}
- bs := BlockSeqFromSlice(blocks)
- if got, want := bs.NumBytes(), uint64(4); got != want {
- t.Errorf("%v.NumBytes(): got %d, wanted %d", bs, got, want)
- }
- bs = bs.TakeFirst(1)
- if got, want := bs.NumBytes(), uint64(1); got != want {
- t.Errorf("%v.NumBytes(): got %d, wanted %d", bs, got, want)
- }
- bs = bs.DropFirst(2)
- if got, want := bs.NumBytes(), uint64(0); got != want {
- t.Errorf("%v.NumBytes(): got %d, wanted %d", bs, got, want)
- }
-}
diff --git a/pkg/sentry/safemem/seq_unsafe.go b/pkg/sentry/safemem/seq_unsafe.go
deleted file mode 100644
index 354a95dde..000000000
--- a/pkg/sentry/safemem/seq_unsafe.go
+++ /dev/null
@@ -1,299 +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 safemem
-
-import (
- "bytes"
- "fmt"
- "reflect"
- "unsafe"
-)
-
-// A BlockSeq represents a sequence of Blocks, each of which has non-zero
-// length.
-//
-// BlockSeqs are immutable and may be copied by value. The zero value of
-// BlockSeq represents an empty sequence.
-type BlockSeq struct {
- // If length is 0, then the BlockSeq is empty. Invariants: data == 0;
- // offset == 0; limit == 0.
- //
- // If length is -1, then the BlockSeq represents the single Block{data,
- // limit, false}. Invariants: offset == 0; limit > 0; limit does not
- // overflow the range of an int.
- //
- // If length is -2, then the BlockSeq represents the single Block{data,
- // limit, true}. Invariants: offset == 0; limit > 0; limit does not
- // overflow the range of an int.
- //
- // Otherwise, length >= 2, and the BlockSeq represents the `length` Blocks
- // in the array of Blocks starting at address `data`, starting at `offset`
- // bytes into the first Block and limited to the following `limit` bytes.
- // Invariants: data != 0; offset < len(data[0]); limit > 0; offset+limit <=
- // the combined length of all Blocks in the array; the first Block in the
- // array has non-zero length.
- //
- // length is never 1; sequences consisting of a single Block are always
- // stored inline (with length < 0).
- data unsafe.Pointer
- length int
- offset int
- limit uint64
-}
-
-// BlockSeqOf returns a BlockSeq representing the single Block b.
-func BlockSeqOf(b Block) BlockSeq {
- bs := BlockSeq{
- data: b.start,
- length: -1,
- limit: uint64(b.length),
- }
- if b.needSafecopy {
- bs.length = -2
- }
- return bs
-}
-
-// BlockSeqFromSlice returns a BlockSeq representing all Blocks in slice.
-// If slice contains Blocks with zero length, BlockSeq will skip them during
-// iteration.
-//
-// Whether the returned BlockSeq shares memory with slice is unspecified;
-// clients should avoid mutating slices passed to BlockSeqFromSlice.
-//
-// Preconditions: The combined length of all Blocks in slice <= math.MaxUint64.
-func BlockSeqFromSlice(slice []Block) BlockSeq {
- slice = skipEmpty(slice)
- var limit uint64
- for _, b := range slice {
- sum := limit + uint64(b.Len())
- if sum < limit {
- panic("BlockSeq length overflows uint64")
- }
- limit = sum
- }
- return blockSeqFromSliceLimited(slice, limit)
-}
-
-// Preconditions: The combined length of all Blocks in slice <= limit. If
-// len(slice) != 0, the first Block in slice has non-zero length, and limit >
-// 0.
-func blockSeqFromSliceLimited(slice []Block, limit uint64) BlockSeq {
- switch len(slice) {
- case 0:
- return BlockSeq{}
- case 1:
- return BlockSeqOf(slice[0].TakeFirst64(limit))
- default:
- return BlockSeq{
- data: unsafe.Pointer(&slice[0]),
- length: len(slice),
- limit: limit,
- }
- }
-}
-
-func skipEmpty(slice []Block) []Block {
- for i, b := range slice {
- if b.Len() != 0 {
- return slice[i:]
- }
- }
- return nil
-}
-
-// IsEmpty returns true if bs contains no Blocks.
-//
-// Invariants: bs.IsEmpty() == (bs.NumBlocks() == 0) == (bs.NumBytes() == 0).
-// (Of these, prefer to use bs.IsEmpty().)
-func (bs BlockSeq) IsEmpty() bool {
- return bs.length == 0
-}
-
-// NumBlocks returns the number of Blocks in bs.
-func (bs BlockSeq) NumBlocks() int {
- // In general, we have to count: if bs represents a windowed slice then the
- // slice may contain Blocks with zero length, and bs.length may be larger
- // than the actual number of Blocks due to bs.limit.
- var n int
- for !bs.IsEmpty() {
- n++
- bs = bs.Tail()
- }
- return n
-}
-
-// NumBytes returns the sum of Block.Len() for all Blocks in bs.
-func (bs BlockSeq) NumBytes() uint64 {
- return bs.limit
-}
-
-// Head returns the first Block in bs.
-//
-// Preconditions: !bs.IsEmpty().
-func (bs BlockSeq) Head() Block {
- if bs.length == 0 {
- panic("empty BlockSeq")
- }
- if bs.length < 0 {
- return bs.internalBlock()
- }
- return (*Block)(bs.data).DropFirst(bs.offset).TakeFirst64(bs.limit)
-}
-
-// Preconditions: bs.length < 0.
-func (bs BlockSeq) internalBlock() Block {
- return Block{
- start: bs.data,
- length: int(bs.limit),
- needSafecopy: bs.length == -2,
- }
-}
-
-// Tail returns a BlockSeq consisting of all Blocks in bs after the first.
-//
-// Preconditions: !bs.IsEmpty().
-func (bs BlockSeq) Tail() BlockSeq {
- if bs.length == 0 {
- panic("empty BlockSeq")
- }
- if bs.length < 0 {
- return BlockSeq{}
- }
- head := (*Block)(bs.data).DropFirst(bs.offset)
- headLen := uint64(head.Len())
- if headLen >= bs.limit {
- // The head Block exhausts the limit, so the tail is empty.
- return BlockSeq{}
- }
- var extSlice []Block
- extSliceHdr := (*reflect.SliceHeader)(unsafe.Pointer(&extSlice))
- extSliceHdr.Data = uintptr(bs.data)
- extSliceHdr.Len = bs.length
- extSliceHdr.Cap = bs.length
- tailSlice := skipEmpty(extSlice[1:])
- tailLimit := bs.limit - headLen
- return blockSeqFromSliceLimited(tailSlice, tailLimit)
-}
-
-// DropFirst returns a BlockSeq equivalent to bs, but with the first n bytes
-// omitted. If n > bs.NumBytes(), DropFirst returns an empty BlockSeq.
-//
-// Preconditions: n >= 0.
-func (bs BlockSeq) DropFirst(n int) BlockSeq {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- return bs.DropFirst64(uint64(n))
-}
-
-// DropFirst64 is equivalent to DropFirst but takes an uint64.
-func (bs BlockSeq) DropFirst64(n uint64) BlockSeq {
- if n >= bs.limit {
- return BlockSeq{}
- }
- for {
- // Calling bs.Head() here is surprisingly expensive, so inline getting
- // the head's length.
- var headLen uint64
- if bs.length < 0 {
- headLen = bs.limit
- } else {
- headLen = uint64((*Block)(bs.data).Len() - bs.offset)
- }
- if n < headLen {
- // Dropping ends partway through the head Block.
- if bs.length < 0 {
- return BlockSeqOf(bs.internalBlock().DropFirst64(n))
- }
- bs.offset += int(n)
- bs.limit -= n
- return bs
- }
- n -= headLen
- bs = bs.Tail()
- }
-}
-
-// TakeFirst returns a BlockSeq equivalent to the first n bytes of bs. If n >
-// bs.NumBytes(), TakeFirst returns a BlockSeq equivalent to bs.
-//
-// Preconditions: n >= 0.
-func (bs BlockSeq) TakeFirst(n int) BlockSeq {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- return bs.TakeFirst64(uint64(n))
-}
-
-// TakeFirst64 is equivalent to TakeFirst but takes a uint64.
-func (bs BlockSeq) TakeFirst64(n uint64) BlockSeq {
- if n == 0 {
- return BlockSeq{}
- }
- if bs.limit > n {
- bs.limit = n
- }
- return bs
-}
-
-// String implements fmt.Stringer.String.
-func (bs BlockSeq) String() string {
- var buf bytes.Buffer
- buf.WriteByte('[')
- var sep string
- for !bs.IsEmpty() {
- buf.WriteString(sep)
- sep = " "
- buf.WriteString(bs.Head().String())
- bs = bs.Tail()
- }
- buf.WriteByte(']')
- return buf.String()
-}
-
-// CopySeq copies srcs.NumBytes() or dsts.NumBytes() bytes, whichever is less,
-// from srcs to dsts and returns the number of bytes copied.
-//
-// If srcs and dsts overlap, the data stored in dsts is unspecified.
-func CopySeq(dsts, srcs BlockSeq) (uint64, error) {
- var done uint64
- for !dsts.IsEmpty() && !srcs.IsEmpty() {
- dst := dsts.Head()
- src := srcs.Head()
- n, err := Copy(dst, src)
- done += uint64(n)
- if err != nil {
- return done, err
- }
- dsts = dsts.DropFirst(n)
- srcs = srcs.DropFirst(n)
- }
- return done, nil
-}
-
-// ZeroSeq sets all bytes in dsts to 0 and returns the number of bytes zeroed.
-func ZeroSeq(dsts BlockSeq) (uint64, error) {
- var done uint64
- for !dsts.IsEmpty() {
- n, err := Zero(dsts.Head())
- done += uint64(n)
- if err != nil {
- return done, err
- }
- dsts = dsts.DropFirst(n)
- }
- return done, nil
-}
diff --git a/pkg/sentry/sighandling/BUILD b/pkg/sentry/sighandling/BUILD
index f561670c7..6c38a3f44 100644
--- a/pkg/sentry/sighandling/BUILD
+++ b/pkg/sentry/sighandling/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -8,7 +8,6 @@ go_library(
"sighandling.go",
"sighandling_unsafe.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/sighandling",
visibility = ["//pkg/sentry:internal"],
deps = ["//pkg/abi/linux"],
)
diff --git a/pkg/sentry/socket/BUILD b/pkg/sentry/socket/BUILD
index 26176b10d..611fa22c3 100644
--- a/pkg/sentry/socket/BUILD
+++ b/pkg/sentry/socket/BUILD
@@ -1,24 +1,23 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "socket",
srcs = ["socket.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/time",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/syserr",
"//pkg/tcpip",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/socket/control/BUILD b/pkg/sentry/socket/control/BUILD
index 357517ed4..79e16d6e8 100644
--- a/pkg/sentry/socket/control/BUILD
+++ b/pkg/sentry/socket/control/BUILD
@@ -1,11 +1,10 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "control",
srcs = ["control.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/control",
imports = [
"gvisor.dev/gvisor/pkg/sentry/fs",
],
@@ -13,13 +12,13 @@ go_library(
deps = [
"//pkg/abi/linux",
"//pkg/binary",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/fs",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/socket",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go
index 1684dfc24..00265f15b 100644
--- a/pkg/sentry/socket/control/control.go
+++ b/pkg/sentry/socket/control/control.go
@@ -19,14 +19,14 @@ package control
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const maxInt = int(^uint(0) >> 1)
diff --git a/pkg/sentry/socket/hostinet/BUILD b/pkg/sentry/socket/hostinet/BUILD
index 4c44c7c0f..5a07d5d0e 100644
--- a/pkg/sentry/socket/hostinet/BUILD
+++ b/pkg/sentry/socket/hostinet/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -12,28 +12,27 @@ go_library(
"socket_unsafe.go",
"stack.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/hostinet",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/fdnotifier",
"//pkg/log",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/inet",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/time",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket",
"//pkg/sentry/socket/control",
- "//pkg/sentry/usermem",
"//pkg/syserr",
"//pkg/syserror",
"//pkg/tcpip/stack",
+ "//pkg/usermem",
"//pkg/waiter",
"@org_golang_x_sys//unix:go_default_library",
],
diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go
index c957b0f1d..bde4c7a1e 100644
--- a/pkg/sentry/socket/hostinet/socket.go
+++ b/pkg/sentry/socket/hostinet/socket.go
@@ -21,19 +21,19 @@ import (
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/control"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/socket/hostinet/socket_unsafe.go b/pkg/sentry/socket/hostinet/socket_unsafe.go
index e69ec38c2..cd67234d2 100644
--- a/pkg/sentry/socket/hostinet/socket_unsafe.go
+++ b/pkg/sentry/socket/hostinet/socket_unsafe.go
@@ -19,14 +19,14 @@ import (
"unsafe"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/socket"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func firstBytePtr(bs []byte) unsafe.Pointer {
diff --git a/pkg/sentry/socket/hostinet/stack.go b/pkg/sentry/socket/hostinet/stack.go
index e67b46c9e..034eca676 100644
--- a/pkg/sentry/socket/hostinet/stack.go
+++ b/pkg/sentry/socket/hostinet/stack.go
@@ -25,13 +25,13 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/inet"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
"gvisor.dev/gvisor/pkg/tcpip/stack"
+ "gvisor.dev/gvisor/pkg/usermem"
)
var defaultRecvBufSize = inet.TCPBufferSize{
diff --git a/pkg/sentry/socket/netfilter/BUILD b/pkg/sentry/socket/netfilter/BUILD
index b70047d81..fa2a2cb66 100644
--- a/pkg/sentry/socket/netfilter/BUILD
+++ b/pkg/sentry/socket/netfilter/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -7,7 +7,6 @@ go_library(
srcs = [
"netfilter.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/netfilter",
# This target depends on netstack and should only be used by epsocket,
# which is allowed to depend on netstack.
visibility = ["//pkg/sentry:internal"],
@@ -16,10 +15,10 @@ go_library(
"//pkg/binary",
"//pkg/log",
"//pkg/sentry/kernel",
- "//pkg/sentry/usermem",
"//pkg/syserr",
"//pkg/tcpip",
"//pkg/tcpip/iptables",
"//pkg/tcpip/stack",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/socket/netfilter/netfilter.go b/pkg/sentry/socket/netfilter/netfilter.go
index a06562743..3dda6c7a1 100644
--- a/pkg/sentry/socket/netfilter/netfilter.go
+++ b/pkg/sentry/socket/netfilter/netfilter.go
@@ -23,11 +23,11 @@ import (
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/iptables"
"gvisor.dev/gvisor/pkg/tcpip/stack"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// errorTargetName is used to mark targets as error targets. Error targets
diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD
index 103933144..f8b8e467d 100644
--- a/pkg/sentry/socket/netlink/BUILD
+++ b/pkg/sentry/socket/netlink/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -9,13 +9,12 @@ go_library(
"provider.go",
"socket.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/netlink",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
@@ -26,11 +25,11 @@ go_library(
"//pkg/sentry/socket/netlink/port",
"//pkg/sentry/socket/unix",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserr",
"//pkg/syserror",
"//pkg/tcpip",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/socket/netlink/message.go b/pkg/sentry/socket/netlink/message.go
index ce0a1afd0..b21e0ca4b 100644
--- a/pkg/sentry/socket/netlink/message.go
+++ b/pkg/sentry/socket/netlink/message.go
@@ -20,7 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// alignUp rounds a length up to an alignment.
diff --git a/pkg/sentry/socket/netlink/port/BUILD b/pkg/sentry/socket/netlink/port/BUILD
index 2d9f4ba9b..3a22923d8 100644
--- a/pkg/sentry/socket/netlink/port/BUILD
+++ b/pkg/sentry/socket/netlink/port/BUILD
@@ -1,12 +1,10 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library", "go_test")
package(licenses = ["notice"])
go_library(
name = "port",
srcs = ["port.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/netlink/port",
visibility = ["//pkg/sentry:internal"],
deps = ["//pkg/sync"],
)
@@ -14,5 +12,5 @@ go_library(
go_test(
name = "port_test",
srcs = ["port_test.go"],
- embed = [":port"],
+ library = ":port",
)
diff --git a/pkg/sentry/socket/netlink/provider.go b/pkg/sentry/socket/netlink/provider.go
index be005df24..07f860a49 100644
--- a/pkg/sentry/socket/netlink/provider.go
+++ b/pkg/sentry/socket/netlink/provider.go
@@ -18,7 +18,7 @@ import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/socket"
diff --git a/pkg/sentry/socket/netlink/route/BUILD b/pkg/sentry/socket/netlink/route/BUILD
index 1d4912753..622a1eafc 100644
--- a/pkg/sentry/socket/netlink/route/BUILD
+++ b/pkg/sentry/socket/netlink/route/BUILD
@@ -1,19 +1,22 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "route",
- srcs = ["protocol.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/netlink/route",
+ srcs = [
+ "protocol.go",
+ ],
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/binary",
+ "//pkg/context",
"//pkg/sentry/inet",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/socket/netlink",
"//pkg/syserr",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/socket/netlink/route/protocol.go b/pkg/sentry/socket/netlink/route/protocol.go
index 6b4a0ecf4..2b3c7f5b3 100644
--- a/pkg/sentry/socket/netlink/route/protocol.go
+++ b/pkg/sentry/socket/netlink/route/protocol.go
@@ -19,12 +19,14 @@ import (
"bytes"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/socket/netlink"
"gvisor.dev/gvisor/pkg/syserr"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// commandKind describes the operational class of a message type.
@@ -66,8 +68,14 @@ func (p *Protocol) CanSend() bool {
return true
}
-// dumpLinks handles RTM_GETLINK + NLM_F_DUMP requests.
+// dumpLinks handles RTM_GETLINK dump requests.
func (p *Protocol) dumpLinks(ctx context.Context, hdr linux.NetlinkMessageHeader, data []byte, ms *netlink.MessageSet) *syserr.Error {
+ // TODO(b/68878065): Only the dump variant of the types below are
+ // supported.
+ if hdr.Flags&linux.NLM_F_DUMP != linux.NLM_F_DUMP {
+ return syserr.ErrNotSupported
+ }
+
// NLM_F_DUMP + RTM_GETLINK messages are supposed to include an
// ifinfomsg. However, Linux <3.9 only checked for rtgenmsg, and some
// userspace applications (including glibc) still include rtgenmsg.
@@ -121,8 +129,14 @@ func (p *Protocol) dumpLinks(ctx context.Context, hdr linux.NetlinkMessageHeader
return nil
}
-// dumpAddrs handles RTM_GETADDR + NLM_F_DUMP requests.
+// dumpAddrs handles RTM_GETADDR dump requests.
func (p *Protocol) dumpAddrs(ctx context.Context, hdr linux.NetlinkMessageHeader, data []byte, ms *netlink.MessageSet) *syserr.Error {
+ // TODO(b/68878065): Only the dump variant of the types below are
+ // supported.
+ if hdr.Flags&linux.NLM_F_DUMP != linux.NLM_F_DUMP {
+ return syserr.ErrNotSupported
+ }
+
// RTM_GETADDR dump requests need not contain anything more than the
// netlink header and 1 byte protocol family common to all
// NETLINK_ROUTE requests.
@@ -163,22 +177,146 @@ func (p *Protocol) dumpAddrs(ctx context.Context, hdr linux.NetlinkMessageHeader
return nil
}
-// dumpRoutes handles RTM_GETROUTE + NLM_F_DUMP requests.
+// commonPrefixLen reports the length of the longest IP address prefix.
+// This is a simplied version from Golang's src/net/addrselect.go.
+func commonPrefixLen(a, b []byte) (cpl int) {
+ for len(a) > 0 {
+ if a[0] == b[0] {
+ cpl += 8
+ a = a[1:]
+ b = b[1:]
+ continue
+ }
+ bits := 8
+ ab, bb := a[0], b[0]
+ for {
+ ab >>= 1
+ bb >>= 1
+ bits--
+ if ab == bb {
+ cpl += bits
+ return
+ }
+ }
+ }
+ return
+}
+
+// fillRoute returns the Route using LPM algorithm. Refer to Linux's
+// net/ipv4/route.c:rt_fill_info().
+func fillRoute(routes []inet.Route, addr []byte) (inet.Route, *syserr.Error) {
+ family := uint8(linux.AF_INET)
+ if len(addr) != 4 {
+ family = linux.AF_INET6
+ }
+
+ idx := -1 // Index of the Route rule to be returned.
+ idxDef := -1 // Index of the default route rule.
+ prefix := 0 // Current longest prefix.
+ for i, route := range routes {
+ if route.Family != family {
+ continue
+ }
+
+ if len(route.GatewayAddr) > 0 && route.DstLen == 0 {
+ idxDef = i
+ continue
+ }
+
+ cpl := commonPrefixLen(addr, route.DstAddr)
+ if cpl < int(route.DstLen) {
+ continue
+ }
+ cpl = int(route.DstLen)
+ if cpl > prefix {
+ idx = i
+ prefix = cpl
+ }
+ }
+ if idx == -1 {
+ idx = idxDef
+ }
+ if idx == -1 {
+ return inet.Route{}, syserr.ErrNoRoute
+ }
+
+ route := routes[idx]
+ if family == linux.AF_INET {
+ route.DstLen = 32
+ } else {
+ route.DstLen = 128
+ }
+ route.DstAddr = addr
+ route.Flags |= linux.RTM_F_CLONED // This route is cloned.
+ return route, nil
+}
+
+// parseForDestination parses a message as format of RouteMessage-RtAttr-dst.
+func parseForDestination(data []byte) ([]byte, *syserr.Error) {
+ var rtMsg linux.RouteMessage
+ if len(data) < linux.SizeOfRouteMessage {
+ return nil, syserr.ErrInvalidArgument
+ }
+ binary.Unmarshal(data[:linux.SizeOfRouteMessage], usermem.ByteOrder, &rtMsg)
+ // iproute2 added the RTM_F_LOOKUP_TABLE flag in version v4.4.0. See
+ // commit bc234301af12. Note we don't check this flag for backward
+ // compatibility.
+ if rtMsg.Flags != 0 && rtMsg.Flags != linux.RTM_F_LOOKUP_TABLE {
+ return nil, syserr.ErrNotSupported
+ }
+
+ data = data[linux.SizeOfRouteMessage:]
+
+ // TODO(gvisor.dev/issue/1611): Add generic attribute parsing.
+ var rtAttr linux.RtAttr
+ if len(data) < linux.SizeOfRtAttr {
+ return nil, syserr.ErrInvalidArgument
+ }
+ binary.Unmarshal(data[:linux.SizeOfRtAttr], usermem.ByteOrder, &rtAttr)
+ if rtAttr.Type != linux.RTA_DST {
+ return nil, syserr.ErrInvalidArgument
+ }
+
+ if len(data) < int(rtAttr.Len) {
+ return nil, syserr.ErrInvalidArgument
+ }
+ return data[linux.SizeOfRtAttr:rtAttr.Len], nil
+}
+
+// dumpRoutes handles RTM_GETROUTE requests.
func (p *Protocol) dumpRoutes(ctx context.Context, hdr linux.NetlinkMessageHeader, data []byte, ms *netlink.MessageSet) *syserr.Error {
// RTM_GETROUTE dump requests need not contain anything more than the
// netlink header and 1 byte protocol family common to all
// NETLINK_ROUTE requests.
- // We always send back an NLMSG_DONE.
- ms.Multi = true
-
stack := inet.StackFromContext(ctx)
if stack == nil {
// No network routes.
return nil
}
- for _, rt := range stack.RouteTable() {
+ routeTables := stack.RouteTable()
+
+ if hdr.Flags == linux.NLM_F_REQUEST {
+ dst, err := parseForDestination(data)
+ if err != nil {
+ return err
+ }
+ route, err := fillRoute(routeTables, dst)
+ if err != nil {
+ // TODO(gvisor.dev/issue/1237): return NLMSG_ERROR with ENETUNREACH.
+ return syserr.ErrNotSupported
+ }
+ routeTables = append([]inet.Route{}, route)
+ } else if hdr.Flags&linux.NLM_F_DUMP == linux.NLM_F_DUMP {
+ // We always send back an NLMSG_DONE.
+ ms.Multi = true
+ } else {
+ // TODO(b/68878065): Only above cases are supported.
+ return syserr.ErrNotSupported
+ }
+
+ for _, rt := range routeTables {
m := ms.AddMessage(linux.NetlinkMessageHeader{
Type: linux.RTM_NEWROUTE,
})
@@ -236,12 +374,6 @@ func (p *Protocol) ProcessMessage(ctx context.Context, hdr linux.NetlinkMessageH
}
}
- // TODO(b/68878065): Only the dump variant of the types below are
- // supported.
- if hdr.Flags&linux.NLM_F_DUMP != linux.NLM_F_DUMP {
- return syserr.ErrNotSupported
- }
-
switch hdr.Type {
case linux.RTM_GETLINK:
return p.dumpLinks(ctx, hdr, data, ms)
diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go
index cea56f4ed..c4b95debb 100644
--- a/pkg/sentry/socket/netlink/socket.go
+++ b/pkg/sentry/socket/netlink/socket.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
@@ -32,11 +32,11 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket/netlink/port"
"gvisor.dev/gvisor/pkg/sentry/socket/unix"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
"gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/socket/netlink/uevent/BUILD b/pkg/sentry/socket/netlink/uevent/BUILD
index 0777f3baf..b6434923c 100644
--- a/pkg/sentry/socket/netlink/uevent/BUILD
+++ b/pkg/sentry/socket/netlink/uevent/BUILD
@@ -1,15 +1,14 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "uevent",
srcs = ["protocol.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/netlink/uevent",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/kernel",
"//pkg/sentry/socket/netlink",
"//pkg/syserr",
diff --git a/pkg/sentry/socket/netlink/uevent/protocol.go b/pkg/sentry/socket/netlink/uevent/protocol.go
index b5d7808d7..1ee4296bc 100644
--- a/pkg/sentry/socket/netlink/uevent/protocol.go
+++ b/pkg/sentry/socket/netlink/uevent/protocol.go
@@ -20,7 +20,7 @@ package uevent
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/socket/netlink"
"gvisor.dev/gvisor/pkg/syserr"
diff --git a/pkg/sentry/socket/netstack/BUILD b/pkg/sentry/socket/netstack/BUILD
index f78784569..ab01cb4fa 100644
--- a/pkg/sentry/socket/netstack/BUILD
+++ b/pkg/sentry/socket/netstack/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -11,17 +11,17 @@ go_library(
"save_restore.go",
"stack.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/netstack",
visibility = [
"//pkg/sentry:internal",
],
deps = [
"//pkg/abi/linux",
"//pkg/binary",
+ "//pkg/context",
"//pkg/log",
"//pkg/metric",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
@@ -29,11 +29,9 @@ go_library(
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket",
"//pkg/sentry/socket/netfilter",
"//pkg/sentry/unimpl",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserr",
"//pkg/syserror",
@@ -46,6 +44,7 @@ go_library(
"//pkg/tcpip/stack",
"//pkg/tcpip/transport/tcp",
"//pkg/tcpip/transport/udp",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go
index 318acbeff..8619cc506 100644
--- a/pkg/sentry/socket/netstack/netstack.go
+++ b/pkg/sentry/socket/netstack/netstack.go
@@ -34,20 +34,19 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/metric"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/netfilter"
"gvisor.dev/gvisor/pkg/sentry/unimpl"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
@@ -57,6 +56,7 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/socket/netstack/provider.go b/pkg/sentry/socket/netstack/provider.go
index 2d2c1ba2a..5afff2564 100644
--- a/pkg/sentry/socket/netstack/provider.go
+++ b/pkg/sentry/socket/netstack/provider.go
@@ -18,7 +18,7 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
diff --git a/pkg/sentry/socket/socket.go b/pkg/sentry/socket/socket.go
index 2389a9cdb..50d9744e6 100644
--- a/pkg/sentry/socket/socket.go
+++ b/pkg/sentry/socket/socket.go
@@ -24,16 +24,16 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/device"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ControlMessages represents the union of unix control messages and tcpip
diff --git a/pkg/sentry/socket/unix/BUILD b/pkg/sentry/socket/unix/BUILD
index 5b6a154f6..08743deba 100644
--- a/pkg/sentry/socket/unix/BUILD
+++ b/pkg/sentry/socket/unix/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -9,27 +9,26 @@ go_library(
"io.go",
"unix.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/unix",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/refs",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/time",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket",
"//pkg/sentry/socket/control",
"//pkg/sentry/socket/netstack",
"//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/usermem",
"//pkg/syserr",
"//pkg/syserror",
"//pkg/tcpip",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/socket/unix/io.go b/pkg/sentry/socket/unix/io.go
index 2447f24ef..129949990 100644
--- a/pkg/sentry/socket/unix/io.go
+++ b/pkg/sentry/socket/unix/io.go
@@ -15,8 +15,8 @@
package unix
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/tcpip"
)
diff --git a/pkg/sentry/socket/unix/transport/BUILD b/pkg/sentry/socket/unix/transport/BUILD
index d7ba95dff..74bcd6300 100644
--- a/pkg/sentry/socket/unix/transport/BUILD
+++ b/pkg/sentry/socket/unix/transport/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
load("//tools/go_generics:defs.bzl", "go_template_instance")
package(licenses = ["notice"])
@@ -25,13 +25,12 @@ go_library(
"transport_message_list.go",
"unix.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/socket/unix/transport",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/ilist",
"//pkg/refs",
- "//pkg/sentry/context",
"//pkg/sync",
"//pkg/syserr",
"//pkg/tcpip",
diff --git a/pkg/sentry/socket/unix/transport/connectioned.go b/pkg/sentry/socket/unix/transport/connectioned.go
index 9e6fbc111..ce5b94ee7 100644
--- a/pkg/sentry/socket/unix/transport/connectioned.go
+++ b/pkg/sentry/socket/unix/transport/connectioned.go
@@ -16,7 +16,7 @@ package transport
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
diff --git a/pkg/sentry/socket/unix/transport/connectionless.go b/pkg/sentry/socket/unix/transport/connectionless.go
index 0322dec0b..4b06d63ac 100644
--- a/pkg/sentry/socket/unix/transport/connectionless.go
+++ b/pkg/sentry/socket/unix/transport/connectionless.go
@@ -16,7 +16,7 @@ package transport
import (
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/waiter"
diff --git a/pkg/sentry/socket/unix/transport/queue.go b/pkg/sentry/socket/unix/transport/queue.go
index 5dcd3d95e..d8f3ad63d 100644
--- a/pkg/sentry/socket/unix/transport/queue.go
+++ b/pkg/sentry/socket/unix/transport/queue.go
@@ -18,6 +18,8 @@ import (
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserr"
+ "gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/tcpip/buffer"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -100,12 +102,16 @@ func (q *queue) IsWritable() bool {
// Enqueue adds an entry to the data queue if room is available.
//
+// If discardEmpty is true and there are zero bytes of data, the packet is
+// dropped.
+//
// If truncate is true, Enqueue may truncate the message before enqueuing it.
-// Otherwise, the entire message must fit. If n < e.Length(), err indicates why.
+// Otherwise, the entire message must fit. If l is less than the size of data,
+// err indicates why.
//
// If notify is true, ReaderQueue.Notify must be called:
// q.ReaderQueue.Notify(waiter.EventIn)
-func (q *queue) Enqueue(e *message, truncate bool) (l int64, notify bool, err *syserr.Error) {
+func (q *queue) Enqueue(data [][]byte, c ControlMessages, from tcpip.FullAddress, discardEmpty bool, truncate bool) (l int64, notify bool, err *syserr.Error) {
q.mu.Lock()
if q.closed {
@@ -113,9 +119,16 @@ func (q *queue) Enqueue(e *message, truncate bool) (l int64, notify bool, err *s
return 0, false, syserr.ErrClosedForSend
}
- free := q.limit - q.used
+ for _, d := range data {
+ l += int64(len(d))
+ }
+ if discardEmpty && l == 0 {
+ q.mu.Unlock()
+ c.Release()
+ return 0, false, nil
+ }
- l = e.Length()
+ free := q.limit - q.used
if l > free && truncate {
if free == 0 {
@@ -124,8 +137,7 @@ func (q *queue) Enqueue(e *message, truncate bool) (l int64, notify bool, err *s
return 0, false, syserr.ErrWouldBlock
}
- e.Truncate(free)
- l = e.Length()
+ l = free
err = syserr.ErrWouldBlock
}
@@ -136,14 +148,26 @@ func (q *queue) Enqueue(e *message, truncate bool) (l int64, notify bool, err *s
}
if l > free {
- // Message can't fit right now.
+ // Message can't fit right now, and could not be truncated.
q.mu.Unlock()
return 0, false, syserr.ErrWouldBlock
}
+ // Aggregate l bytes of data. This will truncate the data if l is less than
+ // the total bytes held in data.
+ v := make([]byte, l)
+ for i, b := 0, v; i < len(data) && len(b) > 0; i++ {
+ n := copy(b, data[i])
+ b = b[n:]
+ }
+
notify = q.dataList.Front() == nil
q.used += l
- q.dataList.PushBack(e)
+ q.dataList.PushBack(&message{
+ Data: buffer.View(v),
+ Control: c,
+ Address: from,
+ })
q.mu.Unlock()
diff --git a/pkg/sentry/socket/unix/transport/unix.go b/pkg/sentry/socket/unix/transport/unix.go
index fcc0da332..2ef654235 100644
--- a/pkg/sentry/socket/unix/transport/unix.go
+++ b/pkg/sentry/socket/unix/transport/unix.go
@@ -19,7 +19,7 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
@@ -581,7 +581,7 @@ type ConnectedEndpoint interface {
//
// syserr.ErrWouldBlock can be returned along with a partial write if
// the caller should block to send the rest of the data.
- Send(data [][]byte, controlMessages ControlMessages, from tcpip.FullAddress) (n int64, notify bool, err *syserr.Error)
+ Send(data [][]byte, c ControlMessages, from tcpip.FullAddress) (n int64, notify bool, err *syserr.Error)
// SendNotify notifies the ConnectedEndpoint of a successful Send. This
// must not be called while holding any endpoint locks.
@@ -653,35 +653,22 @@ func (e *connectedEndpoint) GetLocalAddress() (tcpip.FullAddress, *tcpip.Error)
}
// Send implements ConnectedEndpoint.Send.
-func (e *connectedEndpoint) Send(data [][]byte, controlMessages ControlMessages, from tcpip.FullAddress) (int64, bool, *syserr.Error) {
- var l int64
- for _, d := range data {
- l += int64(len(d))
- }
-
+func (e *connectedEndpoint) Send(data [][]byte, c ControlMessages, from tcpip.FullAddress) (int64, bool, *syserr.Error) {
+ discardEmpty := false
truncate := false
if e.endpoint.Type() == linux.SOCK_STREAM {
- // Since stream sockets don't preserve message boundaries, we
- // can write only as much of the message as fits in the queue.
- truncate = true
-
// Discard empty stream packets. Since stream sockets don't
// preserve message boundaries, sending zero bytes is a no-op.
// In Linux, the receiver actually uses a zero-length receive
// as an indication that the stream was closed.
- if l == 0 {
- controlMessages.Release()
- return 0, false, nil
- }
- }
+ discardEmpty = true
- v := make([]byte, 0, l)
- for _, d := range data {
- v = append(v, d...)
+ // Since stream sockets don't preserve message boundaries, we
+ // can write only as much of the message as fits in the queue.
+ truncate = true
}
- l, notify, err := e.writeQueue.Enqueue(&message{Data: buffer.View(v), Control: controlMessages, Address: from}, truncate)
- return int64(l), notify, err
+ return e.writeQueue.Enqueue(data, c, from, discardEmpty, truncate)
}
// SendNotify implements ConnectedEndpoint.SendNotify.
diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go
index 7f49ba864..4d30aa714 100644
--- a/pkg/sentry/socket/unix/unix.go
+++ b/pkg/sentry/socket/unix/unix.go
@@ -22,9 +22,9 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
@@ -33,10 +33,10 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket/control"
"gvisor.dev/gvisor/pkg/sentry/socket/netstack"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
"gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD
index 88765f4d6..0ea4aab8b 100644
--- a/pkg/sentry/state/BUILD
+++ b/pkg/sentry/state/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -9,7 +9,6 @@ go_library(
"state_metadata.go",
"state_unsafe.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/state",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
diff --git a/pkg/sentry/strace/BUILD b/pkg/sentry/strace/BUILD
index aa1ac720c..762a946fe 100644
--- a/pkg/sentry/strace/BUILD
+++ b/pkg/sentry/strace/BUILD
@@ -1,6 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("//tools:defs.bzl", "go_library", "proto_library")
package(licenses = ["notice"])
@@ -21,7 +19,6 @@ go_library(
"strace.go",
"syscalls.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/strace",
visibility = ["//:sandbox"],
deps = [
":strace_go_proto",
@@ -37,25 +34,12 @@ go_library(
"//pkg/sentry/socket/netlink",
"//pkg/sentry/socket/netstack",
"//pkg/sentry/syscalls/linux",
- "//pkg/sentry/usermem",
+ "//pkg/usermem",
],
)
proto_library(
- name = "strace_proto",
+ name = "strace",
srcs = ["strace.proto"],
visibility = ["//visibility:public"],
)
-
-cc_proto_library(
- name = "strace_cc_proto",
- visibility = ["//visibility:public"],
- deps = [":strace_proto"],
-)
-
-go_proto_library(
- name = "strace_go_proto",
- importpath = "gvisor.dev/gvisor/pkg/sentry/strace/strace_go_proto",
- proto = ":strace_proto",
- visibility = ["//visibility:public"],
-)
diff --git a/pkg/sentry/strace/linux64_amd64.go b/pkg/sentry/strace/linux64_amd64.go
index 1e823b685..85ec66fd3 100644
--- a/pkg/sentry/strace/linux64_amd64.go
+++ b/pkg/sentry/strace/linux64_amd64.go
@@ -37,7 +37,7 @@ var linuxAMD64 = SyscallMap{
10: makeSyscallInfo("mprotect", Hex, Hex, Hex),
11: makeSyscallInfo("munmap", Hex, Hex),
12: makeSyscallInfo("brk", Hex),
- 13: makeSyscallInfo("rt_sigaction", Signal, SigAction, PostSigAction),
+ 13: makeSyscallInfo("rt_sigaction", Signal, SigAction, PostSigAction, Hex),
14: makeSyscallInfo("rt_sigprocmask", SignalMaskAction, SigSet, PostSigSet, Hex),
15: makeSyscallInfo("rt_sigreturn"),
16: makeSyscallInfo("ioctl", FD, Hex, Hex),
diff --git a/pkg/sentry/strace/linux64_arm64.go b/pkg/sentry/strace/linux64_arm64.go
index c3ac5248d..8bc38545f 100644
--- a/pkg/sentry/strace/linux64_arm64.go
+++ b/pkg/sentry/strace/linux64_arm64.go
@@ -158,7 +158,7 @@ var linuxARM64 = SyscallMap{
131: makeSyscallInfo("tgkill", Hex, Hex, Signal),
132: makeSyscallInfo("sigaltstack", Hex, Hex),
133: makeSyscallInfo("rt_sigsuspend", Hex),
- 134: makeSyscallInfo("rt_sigaction", Signal, SigAction, PostSigAction),
+ 134: makeSyscallInfo("rt_sigaction", Signal, SigAction, PostSigAction, Hex),
135: makeSyscallInfo("rt_sigprocmask", SignalMaskAction, SigSet, PostSigSet, Hex),
136: makeSyscallInfo("rt_sigpending", Hex),
137: makeSyscallInfo("rt_sigtimedwait", SigSet, Hex, Timespec, Hex),
diff --git a/pkg/sentry/strace/poll.go b/pkg/sentry/strace/poll.go
index 5187594a7..074e80f9b 100644
--- a/pkg/sentry/strace/poll.go
+++ b/pkg/sentry/strace/poll.go
@@ -22,7 +22,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/kernel"
slinux "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// PollEventSet is the set of poll(2) event flags.
diff --git a/pkg/sentry/strace/select.go b/pkg/sentry/strace/select.go
index c77d418e6..3a4c32aa0 100644
--- a/pkg/sentry/strace/select.go
+++ b/pkg/sentry/strace/select.go
@@ -19,7 +19,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
func fdsFromSet(t *kernel.Task, set []byte) []int {
diff --git a/pkg/sentry/strace/signal.go b/pkg/sentry/strace/signal.go
index 5656d53eb..c41f36e3f 100644
--- a/pkg/sentry/strace/signal.go
+++ b/pkg/sentry/strace/signal.go
@@ -21,7 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// signalNames contains the names of all named signals.
diff --git a/pkg/sentry/strace/socket.go b/pkg/sentry/strace/socket.go
index b6d7177f4..d2079c85f 100644
--- a/pkg/sentry/strace/socket.go
+++ b/pkg/sentry/strace/socket.go
@@ -26,7 +26,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket/netlink"
"gvisor.dev/gvisor/pkg/sentry/socket/netstack"
slinux "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// SocketFamily are the possible socket(2) families.
diff --git a/pkg/sentry/strace/strace.go b/pkg/sentry/strace/strace.go
index 629c1f308..3fc4a47fc 100644
--- a/pkg/sentry/strace/strace.go
+++ b/pkg/sentry/strace/strace.go
@@ -33,7 +33,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
pb "gvisor.dev/gvisor/pkg/sentry/strace/strace_go_proto"
slinux "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// DefaultLogMaximumSize is the default LogMaximumSize.
diff --git a/pkg/sentry/syscalls/BUILD b/pkg/sentry/syscalls/BUILD
index 79d972202..b8d1bd415 100644
--- a/pkg/sentry/syscalls/BUILD
+++ b/pkg/sentry/syscalls/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -8,7 +8,6 @@ go_library(
"epoll.go",
"syscalls.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/syscalls",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi/linux",
diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD
index 917f74e07..be16ee686 100644
--- a/pkg/sentry/syscalls/linux/BUILD
+++ b/pkg/sentry/syscalls/linux/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -57,18 +57,18 @@ go_library(
"sys_xattr.go",
"timespec.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/syscalls/linux",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi",
"//pkg/abi/linux",
"//pkg/binary",
"//pkg/bpf",
+ "//pkg/context",
"//pkg/log",
"//pkg/metric",
"//pkg/rand",
+ "//pkg/safemem",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/lock",
@@ -88,16 +88,16 @@ go_library(
"//pkg/sentry/loader",
"//pkg/sentry/memmap",
"//pkg/sentry/mm",
- "//pkg/sentry/safemem",
"//pkg/sentry/socket",
"//pkg/sentry/socket/control",
"//pkg/sentry/socket/unix/transport",
"//pkg/sentry/syscalls",
"//pkg/sentry/usage",
- "//pkg/sentry/usermem",
+ "//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserr",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go
index 60469549d..64de56ac5 100644
--- a/pkg/sentry/syscalls/linux/error.go
+++ b/pkg/sentry/syscalls/linux/error.go
@@ -22,6 +22,7 @@ import (
"gvisor.dev/gvisor/pkg/metric"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
)
@@ -31,20 +32,58 @@ var (
partialResultOnce sync.Once
)
+// HandleIOErrorVFS2 handles special error cases for partial results. For some
+// errors, we may consume the error and return only the partial read/write.
+//
+// op and f are used only for panics.
+func HandleIOErrorVFS2(t *kernel.Task, partialResult bool, err, intr error, op string, f *vfs.FileDescription) error {
+ known, err := handleIOErrorImpl(t, partialResult, err, intr, op)
+ if err != nil {
+ return err
+ }
+ if !known {
+ // An unknown error is encountered with a partial read/write.
+ fs := f.Mount().Filesystem().VirtualFilesystem()
+ root := vfs.RootFromContext(t)
+ name, _ := fs.PathnameWithDeleted(t, root, f.VirtualDentry())
+ log.Traceback("Invalid request partialResult %v and err (type %T) %v for %s operation on %q", partialResult, err, err, op, name)
+ partialResultOnce.Do(partialResultMetric.Increment)
+ }
+ return nil
+}
+
// handleIOError handles special error cases for partial results. For some
// errors, we may consume the error and return only the partial read/write.
//
// op and f are used only for panics.
func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op string, f *fs.File) error {
+ known, err := handleIOErrorImpl(t, partialResult, err, intr, op)
+ if err != nil {
+ return err
+ }
+ if !known {
+ // An unknown error is encountered with a partial read/write.
+ name, _ := f.Dirent.FullName(nil /* ignore chroot */)
+ log.Traceback("Invalid request partialResult %v and err (type %T) %v for %s operation on %q, %T", partialResult, err, err, op, name, f.FileOperations)
+ partialResultOnce.Do(partialResultMetric.Increment)
+ }
+ return nil
+}
+
+// handleIOError handles special error cases for partial results. For some
+// errors, we may consume the error and return only the partial read/write.
+//
+// Returns false if error is unknown.
+func handleIOErrorImpl(t *kernel.Task, partialResult bool, err, intr error, op string) (bool, error) {
switch err {
case nil:
// Typical successful syscall.
- return nil
+ return true, nil
case io.EOF:
// EOF is always consumed. If this is a partial read/write
// (result != 0), the application will see that, otherwise
// they will see 0.
- return nil
+ return true, nil
case syserror.ErrExceedsFileSizeLimit:
// Ignore partialResult because this error only applies to
// normal files, and for those files we cannot accumulate
@@ -53,20 +92,20 @@ func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op strin
// Do not consume the error and return it as EFBIG.
// Simultaneously send a SIGXFSZ per setrlimit(2).
t.SendSignal(kernel.SignalInfoNoInfo(linux.SIGXFSZ, t, t))
- return syserror.EFBIG
+ return true, syserror.EFBIG
case syserror.ErrInterrupted:
// The syscall was interrupted. Return nil if it completed
// partially, otherwise return the error code that the syscall
// needs (to indicate to the kernel what it should do).
if partialResult {
- return nil
+ return true, nil
}
- return intr
+ return true, intr
}
if !partialResult {
// Typical syscall error.
- return err
+ return true, err
}
switch err {
@@ -75,14 +114,14 @@ func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op strin
// read/write. Like ErrWouldBlock, since we have a
// partial read/write, we consume the error and return
// the partial result.
- return nil
+ return true, nil
case syserror.EFAULT:
// EFAULT is only shown the user if nothing was
// read/written. If we read something (this case), they see
// a partial read/write. They will then presumably try again
// with an incremented buffer, which will EFAULT with
// result == 0.
- return nil
+ return true, nil
case syserror.EPIPE:
// Writes to a pipe or socket will return EPIPE if the other
// side is gone. The partial write is returned. EPIPE will be
@@ -90,32 +129,29 @@ func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op strin
//
// TODO(gvisor.dev/issue/161): In some cases SIGPIPE should
// also be sent to the application.
- return nil
+ return true, nil
case syserror.ENOSPC:
// Similar to EPIPE. Return what we wrote this time, and let
// ENOSPC be returned on the next call.
- return nil
+ return true, nil
case syserror.ECONNRESET:
// For TCP sendfile connections, we may have a reset. But we
// should just return n as the result.
- return nil
+ return true, nil
case syserror.ErrWouldBlock:
// Syscall would block, but completed a partial read/write.
// This case should only be returned by IssueIO for nonblocking
// files. Since we have a partial read/write, we consume
// ErrWouldBlock, returning the partial result.
- return nil
+ return true, nil
}
switch err.(type) {
case kernel.SyscallRestartErrno:
// Identical to the EINTR case.
- return nil
+ return true, nil
}
- // An unknown error is encountered with a partial read/write.
- name, _ := f.Dirent.FullName(nil /* ignore chroot */)
- log.Traceback("Invalid request partialResult %v and err (type %T) %v for %s operation on %q, %T", partialResult, err, err, op, name, f.FileOperations)
- partialResultOnce.Do(partialResultMetric.Increment)
- return nil
+ // Error is unknown and cannot be properly handled.
+ return false, nil
}
diff --git a/pkg/sentry/syscalls/linux/linux64_amd64.go b/pkg/sentry/syscalls/linux/linux64_amd64.go
index c76771a54..7435b50bf 100644
--- a/pkg/sentry/syscalls/linux/linux64_amd64.go
+++ b/pkg/sentry/syscalls/linux/linux64_amd64.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/syscalls"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// AMD64 is a table of Linux amd64 syscall API with the corresponding syscall
diff --git a/pkg/sentry/syscalls/linux/linux64_arm64.go b/pkg/sentry/syscalls/linux/linux64_arm64.go
index d3587fda6..03a39fe65 100644
--- a/pkg/sentry/syscalls/linux/linux64_arm64.go
+++ b/pkg/sentry/syscalls/linux/linux64_arm64.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/syscalls"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// ARM64 is a table of Linux arm64 syscall API with the corresponding syscall
diff --git a/pkg/sentry/syscalls/linux/sigset.go b/pkg/sentry/syscalls/linux/sigset.go
index 333013d8c..2ddb2b146 100644
--- a/pkg/sentry/syscalls/linux/sigset.go
+++ b/pkg/sentry/syscalls/linux/sigset.go
@@ -17,8 +17,8 @@ package linux
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// copyInSigSet copies in a sigset_t, checks its size, and ensures that KILL and
diff --git a/pkg/sentry/syscalls/linux/sys_aio.go b/pkg/sentry/syscalls/linux/sys_aio.go
index f56411bfe..b401978db 100644
--- a/pkg/sentry/syscalls/linux/sys_aio.go
+++ b/pkg/sentry/syscalls/linux/sys_aio.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/eventfd"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// I/O commands.
diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go
index 65b4a227b..5f11b496c 100644
--- a/pkg/sentry/syscalls/linux/sys_epoll.go
+++ b/pkg/sentry/syscalls/linux/sys_epoll.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/epoll"
"gvisor.dev/gvisor/pkg/sentry/syscalls"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go
index 9bc2445a5..421845ebb 100644
--- a/pkg/sentry/syscalls/linux/sys_file.go
+++ b/pkg/sentry/syscalls/linux/sys_file.go
@@ -18,8 +18,8 @@ import (
"syscall"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/fs/lock"
"gvisor.dev/gvisor/pkg/sentry/fs/tmpfs"
@@ -28,8 +28,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/fasync"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/limits"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// fileOpAt performs an operation on the second last component in the path.
@@ -767,7 +767,7 @@ func Close(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
// Note that Remove provides a reference on the file that we may use to
// flush. It is still active until we drop the final reference below
// (and other reference-holding operations complete).
- file := t.FDTable().Remove(fd)
+ file, _ := t.FDTable().Remove(fd)
if file == nil {
return 0, nil, syserror.EBADF
}
diff --git a/pkg/sentry/syscalls/linux/sys_futex.go b/pkg/sentry/syscalls/linux/sys_futex.go
index bde17a767..b68261f72 100644
--- a/pkg/sentry/syscalls/linux/sys_futex.go
+++ b/pkg/sentry/syscalls/linux/sys_futex.go
@@ -21,8 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// futexWaitRestartBlock encapsulates the state required to restart futex(2)
diff --git a/pkg/sentry/syscalls/linux/sys_getdents.go b/pkg/sentry/syscalls/linux/sys_getdents.go
index 912cbe4ff..f66f4ffde 100644
--- a/pkg/sentry/syscalls/linux/sys_getdents.go
+++ b/pkg/sentry/syscalls/linux/sys_getdents.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Getdents implements linux syscall getdents(2) for 64bit systems.
diff --git a/pkg/sentry/syscalls/linux/sys_mempolicy.go b/pkg/sentry/syscalls/linux/sys_mempolicy.go
index f5a519d8a..ac934dc6f 100644
--- a/pkg/sentry/syscalls/linux/sys_mempolicy.go
+++ b/pkg/sentry/syscalls/linux/sys_mempolicy.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// We unconditionally report a single NUMA node. This also means that our
diff --git a/pkg/sentry/syscalls/linux/sys_mmap.go b/pkg/sentry/syscalls/linux/sys_mmap.go
index 58a05b5bb..9959f6e61 100644
--- a/pkg/sentry/syscalls/linux/sys_mmap.go
+++ b/pkg/sentry/syscalls/linux/sys_mmap.go
@@ -22,8 +22,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/sentry/mm"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Brk implements linux syscall brk(2).
diff --git a/pkg/sentry/syscalls/linux/sys_mount.go b/pkg/sentry/syscalls/linux/sys_mount.go
index 8c13e2d82..eb5ff48f5 100644
--- a/pkg/sentry/syscalls/linux/sys_mount.go
+++ b/pkg/sentry/syscalls/linux/sys_mount.go
@@ -19,8 +19,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Mount implements Linux syscall mount(2).
diff --git a/pkg/sentry/syscalls/linux/sys_pipe.go b/pkg/sentry/syscalls/linux/sys_pipe.go
index 418d7fa5f..798344042 100644
--- a/pkg/sentry/syscalls/linux/sys_pipe.go
+++ b/pkg/sentry/syscalls/linux/sys_pipe.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/pipe"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// pipe2 implements the actual system call with flags.
diff --git a/pkg/sentry/syscalls/linux/sys_poll.go b/pkg/sentry/syscalls/linux/sys_poll.go
index 2b2df989a..4f8762d7d 100644
--- a/pkg/sentry/syscalls/linux/sys_poll.go
+++ b/pkg/sentry/syscalls/linux/sys_poll.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/limits"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/syscalls/linux/sys_random.go b/pkg/sentry/syscalls/linux/sys_random.go
index bc4c588bf..c0aa0fd60 100644
--- a/pkg/sentry/syscalls/linux/sys_random.go
+++ b/pkg/sentry/syscalls/linux/sys_random.go
@@ -19,11 +19,11 @@ import (
"math"
"gvisor.dev/gvisor/pkg/rand"
+ "gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/syscalls/linux/sys_read.go b/pkg/sentry/syscalls/linux/sys_read.go
index cd31e0649..227692f06 100644
--- a/pkg/sentry/syscalls/linux/sys_read.go
+++ b/pkg/sentry/syscalls/linux/sys_read.go
@@ -23,13 +23,13 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/socket"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
const (
- // EventMaskRead contains events that can be triggerd on reads.
+ // EventMaskRead contains events that can be triggered on reads.
EventMaskRead = waiter.EventIn | waiter.EventHUp | waiter.EventErr
)
diff --git a/pkg/sentry/syscalls/linux/sys_rlimit.go b/pkg/sentry/syscalls/linux/sys_rlimit.go
index 51e3f836b..e08c333d6 100644
--- a/pkg/sentry/syscalls/linux/sys_rlimit.go
+++ b/pkg/sentry/syscalls/linux/sys_rlimit.go
@@ -19,8 +19,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/limits"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// rlimit describes an implementation of 'struct rlimit', which may vary from
diff --git a/pkg/sentry/syscalls/linux/sys_seccomp.go b/pkg/sentry/syscalls/linux/sys_seccomp.go
index 18510ead8..5b7a66f4d 100644
--- a/pkg/sentry/syscalls/linux/sys_seccomp.go
+++ b/pkg/sentry/syscalls/linux/sys_seccomp.go
@@ -19,8 +19,8 @@ import (
"gvisor.dev/gvisor/pkg/bpf"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// userSockFprog is equivalent to Linux's struct sock_fprog on amd64.
diff --git a/pkg/sentry/syscalls/linux/sys_sem.go b/pkg/sentry/syscalls/linux/sys_sem.go
index cde3b54e7..5f54f2456 100644
--- a/pkg/sentry/syscalls/linux/sys_sem.go
+++ b/pkg/sentry/syscalls/linux/sys_sem.go
@@ -22,8 +22,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const opsMax = 500 // SEMOPM
diff --git a/pkg/sentry/syscalls/linux/sys_signal.go b/pkg/sentry/syscalls/linux/sys_signal.go
index fb6efd5d8..7e1747a0c 100644
--- a/pkg/sentry/syscalls/linux/sys_signal.go
+++ b/pkg/sentry/syscalls/linux/sys_signal.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/signalfd"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// "For a process to have permission to send a signal it must
@@ -245,6 +245,11 @@ func RtSigaction(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.S
sig := linux.Signal(args[0].Int())
newactarg := args[1].Pointer()
oldactarg := args[2].Pointer()
+ sigsetsize := args[3].SizeT()
+
+ if sigsetsize != linux.SignalSetSize {
+ return 0, nil, syserror.EINVAL
+ }
var newactptr *arch.SignalAct
if newactarg != 0 {
diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go
index cda517a81..2919228d0 100644
--- a/pkg/sentry/syscalls/linux/sys_socket.go
+++ b/pkg/sentry/syscalls/linux/sys_socket.go
@@ -26,9 +26,9 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/control"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// minListenBacklog is the minimum reasonable backlog for listening sockets.
diff --git a/pkg/sentry/syscalls/linux/sys_splice.go b/pkg/sentry/syscalls/linux/sys_splice.go
index dd3a5807f..f43d6c155 100644
--- a/pkg/sentry/syscalls/linux/sys_splice.go
+++ b/pkg/sentry/syscalls/linux/sys_splice.go
@@ -211,8 +211,10 @@ func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
opts := fs.SpliceOpts{
Length: count,
}
+ inFileAttr := inFile.Dirent.Inode.StableAttr
+ outFileAttr := outFile.Dirent.Inode.StableAttr
switch {
- case fs.IsPipe(inFile.Dirent.Inode.StableAttr) && !fs.IsPipe(outFile.Dirent.Inode.StableAttr):
+ case fs.IsPipe(inFileAttr) && !fs.IsPipe(outFileAttr):
if inOffset != 0 {
return 0, nil, syserror.ESPIPE
}
@@ -229,7 +231,7 @@ func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
opts.DstOffset = true
opts.DstStart = offset
}
- case !fs.IsPipe(inFile.Dirent.Inode.StableAttr) && fs.IsPipe(outFile.Dirent.Inode.StableAttr):
+ case !fs.IsPipe(inFileAttr) && fs.IsPipe(outFileAttr):
if outOffset != 0 {
return 0, nil, syserror.ESPIPE
}
@@ -246,13 +248,13 @@ func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
opts.SrcOffset = true
opts.SrcStart = offset
}
- case fs.IsPipe(inFile.Dirent.Inode.StableAttr) && fs.IsPipe(outFile.Dirent.Inode.StableAttr):
+ case fs.IsPipe(inFileAttr) && fs.IsPipe(outFileAttr):
if inOffset != 0 || outOffset != 0 {
return 0, nil, syserror.ESPIPE
}
// 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 {
+ if inFileAttr.InodeID == outFileAttr.InodeID {
return 0, nil, syserror.EINVAL
}
default:
@@ -262,6 +264,15 @@ func Splice(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscal
// Splice data.
n, err := doSplice(t, outFile, inFile, opts, nonBlock)
+ // Special files can have additional requirements for granularity. For
+ // example, read from eventfd returns EINVAL if a size is less 8 bytes.
+ // Inotify is another example. read will return EINVAL is a buffer is
+ // too small to return the next event, but a size of an event isn't
+ // fixed, it is sizeof(struct inotify_event) + {NAME_LEN} + 1.
+ if n != 0 && err != nil && (fs.IsAnonymous(inFileAttr) || fs.IsAnonymous(outFileAttr)) {
+ err = nil
+ }
+
// See above; inFile is chosen arbitrarily here.
return uintptr(n), nil, handleIOError(t, n != 0, err, kernel.ERESTARTSYS, "splice", inFile)
}
diff --git a/pkg/sentry/syscalls/linux/sys_stat.go b/pkg/sentry/syscalls/linux/sys_stat.go
index 69b17b799..c841abccb 100644
--- a/pkg/sentry/syscalls/linux/sys_stat.go
+++ b/pkg/sentry/syscalls/linux/sys_stat.go
@@ -19,8 +19,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// Stat implements linux syscall stat(2).
diff --git a/pkg/sentry/syscalls/linux/sys_stat_amd64.go b/pkg/sentry/syscalls/linux/sys_stat_amd64.go
index 58afb4a9a..75a567bd4 100644
--- a/pkg/sentry/syscalls/linux/sys_stat_amd64.go
+++ b/pkg/sentry/syscalls/linux/sys_stat_amd64.go
@@ -21,7 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// copyOutStat copies the attributes (sattr, uattr) to the struct stat at
diff --git a/pkg/sentry/syscalls/linux/sys_stat_arm64.go b/pkg/sentry/syscalls/linux/sys_stat_arm64.go
index 3e1251e0b..80c98d05c 100644
--- a/pkg/sentry/syscalls/linux/sys_stat_arm64.go
+++ b/pkg/sentry/syscalls/linux/sys_stat_arm64.go
@@ -21,7 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/binary"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// copyOutStat copies the attributes (sattr, uattr) to the struct stat at
diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go
index b47c3b5c4..0c9e2255d 100644
--- a/pkg/sentry/syscalls/linux/sys_thread.go
+++ b/pkg/sentry/syscalls/linux/sys_thread.go
@@ -24,8 +24,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/sched"
"gvisor.dev/gvisor/pkg/sentry/loader"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const (
diff --git a/pkg/sentry/syscalls/linux/sys_time.go b/pkg/sentry/syscalls/linux/sys_time.go
index b887fa9d7..2d2aa0819 100644
--- a/pkg/sentry/syscalls/linux/sys_time.go
+++ b/pkg/sentry/syscalls/linux/sys_time.go
@@ -22,8 +22,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// The most significant 29 bits hold either a pid or a file descriptor.
diff --git a/pkg/sentry/syscalls/linux/sys_timer.go b/pkg/sentry/syscalls/linux/sys_timer.go
index d4134207b..432351917 100644
--- a/pkg/sentry/syscalls/linux/sys_timer.go
+++ b/pkg/sentry/syscalls/linux/sys_timer.go
@@ -20,8 +20,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
const nsecPerSec = int64(time.Second)
diff --git a/pkg/sentry/syscalls/linux/sys_write.go b/pkg/sentry/syscalls/linux/sys_write.go
index ad4b67806..aba892939 100644
--- a/pkg/sentry/syscalls/linux/sys_write.go
+++ b/pkg/sentry/syscalls/linux/sys_write.go
@@ -23,8 +23,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/socket"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
diff --git a/pkg/sentry/syscalls/linux/sys_xattr.go b/pkg/sentry/syscalls/linux/sys_xattr.go
index e35c077d6..efb95555c 100644
--- a/pkg/sentry/syscalls/linux/sys_xattr.go
+++ b/pkg/sentry/syscalls/linux/sys_xattr.go
@@ -21,8 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// GetXattr implements linux syscall getxattr(2).
@@ -103,6 +103,7 @@ func getXattr(t *kernel.Task, d *fs.Dirent, nameAddr usermem.Addr, size uint64)
return 0, "", err
}
+ // TODO(b/148380782): Support xattrs in namespaces other than "user".
if !strings.HasPrefix(name, linux.XATTR_USER_PREFIX) {
return 0, "", syserror.EOPNOTSUPP
}
diff --git a/pkg/sentry/syscalls/linux/timespec.go b/pkg/sentry/syscalls/linux/timespec.go
index 4ff8f9234..ddc3ee26e 100644
--- a/pkg/sentry/syscalls/linux/timespec.go
+++ b/pkg/sentry/syscalls/linux/timespec.go
@@ -19,8 +19,8 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// copyTimespecIn copies a Timespec from the untrusted app range to the kernel.
diff --git a/pkg/sentry/syscalls/linux/vfs2/BUILD b/pkg/sentry/syscalls/linux/vfs2/BUILD
new file mode 100644
index 000000000..6b8a00b6e
--- /dev/null
+++ b/pkg/sentry/syscalls/linux/vfs2/BUILD
@@ -0,0 +1,24 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "vfs2",
+ srcs = [
+ "linux64.go",
+ "linux64_override_amd64.go",
+ "linux64_override_arm64.go",
+ "sys_read.go",
+ ],
+ visibility = ["//:sandbox"],
+ deps = [
+ "//pkg/sentry/arch",
+ "//pkg/sentry/kernel",
+ "//pkg/sentry/syscalls",
+ "//pkg/sentry/syscalls/linux",
+ "//pkg/sentry/vfs",
+ "//pkg/syserror",
+ "//pkg/usermem",
+ "//pkg/waiter",
+ ],
+)
diff --git a/pkg/sentry/safemem/safemem.go b/pkg/sentry/syscalls/linux/vfs2/linux64.go
index 3e70d33a2..19ee36081 100644
--- a/pkg/sentry/safemem/safemem.go
+++ b/pkg/sentry/syscalls/linux/vfs2/linux64.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The gVisor Authors.
+// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,5 +12,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package safemem provides the Block and BlockSeq types.
-package safemem
+// Package vfs2 provides syscall implementations that use VFS2.
+package vfs2
diff --git a/pkg/sentry/usermem/usermem_unsafe.go b/pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go
index 876783e78..c134714ee 100644
--- a/pkg/sentry/usermem/usermem_unsafe.go
+++ b/pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The gVisor Authors.
+// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,16 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package usermem
+package vfs2
import (
- "unsafe"
+ "gvisor.dev/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/syscalls"
)
-// stringFromImmutableBytes is equivalent to string(bs), except that it never
-// copies even if escape analysis can't prove that bs does not escape. This is
-// only valid if bs is never mutated after stringFromImmutableBytes returns.
-func stringFromImmutableBytes(bs []byte) string {
- // Compare strings.Builder.String().
- return *(*string)(unsafe.Pointer(&bs))
+// Override syscall table to add syscalls implementations from this package.
+func Override(table map[uintptr]kernel.Syscall) {
+ table[0] = syscalls.Supported("read", Read)
}
diff --git a/pkg/sentry/usermem/usermem_x86.go b/pkg/sentry/syscalls/linux/vfs2/linux64_override_arm64.go
index 8059b72d2..6af5c400f 100644
--- a/pkg/sentry/usermem/usermem_x86.go
+++ b/pkg/sentry/syscalls/linux/vfs2/linux64_override_arm64.go
@@ -1,4 +1,4 @@
-// Copyright 2018 The gVisor Authors.
+// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,27 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// +build amd64 i386
+package vfs2
-package usermem
-
-import "encoding/binary"
-
-const (
- // PageSize is the system page size.
- PageSize = 1 << PageShift
-
- // HugePageSize is the system huge page size.
- HugePageSize = 1 << HugePageShift
-
- // PageShift is the binary log of the system page size.
- PageShift = 12
-
- // HugePageShift is the binary log of the system huge page size.
- HugePageShift = 21
+import (
+ "gvisor.dev/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/syscalls"
)
-var (
- // ByteOrder is the native byte order (little endian).
- ByteOrder = binary.LittleEndian
-)
+// Override syscall table to add syscalls implementations from this package.
+func Override(table map[uintptr]kernel.Syscall) {
+ table[63] = syscalls.Supported("read", Read)
+}
diff --git a/pkg/sentry/syscalls/linux/vfs2/sys_read.go b/pkg/sentry/syscalls/linux/vfs2/sys_read.go
new file mode 100644
index 000000000..7667524c7
--- /dev/null
+++ b/pkg/sentry/syscalls/linux/vfs2/sys_read.go
@@ -0,0 +1,95 @@
+// Copyright 2020 The 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 vfs2
+
+import (
+ "gvisor.dev/gvisor/pkg/sentry/arch"
+ "gvisor.dev/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
+ "gvisor.dev/gvisor/pkg/waiter"
+)
+
+const (
+ // EventMaskRead contains events that can be triggered on reads.
+ EventMaskRead = waiter.EventIn | waiter.EventHUp | waiter.EventErr
+)
+
+// Read implements linux syscall read(2). Note that we try to get a buffer that
+// is exactly the size requested because some applications like qemu expect
+// they can do large reads all at once. Bug for bug. Same for other read
+// calls below.
+func Read(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ fd := args[0].Int()
+ addr := args[1].Pointer()
+ size := args[2].SizeT()
+
+ file := t.GetFileVFS2(fd)
+ if file == nil {
+ return 0, nil, syserror.EBADF
+ }
+ defer file.DecRef()
+
+ // Check that the size is legitimate.
+ si := int(size)
+ if si < 0 {
+ return 0, nil, syserror.EINVAL
+ }
+
+ // Get the destination of the read.
+ dst, err := t.SingleIOSequence(addr, si, usermem.IOOpts{
+ AddressSpaceActive: true,
+ })
+ if err != nil {
+ return 0, nil, err
+ }
+
+ n, err := read(t, file, dst, vfs.ReadOptions{})
+ t.IOUsage().AccountReadSyscall(n)
+ return uintptr(n), nil, linux.HandleIOErrorVFS2(t, n != 0, err, kernel.ERESTARTSYS, "read", file)
+}
+
+func read(t *kernel.Task, file *vfs.FileDescription, dst usermem.IOSequence, opts vfs.ReadOptions) (int64, error) {
+ n, err := file.Read(t, dst, opts)
+ if err != syserror.ErrWouldBlock {
+ return n, err
+ }
+
+ // Register for notifications.
+ w, ch := waiter.NewChannelEntry(nil)
+ file.EventRegister(&w, EventMaskRead)
+
+ total := n
+ for {
+ // Shorten dst to reflect bytes previously read.
+ dst = dst.DropFirst(int(n))
+
+ // Issue the request and break out if it completes with anything other than
+ // "would block".
+ n, err := file.Read(t, dst, opts)
+ total += n
+ if err != syserror.ErrWouldBlock {
+ break
+ }
+ if err := t.Block(ch); err != nil {
+ break
+ }
+ }
+ file.EventUnregister(&w)
+
+ return total, err
+}
diff --git a/pkg/sentry/time/BUILD b/pkg/sentry/time/BUILD
index 3cde3a0be..04f81a35b 100644
--- a/pkg/sentry/time/BUILD
+++ b/pkg/sentry/time/BUILD
@@ -1,5 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
load("//tools/go_generics:defs.bzl", "go_template_instance")
package(licenses = ["notice"])
@@ -31,7 +30,6 @@ go_library(
"tsc_amd64.s",
"tsc_arm64.s",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/time",
visibility = ["//:sandbox"],
deps = [
"//pkg/log",
@@ -48,5 +46,5 @@ go_test(
"parameters_test.go",
"sampler_test.go",
],
- embed = [":time"],
+ library = ":time",
)
diff --git a/pkg/sentry/unimpl/BUILD b/pkg/sentry/unimpl/BUILD
index fc7614fff..5d4aa3a63 100644
--- a/pkg/sentry/unimpl/BUILD
+++ b/pkg/sentry/unimpl/BUILD
@@ -1,37 +1,20 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load("//tools:defs.bzl", "go_library", "proto_library")
package(licenses = ["notice"])
proto_library(
- name = "unimplemented_syscall_proto",
+ name = "unimplemented_syscall",
srcs = ["unimplemented_syscall.proto"],
visibility = ["//visibility:public"],
deps = ["//pkg/sentry/arch:registers_proto"],
)
-cc_proto_library(
- name = "unimplemented_syscall_cc_proto",
- visibility = ["//visibility:public"],
- deps = [":unimplemented_syscall_proto"],
-)
-
-go_proto_library(
- name = "unimplemented_syscall_go_proto",
- importpath = "gvisor.dev/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.dev/gvisor/pkg/sentry/unimpl",
visibility = ["//:sandbox"],
deps = [
+ "//pkg/context",
"//pkg/log",
- "//pkg/sentry/context",
],
)
diff --git a/pkg/sentry/unimpl/events.go b/pkg/sentry/unimpl/events.go
index 79b5de9e4..73ed9372f 100644
--- a/pkg/sentry/unimpl/events.go
+++ b/pkg/sentry/unimpl/events.go
@@ -17,8 +17,8 @@
package unimpl
import (
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/log"
- "gvisor.dev/gvisor/pkg/sentry/context"
)
// contextID is the events package's type for context.Context.Value keys.
diff --git a/pkg/sentry/uniqueid/BUILD b/pkg/sentry/uniqueid/BUILD
index 86a87edd4..7467e6398 100644
--- a/pkg/sentry/uniqueid/BUILD
+++ b/pkg/sentry/uniqueid/BUILD
@@ -1,14 +1,13 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "uniqueid",
srcs = ["context.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/uniqueid",
visibility = ["//pkg/sentry:internal"],
deps = [
- "//pkg/sentry/context",
+ "//pkg/context",
"//pkg/sentry/socket/unix/transport",
],
)
diff --git a/pkg/sentry/uniqueid/context.go b/pkg/sentry/uniqueid/context.go
index 4e466d66d..1fb884a90 100644
--- a/pkg/sentry/uniqueid/context.go
+++ b/pkg/sentry/uniqueid/context.go
@@ -17,7 +17,7 @@
package uniqueid
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
)
diff --git a/pkg/sentry/usage/BUILD b/pkg/sentry/usage/BUILD
index 5518ac3d0..099315613 100644
--- a/pkg/sentry/usage/BUILD
+++ b/pkg/sentry/usage/BUILD
@@ -1,4 +1,4 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
@@ -11,9 +11,8 @@ go_library(
"memory_unsafe.go",
"usage.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/usage",
visibility = [
- "//pkg/sentry:internal",
+ "//:sandbox",
],
deps = [
"//pkg/bits",
diff --git a/pkg/sentry/usermem/BUILD b/pkg/sentry/usermem/BUILD
deleted file mode 100644
index 684f59a6b..000000000
--- a/pkg/sentry/usermem/BUILD
+++ /dev/null
@@ -1,58 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
-load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library")
-
-package(licenses = ["notice"])
-
-go_template_instance(
- name = "addr_range",
- out = "addr_range.go",
- package = "usermem",
- prefix = "Addr",
- template = "//pkg/segment:generic_range",
- types = {
- "T": "Addr",
- },
-)
-
-go_library(
- name = "usermem",
- srcs = [
- "access_type.go",
- "addr.go",
- "addr_range.go",
- "addr_range_seq_unsafe.go",
- "bytes_io.go",
- "bytes_io_unsafe.go",
- "usermem.go",
- "usermem_arm64.go",
- "usermem_unsafe.go",
- "usermem_x86.go",
- ],
- importpath = "gvisor.dev/gvisor/pkg/sentry/usermem",
- visibility = ["//pkg/sentry:internal"],
- deps = [
- "//pkg/atomicbitops",
- "//pkg/binary",
- "//pkg/log",
- "//pkg/sentry/context",
- "//pkg/sentry/safemem",
- "//pkg/syserror",
- "//pkg/tcpip/buffer",
- ],
-)
-
-go_test(
- name = "usermem_test",
- size = "small",
- srcs = [
- "addr_range_seq_test.go",
- "usermem_test.go",
- ],
- embed = [":usermem"],
- deps = [
- "//pkg/sentry/context",
- "//pkg/sentry/safemem",
- "//pkg/syserror",
- ],
-)
diff --git a/pkg/sentry/usermem/README.md b/pkg/sentry/usermem/README.md
deleted file mode 100644
index f6d2137eb..000000000
--- a/pkg/sentry/usermem/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-This package defines primitives for sentry access to application memory.
-
-Major types:
-
-- The `IO` interface represents a virtual address space and provides I/O
- methods on that address space. `IO` is the lowest-level primitive. The
- primary implementation of the `IO` interface is `mm.MemoryManager`.
-
-- `IOSequence` represents a collection of individually-contiguous address
- ranges in a `IO` that is operated on sequentially, analogous to Linux's
- `struct iov_iter`.
-
-Major usage patterns:
-
-- Access to a task's virtual memory, subject to the application's memory
- protections and while running on that task's goroutine, from a context that
- is at or above the level of the `kernel` package (e.g. most syscall
- implementations in `syscalls/linux`); use the `kernel.Task.Copy*` wrappers
- defined in `kernel/task_usermem.go`.
-
-- Access to a task's virtual memory, from a context that is at or above the
- level of the `kernel` package, but where any of the above constraints does
- not hold (e.g. `PTRACE_POKEDATA`, which ignores application memory
- protections); obtain the task's `mm.MemoryManager` by calling
- `kernel.Task.MemoryManager`, and call its `IO` methods directly.
-
-- Access to a task's virtual memory, from a context that is below the level of
- the `kernel` package (e.g. filesystem I/O); clients must pass I/O arguments
- from higher layers, usually in the form of an `IOSequence`. The
- `kernel.Task.SingleIOSequence` and `kernel.Task.IovecsIOSequence` functions
- in `kernel/task_usermem.go` are convenience functions for doing so.
diff --git a/pkg/sentry/usermem/access_type.go b/pkg/sentry/usermem/access_type.go
deleted file mode 100644
index 9c1742a59..000000000
--- a/pkg/sentry/usermem/access_type.go
+++ /dev/null
@@ -1,128 +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 usermem
-
-import (
- "syscall"
-)
-
-// 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
-
- // Write is write access.
- Write bool
-
- // Execute is executable access.
- Execute bool
-}
-
-// String returns a pretty representation of access. This looks like the
-// familiar r-x, rw-, etc. and can be relied on as such.
-func (a AccessType) String() string {
- bits := [3]byte{'-', '-', '-'}
- if a.Read {
- bits[0] = 'r'
- }
- if a.Write {
- bits[1] = 'w'
- }
- if a.Execute {
- bits[2] = 'x'
- }
- return string(bits[:])
-}
-
-// Any returns true iff at least one of Read, Write or Execute is true.
-func (a AccessType) Any() bool {
- return a.Read || a.Write || a.Execute
-}
-
-// Prot returns the system prot (syscall.PROT_READ, etc.) for this access.
-func (a AccessType) Prot() int {
- var prot int
- if a.Read {
- prot |= syscall.PROT_READ
- }
- if a.Write {
- prot |= syscall.PROT_WRITE
- }
- if a.Execute {
- prot |= syscall.PROT_EXEC
- }
- return prot
-}
-
-// SupersetOf returns true iff the access types in a are a superset of the
-// access types in other.
-func (a AccessType) SupersetOf(other AccessType) bool {
- if !a.Read && other.Read {
- return false
- }
- if !a.Write && other.Write {
- return false
- }
- if !a.Execute && other.Execute {
- return false
- }
- return true
-}
-
-// Intersect returns the access types set in both a and other.
-func (a AccessType) Intersect(other AccessType) AccessType {
- return AccessType{
- Read: a.Read && other.Read,
- Write: a.Write && other.Write,
- Execute: a.Execute && other.Execute,
- }
-}
-
-// Union returns the access types set in either a or other.
-func (a AccessType) Union(other AccessType) AccessType {
- return AccessType{
- Read: a.Read || other.Read,
- Write: a.Write || other.Write,
- Execute: a.Execute || other.Execute,
- }
-}
-
-// Effective returns the set of effective access types allowed by a, even if
-// some types are not explicitly allowed.
-func (a AccessType) Effective() AccessType {
- // In Linux, Write and Execute access generally imply Read access. See
- // mm/mmap.c:protection_map.
- //
- // The notable exception is get_user_pages, which only checks against
- // the original vma flags. That said, most user memory accesses do not
- // use GUP.
- if a.Write || a.Execute {
- a.Read = true
- }
- return a
-}
-
-// Convenient access types.
-var (
- NoAccess = AccessType{}
- Read = AccessType{Read: true}
- Write = AccessType{Write: true}
- Execute = AccessType{Execute: true}
- ReadWrite = AccessType{Read: true, Write: true}
- AnyAccess = AccessType{Read: true, Write: true, Execute: true}
-)
diff --git a/pkg/sentry/usermem/addr.go b/pkg/sentry/usermem/addr.go
deleted file mode 100644
index e79210804..000000000
--- a/pkg/sentry/usermem/addr.go
+++ /dev/null
@@ -1,108 +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 usermem
-
-import (
- "fmt"
-)
-
-// 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
-// iff adding the length did not overflow the range of Addr.
-//
-// Note: This function is usually used to get the end of an address range
-// defined by its start address and length. Since the resulting end is
-// exclusive, end == 0 is technically valid, and corresponds to a range that
-// extends to the end of the address space, but ok will be false. This isn't
-// expected to ever come up in practice.
-func (v Addr) AddLength(length uint64) (end Addr, ok bool) {
- end = v + Addr(length)
- // The second half of the following check is needed in case uintptr is
- // smaller than 64 bits.
- ok = end >= v && length <= uint64(^Addr(0))
- return
-}
-
-// RoundDown returns the address rounded down to the nearest page boundary.
-func (v Addr) RoundDown() Addr {
- return v & ^Addr(PageSize-1)
-}
-
-// RoundUp returns the address rounded up to the nearest page boundary. ok is
-// true iff rounding up did not wrap around.
-func (v Addr) RoundUp() (addr Addr, ok bool) {
- addr = Addr(v + PageSize - 1).RoundDown()
- ok = addr >= v
- return
-}
-
-// MustRoundUp is equivalent to RoundUp, but panics if rounding up wraps
-// around.
-func (v Addr) MustRoundUp() Addr {
- addr, ok := v.RoundUp()
- if !ok {
- panic(fmt.Sprintf("usermem.Addr(%d).RoundUp() wraps", v))
- }
- return addr
-}
-
-// HugeRoundDown returns the address rounded down to the nearest huge page
-// boundary.
-func (v Addr) HugeRoundDown() Addr {
- return v & ^Addr(HugePageSize-1)
-}
-
-// HugeRoundUp returns the address rounded up to the nearest huge page boundary.
-// ok is true iff rounding up did not wrap around.
-func (v Addr) HugeRoundUp() (addr Addr, ok bool) {
- addr = Addr(v + HugePageSize - 1).HugeRoundDown()
- ok = addr >= v
- return
-}
-
-// PageOffset returns the offset of v into the current page.
-func (v Addr) PageOffset() uint64 {
- return uint64(v & Addr(PageSize-1))
-}
-
-// IsPageAligned returns true if v.PageOffset() == 0.
-func (v Addr) IsPageAligned() bool {
- return v.PageOffset() == 0
-}
-
-// AddrRange is a range of Addrs.
-//
-// type AddrRange <generated by go_generics>
-
-// ToRange returns [v, v+length).
-func (v Addr) ToRange(length uint64) (AddrRange, bool) {
- end, ok := v.AddLength(length)
- return AddrRange{v, end}, ok
-}
-
-// IsPageAligned returns true if ar.Start.IsPageAligned() and
-// ar.End.IsPageAligned().
-func (ar AddrRange) IsPageAligned() bool {
- return ar.Start.IsPageAligned() && ar.End.IsPageAligned()
-}
-
-// String implements fmt.Stringer.String.
-func (ar AddrRange) String() string {
- return fmt.Sprintf("[%#x, %#x)", ar.Start, ar.End)
-}
diff --git a/pkg/sentry/usermem/addr_range_seq_test.go b/pkg/sentry/usermem/addr_range_seq_test.go
deleted file mode 100644
index 82f735026..000000000
--- a/pkg/sentry/usermem/addr_range_seq_test.go
+++ /dev/null
@@ -1,197 +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 usermem
-
-import (
- "testing"
-)
-
-var addrRangeSeqTests = []struct {
- desc string
- ranges []AddrRange
-}{
- {
- desc: "Empty sequence",
- },
- {
- desc: "Single empty AddrRange",
- ranges: []AddrRange{
- {0x10, 0x10},
- },
- },
- {
- desc: "Single non-empty AddrRange of length 1",
- ranges: []AddrRange{
- {0x10, 0x11},
- },
- },
- {
- desc: "Single non-empty AddrRange of length 2",
- ranges: []AddrRange{
- {0x10, 0x12},
- },
- },
- {
- desc: "Multiple non-empty AddrRanges",
- ranges: []AddrRange{
- {0x10, 0x11},
- {0x20, 0x22},
- },
- },
- {
- desc: "Multiple AddrRanges including empty AddrRanges",
- ranges: []AddrRange{
- {0x10, 0x10},
- {0x20, 0x20},
- {0x30, 0x33},
- {0x40, 0x44},
- {0x50, 0x50},
- {0x60, 0x60},
- {0x70, 0x77},
- {0x80, 0x88},
- {0x90, 0x90},
- {0xa0, 0xa0},
- },
- },
-}
-
-func testAddrRangeSeqEqualityWithTailIteration(t *testing.T, ars AddrRangeSeq, wantRanges []AddrRange) {
- var wantLen int64
- for _, ar := range wantRanges {
- wantLen += int64(ar.Length())
- }
-
- var i int
- for !ars.IsEmpty() {
- if gotLen := ars.NumBytes(); gotLen != wantLen {
- t.Errorf("Iteration %d: %v.NumBytes(): got %d, wanted %d", i, ars, gotLen, wantLen)
- }
- if gotN, wantN := ars.NumRanges(), len(wantRanges)-i; gotN != wantN {
- t.Errorf("Iteration %d: %v.NumRanges(): got %d, wanted %d", i, ars, gotN, wantN)
- }
- got := ars.Head()
- if i >= len(wantRanges) {
- t.Errorf("Iteration %d: %v.Head(): got %s, wanted <end of sequence>", i, ars, got)
- } else if want := wantRanges[i]; got != want {
- t.Errorf("Iteration %d: %v.Head(): got %s, wanted %s", i, ars, got, want)
- }
- ars = ars.Tail()
- wantLen -= int64(got.Length())
- i++
- }
- if gotLen := ars.NumBytes(); gotLen != 0 || wantLen != 0 {
- t.Errorf("Iteration %d: %v.NumBytes(): got %d, wanted %d (which should be 0)", i, ars, gotLen, wantLen)
- }
- if gotN := ars.NumRanges(); gotN != 0 {
- t.Errorf("Iteration %d: %v.NumRanges(): got %d, wanted 0", i, ars, gotN)
- }
-}
-
-func TestAddrRangeSeqTailIteration(t *testing.T) {
- for _, test := range addrRangeSeqTests {
- t.Run(test.desc, func(t *testing.T) {
- testAddrRangeSeqEqualityWithTailIteration(t, AddrRangeSeqFromSlice(test.ranges), test.ranges)
- })
- }
-}
-
-func TestAddrRangeSeqDropFirstEmpty(t *testing.T) {
- var ars AddrRangeSeq
- if got, want := ars.DropFirst(1), ars; got != want {
- t.Errorf("%v.DropFirst(1): got %v, wanted %v", ars, got, want)
- }
-}
-
-func TestAddrRangeSeqDropSingleByteIteration(t *testing.T) {
- // Tests AddrRangeSeq iteration using Head/DropFirst, simulating
- // I/O-per-AddrRange.
- for _, test := range addrRangeSeqTests {
- t.Run(test.desc, func(t *testing.T) {
- // Figure out what AddrRanges we expect to see.
- var wantLen int64
- var wantRanges []AddrRange
- for _, ar := range test.ranges {
- wantLen += int64(ar.Length())
- wantRanges = append(wantRanges, ar)
- if ar.Length() == 0 {
- // We "do" 0 bytes of I/O and then call DropFirst(0),
- // advancing to the next AddrRange.
- continue
- }
- // Otherwise we "do" 1 byte of I/O and then call DropFirst(1),
- // advancing the AddrRange by 1 byte, or to the next AddrRange
- // if this one is exhausted.
- for ar.Start++; ar.Length() != 0; ar.Start++ {
- wantRanges = append(wantRanges, ar)
- }
- }
- t.Logf("Expected AddrRanges: %s (%d bytes)", wantRanges, wantLen)
-
- ars := AddrRangeSeqFromSlice(test.ranges)
- var i int
- for !ars.IsEmpty() {
- if gotLen := ars.NumBytes(); gotLen != wantLen {
- t.Errorf("Iteration %d: %v.NumBytes(): got %d, wanted %d", i, ars, gotLen, wantLen)
- }
- got := ars.Head()
- if i >= len(wantRanges) {
- t.Errorf("Iteration %d: %v.Head(): got %s, wanted <end of sequence>", i, ars, got)
- } else if want := wantRanges[i]; got != want {
- t.Errorf("Iteration %d: %v.Head(): got %s, wanted %s", i, ars, got, want)
- }
- if got.Length() == 0 {
- ars = ars.DropFirst(0)
- } else {
- ars = ars.DropFirst(1)
- wantLen--
- }
- i++
- }
- if gotLen := ars.NumBytes(); gotLen != 0 || wantLen != 0 {
- t.Errorf("Iteration %d: %v.NumBytes(): got %d, wanted %d (which should be 0)", i, ars, gotLen, wantLen)
- }
- })
- }
-}
-
-func TestAddrRangeSeqTakeFirstEmpty(t *testing.T) {
- var ars AddrRangeSeq
- if got, want := ars.TakeFirst(1), ars; got != want {
- t.Errorf("%v.TakeFirst(1): got %v, wanted %v", ars, got, want)
- }
-}
-
-func TestAddrRangeSeqTakeFirst(t *testing.T) {
- ranges := []AddrRange{
- {0x10, 0x11},
- {0x20, 0x22},
- {0x30, 0x30},
- {0x40, 0x44},
- {0x50, 0x55},
- {0x60, 0x60},
- {0x70, 0x77},
- }
- ars := AddrRangeSeqFromSlice(ranges).TakeFirst(5)
- want := []AddrRange{
- {0x10, 0x11}, // +1 byte (total 1 byte), not truncated
- {0x20, 0x22}, // +2 bytes (total 3 bytes), not truncated
- {0x30, 0x30}, // +0 bytes (total 3 bytes), no change
- {0x40, 0x42}, // +2 bytes (total 5 bytes), partially truncated
- {0x50, 0x50}, // +0 bytes (total 5 bytes), fully truncated
- {0x60, 0x60}, // +0 bytes (total 5 bytes), "fully truncated" (no change)
- {0x70, 0x70}, // +0 bytes (total 5 bytes), fully truncated
- }
- testAddrRangeSeqEqualityWithTailIteration(t, ars, want)
-}
diff --git a/pkg/sentry/usermem/addr_range_seq_unsafe.go b/pkg/sentry/usermem/addr_range_seq_unsafe.go
deleted file mode 100644
index c09337c15..000000000
--- a/pkg/sentry/usermem/addr_range_seq_unsafe.go
+++ /dev/null
@@ -1,277 +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 usermem
-
-import (
- "bytes"
- "fmt"
- "reflect"
- "unsafe"
-)
-
-// An AddrRangeSeq represents a sequence of AddrRanges.
-//
-// AddrRangeSeqs are immutable and may be copied by value. The zero value of
-// AddrRangeSeq represents an empty sequence.
-//
-// An AddrRangeSeq may contain AddrRanges with a length of 0. This is necessary
-// since zero-length AddrRanges are significant to MM bounds checks.
-type AddrRangeSeq struct {
- // If length is 0, then the AddrRangeSeq represents no AddrRanges.
- // Invariants: data == 0; offset == 0; limit == 0.
- //
- // If length is 1, then the AddrRangeSeq represents the single
- // AddrRange{offset, offset+limit}. Invariants: data == 0.
- //
- // Otherwise, length >= 2, and the AddrRangeSeq represents the `length`
- // AddrRanges in the array of AddrRanges starting at address `data`,
- // starting at `offset` bytes into the first AddrRange and limited to the
- // following `limit` bytes. (AddrRanges after `limit` are still iterated,
- // but are truncated to a length of 0.) Invariants: data != 0; offset <=
- // data[0].Length(); limit > 0; offset+limit <= the combined length of all
- // AddrRanges in the array.
- data unsafe.Pointer
- length int
- offset Addr
- limit Addr
-}
-
-// AddrRangeSeqOf returns an AddrRangeSeq representing the single AddrRange ar.
-func AddrRangeSeqOf(ar AddrRange) AddrRangeSeq {
- return AddrRangeSeq{
- length: 1,
- offset: ar.Start,
- limit: ar.Length(),
- }
-}
-
-// AddrRangeSeqFromSlice returns an AddrRangeSeq representing all AddrRanges in
-// slice.
-//
-// Whether the returned AddrRangeSeq shares memory with slice is unspecified;
-// clients should avoid mutating slices passed to AddrRangeSeqFromSlice.
-//
-// Preconditions: The combined length of all AddrRanges in slice <=
-// math.MaxInt64.
-func AddrRangeSeqFromSlice(slice []AddrRange) AddrRangeSeq {
- var limit int64
- for _, ar := range slice {
- len64 := int64(ar.Length())
- if len64 < 0 {
- panic(fmt.Sprintf("Length of AddrRange %v overflows int64", ar))
- }
- sum := limit + len64
- if sum < limit {
- panic(fmt.Sprintf("Total length of AddrRanges %v overflows int64", slice))
- }
- limit = sum
- }
- return addrRangeSeqFromSliceLimited(slice, limit)
-}
-
-// Preconditions: The combined length of all AddrRanges in slice <= limit.
-// limit >= 0. If len(slice) != 0, then limit > 0.
-func addrRangeSeqFromSliceLimited(slice []AddrRange, limit int64) AddrRangeSeq {
- switch len(slice) {
- case 0:
- return AddrRangeSeq{}
- case 1:
- return AddrRangeSeq{
- length: 1,
- offset: slice[0].Start,
- limit: Addr(limit),
- }
- default:
- return AddrRangeSeq{
- data: unsafe.Pointer(&slice[0]),
- length: len(slice),
- limit: Addr(limit),
- }
- }
-}
-
-// IsEmpty returns true if ars.NumRanges() == 0.
-//
-// Note that since AddrRangeSeq may contain AddrRanges with a length of zero,
-// an AddrRange representing 0 bytes (AddrRangeSeq.NumBytes() == 0) is not
-// necessarily empty.
-func (ars AddrRangeSeq) IsEmpty() bool {
- return ars.length == 0
-}
-
-// NumRanges returns the number of AddrRanges in ars.
-func (ars AddrRangeSeq) NumRanges() int {
- return ars.length
-}
-
-// NumBytes returns the number of bytes represented by ars.
-func (ars AddrRangeSeq) NumBytes() int64 {
- return int64(ars.limit)
-}
-
-// Head returns the first AddrRange in ars.
-//
-// Preconditions: !ars.IsEmpty().
-func (ars AddrRangeSeq) Head() AddrRange {
- if ars.length == 0 {
- panic("empty AddrRangeSeq")
- }
- if ars.length == 1 {
- return AddrRange{ars.offset, ars.offset + ars.limit}
- }
- ar := *(*AddrRange)(ars.data)
- ar.Start += ars.offset
- if ar.Length() > ars.limit {
- ar.End = ar.Start + ars.limit
- }
- return ar
-}
-
-// Tail returns an AddrRangeSeq consisting of all AddrRanges in ars after the
-// first.
-//
-// Preconditions: !ars.IsEmpty().
-func (ars AddrRangeSeq) Tail() AddrRangeSeq {
- if ars.length == 0 {
- panic("empty AddrRangeSeq")
- }
- if ars.length == 1 {
- return AddrRangeSeq{}
- }
- return ars.externalTail()
-}
-
-// Preconditions: ars.length >= 2.
-func (ars AddrRangeSeq) externalTail() AddrRangeSeq {
- headLen := (*AddrRange)(ars.data).Length() - ars.offset
- var tailLimit int64
- if ars.limit > headLen {
- tailLimit = int64(ars.limit - headLen)
- }
- var extSlice []AddrRange
- extSliceHdr := (*reflect.SliceHeader)(unsafe.Pointer(&extSlice))
- extSliceHdr.Data = uintptr(ars.data)
- extSliceHdr.Len = ars.length
- extSliceHdr.Cap = ars.length
- return addrRangeSeqFromSliceLimited(extSlice[1:], tailLimit)
-}
-
-// DropFirst returns an AddrRangeSeq equivalent to ars, but with the first n
-// bytes omitted. If n > ars.NumBytes(), DropFirst returns an empty
-// AddrRangeSeq.
-//
-// If !ars.IsEmpty() and ars.Head().Length() == 0, DropFirst will always omit
-// at least ars.Head(), even if n == 0. This guarantees that the basic pattern
-// of:
-//
-// for !ars.IsEmpty() {
-// n, err = doIOWith(ars.Head())
-// if err != nil {
-// return err
-// }
-// ars = ars.DropFirst(n)
-// }
-//
-// works even in the presence of zero-length AddrRanges.
-//
-// Preconditions: n >= 0.
-func (ars AddrRangeSeq) DropFirst(n int) AddrRangeSeq {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- return ars.DropFirst64(int64(n))
-}
-
-// DropFirst64 is equivalent to DropFirst but takes an int64.
-func (ars AddrRangeSeq) DropFirst64(n int64) AddrRangeSeq {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- if Addr(n) > ars.limit {
- return AddrRangeSeq{}
- }
- // Handle initial empty AddrRange.
- switch ars.length {
- case 0:
- return AddrRangeSeq{}
- case 1:
- if ars.limit == 0 {
- return AddrRangeSeq{}
- }
- default:
- if rawHeadLen := (*AddrRange)(ars.data).Length(); ars.offset == rawHeadLen {
- ars = ars.externalTail()
- }
- }
- for n != 0 {
- // Calling ars.Head() here is surprisingly expensive, so inline getting
- // the head's length.
- var headLen Addr
- if ars.length == 1 {
- headLen = ars.limit
- } else {
- headLen = (*AddrRange)(ars.data).Length() - ars.offset
- }
- if Addr(n) < headLen {
- // Dropping ends partway through the head AddrRange.
- ars.offset += Addr(n)
- ars.limit -= Addr(n)
- return ars
- }
- n -= int64(headLen)
- ars = ars.Tail()
- }
- return ars
-}
-
-// TakeFirst returns an AddrRangeSeq equivalent to ars, but iterating at most n
-// bytes. TakeFirst never removes AddrRanges from ars; AddrRanges beyond the
-// first n bytes are reduced to a length of zero, but will still be iterated.
-//
-// Preconditions: n >= 0.
-func (ars AddrRangeSeq) TakeFirst(n int) AddrRangeSeq {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- return ars.TakeFirst64(int64(n))
-}
-
-// TakeFirst64 is equivalent to TakeFirst but takes an int64.
-func (ars AddrRangeSeq) TakeFirst64(n int64) AddrRangeSeq {
- if n < 0 {
- panic(fmt.Sprintf("invalid n: %d", n))
- }
- if ars.limit > Addr(n) {
- ars.limit = Addr(n)
- }
- return ars
-}
-
-// String implements fmt.Stringer.String.
-func (ars AddrRangeSeq) String() string {
- // This is deliberately chosen to be the same as fmt's automatic stringer
- // for []AddrRange.
- var buf bytes.Buffer
- buf.WriteByte('[')
- var sep string
- for !ars.IsEmpty() {
- buf.WriteString(sep)
- sep = " "
- buf.WriteString(ars.Head().String())
- ars = ars.Tail()
- }
- buf.WriteByte(']')
- return buf.String()
-}
diff --git a/pkg/sentry/usermem/bytes_io.go b/pkg/sentry/usermem/bytes_io.go
deleted file mode 100644
index 7898851b3..000000000
--- a/pkg/sentry/usermem/bytes_io.go
+++ /dev/null
@@ -1,141 +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 usermem
-
-import (
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/syserror"
-)
-
-const maxInt = int(^uint(0) >> 1)
-
-// BytesIO implements IO using a byte slice. Addresses are interpreted as
-// offsets into the slice. Reads and writes beyond the end of the slice return
-// EFAULT.
-type BytesIO struct {
- Bytes []byte
-}
-
-// CopyOut implements IO.CopyOut.
-func (b *BytesIO) CopyOut(ctx context.Context, addr Addr, src []byte, opts IOOpts) (int, error) {
- rngN, rngErr := b.rangeCheck(addr, len(src))
- if rngN == 0 {
- return 0, rngErr
- }
- return copy(b.Bytes[int(addr):], src[:rngN]), rngErr
-}
-
-// CopyIn implements IO.CopyIn.
-func (b *BytesIO) CopyIn(ctx context.Context, addr Addr, dst []byte, opts IOOpts) (int, error) {
- rngN, rngErr := b.rangeCheck(addr, len(dst))
- if rngN == 0 {
- return 0, rngErr
- }
- return copy(dst[:rngN], b.Bytes[int(addr):]), rngErr
-}
-
-// ZeroOut implements IO.ZeroOut.
-func (b *BytesIO) ZeroOut(ctx context.Context, addr Addr, toZero int64, opts IOOpts) (int64, error) {
- if toZero > int64(maxInt) {
- return 0, syserror.EINVAL
- }
- rngN, rngErr := b.rangeCheck(addr, int(toZero))
- if rngN == 0 {
- return 0, rngErr
- }
- zeroSlice := b.Bytes[int(addr) : int(addr)+rngN]
- for i := range zeroSlice {
- zeroSlice[i] = 0
- }
- return int64(rngN), rngErr
-}
-
-// CopyOutFrom implements IO.CopyOutFrom.
-func (b *BytesIO) CopyOutFrom(ctx context.Context, ars AddrRangeSeq, src safemem.Reader, opts IOOpts) (int64, error) {
- dsts, rngErr := b.blocksFromAddrRanges(ars)
- n, err := src.ReadToBlocks(dsts)
- if err != nil {
- return int64(n), err
- }
- return int64(n), rngErr
-}
-
-// CopyInTo implements IO.CopyInTo.
-func (b *BytesIO) CopyInTo(ctx context.Context, ars AddrRangeSeq, dst safemem.Writer, opts IOOpts) (int64, error) {
- srcs, rngErr := b.blocksFromAddrRanges(ars)
- n, err := dst.WriteFromBlocks(srcs)
- if err != nil {
- return int64(n), err
- }
- return int64(n), rngErr
-}
-
-func (b *BytesIO) rangeCheck(addr Addr, length int) (int, error) {
- if length == 0 {
- return 0, nil
- }
- if length < 0 {
- return 0, syserror.EINVAL
- }
- max := Addr(len(b.Bytes))
- if addr >= max {
- return 0, syserror.EFAULT
- }
- end, ok := addr.AddLength(uint64(length))
- if !ok || end > max {
- return int(max - addr), syserror.EFAULT
- }
- return length, nil
-}
-
-func (b *BytesIO) blocksFromAddrRanges(ars AddrRangeSeq) (safemem.BlockSeq, error) {
- switch ars.NumRanges() {
- case 0:
- return safemem.BlockSeq{}, nil
- case 1:
- block, err := b.blockFromAddrRange(ars.Head())
- return safemem.BlockSeqOf(block), err
- default:
- blocks := make([]safemem.Block, 0, ars.NumRanges())
- for !ars.IsEmpty() {
- block, err := b.blockFromAddrRange(ars.Head())
- if block.Len() != 0 {
- blocks = append(blocks, block)
- }
- if err != nil {
- return safemem.BlockSeqFromSlice(blocks), err
- }
- ars = ars.Tail()
- }
- return safemem.BlockSeqFromSlice(blocks), nil
- }
-}
-
-func (b *BytesIO) blockFromAddrRange(ar AddrRange) (safemem.Block, error) {
- n, err := b.rangeCheck(ar.Start, int(ar.Length()))
- if n == 0 {
- return safemem.Block{}, err
- }
- return safemem.BlockFromSafeSlice(b.Bytes[int(ar.Start) : int(ar.Start)+n]), err
-}
-
-// BytesIOSequence returns an IOSequence representing the given byte slice.
-func BytesIOSequence(buf []byte) IOSequence {
- return IOSequence{
- IO: &BytesIO{buf},
- Addrs: AddrRangeSeqOf(AddrRange{0, Addr(len(buf))}),
- }
-}
diff --git a/pkg/sentry/usermem/bytes_io_unsafe.go b/pkg/sentry/usermem/bytes_io_unsafe.go
deleted file mode 100644
index fca5952f4..000000000
--- a/pkg/sentry/usermem/bytes_io_unsafe.go
+++ /dev/null
@@ -1,47 +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 usermem
-
-import (
- "sync/atomic"
- "unsafe"
-
- "gvisor.dev/gvisor/pkg/atomicbitops"
- "gvisor.dev/gvisor/pkg/sentry/context"
-)
-
-// SwapUint32 implements IO.SwapUint32.
-func (b *BytesIO) SwapUint32(ctx context.Context, addr Addr, new uint32, opts IOOpts) (uint32, error) {
- if _, rngErr := b.rangeCheck(addr, 4); rngErr != nil {
- return 0, rngErr
- }
- return atomic.SwapUint32((*uint32)(unsafe.Pointer(&b.Bytes[int(addr)])), new), nil
-}
-
-// CompareAndSwapUint32 implements IO.CompareAndSwapUint32.
-func (b *BytesIO) CompareAndSwapUint32(ctx context.Context, addr Addr, old, new uint32, opts IOOpts) (uint32, error) {
- if _, rngErr := b.rangeCheck(addr, 4); rngErr != nil {
- return 0, rngErr
- }
- 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
deleted file mode 100644
index 7b1f312b1..000000000
--- a/pkg/sentry/usermem/usermem.go
+++ /dev/null
@@ -1,597 +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 usermem governs access to user memory.
-package usermem
-
-import (
- "bytes"
- "errors"
- "io"
- "strconv"
-
- "gvisor.dev/gvisor/pkg/binary"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/syserror"
-)
-
-// IO provides access to the contents of a virtual memory space.
-//
-// FIXME(b/38173783): Implementations of IO cannot expect ctx to contain any
-// meaningful data.
-type IO interface {
- // CopyOut copies len(src) bytes from src to the memory mapped at addr. It
- // returns the number of bytes copied. If the number of bytes copied is <
- // len(src), it returns a non-nil error explaining why.
- //
- // Preconditions: The caller must not hold mm.MemoryManager.mappingMu or
- // any following locks in the lock order.
- //
- // Postconditions: CopyOut does not retain src.
- CopyOut(ctx context.Context, addr Addr, src []byte, opts IOOpts) (int, error)
-
- // CopyIn copies len(dst) bytes from the memory mapped at addr to dst.
- // It returns the number of bytes copied. If the number of bytes copied is
- // < len(dst), it returns a non-nil error explaining why.
- //
- // Preconditions: The caller must not hold mm.MemoryManager.mappingMu or
- // any following locks in the lock order.
- //
- // Postconditions: CopyIn does not retain dst.
- CopyIn(ctx context.Context, addr Addr, dst []byte, opts IOOpts) (int, error)
-
- // ZeroOut sets toZero bytes to 0, starting at addr. It returns the number
- // of bytes zeroed. If the number of bytes zeroed is < toZero, it returns a
- // non-nil error explaining why.
- //
- // Preconditions: The caller must not hold mm.MemoryManager.mappingMu or
- // any following locks in the lock order. toZero >= 0.
- ZeroOut(ctx context.Context, addr Addr, toZero int64, opts IOOpts) (int64, error)
-
- // CopyOutFrom copies ars.NumBytes() bytes from src to the memory mapped at
- // ars. It returns the number of bytes copied, which may be less than the
- // number of bytes read from src if copying fails. CopyOutFrom may return a
- // partial copy without an error iff src.ReadToBlocks returns a partial
- // read without an error.
- //
- // CopyOutFrom calls src.ReadToBlocks at most once.
- //
- // Preconditions: The caller must not hold mm.MemoryManager.mappingMu or
- // any following locks in the lock order. src.ReadToBlocks must not block
- // on mm.MemoryManager.activeMu or any preceding locks in the lock order.
- CopyOutFrom(ctx context.Context, ars AddrRangeSeq, src safemem.Reader, opts IOOpts) (int64, error)
-
- // CopyInTo copies ars.NumBytes() bytes from the memory mapped at ars to
- // dst. It returns the number of bytes copied. CopyInTo may return a
- // partial copy without an error iff dst.WriteFromBlocks returns a partial
- // write without an error.
- //
- // CopyInTo calls dst.WriteFromBlocks at most once.
- //
- // Preconditions: The caller must not hold mm.MemoryManager.mappingMu or
- // any following locks in the lock order. dst.WriteFromBlocks must not
- // block on mm.MemoryManager.activeMu or any preceding locks in the lock
- // order.
- CopyInTo(ctx context.Context, ars AddrRangeSeq, dst safemem.Writer, opts IOOpts) (int64, error)
-
- // TODO(jamieliu): The requirement that CopyOutFrom/CopyInTo call src/dst
- // at most once, which is unnecessary in most cases, forces implementations
- // to gather safemem.Blocks into a single slice to pass to src/dst. Add
- // CopyOutFromIter/CopyInToIter, which relaxes this restriction, to avoid
- // this allocation.
-
- // SwapUint32 atomically sets the uint32 value at addr to new and
- // returns the previous value.
- //
- // 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.
- SwapUint32(ctx context.Context, addr Addr, new uint32, opts IOOpts) (uint32, error)
-
- // CompareAndSwapUint32 atomically compares the uint32 value at addr to
- // old; if they are equal, the value in memory is replaced by new. In
- // either case, the previous value stored in memory is returned.
- //
- // 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.
- 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.
-type IOOpts struct {
- // If IgnorePermissions is true, application-defined memory protections set
- // by mmap(2) or mprotect(2) will be ignored. (Memory protections required
- // by the target of the mapping are never ignored.)
- IgnorePermissions bool
-
- // If AddressSpaceActive is true, the IO implementation may assume that it
- // has an active AddressSpace and can therefore use AddressSpace copying
- // without performing activation. See mm/io.go for details.
- AddressSpaceActive bool
-}
-
-// IOReadWriter is an io.ReadWriter that reads from / writes to addresses
-// starting at addr in IO. The preconditions that apply to IO.CopyIn and
-// IO.CopyOut also apply to IOReadWriter.Read and IOReadWriter.Write
-// respectively.
-type IOReadWriter struct {
- Ctx context.Context
- IO IO
- Addr Addr
- Opts IOOpts
-}
-
-// Read implements io.Reader.Read.
-//
-// Note that an address space does not have an "end of file", so Read can only
-// return io.EOF if IO.CopyIn returns io.EOF. Attempts to read unmapped or
-// unreadable memory, or beyond the end of the address space, should return
-// EFAULT.
-func (rw *IOReadWriter) Read(dst []byte) (int, error) {
- n, err := rw.IO.CopyIn(rw.Ctx, rw.Addr, dst, rw.Opts)
- end, ok := rw.Addr.AddLength(uint64(n))
- if ok {
- rw.Addr = end
- } else {
- // Disallow wraparound.
- rw.Addr = ^Addr(0)
- if err != nil {
- err = syserror.EFAULT
- }
- }
- return n, err
-}
-
-// Writer implements io.Writer.Write.
-func (rw *IOReadWriter) Write(src []byte) (int, error) {
- n, err := rw.IO.CopyOut(rw.Ctx, rw.Addr, src, rw.Opts)
- end, ok := rw.Addr.AddLength(uint64(n))
- if ok {
- rw.Addr = end
- } else {
- // Disallow wraparound.
- rw.Addr = ^Addr(0)
- if err != nil {
- err = syserror.EFAULT
- }
- }
- return n, err
-}
-
-// CopyObjectOut copies a fixed-size value or slice of fixed-size values from
-// src to the memory mapped at addr in uio. It returns the number of bytes
-// copied.
-//
-// CopyObjectOut must use reflection to encode src; performance-sensitive
-// clients should do encoding manually and use uio.CopyOut directly.
-//
-// Preconditions: As for IO.CopyOut.
-func CopyObjectOut(ctx context.Context, uio IO, addr Addr, src interface{}, opts IOOpts) (int, error) {
- w := &IOReadWriter{
- Ctx: ctx,
- IO: uio,
- Addr: addr,
- Opts: opts,
- }
- // Allocate a byte slice the size of the object being marshaled. This
- // adds an extra reflection call, but avoids needing to grow the slice
- // during encoding, which can result in many heap-allocated slices.
- b := make([]byte, 0, binary.Size(src))
- return w.Write(binary.Marshal(b, ByteOrder, src))
-}
-
-// CopyObjectIn copies a fixed-size value or slice of fixed-size values from
-// the memory mapped at addr in uio to dst. It returns the number of bytes
-// copied.
-//
-// CopyObjectIn must use reflection to decode dst; performance-sensitive
-// clients should use uio.CopyIn directly and do decoding manually.
-//
-// Preconditions: As for IO.CopyIn.
-func CopyObjectIn(ctx context.Context, uio IO, addr Addr, dst interface{}, opts IOOpts) (int, error) {
- r := &IOReadWriter{
- Ctx: ctx,
- IO: uio,
- Addr: addr,
- Opts: opts,
- }
- buf := make([]byte, binary.Size(dst))
- if _, err := io.ReadFull(r, buf); err != nil {
- return 0, err
- }
- binary.Unmarshal(buf, ByteOrder, dst)
- return int(r.Addr - addr), nil
-}
-
-// CopyStringIn tuning parameters, defined outside that function for tests.
-const (
- copyStringIncrement = 64
- copyStringMaxInitBufLen = 256
-)
-
-// CopyStringIn copies a NUL-terminated string of unknown length from the
-// memory mapped at addr in uio and returns it as a string (not including the
-// trailing NUL). If the length of the string, including the terminating NUL,
-// would exceed maxlen, CopyStringIn returns the string truncated to maxlen and
-// ENAMETOOLONG.
-//
-// Preconditions: As for IO.CopyFromUser. maxlen >= 0.
-func CopyStringIn(ctx context.Context, uio IO, addr Addr, maxlen int, opts IOOpts) (string, error) {
- initLen := maxlen
- if initLen > copyStringMaxInitBufLen {
- initLen = copyStringMaxInitBufLen
- }
- buf := make([]byte, initLen)
- var done int
- for done < maxlen {
- // Read up to copyStringIncrement bytes at a time.
- readlen := copyStringIncrement
- if readlen > maxlen-done {
- readlen = maxlen - done
- }
- end, ok := addr.AddLength(uint64(readlen))
- if !ok {
- return stringFromImmutableBytes(buf[:done]), syserror.EFAULT
- }
- // Shorten the read to avoid crossing page boundaries, since faulting
- // in a page unnecessarily is expensive. This also ensures that partial
- // copies up to the end of application-mappable memory succeed.
- if addr.RoundDown() != end.RoundDown() {
- end = end.RoundDown()
- readlen = int(end - addr)
- }
- // Ensure that our buffer is large enough to accommodate the read.
- if done+readlen > len(buf) {
- newBufLen := len(buf) * 2
- if newBufLen > maxlen {
- newBufLen = maxlen
- }
- buf = append(buf, make([]byte, newBufLen-len(buf))...)
- }
- n, err := uio.CopyIn(ctx, addr, buf[done:done+readlen], opts)
- // Look for the terminating zero byte, which may have occurred before
- // hitting err.
- if i := bytes.IndexByte(buf[done:done+n], byte(0)); i >= 0 {
- return stringFromImmutableBytes(buf[:done+i]), nil
- }
-
- done += n
- if err != nil {
- return stringFromImmutableBytes(buf[:done]), err
- }
- addr = end
- }
- return stringFromImmutableBytes(buf), syserror.ENAMETOOLONG
-}
-
-// CopyOutVec copies bytes from src to the memory mapped at ars in uio. The
-// maximum number of bytes copied is ars.NumBytes() or len(src), whichever is
-// less. CopyOutVec returns the number of bytes copied; if this is less than
-// the maximum, it returns a non-nil error explaining why.
-//
-// Preconditions: As for IO.CopyOut.
-func CopyOutVec(ctx context.Context, uio IO, ars AddrRangeSeq, src []byte, opts IOOpts) (int, error) {
- var done int
- for !ars.IsEmpty() && done < len(src) {
- ar := ars.Head()
- cplen := len(src) - done
- if Addr(cplen) >= ar.Length() {
- cplen = int(ar.Length())
- }
- n, err := uio.CopyOut(ctx, ar.Start, src[done:done+cplen], opts)
- done += n
- if err != nil {
- return done, err
- }
- ars = ars.DropFirst(n)
- }
- return done, nil
-}
-
-// CopyInVec copies bytes from the memory mapped at ars in uio to dst. The
-// maximum number of bytes copied is ars.NumBytes() or len(dst), whichever is
-// less. CopyInVec returns the number of bytes copied; if this is less than the
-// maximum, it returns a non-nil error explaining why.
-//
-// Preconditions: As for IO.CopyIn.
-func CopyInVec(ctx context.Context, uio IO, ars AddrRangeSeq, dst []byte, opts IOOpts) (int, error) {
- var done int
- for !ars.IsEmpty() && done < len(dst) {
- ar := ars.Head()
- cplen := len(dst) - done
- if Addr(cplen) >= ar.Length() {
- cplen = int(ar.Length())
- }
- n, err := uio.CopyIn(ctx, ar.Start, dst[done:done+cplen], opts)
- done += n
- if err != nil {
- return done, err
- }
- ars = ars.DropFirst(n)
- }
- return done, nil
-}
-
-// ZeroOutVec writes zeroes to the memory mapped at ars in uio. The maximum
-// number of bytes written is ars.NumBytes() or toZero, whichever is less.
-// ZeroOutVec returns the number of bytes written; if this is less than the
-// maximum, it returns a non-nil error explaining why.
-//
-// Preconditions: As for IO.ZeroOut.
-func ZeroOutVec(ctx context.Context, uio IO, ars AddrRangeSeq, toZero int64, opts IOOpts) (int64, error) {
- var done int64
- for !ars.IsEmpty() && done < toZero {
- ar := ars.Head()
- cplen := toZero - done
- if Addr(cplen) >= ar.Length() {
- cplen = int64(ar.Length())
- }
- n, err := uio.ZeroOut(ctx, ar.Start, cplen, opts)
- done += n
- if err != nil {
- return done, err
- }
- ars = ars.DropFirst64(n)
- }
- return done, nil
-}
-
-func isASCIIWhitespace(b byte) bool {
- // Compare Linux include/linux/ctype.h, lib/ctype.c.
- // 9 => horizontal tab '\t'
- // 10 => line feed '\n'
- // 11 => vertical tab '\v'
- // 12 => form feed '\c'
- // 13 => carriage return '\r'
- return b == ' ' || (b >= 9 && b <= 13)
-}
-
-// CopyInt32StringsInVec copies up to len(dsts) whitespace-separated decimal
-// strings from the memory mapped at ars in uio and converts them to int32
-// values in dsts. It returns the number of bytes read.
-//
-// CopyInt32StringsInVec shares the following properties with Linux's
-// kernel/sysctl.c:proc_dointvec(write=1):
-//
-// - If any read value overflows the range of int32, or any invalid characters
-// are encountered during the read, CopyInt32StringsInVec returns EINVAL.
-//
-// - If, upon reaching the end of ars, fewer than len(dsts) values have been
-// read, CopyInt32StringsInVec returns no error if at least 1 value was read
-// and EINVAL otherwise.
-//
-// - Trailing whitespace after the last successfully read value is counted in
-// the number of bytes read.
-//
-// Unlike proc_dointvec():
-//
-// - CopyInt32StringsInVec does not implicitly limit ars.NumBytes() to
-// PageSize-1; callers that require this must do so explicitly.
-//
-// - CopyInt32StringsInVec returns EINVAL if ars.NumBytes() == 0.
-//
-// Preconditions: As for CopyInVec.
-func CopyInt32StringsInVec(ctx context.Context, uio IO, ars AddrRangeSeq, dsts []int32, opts IOOpts) (int64, error) {
- if len(dsts) == 0 {
- return 0, nil
- }
-
- buf := make([]byte, ars.NumBytes())
- n, cperr := CopyInVec(ctx, uio, ars, buf, opts)
- buf = buf[:n]
-
- var i, j int
- for ; j < len(dsts); j++ {
- // Skip leading whitespace.
- for i < len(buf) && isASCIIWhitespace(buf[i]) {
- i++
- }
- if i == len(buf) {
- break
- }
-
- // Find the end of the value to be parsed (next whitespace or end of string).
- nextI := i + 1
- for nextI < len(buf) && !isASCIIWhitespace(buf[nextI]) {
- nextI++
- }
-
- // Parse a single value.
- val, err := strconv.ParseInt(string(buf[i:nextI]), 10, 32)
- if err != nil {
- return int64(i), syserror.EINVAL
- }
- dsts[j] = int32(val)
-
- i = nextI
- }
-
- // Skip trailing whitespace.
- for i < len(buf) && isASCIIWhitespace(buf[i]) {
- i++
- }
-
- if cperr != nil {
- return int64(i), cperr
- }
- if j == 0 {
- return int64(i), syserror.EINVAL
- }
- return int64(i), nil
-}
-
-// CopyInt32StringInVec is equivalent to CopyInt32StringsInVec, but copies at
-// most one int32.
-func CopyInt32StringInVec(ctx context.Context, uio IO, ars AddrRangeSeq, dst *int32, opts IOOpts) (int64, error) {
- dsts := [1]int32{*dst}
- n, err := CopyInt32StringsInVec(ctx, uio, ars, dsts[:], opts)
- *dst = dsts[0]
- return n, err
-}
-
-// IOSequence holds arguments to IO methods.
-type IOSequence struct {
- IO IO
- Addrs AddrRangeSeq
- Opts IOOpts
-}
-
-// NumBytes returns s.Addrs.NumBytes().
-//
-// Note that NumBytes() may return 0 even if !s.Addrs.IsEmpty(), since
-// s.Addrs may contain a non-zero number of zero-length AddrRanges.
-// Many clients of
-// IOSequence currently do something like:
-//
-// if ioseq.NumBytes() == 0 {
-// return 0, nil
-// }
-// if f.availableBytes == 0 {
-// return 0, syserror.ErrWouldBlock
-// }
-// return ioseq.CopyOutFrom(..., reader)
-//
-// In such cases, using s.Addrs.IsEmpty() will cause them to have the wrong
-// behavior for zero-length I/O. However, using s.NumBytes() == 0 instead means
-// that we will return success for zero-length I/O in cases where Linux would
-// return EFAULT due to a failed access_ok() check, so in the long term we
-// should move checks for ErrWouldBlock etc. into the body of
-// reader.ReadToBlocks and use s.Addrs.IsEmpty() instead.
-func (s IOSequence) NumBytes() int64 {
- return s.Addrs.NumBytes()
-}
-
-// DropFirst returns a copy of s with s.Addrs.DropFirst(n).
-//
-// Preconditions: As for AddrRangeSeq.DropFirst.
-func (s IOSequence) DropFirst(n int) IOSequence {
- return IOSequence{s.IO, s.Addrs.DropFirst(n), s.Opts}
-}
-
-// DropFirst64 returns a copy of s with s.Addrs.DropFirst64(n).
-//
-// Preconditions: As for AddrRangeSeq.DropFirst64.
-func (s IOSequence) DropFirst64(n int64) IOSequence {
- return IOSequence{s.IO, s.Addrs.DropFirst64(n), s.Opts}
-}
-
-// TakeFirst returns a copy of s with s.Addrs.TakeFirst(n).
-//
-// Preconditions: As for AddrRangeSeq.TakeFirst.
-func (s IOSequence) TakeFirst(n int) IOSequence {
- return IOSequence{s.IO, s.Addrs.TakeFirst(n), s.Opts}
-}
-
-// TakeFirst64 returns a copy of s with s.Addrs.TakeFirst64(n).
-//
-// Preconditions: As for AddrRangeSeq.TakeFirst64.
-func (s IOSequence) TakeFirst64(n int64) IOSequence {
- return IOSequence{s.IO, s.Addrs.TakeFirst64(n), s.Opts}
-}
-
-// CopyOut invokes CopyOutVec over s.Addrs.
-//
-// As with CopyOutVec, if s.NumBytes() < len(src), the copy will be truncated
-// to s.NumBytes(), and a nil error will be returned.
-//
-// Preconditions: As for CopyOutVec.
-func (s IOSequence) CopyOut(ctx context.Context, src []byte) (int, error) {
- return CopyOutVec(ctx, s.IO, s.Addrs, src, s.Opts)
-}
-
-// CopyIn invokes CopyInVec over s.Addrs.
-//
-// As with CopyInVec, if s.NumBytes() < len(dst), the copy will be truncated to
-// s.NumBytes(), and a nil error will be returned.
-//
-// Preconditions: As for CopyInVec.
-func (s IOSequence) CopyIn(ctx context.Context, dst []byte) (int, error) {
- return CopyInVec(ctx, s.IO, s.Addrs, dst, s.Opts)
-}
-
-// ZeroOut invokes ZeroOutVec over s.Addrs.
-//
-// As with ZeroOutVec, if s.NumBytes() < toZero, the write will be truncated
-// to s.NumBytes(), and a nil error will be returned.
-//
-// Preconditions: As for ZeroOutVec.
-func (s IOSequence) ZeroOut(ctx context.Context, toZero int64) (int64, error) {
- return ZeroOutVec(ctx, s.IO, s.Addrs, toZero, s.Opts)
-}
-
-// CopyOutFrom invokes s.CopyOutFrom over s.Addrs.
-//
-// Preconditions: As for IO.CopyOutFrom.
-func (s IOSequence) CopyOutFrom(ctx context.Context, src safemem.Reader) (int64, error) {
- return s.IO.CopyOutFrom(ctx, s.Addrs, src, s.Opts)
-}
-
-// CopyInTo invokes s.CopyInTo over s.Addrs.
-//
-// Preconditions: As for IO.CopyInTo.
-func (s IOSequence) CopyInTo(ctx context.Context, dst safemem.Writer) (int64, error) {
- return s.IO.CopyInTo(ctx, s.Addrs, dst, s.Opts)
-}
-
-// Reader returns an io.Reader that reads from s. Reads beyond the end of s
-// return io.EOF. The preconditions that apply to s.CopyIn also apply to the
-// returned io.Reader.Read.
-func (s IOSequence) Reader(ctx context.Context) io.Reader {
- return &ioSequenceReadWriter{ctx, s}
-}
-
-// Writer returns an io.Writer that writes to s. Writes beyond the end of s
-// return ErrEndOfIOSequence. The preconditions that apply to s.CopyOut also
-// apply to the returned io.Writer.Write.
-func (s IOSequence) Writer(ctx context.Context) io.Writer {
- return &ioSequenceReadWriter{ctx, s}
-}
-
-// ErrEndOfIOSequence is returned by IOSequence.Writer().Write() when
-// attempting to write beyond the end of the IOSequence.
-var ErrEndOfIOSequence = errors.New("write beyond end of IOSequence")
-
-type ioSequenceReadWriter struct {
- ctx context.Context
- s IOSequence
-}
-
-// Read implements io.Reader.Read.
-func (rw *ioSequenceReadWriter) Read(dst []byte) (int, error) {
- n, err := rw.s.CopyIn(rw.ctx, dst)
- rw.s = rw.s.DropFirst(n)
- if err == nil && rw.s.NumBytes() == 0 {
- err = io.EOF
- }
- return n, err
-}
-
-// Write implements io.Writer.Write.
-func (rw *ioSequenceReadWriter) Write(src []byte) (int, error) {
- n, err := rw.s.CopyOut(rw.ctx, src)
- rw.s = rw.s.DropFirst(n)
- if err == nil && n < len(src) {
- err = ErrEndOfIOSequence
- }
- return n, err
-}
diff --git a/pkg/sentry/usermem/usermem_arm64.go b/pkg/sentry/usermem/usermem_arm64.go
deleted file mode 100644
index fdfc30a66..000000000
--- a/pkg/sentry/usermem/usermem_arm64.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.
-
-// +build arm64
-
-package usermem
-
-import (
- "encoding/binary"
- "syscall"
-)
-
-const (
- // PageSize is the system page size.
- // arm64 support 4K/16K/64K page size,
- // which can be get by syscall.Getpagesize().
- // Currently, only 4K page size is supported.
- PageSize = 1 << PageShift
-
- // HugePageSize is the system huge page size.
- HugePageSize = 1 << HugePageShift
-
- // PageShift is the binary log of the system page size.
- PageShift = 12
-
- // HugePageShift is the binary log of the system huge page size.
- // Should be calculated by "PageShift + (PageShift - 3)"
- // when multiple page size support is ready.
- HugePageShift = 21
-)
-
-var (
- // ByteOrder is the native byte order (little endian).
- ByteOrder = binary.LittleEndian
-)
-
-func init() {
- // Make sure the page size is 4K on arm64 platform.
- if size := syscall.Getpagesize(); size != PageSize {
- panic("Only 4K page size is supported on arm64!")
- }
-}
diff --git a/pkg/sentry/usermem/usermem_test.go b/pkg/sentry/usermem/usermem_test.go
deleted file mode 100644
index 299f64754..000000000
--- a/pkg/sentry/usermem/usermem_test.go
+++ /dev/null
@@ -1,424 +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 usermem
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "reflect"
- "strings"
- "testing"
-
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/safemem"
- "gvisor.dev/gvisor/pkg/syserror"
-)
-
-// newContext returns a context.Context that we can use in these tests (we
-// can't use contexttest because it depends on usermem).
-func newContext() context.Context {
- return context.Background()
-}
-
-func newBytesIOString(s string) *BytesIO {
- return &BytesIO{[]byte(s)}
-}
-
-func TestBytesIOCopyOutSuccess(t *testing.T) {
- b := newBytesIOString("ABCDE")
- n, err := b.CopyOut(newContext(), 1, []byte("foo"), IOOpts{})
- if wantN := 3; n != wantN || err != nil {
- t.Errorf("CopyOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := b.Bytes, []byte("AfooE"); !bytes.Equal(got, want) {
- t.Errorf("Bytes: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyOutFailure(t *testing.T) {
- b := newBytesIOString("ABC")
- n, err := b.CopyOut(newContext(), 1, []byte("foo"), IOOpts{})
- if wantN, wantErr := 2, syserror.EFAULT; n != wantN || err != wantErr {
- t.Errorf("CopyOut: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr)
- }
- if got, want := b.Bytes, []byte("Afo"); !bytes.Equal(got, want) {
- t.Errorf("Bytes: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyInSuccess(t *testing.T) {
- b := newBytesIOString("AfooE")
- var dst [3]byte
- n, err := b.CopyIn(newContext(), 1, dst[:], IOOpts{})
- if wantN := 3; n != wantN || err != nil {
- t.Errorf("CopyIn: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst[:], []byte("foo"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyInFailure(t *testing.T) {
- b := newBytesIOString("Afo")
- var dst [3]byte
- n, err := b.CopyIn(newContext(), 1, dst[:], IOOpts{})
- if wantN, wantErr := 2, syserror.EFAULT; n != wantN || err != wantErr {
- t.Errorf("CopyIn: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr)
- }
- if got, want := dst[:], []byte("fo\x00"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOZeroOutSuccess(t *testing.T) {
- b := newBytesIOString("ABCD")
- n, err := b.ZeroOut(newContext(), 1, 2, IOOpts{})
- if wantN := int64(2); n != wantN || err != nil {
- t.Errorf("ZeroOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := b.Bytes, []byte("A\x00\x00D"); !bytes.Equal(got, want) {
- t.Errorf("Bytes: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOZeroOutFailure(t *testing.T) {
- b := newBytesIOString("ABC")
- n, err := b.ZeroOut(newContext(), 1, 3, IOOpts{})
- if wantN, wantErr := int64(2), syserror.EFAULT; n != wantN || err != wantErr {
- t.Errorf("ZeroOut: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr)
- }
- if got, want := b.Bytes, []byte("A\x00\x00"); !bytes.Equal(got, want) {
- t.Errorf("Bytes: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyOutFromSuccess(t *testing.T) {
- b := newBytesIOString("ABCDEFGH")
- n, err := b.CopyOutFrom(newContext(), AddrRangeSeqFromSlice([]AddrRange{
- {Start: 4, End: 7},
- {Start: 1, End: 4},
- }), safemem.FromIOReader{bytes.NewBufferString("barfoo")}, IOOpts{})
- if wantN := int64(6); n != wantN || err != nil {
- t.Errorf("CopyOutFrom: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := b.Bytes, []byte("AfoobarH"); !bytes.Equal(got, want) {
- t.Errorf("Bytes: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyOutFromFailure(t *testing.T) {
- b := newBytesIOString("ABCDE")
- n, err := b.CopyOutFrom(newContext(), AddrRangeSeqFromSlice([]AddrRange{
- {Start: 1, End: 4},
- {Start: 4, End: 7},
- }), safemem.FromIOReader{bytes.NewBufferString("foobar")}, IOOpts{})
- if wantN, wantErr := int64(4), syserror.EFAULT; n != wantN || err != wantErr {
- t.Errorf("CopyOutFrom: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr)
- }
- if got, want := b.Bytes, []byte("Afoob"); !bytes.Equal(got, want) {
- t.Errorf("Bytes: got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyInToSuccess(t *testing.T) {
- b := newBytesIOString("AfoobarH")
- var dst bytes.Buffer
- n, err := b.CopyInTo(newContext(), AddrRangeSeqFromSlice([]AddrRange{
- {Start: 4, End: 7},
- {Start: 1, End: 4},
- }), safemem.FromIOWriter{&dst}, IOOpts{})
- if wantN := int64(6); n != wantN || err != nil {
- t.Errorf("CopyInTo: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst.Bytes(), []byte("barfoo"); !bytes.Equal(got, want) {
- t.Errorf("dst.Bytes(): got %q, wanted %q", got, want)
- }
-}
-
-func TestBytesIOCopyInToFailure(t *testing.T) {
- b := newBytesIOString("Afoob")
- var dst bytes.Buffer
- n, err := b.CopyInTo(newContext(), AddrRangeSeqFromSlice([]AddrRange{
- {Start: 1, End: 4},
- {Start: 4, End: 7},
- }), safemem.FromIOWriter{&dst}, IOOpts{})
- if wantN, wantErr := int64(4), syserror.EFAULT; n != wantN || err != wantErr {
- t.Errorf("CopyOutFrom: got (%v, %v), wanted (%v, %v)", n, err, wantN, wantErr)
- }
- if got, want := dst.Bytes(), []byte("foob"); !bytes.Equal(got, want) {
- t.Errorf("dst.Bytes(): got %q, wanted %q", got, want)
- }
-}
-
-type testStruct struct {
- Int8 int8
- Uint8 uint8
- Int16 int16
- Uint16 uint16
- Int32 int32
- Uint32 uint32
- Int64 int64
- Uint64 uint64
-}
-
-func TestCopyObject(t *testing.T) {
- wantObj := testStruct{1, 2, 3, 4, 5, 6, 7, 8}
- wantN := binary.Size(wantObj)
- b := &BytesIO{make([]byte, wantN)}
- ctx := newContext()
- if n, err := CopyObjectOut(ctx, b, 0, &wantObj, IOOpts{}); n != wantN || err != nil {
- t.Fatalf("CopyObjectOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- var gotObj testStruct
- if n, err := CopyObjectIn(ctx, b, 0, &gotObj, IOOpts{}); n != wantN || err != nil {
- t.Errorf("CopyObjectIn: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if gotObj != wantObj {
- t.Errorf("CopyObject round trip: got %+v, wanted %+v", gotObj, wantObj)
- }
-}
-
-func TestCopyStringInShort(t *testing.T) {
- // Tests for string length <= copyStringIncrement.
- want := strings.Repeat("A", copyStringIncrement-2)
- mem := want + "\x00"
- if got, err := CopyStringIn(newContext(), newBytesIOString(mem), 0, 2*copyStringIncrement, IOOpts{}); got != want || err != nil {
- t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, nil)", got, err, want)
- }
-}
-
-func TestCopyStringInLong(t *testing.T) {
- // Tests for copyStringIncrement < string length <= copyStringMaxInitBufLen
- // (requiring multiple calls to IO.CopyIn()).
- want := strings.Repeat("A", copyStringIncrement*3/4) + strings.Repeat("B", copyStringIncrement*3/4)
- mem := want + "\x00"
- if got, err := CopyStringIn(newContext(), newBytesIOString(mem), 0, 2*copyStringIncrement, IOOpts{}); got != want || err != nil {
- t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, nil)", got, err, want)
- }
-}
-
-func TestCopyStringInVeryLong(t *testing.T) {
- // Tests for string length > copyStringMaxInitBufLen (requiring buffer
- // reallocation).
- want := strings.Repeat("A", copyStringMaxInitBufLen*3/4) + strings.Repeat("B", copyStringMaxInitBufLen*3/4)
- mem := want + "\x00"
- if got, err := CopyStringIn(newContext(), newBytesIOString(mem), 0, 2*copyStringMaxInitBufLen, IOOpts{}); got != want || err != nil {
- t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, nil)", got, err, want)
- }
-}
-
-func TestCopyStringInNoTerminatingZeroByte(t *testing.T) {
- want := strings.Repeat("A", copyStringIncrement-1)
- got, err := CopyStringIn(newContext(), newBytesIOString(want), 0, 2*copyStringIncrement, IOOpts{})
- if wantErr := syserror.EFAULT; got != want || err != wantErr {
- t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, %v)", got, err, want, wantErr)
- }
-}
-
-func TestCopyStringInTruncatedByMaxlen(t *testing.T) {
- got, err := CopyStringIn(newContext(), newBytesIOString(strings.Repeat("A", 10)), 0, 5, IOOpts{})
- if want, wantErr := strings.Repeat("A", 5), syserror.ENAMETOOLONG; got != want || err != wantErr {
- t.Errorf("CopyStringIn: got (%q, %v), wanted (%q, %v)", got, err, want, wantErr)
- }
-}
-
-func TestCopyInt32StringsInVec(t *testing.T) {
- for _, test := range []struct {
- str string
- n int
- initial []int32
- final []int32
- }{
- {
- str: "100 200",
- n: len("100 200"),
- initial: []int32{1, 2},
- final: []int32{100, 200},
- },
- {
- // Fewer values ok
- str: "100",
- n: len("100"),
- initial: []int32{1, 2},
- final: []int32{100, 2},
- },
- {
- // Extra values ok
- str: "100 200 300",
- n: len("100 200 "),
- initial: []int32{1, 2},
- final: []int32{100, 200},
- },
- {
- // Leading and trailing whitespace ok
- str: " 100\t200\n",
- n: len(" 100\t200\n"),
- initial: []int32{1, 2},
- final: []int32{100, 200},
- },
- } {
- t.Run(fmt.Sprintf("%q", test.str), func(t *testing.T) {
- src := BytesIOSequence([]byte(test.str))
- dsts := append([]int32(nil), test.initial...)
- if n, err := CopyInt32StringsInVec(newContext(), src.IO, src.Addrs, dsts, src.Opts); n != int64(test.n) || err != nil {
- t.Errorf("CopyInt32StringsInVec: got (%d, %v), wanted (%d, nil)", n, err, test.n)
- }
- if !reflect.DeepEqual(dsts, test.final) {
- t.Errorf("dsts: got %v, wanted %v", dsts, test.final)
- }
- })
- }
-}
-
-func TestCopyInt32StringsInVecRequiresOneValidValue(t *testing.T) {
- for _, s := range []string{"", "\n", "a123"} {
- t.Run(fmt.Sprintf("%q", s), func(t *testing.T) {
- src := BytesIOSequence([]byte(s))
- initial := []int32{1, 2}
- dsts := append([]int32(nil), initial...)
- if n, err := CopyInt32StringsInVec(newContext(), src.IO, src.Addrs, dsts, src.Opts); err != syserror.EINVAL {
- t.Errorf("CopyInt32StringsInVec: got (%d, %v), wanted (_, %v)", n, err, syserror.EINVAL)
- }
- if !reflect.DeepEqual(dsts, initial) {
- t.Errorf("dsts: got %v, wanted %v", dsts, initial)
- }
- })
- }
-}
-
-func TestIOSequenceCopyOut(t *testing.T) {
- buf := []byte("ABCD")
- s := BytesIOSequence(buf)
-
- // CopyOut limited by len(src).
- n, err := s.CopyOut(newContext(), []byte("fo"))
- if wantN := 2; n != wantN || err != nil {
- t.Errorf("CopyOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if want := []byte("foCD"); !bytes.Equal(buf, want) {
- t.Errorf("buf: got %q, wanted %q", buf, want)
- }
- s = s.DropFirst(2)
- if got, want := s.NumBytes(), int64(2); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-
- // CopyOut limited by s.NumBytes().
- n, err = s.CopyOut(newContext(), []byte("obar"))
- if wantN := 2; n != wantN || err != nil {
- t.Errorf("CopyOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if want := []byte("foob"); !bytes.Equal(buf, want) {
- t.Errorf("buf: got %q, wanted %q", buf, want)
- }
- s = s.DropFirst(2)
- if got, want := s.NumBytes(), int64(0); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-}
-
-func TestIOSequenceCopyIn(t *testing.T) {
- s := BytesIOSequence([]byte("foob"))
- dst := []byte("ABCDEF")
-
- // CopyIn limited by len(dst).
- n, err := s.CopyIn(newContext(), dst[:2])
- if wantN := 2; n != wantN || err != nil {
- t.Errorf("CopyIn: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if want := []byte("foCDEF"); !bytes.Equal(dst, want) {
- t.Errorf("dst: got %q, wanted %q", dst, want)
- }
- s = s.DropFirst(2)
- if got, want := s.NumBytes(), int64(2); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-
- // CopyIn limited by s.Remaining().
- n, err = s.CopyIn(newContext(), dst[2:])
- if wantN := 2; n != wantN || err != nil {
- t.Errorf("CopyIn: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if want := []byte("foobEF"); !bytes.Equal(dst, want) {
- t.Errorf("dst: got %q, wanted %q", dst, want)
- }
- s = s.DropFirst(2)
- if got, want := s.NumBytes(), int64(0); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-}
-
-func TestIOSequenceZeroOut(t *testing.T) {
- buf := []byte("ABCD")
- s := BytesIOSequence(buf)
-
- // ZeroOut limited by toZero.
- n, err := s.ZeroOut(newContext(), 2)
- if wantN := int64(2); n != wantN || err != nil {
- t.Errorf("ZeroOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if want := []byte("\x00\x00CD"); !bytes.Equal(buf, want) {
- t.Errorf("buf: got %q, wanted %q", buf, want)
- }
- s = s.DropFirst(2)
- if got, want := s.NumBytes(), int64(2); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-
- // ZeroOut limited by s.NumBytes().
- n, err = s.ZeroOut(newContext(), 4)
- if wantN := int64(2); n != wantN || err != nil {
- t.Errorf("CopyOut: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if want := []byte("\x00\x00\x00\x00"); !bytes.Equal(buf, want) {
- t.Errorf("buf: got %q, wanted %q", buf, want)
- }
- s = s.DropFirst(2)
- if got, want := s.NumBytes(), int64(0); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-}
-
-func TestIOSequenceTakeFirst(t *testing.T) {
- s := BytesIOSequence([]byte("foobar"))
- if got, want := s.NumBytes(), int64(6); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-
- s = s.TakeFirst(3)
- if got, want := s.NumBytes(), int64(3); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-
- // TakeFirst(n) where n > s.NumBytes() is a no-op.
- s = s.TakeFirst(9)
- if got, want := s.NumBytes(), int64(3); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-
- var dst [3]byte
- n, err := s.CopyIn(newContext(), dst[:])
- if wantN := 3; n != wantN || err != nil {
- t.Errorf("CopyIn: got (%v, %v), wanted (%v, nil)", n, err, wantN)
- }
- if got, want := dst[:], []byte("foo"); !bytes.Equal(got, want) {
- t.Errorf("dst: got %q, wanted %q", got, want)
- }
- s = s.DropFirst(3)
- if got, want := s.NumBytes(), int64(0); got != want {
- t.Errorf("NumBytes: got %v, wanted %v", got, want)
- }
-}
diff --git a/pkg/sentry/vfs/BUILD b/pkg/sentry/vfs/BUILD
index 35c7be259..14b39eb9d 100644
--- a/pkg/sentry/vfs/BUILD
+++ b/pkg/sentry/vfs/BUILD
@@ -1,15 +1,30 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_test")
+load("//tools:defs.bzl", "go_library", "go_test")
+load("//tools/go_generics:defs.bzl", "go_template_instance")
-package(licenses = ["notice"])
+licenses(["notice"])
+
+go_template_instance(
+ name = "epoll_interest_list",
+ out = "epoll_interest_list.go",
+ package = "vfs",
+ prefix = "epollInterest",
+ template = "//pkg/ilist:generic_list",
+ types = {
+ "Element": "*epollInterest",
+ "Linker": "*epollInterest",
+ },
+)
go_library(
name = "vfs",
srcs = [
+ "anonfs.go",
"context.go",
"debug.go",
"dentry.go",
"device.go",
+ "epoll.go",
+ "epoll_interest_list.go",
"file_description.go",
"file_description_impl_util.go",
"filesystem.go",
@@ -21,21 +36,20 @@ go_library(
"pathname.go",
"permissions.go",
"resolving_path.go",
- "testutil.go",
"vfs.go",
],
- importpath = "gvisor.dev/gvisor/pkg/sentry/vfs",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/context",
"//pkg/fspath",
"//pkg/sentry/arch",
- "//pkg/sentry/context",
+ "//pkg/sentry/fs/lock",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/memmap",
- "//pkg/sentry/usermem",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
"//pkg/waiter",
],
)
@@ -47,14 +61,13 @@ go_test(
"file_description_impl_util_test.go",
"mount_test.go",
],
- embed = [":vfs"],
+ library = ":vfs",
deps = [
"//pkg/abi/linux",
- "//pkg/sentry/context",
- "//pkg/sentry/context/contexttest",
- "//pkg/sentry/kernel/auth",
- "//pkg/sentry/usermem",
+ "//pkg/context",
+ "//pkg/sentry/contexttest",
"//pkg/sync",
"//pkg/syserror",
+ "//pkg/usermem",
],
)
diff --git a/pkg/sentry/vfs/anonfs.go b/pkg/sentry/vfs/anonfs.go
new file mode 100644
index 000000000..2db25be49
--- /dev/null
+++ b/pkg/sentry/vfs/anonfs.go
@@ -0,0 +1,259 @@
+// Copyright 2020 The 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 vfs
+
+import (
+ "fmt"
+
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/fspath"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
+)
+
+// NewAnonVirtualDentry returns a VirtualDentry with the given synthetic name,
+// consistent with Linux's fs/anon_inodes.c:anon_inode_getfile(). References
+// are taken on the returned VirtualDentry.
+func (vfs *VirtualFilesystem) NewAnonVirtualDentry(name string) VirtualDentry {
+ d := anonDentry{
+ name: name,
+ }
+ d.vfsd.Init(&d)
+ vfs.anonMount.IncRef()
+ // anonDentry no-ops refcounting.
+ return VirtualDentry{
+ mount: vfs.anonMount,
+ dentry: &d.vfsd,
+ }
+}
+
+const anonfsBlockSize = usermem.PageSize // via fs/libfs.c:pseudo_fs_fill_super()
+
+// anonFilesystem is the implementation of FilesystemImpl that backs
+// VirtualDentries returned by VirtualFilesystem.NewAnonVirtualDentry().
+//
+// Since all Dentries in anonFilesystem are non-directories, all FilesystemImpl
+// methods that would require an anonDentry to be a directory return ENOTDIR.
+type anonFilesystem struct {
+ vfsfs Filesystem
+
+ devMinor uint32
+}
+
+type anonDentry struct {
+ vfsd Dentry
+
+ name string
+}
+
+// Release implements FilesystemImpl.Release.
+func (fs *anonFilesystem) Release() {
+}
+
+// Sync implements FilesystemImpl.Sync.
+func (fs *anonFilesystem) Sync(ctx context.Context) error {
+ return nil
+}
+
+// GetDentryAt implements FilesystemImpl.GetDentryAt.
+func (fs *anonFilesystem) GetDentryAt(ctx context.Context, rp *ResolvingPath, opts GetDentryOptions) (*Dentry, error) {
+ if !rp.Done() {
+ return nil, syserror.ENOTDIR
+ }
+ if opts.CheckSearchable {
+ return nil, syserror.ENOTDIR
+ }
+ // anonDentry no-ops refcounting.
+ return rp.Start(), nil
+}
+
+// GetParentDentryAt implements FilesystemImpl.GetParentDentryAt.
+func (fs *anonFilesystem) GetParentDentryAt(ctx context.Context, rp *ResolvingPath) (*Dentry, error) {
+ if !rp.Final() {
+ return nil, syserror.ENOTDIR
+ }
+ // anonDentry no-ops refcounting.
+ return rp.Start(), nil
+}
+
+// LinkAt implements FilesystemImpl.LinkAt.
+func (fs *anonFilesystem) LinkAt(ctx context.Context, rp *ResolvingPath, vd VirtualDentry) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// MkdirAt implements FilesystemImpl.MkdirAt.
+func (fs *anonFilesystem) MkdirAt(ctx context.Context, rp *ResolvingPath, opts MkdirOptions) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// MknodAt implements FilesystemImpl.MknodAt.
+func (fs *anonFilesystem) MknodAt(ctx context.Context, rp *ResolvingPath, opts MknodOptions) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// OpenAt implements FilesystemImpl.OpenAt.
+func (fs *anonFilesystem) OpenAt(ctx context.Context, rp *ResolvingPath, opts OpenOptions) (*FileDescription, error) {
+ if !rp.Done() {
+ return nil, syserror.ENOTDIR
+ }
+ return nil, syserror.ENODEV
+}
+
+// ReadlinkAt implements FilesystemImpl.ReadlinkAt.
+func (fs *anonFilesystem) ReadlinkAt(ctx context.Context, rp *ResolvingPath) (string, error) {
+ if !rp.Done() {
+ return "", syserror.ENOTDIR
+ }
+ return "", syserror.EINVAL
+}
+
+// RenameAt implements FilesystemImpl.RenameAt.
+func (fs *anonFilesystem) RenameAt(ctx context.Context, rp *ResolvingPath, oldParentVD VirtualDentry, oldName string, opts RenameOptions) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// RmdirAt implements FilesystemImpl.RmdirAt.
+func (fs *anonFilesystem) RmdirAt(ctx context.Context, rp *ResolvingPath) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// SetStatAt implements FilesystemImpl.SetStatAt.
+func (fs *anonFilesystem) SetStatAt(ctx context.Context, rp *ResolvingPath, opts SetStatOptions) error {
+ if !rp.Done() {
+ return syserror.ENOTDIR
+ }
+ // Linux actually permits anon_inode_inode's metadata to be set, which is
+ // visible to all users of anon_inode_inode. We just silently ignore
+ // metadata changes.
+ return nil
+}
+
+// StatAt implements FilesystemImpl.StatAt.
+func (fs *anonFilesystem) StatAt(ctx context.Context, rp *ResolvingPath, opts StatOptions) (linux.Statx, error) {
+ if !rp.Done() {
+ return linux.Statx{}, syserror.ENOTDIR
+ }
+ // See fs/anon_inodes.c:anon_inode_init() => fs/libfs.c:alloc_anon_inode().
+ return linux.Statx{
+ Mask: linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_NLINK | linux.STATX_UID | linux.STATX_GID | linux.STATX_INO | linux.STATX_SIZE | linux.STATX_BLOCKS,
+ Blksize: anonfsBlockSize,
+ Nlink: 1,
+ UID: uint32(auth.RootKUID),
+ GID: uint32(auth.RootKGID),
+ Mode: 0600, // no type is correct
+ Ino: 1,
+ Size: 0,
+ Blocks: 0,
+ DevMajor: 0,
+ DevMinor: fs.devMinor,
+ }, nil
+}
+
+// StatFSAt implements FilesystemImpl.StatFSAt.
+func (fs *anonFilesystem) StatFSAt(ctx context.Context, rp *ResolvingPath) (linux.Statfs, error) {
+ if !rp.Done() {
+ return linux.Statfs{}, syserror.ENOTDIR
+ }
+ return linux.Statfs{
+ Type: linux.ANON_INODE_FS_MAGIC,
+ BlockSize: anonfsBlockSize,
+ }, nil
+}
+
+// SymlinkAt implements FilesystemImpl.SymlinkAt.
+func (fs *anonFilesystem) SymlinkAt(ctx context.Context, rp *ResolvingPath, target string) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// UnlinkAt implements FilesystemImpl.UnlinkAt.
+func (fs *anonFilesystem) UnlinkAt(ctx context.Context, rp *ResolvingPath) error {
+ if !rp.Final() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// ListxattrAt implements FilesystemImpl.ListxattrAt.
+func (fs *anonFilesystem) ListxattrAt(ctx context.Context, rp *ResolvingPath) ([]string, error) {
+ if !rp.Done() {
+ return nil, syserror.ENOTDIR
+ }
+ return nil, nil
+}
+
+// GetxattrAt implements FilesystemImpl.GetxattrAt.
+func (fs *anonFilesystem) GetxattrAt(ctx context.Context, rp *ResolvingPath, name string) (string, error) {
+ if !rp.Done() {
+ return "", syserror.ENOTDIR
+ }
+ return "", syserror.ENOTSUP
+}
+
+// SetxattrAt implements FilesystemImpl.SetxattrAt.
+func (fs *anonFilesystem) SetxattrAt(ctx context.Context, rp *ResolvingPath, opts SetxattrOptions) error {
+ if !rp.Done() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// RemovexattrAt implements FilesystemImpl.RemovexattrAt.
+func (fs *anonFilesystem) RemovexattrAt(ctx context.Context, rp *ResolvingPath, name string) error {
+ if !rp.Done() {
+ return syserror.ENOTDIR
+ }
+ return syserror.EPERM
+}
+
+// PrependPath implements FilesystemImpl.PrependPath.
+func (fs *anonFilesystem) PrependPath(ctx context.Context, vfsroot, vd VirtualDentry, b *fspath.Builder) error {
+ b.PrependComponent(fmt.Sprintf("anon_inode:%s", vd.dentry.impl.(*anonDentry).name))
+ return PrependPathSyntheticError{}
+}
+
+// IncRef implements DentryImpl.IncRef.
+func (d *anonDentry) IncRef() {
+ // no-op
+}
+
+// TryIncRef implements DentryImpl.TryIncRef.
+func (d *anonDentry) TryIncRef() bool {
+ return true
+}
+
+// DecRef implements DentryImpl.DecRef.
+func (d *anonDentry) DecRef() {
+ // no-op
+}
diff --git a/pkg/sentry/vfs/context.go b/pkg/sentry/vfs/context.go
index 705194ebc..d97362b9a 100644
--- a/pkg/sentry/vfs/context.go
+++ b/pkg/sentry/vfs/context.go
@@ -15,7 +15,7 @@
package vfs
import (
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
)
// contextID is this package's type for context.Context.Value keys.
diff --git a/pkg/sentry/vfs/device.go b/pkg/sentry/vfs/device.go
index 9f9d6e783..3af2aa58d 100644
--- a/pkg/sentry/vfs/device.go
+++ b/pkg/sentry/vfs/device.go
@@ -17,7 +17,7 @@ package vfs
import (
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/vfs/epoll.go b/pkg/sentry/vfs/epoll.go
new file mode 100644
index 000000000..7c83f9a5a
--- /dev/null
+++ b/pkg/sentry/vfs/epoll.go
@@ -0,0 +1,377 @@
+// Copyright 2020 The 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 vfs
+
+import (
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sync"
+ "gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/waiter"
+)
+
+// epollCycleMu serializes attempts to register EpollInstances with other
+// EpollInstances in order to check for cycles.
+var epollCycleMu sync.Mutex
+
+// EpollInstance represents an epoll instance, as described by epoll(7).
+type EpollInstance struct {
+ vfsfd FileDescription
+ FileDescriptionDefaultImpl
+ DentryMetadataFileDescriptionImpl
+
+ // q holds waiters on this EpollInstance.
+ q waiter.Queue
+
+ // interest is the set of file descriptors that are registered with the
+ // EpollInstance for monitoring. interest is protected by interestMu.
+ interestMu sync.Mutex
+ interest map[epollInterestKey]*epollInterest
+
+ // mu protects fields in registered epollInterests.
+ mu sync.Mutex
+
+ // ready is the set of file descriptors that may be "ready" for I/O. Note
+ // that this must be an ordered list, not a map: "If more than maxevents
+ // file descriptors are ready when epoll_wait() is called, then successive
+ // epoll_wait() calls will round robin through the set of ready file
+ // descriptors. This behavior helps avoid starvation scenarios, where a
+ // process fails to notice that additional file descriptors are ready
+ // because it focuses on a set of file descriptors that are already known
+ // to be ready." - epoll_wait(2)
+ ready epollInterestList
+}
+
+type epollInterestKey struct {
+ // file is the registered FileDescription. No reference is held on file;
+ // instead, when the last reference is dropped, FileDescription.DecRef()
+ // removes the FileDescription from all EpollInstances. file is immutable.
+ file *FileDescription
+
+ // num is the file descriptor number with which this entry was registered.
+ // num is immutable.
+ num int32
+}
+
+// epollInterest represents an EpollInstance's interest in a file descriptor.
+type epollInterest struct {
+ // epoll is the owning EpollInstance. epoll is immutable.
+ epoll *EpollInstance
+
+ // key is the file to which this epollInterest applies. key is immutable.
+ key epollInterestKey
+
+ // waiter is registered with key.file. entry is protected by epoll.mu.
+ waiter waiter.Entry
+
+ // mask is the event mask associated with this registration, including
+ // flags EPOLLET and EPOLLONESHOT. mask is protected by epoll.mu.
+ mask uint32
+
+ // ready is true if epollInterestEntry is linked into epoll.ready. ready
+ // and epollInterestEntry are protected by epoll.mu.
+ ready bool
+ epollInterestEntry
+
+ // userData is the epoll_data_t associated with this epollInterest.
+ // userData is protected by epoll.mu.
+ userData [2]int32
+}
+
+// NewEpollInstanceFD returns a FileDescription representing a new epoll
+// instance. A reference is taken on the returned FileDescription.
+func (vfs *VirtualFilesystem) NewEpollInstanceFD() (*FileDescription, error) {
+ vd := vfs.NewAnonVirtualDentry("[eventpoll]")
+ defer vd.DecRef()
+ ep := &EpollInstance{
+ interest: make(map[epollInterestKey]*epollInterest),
+ }
+ if err := ep.vfsfd.Init(ep, linux.O_RDWR, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{
+ UseDentryMetadata: true,
+ }); err != nil {
+ return nil, err
+ }
+ return &ep.vfsfd, nil
+}
+
+// Release implements FileDescriptionImpl.Release.
+func (ep *EpollInstance) Release() {
+ // Unregister all polled fds.
+ ep.interestMu.Lock()
+ defer ep.interestMu.Unlock()
+ for key, epi := range ep.interest {
+ file := key.file
+ file.epollMu.Lock()
+ delete(file.epolls, epi)
+ file.epollMu.Unlock()
+ file.EventUnregister(&epi.waiter)
+ }
+ ep.interest = nil
+}
+
+// Readiness implements waiter.Waitable.Readiness.
+func (ep *EpollInstance) Readiness(mask waiter.EventMask) waiter.EventMask {
+ if mask&waiter.EventIn == 0 {
+ return 0
+ }
+ ep.mu.Lock()
+ for epi := ep.ready.Front(); epi != nil; epi = epi.Next() {
+ wmask := waiter.EventMaskFromLinux(epi.mask)
+ if epi.key.file.Readiness(wmask)&wmask != 0 {
+ ep.mu.Unlock()
+ return waiter.EventIn
+ }
+ }
+ ep.mu.Unlock()
+ return 0
+}
+
+// EventRegister implements waiter.Waitable.EventRegister.
+func (ep *EpollInstance) EventRegister(e *waiter.Entry, mask waiter.EventMask) {
+ ep.q.EventRegister(e, mask)
+}
+
+// EventUnregister implements waiter.Waitable.EventUnregister.
+func (ep *EpollInstance) EventUnregister(e *waiter.Entry) {
+ ep.q.EventUnregister(e)
+}
+
+// Seek implements FileDescriptionImpl.Seek.
+func (ep *EpollInstance) Seek(ctx context.Context, offset int64, whence int32) (int64, error) {
+ // Linux: fs/eventpoll.c:eventpoll_fops.llseek == noop_llseek
+ return 0, nil
+}
+
+// AddInterest implements the semantics of EPOLL_CTL_ADD.
+//
+// Preconditions: A reference must be held on file.
+func (ep *EpollInstance) AddInterest(file *FileDescription, num int32, mask uint32, userData [2]int32) error {
+ // Check for cyclic polling if necessary.
+ subep, _ := file.impl.(*EpollInstance)
+ if subep != nil {
+ epollCycleMu.Lock()
+ // epollCycleMu must be locked for the rest of AddInterest to ensure
+ // that cyclic polling is not introduced after the check.
+ defer epollCycleMu.Unlock()
+ if subep.mightPoll(ep) {
+ return syserror.ELOOP
+ }
+ }
+
+ ep.interestMu.Lock()
+ defer ep.interestMu.Unlock()
+
+ // Fail if the key is already registered.
+ key := epollInterestKey{
+ file: file,
+ num: num,
+ }
+ if _, ok := ep.interest[key]; ok {
+ return syserror.EEXIST
+ }
+
+ // Register interest in file.
+ mask |= linux.EPOLLERR | linux.EPOLLRDHUP
+ epi := &epollInterest{
+ epoll: ep,
+ key: key,
+ mask: mask,
+ userData: userData,
+ }
+ ep.interest[key] = epi
+ wmask := waiter.EventMaskFromLinux(mask)
+ file.EventRegister(&epi.waiter, wmask)
+
+ // Check if the file is already ready.
+ if file.Readiness(wmask)&wmask != 0 {
+ epi.Callback(nil)
+ }
+
+ // Add epi to file.epolls so that it is removed when the last
+ // FileDescription reference is dropped.
+ file.epollMu.Lock()
+ file.epolls[epi] = struct{}{}
+ file.epollMu.Unlock()
+
+ return nil
+}
+
+func (ep *EpollInstance) mightPoll(ep2 *EpollInstance) bool {
+ return ep.mightPollRecursive(ep2, 4) // Linux: fs/eventpoll.c:EP_MAX_NESTS
+}
+
+func (ep *EpollInstance) mightPollRecursive(ep2 *EpollInstance, remainingRecursion int) bool {
+ ep.interestMu.Lock()
+ defer ep.interestMu.Unlock()
+ for key := range ep.interest {
+ nextep, ok := key.file.impl.(*EpollInstance)
+ if !ok {
+ continue
+ }
+ if nextep == ep2 {
+ return true
+ }
+ if remainingRecursion == 0 {
+ return true
+ }
+ if nextep.mightPollRecursive(ep2, remainingRecursion-1) {
+ return true
+ }
+ }
+ return false
+}
+
+// ModifyInterest implements the semantics of EPOLL_CTL_MOD.
+//
+// Preconditions: A reference must be held on file.
+func (ep *EpollInstance) ModifyInterest(file *FileDescription, num int32, mask uint32, userData [2]int32) error {
+ ep.interestMu.Lock()
+ defer ep.interestMu.Unlock()
+
+ // Fail if the key is not already registered.
+ epi, ok := ep.interest[epollInterestKey{
+ file: file,
+ num: num,
+ }]
+ if !ok {
+ return syserror.ENOENT
+ }
+
+ // Update epi for the next call to ep.ReadEvents().
+ ep.mu.Lock()
+ epi.mask = mask
+ epi.userData = userData
+ ep.mu.Unlock()
+
+ // Re-register with the new mask.
+ mask |= linux.EPOLLERR | linux.EPOLLRDHUP
+ file.EventUnregister(&epi.waiter)
+ wmask := waiter.EventMaskFromLinux(mask)
+ file.EventRegister(&epi.waiter, wmask)
+
+ // Check if the file is already ready with the new mask.
+ if file.Readiness(wmask)&wmask != 0 {
+ epi.Callback(nil)
+ }
+
+ return nil
+}
+
+// DeleteInterest implements the semantics of EPOLL_CTL_DEL.
+//
+// Preconditions: A reference must be held on file.
+func (ep *EpollInstance) DeleteInterest(file *FileDescription, num int32) error {
+ ep.interestMu.Lock()
+ defer ep.interestMu.Unlock()
+
+ // Fail if the key is not already registered.
+ epi, ok := ep.interest[epollInterestKey{
+ file: file,
+ num: num,
+ }]
+ if !ok {
+ return syserror.ENOENT
+ }
+
+ // Unregister from the file so that epi will no longer be readied.
+ file.EventUnregister(&epi.waiter)
+
+ // Forget about epi.
+ ep.removeLocked(epi)
+
+ file.epollMu.Lock()
+ delete(file.epolls, epi)
+ file.epollMu.Unlock()
+
+ return nil
+}
+
+// Callback implements waiter.EntryCallback.Callback.
+func (epi *epollInterest) Callback(*waiter.Entry) {
+ newReady := false
+ epi.epoll.mu.Lock()
+ if !epi.ready {
+ newReady = true
+ epi.ready = true
+ epi.epoll.ready.PushBack(epi)
+ }
+ epi.epoll.mu.Unlock()
+ if newReady {
+ epi.epoll.q.Notify(waiter.EventIn)
+ }
+}
+
+// Preconditions: ep.interestMu must be locked.
+func (ep *EpollInstance) removeLocked(epi *epollInterest) {
+ delete(ep.interest, epi.key)
+ ep.mu.Lock()
+ if epi.ready {
+ epi.ready = false
+ ep.ready.Remove(epi)
+ }
+ ep.mu.Unlock()
+}
+
+// ReadEvents reads up to len(events) ready events into events and returns the
+// number of events read.
+//
+// Preconditions: len(events) != 0.
+func (ep *EpollInstance) ReadEvents(events []linux.EpollEvent) int {
+ i := 0
+ // Hot path: avoid defer.
+ ep.mu.Lock()
+ var next *epollInterest
+ var requeue epollInterestList
+ for epi := ep.ready.Front(); epi != nil; epi = next {
+ next = epi.Next()
+ // Regardless of what else happens, epi is initially removed from the
+ // ready list.
+ ep.ready.Remove(epi)
+ wmask := waiter.EventMaskFromLinux(epi.mask)
+ ievents := epi.key.file.Readiness(wmask) & wmask
+ if ievents == 0 {
+ // Leave epi off the ready list.
+ epi.ready = false
+ continue
+ }
+ // Determine what we should do with epi.
+ switch {
+ case epi.mask&linux.EPOLLONESHOT != 0:
+ // Clear all events from the mask; they must be re-added by
+ // EPOLL_CTL_MOD.
+ epi.mask &= linux.EP_PRIVATE_BITS
+ fallthrough
+ case epi.mask&linux.EPOLLET != 0:
+ // Leave epi off the ready list.
+ epi.ready = false
+ default:
+ // Queue epi to be moved to the end of the ready list.
+ requeue.PushBack(epi)
+ }
+ // Report ievents.
+ events[i] = linux.EpollEvent{
+ Events: ievents.ToLinux(),
+ Fd: epi.userData[0],
+ Data: epi.userData[1],
+ }
+ i++
+ if i == len(events) {
+ break
+ }
+ }
+ ep.ready.PushBackList(&requeue)
+ ep.mu.Unlock()
+ return i
+}
diff --git a/pkg/sentry/vfs/file_description.go b/pkg/sentry/vfs/file_description.go
index 51c95c2d9..5bac660c7 100644
--- a/pkg/sentry/vfs/file_description.go
+++ b/pkg/sentry/vfs/file_description.go
@@ -18,12 +18,14 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/sentry/fs/lock"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -45,6 +47,11 @@ type FileDescription struct {
// memory operations.
statusFlags uint32
+ // epolls is the set of epollInterests registered for this FileDescription.
+ // epolls is protected by epollMu.
+ epollMu sync.Mutex
+ epolls map[*epollInterest]struct{}
+
// vd is the filesystem location at which this FileDescription was opened.
// A reference is held on vd. vd is immutable.
vd VirtualDentry
@@ -141,6 +148,23 @@ func (fd *FileDescription) TryIncRef() bool {
// DecRef decrements fd's reference count.
func (fd *FileDescription) DecRef() {
if refs := atomic.AddInt64(&fd.refs, -1); refs == 0 {
+ // Unregister fd from all epoll instances.
+ fd.epollMu.Lock()
+ epolls := fd.epolls
+ fd.epolls = nil
+ fd.epollMu.Unlock()
+ for epi := range epolls {
+ ep := epi.epoll
+ ep.interestMu.Lock()
+ // Check that epi has not been concurrently unregistered by
+ // EpollInstance.DeleteInterest() or EpollInstance.Release().
+ if _, ok := ep.interest[epi.key]; ok {
+ fd.EventUnregister(&epi.waiter)
+ ep.removeLocked(epi)
+ }
+ ep.interestMu.Unlock()
+ }
+ // Release implementation resources.
fd.impl.Release()
if fd.writable {
fd.vd.mount.EndWrite()
@@ -370,7 +394,25 @@ type FileDescriptionImpl interface {
// Removexattr removes the given extended attribute from the file.
Removexattr(ctx context.Context, name string) error
- // TODO: file locking
+ // LockBSD tries to acquire a BSD-style advisory file lock.
+ //
+ // TODO(gvisor.dev/issue/1480): BSD-style file locking
+ LockBSD(ctx context.Context, uid lock.UniqueID, t lock.LockType, block lock.Blocker) error
+
+ // LockBSD releases a BSD-style advisory file lock.
+ //
+ // TODO(gvisor.dev/issue/1480): BSD-style file locking
+ UnlockBSD(ctx context.Context, uid lock.UniqueID) error
+
+ // LockPOSIX tries to acquire a POSIX-style advisory file lock.
+ //
+ // TODO(gvisor.dev/issue/1480): POSIX-style file locking
+ LockPOSIX(ctx context.Context, uid lock.UniqueID, t lock.LockType, rng lock.LockRange, block lock.Blocker) error
+
+ // UnlockPOSIX releases a POSIX-style advisory file lock.
+ //
+ // TODO(gvisor.dev/issue/1480): POSIX-style file locking
+ UnlockPOSIX(ctx context.Context, uid lock.UniqueID, rng lock.LockRange) error
}
// Dirent holds the information contained in struct linux_dirent64.
@@ -453,6 +495,21 @@ func (fd *FileDescription) StatFS(ctx context.Context) (linux.Statfs, error) {
return fd.impl.StatFS(ctx)
}
+// Readiness returns fd's I/O readiness.
+func (fd *FileDescription) Readiness(mask waiter.EventMask) waiter.EventMask {
+ return fd.impl.Readiness(mask)
+}
+
+// EventRegister registers e for I/O readiness events in mask.
+func (fd *FileDescription) EventRegister(e *waiter.Entry, mask waiter.EventMask) {
+ fd.impl.EventRegister(e, mask)
+}
+
+// EventUnregister unregisters e for I/O readiness events.
+func (fd *FileDescription) EventUnregister(e *waiter.Entry) {
+ fd.impl.EventUnregister(e)
+}
+
// PRead reads from the file represented by fd into dst, starting at the given
// offset, and returns the number of bytes read. PRead is permitted to return
// partial reads with a nil error.
diff --git a/pkg/sentry/vfs/file_description_impl_util.go b/pkg/sentry/vfs/file_description_impl_util.go
index c00b3c84b..c2a52ec1b 100644
--- a/pkg/sentry/vfs/file_description_impl_util.go
+++ b/pkg/sentry/vfs/file_description_impl_util.go
@@ -19,12 +19,13 @@ import (
"io"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/sentry/fs/lock"
"gvisor.dev/gvisor/pkg/sentry/memmap"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -152,6 +153,26 @@ func (FileDescriptionDefaultImpl) Removexattr(ctx context.Context, name string)
return syserror.ENOTSUP
}
+// LockBSD implements FileDescriptionImpl.LockBSD.
+func (FileDescriptionDefaultImpl) LockBSD(ctx context.Context, uid lock.UniqueID, t lock.LockType, block lock.Blocker) error {
+ return syserror.EBADF
+}
+
+// UnlockBSD implements FileDescriptionImpl.UnlockBSD.
+func (FileDescriptionDefaultImpl) UnlockBSD(ctx context.Context, uid lock.UniqueID) error {
+ return syserror.EBADF
+}
+
+// LockPOSIX implements FileDescriptionImpl.LockPOSIX.
+func (FileDescriptionDefaultImpl) LockPOSIX(ctx context.Context, uid lock.UniqueID, t lock.LockType, rng lock.LockRange, block lock.Blocker) error {
+ return syserror.EBADF
+}
+
+// UnlockPOSIX implements FileDescriptionImpl.UnlockPOSIX.
+func (FileDescriptionDefaultImpl) UnlockPOSIX(ctx context.Context, uid lock.UniqueID, rng lock.LockRange) error {
+ return syserror.EBADF
+}
+
// DirectoryFileDescriptionDefaultImpl may be embedded by implementations of
// FileDescriptionImpl that always represent directories to obtain
// implementations of non-directory I/O methods that return EISDIR.
@@ -192,21 +213,6 @@ func (DentryMetadataFileDescriptionImpl) SetStat(ctx context.Context, opts SetSt
panic("illegal call to DentryMetadataFileDescriptionImpl.SetStat")
}
-// DynamicBytesFileDescriptionImpl may be embedded by implementations of
-// FileDescriptionImpl that represent read-only regular files whose contents
-// are backed by a bytes.Buffer that is regenerated when necessary, consistent
-// with Linux's fs/seq_file.c:single_open().
-//
-// DynamicBytesFileDescriptionImpl.SetDataSource() must be called before first
-// use.
-type DynamicBytesFileDescriptionImpl struct {
- data DynamicBytesSource // immutable
- mu sync.Mutex // protects the following fields
- buf bytes.Buffer
- off int64
- lastRead int64 // offset at which the last Read, PRead, or Seek ended
-}
-
// DynamicBytesSource represents a data source for a
// DynamicBytesFileDescriptionImpl.
type DynamicBytesSource interface {
@@ -225,6 +231,30 @@ func (s *StaticData) Generate(ctx context.Context, buf *bytes.Buffer) error {
return nil
}
+// WritableDynamicBytesSource extends DynamicBytesSource to allow writes to the
+// underlying source.
+type WritableDynamicBytesSource interface {
+ DynamicBytesSource
+
+ // Write sends writes to the source.
+ Write(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error)
+}
+
+// DynamicBytesFileDescriptionImpl may be embedded by implementations of
+// FileDescriptionImpl that represent read-only regular files whose contents
+// are backed by a bytes.Buffer that is regenerated when necessary, consistent
+// with Linux's fs/seq_file.c:single_open().
+//
+// DynamicBytesFileDescriptionImpl.SetDataSource() must be called before first
+// use.
+type DynamicBytesFileDescriptionImpl struct {
+ data DynamicBytesSource // immutable
+ mu sync.Mutex // protects the following fields
+ buf bytes.Buffer
+ off int64
+ lastRead int64 // offset at which the last Read, PRead, or Seek ended
+}
+
// SetDataSource must be called exactly once on fd before first use.
func (fd *DynamicBytesFileDescriptionImpl) SetDataSource(data DynamicBytesSource) {
fd.data = data
@@ -304,6 +334,43 @@ func (fd *DynamicBytesFileDescriptionImpl) Seek(ctx context.Context, offset int6
return offset, nil
}
+// Preconditions: fd.mu must be locked.
+func (fd *DynamicBytesFileDescriptionImpl) pwriteLocked(ctx context.Context, src usermem.IOSequence, offset int64, opts WriteOptions) (int64, error) {
+ if opts.Flags&^(linux.RWF_HIPRI|linux.RWF_DSYNC|linux.RWF_SYNC) != 0 {
+ return 0, syserror.EOPNOTSUPP
+ }
+
+ writable, ok := fd.data.(WritableDynamicBytesSource)
+ if !ok {
+ return 0, syserror.EINVAL
+ }
+ n, err := writable.Write(ctx, src, offset)
+ if err != nil {
+ return 0, err
+ }
+
+ // Invalidate cached data that might exist prior to this call.
+ fd.buf.Reset()
+ return n, nil
+}
+
+// PWrite implements FileDescriptionImpl.PWrite.
+func (fd *DynamicBytesFileDescriptionImpl) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts WriteOptions) (int64, error) {
+ fd.mu.Lock()
+ n, err := fd.pwriteLocked(ctx, src, offset, opts)
+ fd.mu.Unlock()
+ return n, err
+}
+
+// Write implements FileDescriptionImpl.Write.
+func (fd *DynamicBytesFileDescriptionImpl) Write(ctx context.Context, src usermem.IOSequence, opts WriteOptions) (int64, error) {
+ fd.mu.Lock()
+ n, err := fd.pwriteLocked(ctx, src, fd.off, opts)
+ fd.off += n
+ fd.mu.Unlock()
+ return n, err
+}
+
// GenericConfigureMMap may be used by most implementations of
// FileDescriptionImpl.ConfigureMMap.
func GenericConfigureMMap(fd *FileDescription, m memmap.Mappable, opts *memmap.MMapOpts) error {
diff --git a/pkg/sentry/vfs/file_description_impl_util_test.go b/pkg/sentry/vfs/file_description_impl_util_test.go
index 9ed58512f..8fa26418e 100644
--- a/pkg/sentry/vfs/file_description_impl_util_test.go
+++ b/pkg/sentry/vfs/file_description_impl_util_test.go
@@ -22,11 +22,10 @@ import (
"testing"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/context/contexttest"
- "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/usermem"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/contexttest"
"gvisor.dev/gvisor/pkg/syserror"
+ "gvisor.dev/gvisor/pkg/usermem"
)
// fileDescription is the common fd struct which a filesystem implementation
@@ -36,68 +35,80 @@ type fileDescription struct {
FileDescriptionDefaultImpl
}
-// genCountFD is a read-only FileDescriptionImpl representing a regular file
-// that contains the number of times its DynamicBytesSource.Generate()
+// genCount contains the number of times its DynamicBytesSource.Generate()
// implementation has been called.
-type genCountFD struct {
- fileDescription
- DynamicBytesFileDescriptionImpl
-
+type genCount struct {
count uint64 // accessed using atomic memory ops
}
-func newGenCountFD(mnt *Mount, vfsd *Dentry) *FileDescription {
- var fd genCountFD
- fd.vfsfd.Init(&fd, 0 /* statusFlags */, mnt, vfsd, &FileDescriptionOptions{})
- fd.DynamicBytesFileDescriptionImpl.SetDataSource(&fd)
- return &fd.vfsfd
+// Generate implements DynamicBytesSource.Generate.
+func (g *genCount) Generate(ctx context.Context, buf *bytes.Buffer) error {
+ fmt.Fprintf(buf, "%d", atomic.AddUint64(&g.count, 1))
+ return nil
}
-// Release implements FileDescriptionImpl.Release.
-func (fd *genCountFD) Release() {
+type storeData struct {
+ data string
+}
+
+var _ WritableDynamicBytesSource = (*storeData)(nil)
+
+// Generate implements DynamicBytesSource.
+func (d *storeData) Generate(ctx context.Context, buf *bytes.Buffer) error {
+ buf.WriteString(d.data)
+ return nil
}
-// StatusFlags implements FileDescriptionImpl.StatusFlags.
-func (fd *genCountFD) StatusFlags(ctx context.Context) (uint32, error) {
+// Generate implements WritableDynamicBytesSource.
+func (d *storeData) Write(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error) {
+ buf := make([]byte, src.NumBytes())
+ n, err := src.CopyIn(ctx, buf)
+ if err != nil {
+ return 0, err
+ }
+
+ d.data = string(buf[:n])
return 0, nil
}
-// SetStatusFlags implements FileDescriptionImpl.SetStatusFlags.
-func (fd *genCountFD) SetStatusFlags(ctx context.Context, flags uint32) error {
- return syserror.EPERM
+// testFD is a read-only FileDescriptionImpl representing a regular file.
+type testFD struct {
+ fileDescription
+ DynamicBytesFileDescriptionImpl
+
+ data DynamicBytesSource
+}
+
+func newTestFD(vfsObj *VirtualFilesystem, statusFlags uint32, data DynamicBytesSource) *FileDescription {
+ vd := vfsObj.NewAnonVirtualDentry("genCountFD")
+ defer vd.DecRef()
+ var fd testFD
+ fd.vfsfd.Init(&fd, statusFlags, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{})
+ fd.DynamicBytesFileDescriptionImpl.SetDataSource(data)
+ return &fd.vfsfd
}
+// Release implements FileDescriptionImpl.Release.
+func (fd *testFD) Release() {
+}
+
+// SetStatusFlags implements FileDescriptionImpl.SetStatusFlags.
// Stat implements FileDescriptionImpl.Stat.
-func (fd *genCountFD) Stat(ctx context.Context, opts StatOptions) (linux.Statx, error) {
+func (fd *testFD) Stat(ctx context.Context, opts StatOptions) (linux.Statx, error) {
// Note that Statx.Mask == 0 in the return value.
return linux.Statx{}, nil
}
// SetStat implements FileDescriptionImpl.SetStat.
-func (fd *genCountFD) SetStat(ctx context.Context, opts SetStatOptions) error {
+func (fd *testFD) SetStat(ctx context.Context, opts SetStatOptions) error {
return syserror.EPERM
}
-// Generate implements DynamicBytesSource.Generate.
-func (fd *genCountFD) Generate(ctx context.Context, buf *bytes.Buffer) error {
- fmt.Fprintf(buf, "%d", atomic.AddUint64(&fd.count, 1))
- return nil
-}
-
func TestGenCountFD(t *testing.T) {
ctx := contexttest.Context(t)
- creds := auth.CredentialsFromContext(ctx)
vfsObj := New() // vfs.New()
- vfsObj.MustRegisterFilesystemType("testfs", FDTestFilesystemType{}, &RegisterFilesystemTypeOptions{})
- mntns, err := vfsObj.NewMountNamespace(ctx, creds, "", "testfs", &GetFilesystemOptions{})
- if err != nil {
- t.Fatalf("failed to create testfs root mount: %v", err)
- }
- vd := mntns.Root()
- defer vd.DecRef()
-
- fd := newGenCountFD(vd.Mount(), vd.Dentry())
+ fd := newTestFD(vfsObj, linux.O_RDWR, &genCount{})
defer fd.DecRef()
// The first read causes Generate to be called to fill the FD's buffer.
@@ -138,4 +149,69 @@ func TestGenCountFD(t *testing.T) {
if want := byte('3'); buf[0] != want {
t.Errorf("PRead: got byte %c, wanted %c", buf[0], want)
}
+
+ // Write and PWrite fails.
+ if _, err := fd.Write(ctx, ioseq, WriteOptions{}); err != syserror.EINVAL {
+ t.Errorf("Write: got err %v, wanted %v", err, syserror.EINVAL)
+ }
+ if _, err := fd.PWrite(ctx, ioseq, 0, WriteOptions{}); err != syserror.EINVAL {
+ t.Errorf("Write: got err %v, wanted %v", err, syserror.EINVAL)
+ }
+}
+
+func TestWritable(t *testing.T) {
+ ctx := contexttest.Context(t)
+
+ vfsObj := New() // vfs.New()
+ fd := newTestFD(vfsObj, linux.O_RDWR, &storeData{data: "init"})
+ defer fd.DecRef()
+
+ buf := make([]byte, 10)
+ ioseq := usermem.BytesIOSequence(buf)
+ if n, err := fd.Read(ctx, ioseq, ReadOptions{}); n != 4 && err != io.EOF {
+ t.Fatalf("Read: got (%v, %v), wanted (4, EOF)", n, err)
+ }
+ if want := "init"; want == string(buf) {
+ t.Fatalf("Read: got %v, wanted %v", string(buf), want)
+ }
+
+ // Test PWrite.
+ want := "write"
+ writeIOSeq := usermem.BytesIOSequence([]byte(want))
+ if n, err := fd.PWrite(ctx, writeIOSeq, 0, WriteOptions{}); int(n) != len(want) && err != nil {
+ t.Errorf("PWrite: got err (%v, %v), wanted (%v, nil)", n, err, len(want))
+ }
+ if n, err := fd.PRead(ctx, ioseq, 0, ReadOptions{}); int(n) != len(want) && err != io.EOF {
+ t.Fatalf("PRead: got (%v, %v), wanted (%v, EOF)", n, err, len(want))
+ }
+ if want == string(buf) {
+ t.Fatalf("PRead: got %v, wanted %v", string(buf), want)
+ }
+
+ // Test Seek to 0 followed by Write.
+ want = "write2"
+ writeIOSeq = usermem.BytesIOSequence([]byte(want))
+ if n, err := fd.Seek(ctx, 0, linux.SEEK_SET); n != 0 && err != nil {
+ t.Errorf("Seek: got err (%v, %v), wanted (0, nil)", n, err)
+ }
+ if n, err := fd.Write(ctx, writeIOSeq, WriteOptions{}); int(n) != len(want) && err != nil {
+ t.Errorf("Write: got err (%v, %v), wanted (%v, nil)", n, err, len(want))
+ }
+ if n, err := fd.PRead(ctx, ioseq, 0, ReadOptions{}); int(n) != len(want) && err != io.EOF {
+ t.Fatalf("PRead: got (%v, %v), wanted (%v, EOF)", n, err, len(want))
+ }
+ if want == string(buf) {
+ t.Fatalf("PRead: got %v, wanted %v", string(buf), want)
+ }
+
+ // Test failure if offset != 0.
+ if n, err := fd.Seek(ctx, 1, linux.SEEK_SET); n != 0 && err != nil {
+ t.Errorf("Seek: got err (%v, %v), wanted (0, nil)", n, err)
+ }
+ if n, err := fd.Write(ctx, writeIOSeq, WriteOptions{}); n != 0 && err != syserror.EINVAL {
+ t.Errorf("Write: got err (%v, %v), wanted (0, EINVAL)", n, err)
+ }
+ if n, err := fd.PWrite(ctx, writeIOSeq, 2, WriteOptions{}); n != 0 && err != syserror.EINVAL {
+ t.Errorf("PWrite: got err (%v, %v), wanted (0, EINVAL)", n, err)
+ }
}
diff --git a/pkg/sentry/vfs/filesystem.go b/pkg/sentry/vfs/filesystem.go
index ea78f555b..a06a6caf3 100644
--- a/pkg/sentry/vfs/filesystem.go
+++ b/pkg/sentry/vfs/filesystem.go
@@ -18,8 +18,8 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
)
// A Filesystem is a tree of nodes represented by Dentries, which forms part of
diff --git a/pkg/sentry/vfs/filesystem_type.go b/pkg/sentry/vfs/filesystem_type.go
index 023301780..c58b70728 100644
--- a/pkg/sentry/vfs/filesystem_type.go
+++ b/pkg/sentry/vfs/filesystem_type.go
@@ -18,7 +18,7 @@ import (
"bytes"
"fmt"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
diff --git a/pkg/sentry/vfs/mount.go b/pkg/sentry/vfs/mount.go
index 00177b371..d39528051 100644
--- a/pkg/sentry/vfs/mount.go
+++ b/pkg/sentry/vfs/mount.go
@@ -19,7 +19,7 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/context"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/vfs/pathname.go b/pkg/sentry/vfs/pathname.go
index cf80df90e..b318c681a 100644
--- a/pkg/sentry/vfs/pathname.go
+++ b/pkg/sentry/vfs/pathname.go
@@ -15,8 +15,8 @@
package vfs
import (
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
)
diff --git a/pkg/sentry/vfs/testutil.go b/pkg/sentry/vfs/testutil.go
deleted file mode 100644
index ee5c8b9e2..000000000
--- a/pkg/sentry/vfs/testutil.go
+++ /dev/null
@@ -1,173 +0,0 @@
-// 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 vfs
-
-import (
- "fmt"
-
- "gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
- "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/syserror"
-)
-
-// FDTestFilesystemType is a test-only FilesystemType that produces Filesystems
-// for which all FilesystemImpl methods taking a path return EPERM. It is used
-// to produce Mounts and Dentries for testing of FileDescriptionImpls that do
-// not depend on their originating Filesystem.
-type FDTestFilesystemType struct{}
-
-// FDTestFilesystem is a test-only FilesystemImpl produced by
-// FDTestFilesystemType.
-type FDTestFilesystem struct {
- vfsfs Filesystem
-}
-
-// GetFilesystem implements FilesystemType.GetFilesystem.
-func (fstype FDTestFilesystemType) GetFilesystem(ctx context.Context, vfsObj *VirtualFilesystem, creds *auth.Credentials, source string, opts GetFilesystemOptions) (*Filesystem, *Dentry, error) {
- var fs FDTestFilesystem
- fs.vfsfs.Init(vfsObj, &fs)
- return &fs.vfsfs, fs.NewDentry(), nil
-}
-
-// Release implements FilesystemImpl.Release.
-func (fs *FDTestFilesystem) Release() {
-}
-
-// Sync implements FilesystemImpl.Sync.
-func (fs *FDTestFilesystem) Sync(ctx context.Context) error {
- return nil
-}
-
-// GetDentryAt implements FilesystemImpl.GetDentryAt.
-func (fs *FDTestFilesystem) GetDentryAt(ctx context.Context, rp *ResolvingPath, opts GetDentryOptions) (*Dentry, error) {
- return nil, syserror.EPERM
-}
-
-// GetParentDentryAt implements FilesystemImpl.GetParentDentryAt.
-func (fs *FDTestFilesystem) GetParentDentryAt(ctx context.Context, rp *ResolvingPath) (*Dentry, error) {
- return nil, syserror.EPERM
-}
-
-// LinkAt implements FilesystemImpl.LinkAt.
-func (fs *FDTestFilesystem) LinkAt(ctx context.Context, rp *ResolvingPath, vd VirtualDentry) error {
- return syserror.EPERM
-}
-
-// MkdirAt implements FilesystemImpl.MkdirAt.
-func (fs *FDTestFilesystem) MkdirAt(ctx context.Context, rp *ResolvingPath, opts MkdirOptions) error {
- return syserror.EPERM
-}
-
-// MknodAt implements FilesystemImpl.MknodAt.
-func (fs *FDTestFilesystem) MknodAt(ctx context.Context, rp *ResolvingPath, opts MknodOptions) error {
- return syserror.EPERM
-}
-
-// OpenAt implements FilesystemImpl.OpenAt.
-func (fs *FDTestFilesystem) OpenAt(ctx context.Context, rp *ResolvingPath, opts OpenOptions) (*FileDescription, error) {
- return nil, syserror.EPERM
-}
-
-// ReadlinkAt implements FilesystemImpl.ReadlinkAt.
-func (fs *FDTestFilesystem) ReadlinkAt(ctx context.Context, rp *ResolvingPath) (string, error) {
- return "", syserror.EPERM
-}
-
-// RenameAt implements FilesystemImpl.RenameAt.
-func (fs *FDTestFilesystem) RenameAt(ctx context.Context, rp *ResolvingPath, oldParentVD VirtualDentry, oldName string, opts RenameOptions) error {
- return syserror.EPERM
-}
-
-// RmdirAt implements FilesystemImpl.RmdirAt.
-func (fs *FDTestFilesystem) RmdirAt(ctx context.Context, rp *ResolvingPath) error {
- return syserror.EPERM
-}
-
-// SetStatAt implements FilesystemImpl.SetStatAt.
-func (fs *FDTestFilesystem) SetStatAt(ctx context.Context, rp *ResolvingPath, opts SetStatOptions) error {
- return syserror.EPERM
-}
-
-// StatAt implements FilesystemImpl.StatAt.
-func (fs *FDTestFilesystem) StatAt(ctx context.Context, rp *ResolvingPath, opts StatOptions) (linux.Statx, error) {
- return linux.Statx{}, syserror.EPERM
-}
-
-// StatFSAt implements FilesystemImpl.StatFSAt.
-func (fs *FDTestFilesystem) StatFSAt(ctx context.Context, rp *ResolvingPath) (linux.Statfs, error) {
- return linux.Statfs{}, syserror.EPERM
-}
-
-// SymlinkAt implements FilesystemImpl.SymlinkAt.
-func (fs *FDTestFilesystem) SymlinkAt(ctx context.Context, rp *ResolvingPath, target string) error {
- return syserror.EPERM
-}
-
-// UnlinkAt implements FilesystemImpl.UnlinkAt.
-func (fs *FDTestFilesystem) UnlinkAt(ctx context.Context, rp *ResolvingPath) error {
- return syserror.EPERM
-}
-
-// ListxattrAt implements FilesystemImpl.ListxattrAt.
-func (fs *FDTestFilesystem) ListxattrAt(ctx context.Context, rp *ResolvingPath) ([]string, error) {
- return nil, syserror.EPERM
-}
-
-// GetxattrAt implements FilesystemImpl.GetxattrAt.
-func (fs *FDTestFilesystem) GetxattrAt(ctx context.Context, rp *ResolvingPath, name string) (string, error) {
- return "", syserror.EPERM
-}
-
-// SetxattrAt implements FilesystemImpl.SetxattrAt.
-func (fs *FDTestFilesystem) SetxattrAt(ctx context.Context, rp *ResolvingPath, opts SetxattrOptions) error {
- return syserror.EPERM
-}
-
-// RemovexattrAt implements FilesystemImpl.RemovexattrAt.
-func (fs *FDTestFilesystem) RemovexattrAt(ctx context.Context, rp *ResolvingPath, name string) error {
- return syserror.EPERM
-}
-
-// PrependPath implements FilesystemImpl.PrependPath.
-func (fs *FDTestFilesystem) PrependPath(ctx context.Context, vfsroot, vd VirtualDentry, b *fspath.Builder) error {
- b.PrependComponent(fmt.Sprintf("vfs.fdTestDentry:%p", vd.dentry.impl.(*fdTestDentry)))
- return PrependPathSyntheticError{}
-}
-
-type fdTestDentry struct {
- vfsd Dentry
-}
-
-// NewDentry returns a new Dentry.
-func (fs *FDTestFilesystem) NewDentry() *Dentry {
- var d fdTestDentry
- d.vfsd.Init(&d)
- return &d.vfsd
-}
-
-// IncRef implements DentryImpl.IncRef.
-func (d *fdTestDentry) IncRef() {
-}
-
-// TryIncRef implements DentryImpl.TryIncRef.
-func (d *fdTestDentry) TryIncRef() bool {
- return true
-}
-
-// DecRef implements DentryImpl.DecRef.
-func (d *fdTestDentry) DecRef() {
-}
diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go
index 1f6f56293..908c69f91 100644
--- a/pkg/sentry/vfs/vfs.go
+++ b/pkg/sentry/vfs/vfs.go
@@ -16,23 +16,27 @@
//
// Lock order:
//
-// FilesystemImpl/FileDescriptionImpl locks
-// VirtualFilesystem.mountMu
-// Dentry.mu
-// Locks acquired by FilesystemImpls between Prepare{Delete,Rename}Dentry and Commit{Delete,Rename*}Dentry
-// VirtualFilesystem.filesystemsMu
+// EpollInstance.interestMu
+// FileDescription.epollMu
+// FilesystemImpl/FileDescriptionImpl locks
+// VirtualFilesystem.mountMu
+// Dentry.mu
+// Locks acquired by FilesystemImpls between Prepare{Delete,Rename}Dentry and Commit{Delete,Rename*}Dentry
+// VirtualFilesystem.filesystemsMu
+// EpollInstance.mu
// VirtualFilesystem.fsTypesMu
//
// Locking Dentry.mu in multiple Dentries requires holding
-// VirtualFilesystem.mountMu.
+// VirtualFilesystem.mountMu. Locking EpollInstance.interestMu in multiple
+// EpollInstances requires holding epollCycleMu.
package vfs
import (
"fmt"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fspath"
- "gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserror"
@@ -75,6 +79,14 @@ type VirtualFilesystem struct {
// mountpoints is analogous to Linux's mountpoint_hashtable.
mountpoints map[*Dentry]map[*Mount]struct{}
+ // anonMount is a Mount, not included in mounts or mountpoints,
+ // representing an anonFilesystem. anonMount is used to back
+ // VirtualDentries returned by VirtualFilesystem.NewAnonVirtualDentry().
+ // anonMount is immutable.
+ //
+ // anonMount is analogous to Linux's anon_inode_mnt.
+ anonMount *Mount
+
// devices contains all registered Devices. devices is protected by
// devicesMu.
devicesMu sync.RWMutex
@@ -110,6 +122,22 @@ func New() *VirtualFilesystem {
filesystems: make(map[*Filesystem]struct{}),
}
vfs.mounts.Init()
+
+ // Construct vfs.anonMount.
+ anonfsDevMinor, err := vfs.GetAnonBlockDevMinor()
+ if err != nil {
+ panic(fmt.Sprintf("VirtualFilesystem.GetAnonBlockDevMinor() failed during VirtualFilesystem construction: %v", err))
+ }
+ anonfs := anonFilesystem{
+ devMinor: anonfsDevMinor,
+ }
+ anonfs.vfsfs.Init(vfs, &anonfs)
+ vfs.anonMount = &Mount{
+ vfs: vfs,
+ fs: &anonfs.vfsfs,
+ refs: 1,
+ }
+
return vfs
}
diff --git a/pkg/sentry/watchdog/BUILD b/pkg/sentry/watchdog/BUILD
index 28f21f13d..1c5a1c9b6 100644
--- a/pkg/sentry/watchdog/BUILD
+++ b/pkg/sentry/watchdog/BUILD
@@ -1,11 +1,10 @@
-load("//tools/go_stateify:defs.bzl", "go_library")
+load("//tools:defs.bzl", "go_library")
package(licenses = ["notice"])
go_library(
name = "watchdog",
srcs = ["watchdog.go"],
- importpath = "gvisor.dev/gvisor/pkg/sentry/watchdog",
visibility = ["//:sandbox"],
deps = [
"//pkg/abi/linux",