summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-02-14 11:11:55 -0800
committergVisor bot <gvisor-bot@google.com>2020-02-14 11:12:47 -0800
commit4075de11be44372c454aae7f9650cdc814c52229 (patch)
tree6c61b83a9cfd07af87446262f917652f58c5205f /pkg/sentry/syscalls
parentb2e86906ea4f7bc43b8d2d3a4735a87eca779b33 (diff)
Plumb VFS2 inside the Sentry
- Added fsbridge package with interface that can be used to open and read from VFS1 and VFS2 files. - Converted ELF loader to use fsbridge - Added VFS2 types to FSContext - Added vfs.MountNamespace to ThreadGroup Updates #1623 PiperOrigin-RevId: 295183950
Diffstat (limited to 'pkg/sentry/syscalls')
-rw-r--r--pkg/sentry/syscalls/linux/BUILD1
-rw-r--r--pkg/sentry/syscalls/linux/sys_prctl.go3
-rw-r--r--pkg/sentry/syscalls/linux/sys_thread.go17
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go106
4 files changed, 121 insertions, 6 deletions
diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD
index be16ee686..0d24fd3c4 100644
--- a/pkg/sentry/syscalls/linux/BUILD
+++ b/pkg/sentry/syscalls/linux/BUILD
@@ -74,6 +74,7 @@ go_library(
"//pkg/sentry/fs/lock",
"//pkg/sentry/fs/timerfd",
"//pkg/sentry/fs/tmpfs",
+ "//pkg/sentry/fsbridge",
"//pkg/sentry/kernel",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/epoll",
diff --git a/pkg/sentry/syscalls/linux/sys_prctl.go b/pkg/sentry/syscalls/linux/sys_prctl.go
index 98db32d77..9c6728530 100644
--- a/pkg/sentry/syscalls/linux/sys_prctl.go
+++ b/pkg/sentry/syscalls/linux/sys_prctl.go
@@ -20,6 +20,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
+ "gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/mm"
@@ -135,7 +136,7 @@ func Prctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
}
// Set the underlying executable.
- t.MemoryManager().SetExecutable(file.Dirent)
+ t.MemoryManager().SetExecutable(fsbridge.NewFSFile(file))
case linux.PR_SET_MM_AUXV,
linux.PR_SET_MM_START_CODE,
diff --git a/pkg/sentry/syscalls/linux/sys_thread.go b/pkg/sentry/syscalls/linux/sys_thread.go
index 0c9e2255d..00915fdde 100644
--- a/pkg/sentry/syscalls/linux/sys_thread.go
+++ b/pkg/sentry/syscalls/linux/sys_thread.go
@@ -21,6 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
+ "gvisor.dev/gvisor/pkg/sentry/fsbridge"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/sched"
"gvisor.dev/gvisor/pkg/sentry/loader"
@@ -119,7 +120,7 @@ func execveat(t *kernel.Task, dirFD int32, pathnameAddr, argvAddr, envvAddr user
defer root.DecRef()
var wd *fs.Dirent
- var executable *fs.File
+ var executable fsbridge.File
var closeOnExec bool
if dirFD == linux.AT_FDCWD || path.IsAbs(pathname) {
// Even if the pathname is absolute, we may still need the wd
@@ -136,7 +137,15 @@ func execveat(t *kernel.Task, dirFD int32, pathnameAddr, argvAddr, envvAddr user
closeOnExec = fdFlags.CloseOnExec
if atEmptyPath && len(pathname) == 0 {
- executable = f
+ // TODO(gvisor.dev/issue/160): Linux requires only execute permission,
+ // not read. However, our backing filesystems may prevent us from reading
+ // the file without read permission. Additionally, a task with a
+ // non-readable executable has additional constraints on access via
+ // ptrace and procfs.
+ if err := f.Dirent.Inode.CheckPermission(t, fs.PermMask{Read: true, Execute: true}); err != nil {
+ return 0, nil, err
+ }
+ executable = fsbridge.NewFSFile(f)
} else {
wd = f.Dirent
wd.IncRef()
@@ -152,9 +161,7 @@ func execveat(t *kernel.Task, dirFD int32, pathnameAddr, argvAddr, envvAddr user
// Load the new TaskContext.
remainingTraversals := uint(linux.MaxSymlinkTraversals)
loadArgs := loader.LoadArgs{
- Mounts: t.MountNamespace(),
- Root: root,
- WorkingDirectory: wd,
+ Opener: fsbridge.NewFSLookup(t.MountNamespace(), root, wd),
RemainingTraversals: &remainingTraversals,
ResolveFinal: resolveFinal,
Filename: pathname,
diff --git a/pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go b/pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go
index c134714ee..e0ac32b33 100644
--- a/pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go
+++ b/pkg/sentry/syscalls/linux/vfs2/linux64_override_amd64.go
@@ -22,4 +22,110 @@ import (
// Override syscall table to add syscalls implementations from this package.
func Override(table map[uintptr]kernel.Syscall) {
table[0] = syscalls.Supported("read", Read)
+
+ // Remove syscalls that haven't been converted yet. It's better to get ENOSYS
+ // rather than a SIGSEGV deep in the stack.
+ delete(table, 1) // write
+ delete(table, 2) // open
+ delete(table, 3) // close
+ delete(table, 4) // stat
+ delete(table, 5) // fstat
+ delete(table, 6) // lstat
+ delete(table, 7) // poll
+ delete(table, 8) // lseek
+ delete(table, 9) // mmap
+ delete(table, 16) // ioctl
+ delete(table, 17) // pread64
+ delete(table, 18) // pwrite64
+ delete(table, 19) // readv
+ delete(table, 20) // writev
+ delete(table, 21) // access
+ delete(table, 22) // pipe
+ delete(table, 32) // dup
+ delete(table, 33) // dup2
+ delete(table, 40) // sendfile
+ delete(table, 59) // execve
+ delete(table, 72) // fcntl
+ delete(table, 73) // flock
+ delete(table, 74) // fsync
+ delete(table, 75) // fdatasync
+ delete(table, 76) // truncate
+ delete(table, 77) // ftruncate
+ delete(table, 78) // getdents
+ delete(table, 79) // getcwd
+ delete(table, 80) // chdir
+ delete(table, 81) // fchdir
+ delete(table, 82) // rename
+ delete(table, 83) // mkdir
+ delete(table, 84) // rmdir
+ delete(table, 85) // creat
+ delete(table, 86) // link
+ delete(table, 87) // unlink
+ delete(table, 88) // symlink
+ delete(table, 89) // readlink
+ delete(table, 90) // chmod
+ delete(table, 91) // fchmod
+ delete(table, 92) // chown
+ delete(table, 93) // fchown
+ delete(table, 94) // lchown
+ delete(table, 133) // mknod
+ delete(table, 137) // statfs
+ delete(table, 138) // fstatfs
+ delete(table, 161) // chroot
+ delete(table, 162) // sync
+ delete(table, 165) // mount
+ delete(table, 166) // umount2
+ delete(table, 172) // iopl
+ delete(table, 173) // ioperm
+ delete(table, 187) // readahead
+ delete(table, 188) // setxattr
+ delete(table, 189) // lsetxattr
+ delete(table, 190) // fsetxattr
+ delete(table, 191) // getxattr
+ delete(table, 192) // lgetxattr
+ delete(table, 193) // fgetxattr
+ delete(table, 206) // io_setup
+ delete(table, 207) // io_destroy
+ delete(table, 208) // io_getevents
+ delete(table, 209) // io_submit
+ delete(table, 210) // io_cancel
+ delete(table, 213) // epoll_create
+ delete(table, 214) // epoll_ctl_old
+ delete(table, 215) // epoll_wait_old
+ delete(table, 216) // remap_file_pages
+ delete(table, 217) // getdents64
+ delete(table, 232) // epoll_wait
+ delete(table, 233) // epoll_ctl
+ delete(table, 253) // inotify_init
+ delete(table, 254) // inotify_add_watch
+ delete(table, 255) // inotify_rm_watch
+ delete(table, 257) // openat
+ delete(table, 258) // mkdirat
+ delete(table, 259) // mknodat
+ delete(table, 260) // fchownat
+ delete(table, 261) // futimesat
+ delete(table, 262) // fstatat
+ delete(table, 263) // unlinkat
+ delete(table, 264) // renameat
+ delete(table, 265) // linkat
+ delete(table, 266) // symlinkat
+ delete(table, 267) // readlinkat
+ delete(table, 268) // fchmodat
+ delete(table, 269) // faccessat
+ delete(table, 270) // pselect
+ delete(table, 271) // ppoll
+ delete(table, 285) // fallocate
+ delete(table, 291) // epoll_create1
+ delete(table, 292) // dup3
+ delete(table, 293) // pipe2
+ delete(table, 294) // inotify_init1
+ delete(table, 295) // preadv
+ delete(table, 296) // pwritev
+ delete(table, 306) // syncfs
+ delete(table, 316) // renameat2
+ delete(table, 319) // memfd_create
+ delete(table, 322) // execveat
+ delete(table, 327) // preadv2
+ delete(table, 328) // pwritev2
+ delete(table, 332) // statx
}