diff options
Diffstat (limited to 'pkg/sentry/fs')
43 files changed, 310 insertions, 299 deletions
diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 5c3e852e9..420fbae34 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -69,6 +69,7 @@ go_library( "//pkg/syserror", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) @@ -131,5 +132,6 @@ go_test( deps = [ "//pkg/context", "//pkg/sentry/contexttest", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/attr.go b/pkg/sentry/fs/attr.go index f60bd423d..b90f7c1be 100644 --- a/pkg/sentry/fs/attr.go +++ b/pkg/sentry/fs/attr.go @@ -17,8 +17,8 @@ package fs import ( "fmt" "os" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/p9" @@ -355,17 +355,17 @@ func (p PermMask) String() string { return fmt.Sprintf("PermMask{Read: %v, Write: %v, Execute: %v}", p.Read, p.Write, p.Execute) } -// Mode returns the system mode (syscall.S_IXOTH, etc.) for these permissions +// Mode returns the system mode (unix.S_IXOTH, etc.) for these permissions // in the "other" bits. func (p PermMask) Mode() (mode os.FileMode) { if p.Read { - mode |= syscall.S_IROTH + mode |= unix.S_IROTH } if p.Write { - mode |= syscall.S_IWOTH + mode |= unix.S_IWOTH } if p.Execute { - mode |= syscall.S_IXOTH + mode |= unix.S_IXOTH } return } diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 00c526b03..9d5d40954 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -18,8 +18,8 @@ import ( "fmt" "path" "sync/atomic" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/refs" @@ -418,7 +418,7 @@ func (d *Dirent) descendantOf(p *Dirent) bool { // * name must must not contain "/"s. func (d *Dirent) walk(ctx context.Context, root *Dirent, name string, walkMayUnlock bool) (*Dirent, error) { if !IsDir(d.Inode.StableAttr) { - return nil, syscall.ENOTDIR + return nil, unix.ENOTDIR } if name == "" || name == "." { @@ -452,7 +452,7 @@ func (d *Dirent) walk(ctx context.Context, root *Dirent, name string, walkMayUnl // hard reference on them, and they contain virtually no state). But this is // good house-keeping. child.DecRef(ctx) - return nil, syscall.ENOENT + return nil, unix.ENOENT } // Do we need to revalidate this child? @@ -518,7 +518,7 @@ func (d *Dirent) walk(ctx context.Context, root *Dirent, name string, walkMayUnl if cd.IsNegative() { // If so, don't leak a reference and short circuit. child.DecRef(ctx) - return nil, syscall.ENOENT + return nil, unix.ENOENT } // We make the judgement call that if c raced with cd they are close enough to have @@ -545,7 +545,7 @@ func (d *Dirent) walk(ctx context.Context, root *Dirent, name string, walkMayUnl if c.IsNegative() { // Don't drop a reference on the negative Dirent, it was just installed and this is the // only reference we'll ever get. d owns the reference. - return nil, syscall.ENOENT + return nil, unix.ENOENT } // Return the positive Dirent. @@ -611,7 +611,7 @@ func (d *Dirent) Create(ctx context.Context, root *Dirent, name string, flags Fi // Does something already exist? if d.exists(ctx, root, name) { - return nil, syscall.EEXIST + return nil, unix.EEXIST } // Try the create. We need to trust the file system to return EEXIST (or something @@ -674,7 +674,7 @@ func (d *Dirent) genericCreate(ctx context.Context, root *Dirent, name string, c // Does something already exist? if d.exists(ctx, root, name) { - return syscall.EEXIST + return unix.EEXIST } // Remove any negative Dirent. We've already asserted above with d.exists @@ -718,12 +718,12 @@ func (d *Dirent) CreateLink(ctx context.Context, root *Dirent, oldname, newname func (d *Dirent) CreateHardLink(ctx context.Context, root *Dirent, target *Dirent, name string) error { // Make sure that target does not span filesystems. if d.Inode.MountSource != target.Inode.MountSource { - return syscall.EXDEV + return unix.EXDEV } // Directories are never linkable. See fs/namei.c:vfs_link. if IsDir(target.Inode.StableAttr) { - return syscall.EPERM + return unix.EPERM } return d.genericCreate(ctx, root, name, func() error { @@ -759,8 +759,8 @@ func (d *Dirent) Bind(ctx context.Context, root *Dirent, name string, data trans d.finishCreate(ctx, childDir, name) return nil }) - if err == syscall.EEXIST { - return nil, syscall.EADDRINUSE + if err == unix.EEXIST { + return nil, unix.EADDRINUSE } if err != nil { return nil, err @@ -1033,14 +1033,14 @@ func (d *Dirent) Remove(ctx context.Context, root *Dirent, name string, dirPath // Remove cannot remove directories. if IsDir(child.Inode.StableAttr) { - return syscall.EISDIR + return unix.EISDIR } else if dirPath { - return syscall.ENOTDIR + return unix.ENOTDIR } // Remove cannot remove a mount point. if child.isMountPoint() { - return syscall.EBUSY + return unix.EBUSY } // Try to remove name on the file system. @@ -1087,11 +1087,11 @@ func (d *Dirent) RemoveDirectory(ctx context.Context, root *Dirent, name string) // Check for dots. if name == "." { // Rejected as the last component by rmdir(2). - return syscall.EINVAL + return unix.EINVAL } if name == ".." { // If d was found, then its parent is not empty. - return syscall.ENOTEMPTY + return unix.ENOTEMPTY } // Try to walk to the node. @@ -1104,12 +1104,12 @@ func (d *Dirent) RemoveDirectory(ctx context.Context, root *Dirent, name string) // RemoveDirectory can only remove directories. if !IsDir(child.Inode.StableAttr) { - return syscall.ENOTDIR + return unix.ENOTDIR } // Remove cannot remove a mount point. if child.isMountPoint() { - return syscall.EBUSY + return unix.EBUSY } // Try to remove name on the file system. @@ -1294,7 +1294,7 @@ func lockForRename(oldParent *Dirent, oldName string, newParent *Dirent, newName // more specifically of oldParent/oldName. That is, we're // trying to rename something into a subdirectory of // itself. - err = syscall.EINVAL + err = unix.EINVAL } return func() { newParent.mu.Unlock() @@ -1420,12 +1420,12 @@ func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string // Check that the renamed dirent is not a mount point. if renamed.isMountPointLocked() { - return syscall.EBUSY + return unix.EBUSY } // Source should not be an ancestor of the target. if newParent.descendantOf(renamed) { - return syscall.EINVAL + return unix.EINVAL } // Per rename(2): "... EACCES: ... or oldpath is a directory and does not @@ -1465,13 +1465,13 @@ func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string // ancestor of target, but ENOTEMPTY if the target is // an ancestor of source (unless RENAME_EXCHANGE flag // is present). See fs/namei.c:renameat2. - return syscall.ENOTEMPTY + return unix.ENOTEMPTY } // Check that replaced is not a mount point. if replaced.isMountPointLocked() { replaced.DecRef(ctx) - return syscall.EBUSY + return unix.EBUSY } // Require that a directory is replaced by a directory. @@ -1479,11 +1479,11 @@ func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string newIsDir := IsDir(replaced.Inode.StableAttr) if !newIsDir && oldIsDir { replaced.DecRef(ctx) - return syscall.ENOTDIR + return unix.ENOTDIR } if !oldIsDir && newIsDir { replaced.DecRef(ctx) - return syscall.EISDIR + return unix.EISDIR } // Allow the file system to drop extra references on replaced. diff --git a/pkg/sentry/fs/dirent_refs_test.go b/pkg/sentry/fs/dirent_refs_test.go index 176b894ba..e2b66f357 100644 --- a/pkg/sentry/fs/dirent_refs_test.go +++ b/pkg/sentry/fs/dirent_refs_test.go @@ -15,9 +15,9 @@ package fs import ( - "syscall" "testing" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/sentry/contexttest" ) @@ -83,8 +83,8 @@ func TestWalkNegative(t *testing.T) { name := "d" for i := 0; i < 100; i++ { _, err := root.walk(ctx, root, name, false) - if err != syscall.ENOENT { - t.Fatalf("root.walk(root, %q) got %v, want %v", name, err, syscall.ENOENT) + if err != unix.ENOENT { + t.Fatalf("root.walk(root, %q) got %v, want %v", name, err, unix.ENOENT) } } @@ -166,8 +166,8 @@ func TestHashNegativeToPositive(t *testing.T) { name := "d" _, err := root.walk(ctx, root, name, false) - if err != syscall.ENOENT { - t.Fatalf("root.walk(root, %q) got %v, want %v", name, err, syscall.ENOENT) + if err != unix.ENOENT { + t.Fatalf("root.walk(root, %q) got %v, want %v", name, err, unix.ENOENT) } if got := root.exists(ctx, root, name); got != false { diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 1d09e983c..c83baf464 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -24,6 +24,7 @@ go_library( "//pkg/syserror", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) @@ -44,5 +45,6 @@ go_test( "//pkg/syserror", "//pkg/usermem", "@com_github_google_uuid//:go_default_library", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index b99199798..757b7d511 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -17,8 +17,8 @@ package fdpipe import ( "os" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/fdnotifier" @@ -82,16 +82,16 @@ func newPipeOperations(ctx context.Context, opener NonBlockingOpener, flags fs.F // init initializes p.file. func (p *pipeOperations) init() error { - var s syscall.Stat_t - if err := syscall.Fstat(p.file.FD(), &s); err != nil { + var s unix.Stat_t + if err := unix.Fstat(p.file.FD(), &s); err != nil { log.Warningf("pipe: cannot stat fd %d: %v", p.file.FD(), err) - return syscall.EINVAL + return unix.EINVAL } - if (s.Mode & syscall.S_IFMT) != syscall.S_IFIFO { + if (s.Mode & unix.S_IFMT) != unix.S_IFIFO { log.Warningf("pipe: cannot load fd %d as pipe, file type: %o", p.file.FD(), s.Mode) - return syscall.EINVAL + return unix.EINVAL } - if err := syscall.SetNonblock(p.file.FD(), true); err != nil { + if err := unix.SetNonblock(p.file.FD(), true); err != nil { return err } return fdnotifier.AddFD(int32(p.file.FD()), &p.Queue) diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go index 0c3595998..adda19168 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener.go @@ -17,9 +17,9 @@ package fdpipe import ( "io" "os" - "syscall" "time" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/sentry/fs" @@ -96,7 +96,7 @@ func (p *pipeOpenState) TryOpen(ctx context.Context, opener NonBlockingOpener, f switch { // Reject invalid configurations so they don't accidentally succeed below. case !flags.Read && !flags.Write: - return nil, syscall.EINVAL + return nil, unix.EINVAL // Handle opening RDWR or with O_NONBLOCK: will never block, so try only once. case (flags.Read && flags.Write) || flags.NonBlocking: @@ -155,7 +155,7 @@ func (p *pipeOpenState) TryOpenReadOnly(ctx context.Context, opener NonBlockingO // Any error that is not EWOULDBLOCK also means we're not // ready yet, and probably never will be ready. In this // case we need to close the host pipe we opened. - if unwrapError(rerr) != syscall.EWOULDBLOCK { + if unwrapError(rerr) != unix.EWOULDBLOCK { p.hostFile.Close() return nil, rerr } @@ -183,7 +183,7 @@ func (p *pipeOpenState) TryOpenReadOnly(ctx context.Context, opener NonBlockingO // to an syserror.ErrWouldBlock, to tell callers to retry. func (*pipeOpenState) TryOpenWriteOnly(ctx context.Context, opener NonBlockingOpener) (*pipeOperations, error) { hostFile, err := opener.NonBlockingOpen(ctx, fs.PermMask{Write: true}) - if unwrapError(err) == syscall.ENXIO { + if unwrapError(err) == unix.ENXIO { return nil, syserror.ErrWouldBlock } if err != nil { diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go index b9cec4b13..7b3ff191f 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go @@ -20,11 +20,11 @@ import ( "io" "os" "path" - "syscall" "testing" "time" "github.com/google/uuid" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" @@ -42,15 +42,15 @@ func (h *hostOpener) NonBlockingOpen(_ context.Context, p fs.PermMask) (*fd.FD, var flags int switch { case p.Read && p.Write: - flags = syscall.O_RDWR + flags = unix.O_RDWR case p.Write: - flags = syscall.O_WRONLY + flags = unix.O_WRONLY case p.Read: - flags = syscall.O_RDONLY + flags = unix.O_RDONLY default: - return nil, syscall.EINVAL + return nil, unix.EINVAL } - f, err := syscall.Open(h.name, flags|syscall.O_NONBLOCK, 0666) + f, err := unix.Open(h.name, flags|unix.O_NONBLOCK, 0666) if err != nil { return nil, err } @@ -62,7 +62,7 @@ func pipename() string { } func mkpipe(name string) error { - return syscall.Mknod(name, syscall.S_IFIFO|0666, 0) + return unix.Mknod(name, unix.S_IFIFO|0666, 0) } func TestTryOpen(t *testing.T) { @@ -87,14 +87,14 @@ func TestTryOpen(t *testing.T) { makePipe: false, flags: fs.FileFlags{}, /* bogus */ expectFile: false, - err: syscall.EINVAL, + err: unix.EINVAL, }, { desc: "NonBlocking Read only error returns immediately", makePipe: false, /* causes the error */ flags: fs.FileFlags{Read: true, NonBlocking: true}, expectFile: false, - err: syscall.ENOENT, + err: unix.ENOENT, }, { desc: "NonBlocking Read only success returns immediately", @@ -108,21 +108,21 @@ func TestTryOpen(t *testing.T) { makePipe: false, /* causes the error */ flags: fs.FileFlags{Write: true, NonBlocking: true}, expectFile: false, - err: syscall.ENOENT, + err: unix.ENOENT, }, { desc: "NonBlocking Write only no reader error returns immediately", makePipe: true, flags: fs.FileFlags{Write: true, NonBlocking: true}, expectFile: false, - err: syscall.ENXIO, + err: unix.ENXIO, }, { desc: "ReadWrite error returns immediately", makePipe: false, /* causes the error */ flags: fs.FileFlags{Read: true, Write: true}, expectFile: false, - err: syscall.ENOENT, + err: unix.ENOENT, }, { desc: "ReadWrite returns immediately", @@ -136,14 +136,14 @@ func TestTryOpen(t *testing.T) { makePipe: false, /* causes the error */ flags: fs.FileFlags{Write: true}, expectFile: false, - err: syscall.ENOENT, /* from bogus perms */ + err: unix.ENOENT, /* from bogus perms */ }, { desc: "Blocking Read only returns open error", makePipe: false, /* causes the error */ flags: fs.FileFlags{Read: true}, expectFile: false, - err: syscall.ENOENT, + err: unix.ENOENT, }, { desc: "Blocking Write only returns with syserror.ErrWouldBlock", @@ -167,7 +167,7 @@ func TestTryOpen(t *testing.T) { t.Errorf("%s: failed to make host pipe: %v", test.desc, err) continue } - defer syscall.Unlink(name) + defer unix.Unlink(name) } // Use a host opener to keep things simple. @@ -238,7 +238,7 @@ func TestPipeOpenUnblocksEventually(t *testing.T) { t.Errorf("%s: failed to make host pipe: %v", test.desc, err) continue } - defer syscall.Unlink(name) + defer unix.Unlink(name) // Spawn the partner. type fderr struct { @@ -249,18 +249,18 @@ func TestPipeOpenUnblocksEventually(t *testing.T) { go func() { var flags int if test.partnerIsReader { - flags = syscall.O_RDONLY + flags = unix.O_RDONLY } else { - flags = syscall.O_WRONLY + flags = unix.O_WRONLY } if test.partnerIsBlocking { - fd, err := syscall.Open(name, flags, 0666) + fd, err := unix.Open(name, flags, 0666) errch <- fderr{fd: fd, err: err} } else { var fd int - err := error(syscall.ENXIO) - for err == syscall.ENXIO { - fd, err = syscall.Open(name, flags|syscall.O_NONBLOCK, 0666) + err := error(unix.ENXIO) + for err == unix.ENXIO { + fd, err = unix.Open(name, flags|unix.O_NONBLOCK, 0666) time.Sleep(1 * time.Second) } errch <- fderr{fd: fd, err: err} @@ -289,7 +289,7 @@ func TestPipeOpenUnblocksEventually(t *testing.T) { continue } // If so, then close the partner fd to avoid leaking an fd. - syscall.Close(e.fd) + unix.Close(e.fd) // Check that our blocking open was successful. if err != nil { @@ -309,7 +309,7 @@ func TestCopiedReadAheadBuffer(t *testing.T) { if err := mkpipe(name); err != nil { t.Fatalf("failed to make host pipe: %v", err) } - defer syscall.Unlink(name) + defer unix.Unlink(name) // We're taking advantage of the fact that pipes opened read only always return // success, but internally they are not deemed "opened" until we're sure that @@ -326,35 +326,35 @@ func TestCopiedReadAheadBuffer(t *testing.T) { pipeOps, err := pipeOpenState.TryOpen(ctx, opener, fs.FileFlags{Read: true}) if pipeOps != nil { pipeOps.Release(ctx) - t.Fatalf("open(%s, %o) got file, want nil", name, syscall.O_RDONLY) + t.Fatalf("open(%s, %o) got file, want nil", name, unix.O_RDONLY) } if err != syserror.ErrWouldBlock { - t.Fatalf("open(%s, %o) got error %v, want %v", name, syscall.O_RDONLY, err, syserror.ErrWouldBlock) + t.Fatalf("open(%s, %o) got error %v, want %v", name, unix.O_RDONLY, err, syserror.ErrWouldBlock) } // Then open the same pipe write only and write some bytes to it. The next // time we try to open the pipe read only again via the pipeOpenState, we should // succeed and buffer some of the bytes written. - fd, err := syscall.Open(name, syscall.O_WRONLY, 0666) + fd, err := unix.Open(name, unix.O_WRONLY, 0666) if err != nil { - t.Fatalf("open(%s, %o) got error %v, want nil", name, syscall.O_WRONLY, err) + t.Fatalf("open(%s, %o) got error %v, want nil", name, unix.O_WRONLY, err) } - defer syscall.Close(fd) + defer unix.Close(fd) data := []byte("hello") - if n, err := syscall.Write(fd, data); n != len(data) || err != nil { + if n, err := unix.Write(fd, data); n != len(data) || err != nil { t.Fatalf("write(%v) got (%d, %v), want (%d, nil)", data, n, err, len(data)) } // Try the read again, knowing that it should succeed this time. pipeOps, err = pipeOpenState.TryOpen(ctx, opener, fs.FileFlags{Read: true}) if pipeOps == nil { - t.Fatalf("open(%s, %o) got nil file, want not nil", name, syscall.O_RDONLY) + t.Fatalf("open(%s, %o) got nil file, want not nil", name, unix.O_RDONLY) } defer pipeOps.Release(ctx) if err != nil { - t.Fatalf("open(%s, %o) got error %v, want nil", name, syscall.O_RDONLY, err) + t.Fatalf("open(%s, %o) got error %v, want nil", name, unix.O_RDONLY, err) } inode := fs.NewMockInode(ctx, fs.NewMockMountSource(nil), fs.StableAttr{ @@ -432,7 +432,7 @@ func TestPipeHangup(t *testing.T) { t.Errorf("%s: failed to make host pipe: %v", test.desc, err) continue } - defer syscall.Unlink(name) + defer unix.Unlink(name) // Fire off a partner routine which tries to open the same pipe blocking, // which will synchronize with us. The channel allows us to get back the @@ -444,11 +444,11 @@ func TestPipeHangup(t *testing.T) { // misconfiguration. var flags int if test.flags.Read { - flags = syscall.O_WRONLY + flags = unix.O_WRONLY } else { - flags = syscall.O_RDONLY + flags = unix.O_RDONLY } - fd, err := syscall.Open(name, flags, 0666) + fd, err := unix.Open(name, flags, 0666) if err != nil { t.Logf("Open(%q, %o, 0666) partner failed: %v", name, flags, err) } @@ -489,7 +489,7 @@ func TestPipeHangup(t *testing.T) { } } else { // Hangup our partner and expect us to get the hangup error. - syscall.Close(f) + unix.Close(f) defer pipeOps.Release(ctx) if test.flags.Read { @@ -515,8 +515,8 @@ func assertReaderHungup(t *testing.T, desc string, reader io.Reader) bool { } func assertWriterHungup(t *testing.T, desc string, writer io.Writer) bool { - if _, err := writer.Write([]byte("hello")); unwrapError(err) != syscall.EPIPE { - t.Errorf("%s: write to self after hangup got error %v, want %v", desc, err, syscall.EPIPE) + if _, err := writer.Write([]byte("hello")); unwrapError(err) != unix.EPIPE { + t.Errorf("%s: write to self after hangup got error %v, want %v", desc, err, unix.EPIPE) return false } return true diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go index 1c9e82562..faeb3908c 100644 --- a/pkg/sentry/fs/fdpipe/pipe_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_test.go @@ -18,9 +18,9 @@ import ( "bytes" "io" "os" - "syscall" "testing" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/fdnotifier" "gvisor.dev/gvisor/pkg/sentry/contexttest" @@ -31,15 +31,15 @@ import ( func singlePipeFD() (int, error) { fds := make([]int, 2) - if err := syscall.Pipe(fds); err != nil { + if err := unix.Pipe(fds); err != nil { return -1, err } - syscall.Close(fds[1]) + unix.Close(fds[1]) return fds[0], nil } func singleDirFD() (int, error) { - return syscall.Open(os.TempDir(), syscall.O_RDONLY, 0666) + return unix.Open(os.TempDir(), unix.O_RDONLY, 0666) } func mockPipeDirent(t *testing.T) *fs.Dirent { @@ -77,12 +77,12 @@ func TestNewPipe(t *testing.T) { { desc: "Cannot make new pipe from bad fd", getfd: func() (int, error) { return -1, nil }, - err: syscall.EINVAL, + err: unix.EINVAL, }, { desc: "Cannot make new pipe from non-pipe fd", getfd: singleDirFD, - err: syscall.EINVAL, + err: unix.EINVAL, }, { desc: "Can make new pipe from pipe fd", @@ -127,12 +127,12 @@ func TestNewPipe(t *testing.T) { t.Errorf("%s: got read ahead buffer length %d, want %d", test.desc, len(p.readAheadBuffer), len(test.readAheadBuffer)) continue } - fileFlags, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(p.file.FD()), syscall.F_GETFL, 0) + fileFlags, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(p.file.FD()), unix.F_GETFL, 0) if errno != 0 { t.Errorf("%s: failed to get file flags for fd %d, got %v, want 0", test.desc, p.file.FD(), errno) continue } - if fileFlags&syscall.O_NONBLOCK == 0 { + if fileFlags&unix.O_NONBLOCK == 0 { t.Errorf("%s: pipe is blocking, expected non-blocking", test.desc) continue } @@ -145,13 +145,13 @@ func TestNewPipe(t *testing.T) { func TestPipeDestruction(t *testing.T) { fds := make([]int, 2) - if err := syscall.Pipe(fds); err != nil { + if err := unix.Pipe(fds); err != nil { t.Fatalf("failed to create pipes: got %v, want nil", err) } f := fd.New(fds[0]) // We don't care about the other end, just use the read end. - syscall.Close(fds[1]) + unix.Close(fds[1]) // Test the read end, but it doesn't really matter which. ctx := contexttest.Context(t) @@ -207,17 +207,17 @@ func TestPipeRequest(t *testing.T) { { desc: "ReadDir on pipe returns ENOTDIR", context: &ReadDir{}, - err: syscall.ENOTDIR, + err: unix.ENOTDIR, }, { desc: "Fsync on pipe returns EINVAL", context: &Fsync{}, - err: syscall.EINVAL, + err: unix.EINVAL, }, { desc: "Seek on pipe returns ESPIPE", context: &Seek{}, - err: syscall.ESPIPE, + err: unix.ESPIPE, }, { desc: "Readv on pipe from empty buffer returns nil", @@ -246,7 +246,7 @@ func TestPipeRequest(t *testing.T) { desc: "Writev on pipe from non-empty buffer and closed partner returns EPIPE", context: &Writev{Src: usermem.BytesIOSequence([]byte("hello"))}, flags: fs.FileFlags{Write: true}, - err: syscall.EPIPE, + err: unix.EPIPE, }, { desc: "Writev on pipe from non-empty buffer and open partner succeeds", @@ -260,7 +260,7 @@ func TestPipeRequest(t *testing.T) { } fds := make([]int, 2) - if err := syscall.Pipe(fds); err != nil { + if err := unix.Pipe(fds); err != nil { t.Errorf("%s: failed to create pipes: got %v, want nil", test.desc, err) continue } @@ -273,9 +273,9 @@ func TestPipeRequest(t *testing.T) { // Configure closing the fds. if test.keepOpenPartner { - defer syscall.Close(partnerFd) + defer unix.Close(partnerFd) } else { - syscall.Close(partnerFd) + unix.Close(partnerFd) } // Create the pipe. @@ -313,17 +313,17 @@ func TestPipeRequest(t *testing.T) { func TestPipeReadAheadBuffer(t *testing.T) { fds := make([]int, 2) - if err := syscall.Pipe(fds); err != nil { + if err := unix.Pipe(fds); err != nil { t.Fatalf("failed to create pipes: got %v, want nil", err) } rfile := fd.New(fds[0]) // Eventually close the write end, which is not wrapped in a pipe object. - defer syscall.Close(fds[1]) + defer unix.Close(fds[1]) // Write some bytes to this end. data := []byte("world") - if n, err := syscall.Write(fds[1], data); n != len(data) || err != nil { + if n, err := unix.Write(fds[1], data); n != len(data) || err != nil { rfile.Close() t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(data)) } @@ -365,13 +365,13 @@ func TestPipeReadAheadBuffer(t *testing.T) { // all of the data (and report it as such). func TestPipeReadsAccumulate(t *testing.T) { fds := make([]int, 2) - if err := syscall.Pipe(fds); err != nil { + if err := unix.Pipe(fds); err != nil { t.Fatalf("failed to create pipes: got %v, want nil", err) } rfile := fd.New(fds[0]) // Eventually close the write end, it doesn't depend on a pipe object. - defer syscall.Close(fds[1]) + defer unix.Close(fds[1]) // Get a new read only pipe reference. ctx := contexttest.Context(t) @@ -391,7 +391,7 @@ func TestPipeReadsAccumulate(t *testing.T) { // Write some some bytes to the pipe. data := []byte("some message") - if n, err := syscall.Write(fds[1], data); n != len(data) || err != nil { + if n, err := unix.Write(fds[1], data); n != len(data) || err != nil { t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(data)) } @@ -409,7 +409,7 @@ func TestPipeReadsAccumulate(t *testing.T) { // Write a few more bytes to allow us to read more/accumulate. extra := []byte("extra") - if n, err := syscall.Write(fds[1], extra); n != len(extra) || err != nil { + if n, err := unix.Write(fds[1], extra); n != len(extra) || err != nil { t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(extra)) } @@ -433,13 +433,13 @@ func TestPipeReadsAccumulate(t *testing.T) { // Same as TestReadsAccumulate. func TestPipeWritesAccumulate(t *testing.T) { fds := make([]int, 2) - if err := syscall.Pipe(fds); err != nil { + if err := unix.Pipe(fds); err != nil { t.Fatalf("failed to create pipes: got %v, want nil", err) } wfile := fd.New(fds[1]) // Eventually close the read end, it doesn't depend on a pipe object. - defer syscall.Close(fds[0]) + defer unix.Close(fds[0]) // Get a new write only pipe reference. ctx := contexttest.Context(t) @@ -457,7 +457,7 @@ func TestPipeWritesAccumulate(t *testing.T) { }) file := fs.NewFile(ctx, fs.NewDirent(ctx, inode, "pipe"), fs.FileFlags{Read: true}, p) - pipeSize, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(wfile.FD()), syscall.F_GETPIPE_SZ, 0) + pipeSize, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(wfile.FD()), unix.F_GETPIPE_SZ, 0) if errno != 0 { t.Fatalf("fcntl(F_GETPIPE_SZ) failed: %v", errno) } @@ -483,7 +483,7 @@ func TestPipeWritesAccumulate(t *testing.T) { // Read the entire pipe buf size to make space for the second half. readBuffer := make([]byte, n) - if n, err := syscall.Read(fds[0], readBuffer); n != len(readBuffer) || err != nil { + if n, err := unix.Read(fds[0], readBuffer); n != len(readBuffer) || err != nil { t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(readBuffer)) } if !bytes.Equal(readBuffer, writeBuffer[:len(readBuffer)]) { diff --git a/pkg/sentry/fs/fsutil/BUILD b/pkg/sentry/fs/fsutil/BUILD index 5fb419bcd..d388f0e92 100644 --- a/pkg/sentry/fs/fsutil/BUILD +++ b/pkg/sentry/fs/fsutil/BUILD @@ -91,6 +91,7 @@ go_library( "//pkg/syserror", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/fsutil/host_file_mapper.go b/pkg/sentry/fs/fsutil/host_file_mapper.go index 4468f5dd2..54f7b7cdc 100644 --- a/pkg/sentry/fs/fsutil/host_file_mapper.go +++ b/pkg/sentry/fs/fsutil/host_file_mapper.go @@ -16,8 +16,8 @@ package fsutil import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/safemem" "gvisor.dev/gvisor/pkg/sentry/memmap" @@ -44,7 +44,7 @@ type HostFileMapper struct { mapsMu sync.Mutex `state:"nosave"` // mappings maps chunk start offsets to mappings of those chunks, - // obtained by calling syscall.Mmap. mappings is protected by + // obtained by calling unix.Mmap. mappings is protected by // mapsMu. mappings map[uint64]mapping `state:"nosave"` } @@ -157,19 +157,19 @@ func (f *HostFileMapper) MapInternal(fr memmap.FileRange, fd int, write bool) (s // Preconditions: f.mapsMu must be locked. func (f *HostFileMapper) forEachMappingBlockLocked(fr memmap.FileRange, fd int, write bool, fn func(safemem.Block)) error { - prot := syscall.PROT_READ + prot := unix.PROT_READ if write { - prot |= syscall.PROT_WRITE + prot |= unix.PROT_WRITE } for chunkStart := fr.Start &^ chunkMask; chunkStart < fr.End; chunkStart += chunkSize { m, ok := f.mappings[chunkStart] if !ok { - addr, _, errno := syscall.Syscall6( - syscall.SYS_MMAP, + addr, _, errno := unix.Syscall6( + unix.SYS_MMAP, 0, chunkSize, uintptr(prot), - syscall.MAP_SHARED, + unix.MAP_SHARED, uintptr(fd), uintptr(chunkStart)) if errno != 0 { @@ -178,12 +178,12 @@ func (f *HostFileMapper) forEachMappingBlockLocked(fr memmap.FileRange, fd int, m = mapping{addr, write} f.mappings[chunkStart] = m } else if write && !m.writable { - addr, _, errno := syscall.Syscall6( - syscall.SYS_MMAP, + addr, _, errno := unix.Syscall6( + unix.SYS_MMAP, m.addr, chunkSize, uintptr(prot), - syscall.MAP_SHARED|syscall.MAP_FIXED, + unix.MAP_SHARED|unix.MAP_FIXED, uintptr(fd), uintptr(chunkStart)) if errno != 0 { @@ -219,7 +219,7 @@ func (f *HostFileMapper) UnmapAll() { // * f.mapsMu must be locked. // * f.mappings[chunkStart] == m. func (f *HostFileMapper) unmapAndRemoveLocked(chunkStart uint64, m mapping) { - if _, _, errno := syscall.Syscall(syscall.SYS_MUNMAP, m.addr, chunkSize, 0); errno != 0 { + if _, _, errno := unix.Syscall(unix.SYS_MUNMAP, m.addr, chunkSize, 0); errno != 0 { // This leaks address space and is unexpected, but is otherwise // harmless, so complain but don't panic. log.Warningf("HostFileMapper: failed to unmap mapping %#x for chunk %#x: %v", m.addr, chunkStart, errno) @@ -234,16 +234,16 @@ func (f *HostFileMapper) RegenerateMappings(fd int) error { defer f.mapsMu.Unlock() for chunkStart, m := range f.mappings { - prot := syscall.PROT_READ + prot := unix.PROT_READ if m.writable { - prot |= syscall.PROT_WRITE + prot |= unix.PROT_WRITE } - _, _, errno := syscall.Syscall6( - syscall.SYS_MMAP, + _, _, errno := unix.Syscall6( + unix.SYS_MMAP, m.addr, chunkSize, uintptr(prot), - syscall.MAP_SHARED|syscall.MAP_FIXED, + unix.MAP_SHARED|unix.MAP_FIXED, uintptr(fd), uintptr(chunkStart)) if errno != 0 { diff --git a/pkg/sentry/fs/gofer/BUILD b/pkg/sentry/fs/gofer/BUILD index 4c30098cd..b210e0e7e 100644 --- a/pkg/sentry/fs/gofer/BUILD +++ b/pkg/sentry/fs/gofer/BUILD @@ -49,6 +49,7 @@ go_library( "//pkg/unet", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) @@ -63,5 +64,6 @@ go_test( "//pkg/p9/p9test", "//pkg/sentry/contexttest", "//pkg/sentry/fs", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/gofer/attr.go b/pkg/sentry/fs/gofer/attr.go index e5579095b..cffc756cc 100644 --- a/pkg/sentry/fs/gofer/attr.go +++ b/pkg/sentry/fs/gofer/attr.go @@ -15,8 +15,7 @@ package gofer import ( - "syscall" - + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/p9" "gvisor.dev/gvisor/pkg/sentry/fs" @@ -36,7 +35,7 @@ func getattr(ctx context.Context, file contextFile) (p9.QID, p9.AttrMask, p9.Att // Require mode, size, and raw device id. if !valid.Mode || !valid.Size || !valid.RDev { - return qid, valid, attr, syscall.EIO + return qid, valid, attr, unix.EIO } return qid, valid, attr, nil diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index bb63448cb..06d450ba6 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -16,9 +16,9 @@ package gofer import ( "fmt" - "syscall" "time" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/p9" @@ -307,7 +307,7 @@ func (f *fileOperations) Fsync(ctx context.Context, file *fs.File, start, end in // Sync remote caches. if f.handles.Host != nil { // Sync the host fd directly. - return syscall.Fsync(f.handles.Host.FD()) + return unix.Fsync(f.handles.Host.FD()) } // Otherwise sync on the p9.File handle. return f.handles.File.fsync(ctx) diff --git a/pkg/sentry/fs/gofer/gofer_test.go b/pkg/sentry/fs/gofer/gofer_test.go index 326fed954..546ee7d04 100644 --- a/pkg/sentry/fs/gofer/gofer_test.go +++ b/pkg/sentry/fs/gofer/gofer_test.go @@ -16,10 +16,10 @@ package gofer import ( "fmt" - "syscall" "testing" "time" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/p9" "gvisor.dev/gvisor/pkg/p9/p9test" @@ -97,7 +97,7 @@ func TestLookup(t *testing.T) { }, { name: "mock Walk fails (function fails)", - want: syscall.ENOENT, + want: unix.ENOENT, }, } @@ -123,7 +123,7 @@ func TestLookup(t *testing.T) { var newInodeOperations fs.InodeOperations if dirent != nil { if dirent.IsNegative() { - err = syscall.ENOENT + err = unix.ENOENT } else { newInodeOperations = dirent.Inode.InodeOperations } diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go index e840b6f5e..b97635ec4 100644 --- a/pkg/sentry/fs/gofer/inode.go +++ b/pkg/sentry/fs/gofer/inode.go @@ -16,8 +16,8 @@ package gofer import ( "errors" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" @@ -273,7 +273,7 @@ func (i *inodeFileState) recreateReadHandles(ctx context.Context, writer *handle // operations on the old will see the new data. Then, make the new handle take // ownereship of the old FD and mark the old readHandle to not close the FD // when done. - if err := syscall.Dup3(h.Host.FD(), i.readHandles.Host.FD(), syscall.O_CLOEXEC); err != nil { + if err := unix.Dup3(h.Host.FD(), i.readHandles.Host.FD(), unix.O_CLOEXEC); err != nil { return err } @@ -489,7 +489,7 @@ func (i *inodeOperations) GetFile(ctx context.Context, d *fs.Dirent, flags fs.Fi func (i *inodeOperations) getFileSocket(ctx context.Context, d *fs.Dirent, flags fs.FileFlags) (*fs.File, error) { f, err := i.fileState.file.connect(ctx, p9.AnonymousSocket) if err != nil { - return nil, syscall.EIO + return nil, unix.EIO } fsf, err := host.NewSocketWithDirent(ctx, d, f, flags) if err != nil { @@ -654,7 +654,7 @@ func (i *inodeOperations) WriteOut(ctx context.Context, inode *fs.Inode) error { // Readlink implements fs.InodeOperations.Readlink. func (i *inodeOperations) Readlink(ctx context.Context, inode *fs.Inode) (string, error) { if !fs.IsSymlink(inode.StableAttr) { - return "", syscall.ENOLINK + return "", unix.ENOLINK } return i.fileState.file.readlink(ctx) } @@ -704,10 +704,10 @@ func (i *inodeOperations) configureMMap(file *fs.File, opts *memmap.MMapOpts) er } func init() { - syserror.AddErrorUnwrapper(func(err error) (syscall.Errno, bool) { + syserror.AddErrorUnwrapper(func(err error) (unix.Errno, bool) { if _, ok := err.(p9.ErrSocket); ok { // Treat as an I/O error. - return syscall.EIO, true + return unix.EIO, true } return 0, false }) diff --git a/pkg/sentry/fs/gofer/util.go b/pkg/sentry/fs/gofer/util.go index 47a6c69bf..3cc6a7f7b 100644 --- a/pkg/sentry/fs/gofer/util.go +++ b/pkg/sentry/fs/gofer/util.go @@ -15,8 +15,7 @@ package gofer import ( - "syscall" - + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/p9" "gvisor.dev/gvisor/pkg/sentry/fs" @@ -67,6 +66,6 @@ func openFlagsFromPerms(p fs.PermMask) (p9.OpenFlags, error) { case p.Read: return p9.ReadOnly, nil default: - return 0, syscall.EINVAL + return 0, unix.EINVAL } } diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD index 1368014c4..3c45f6cc5 100644 --- a/pkg/sentry/fs/host/BUILD +++ b/pkg/sentry/fs/host/BUILD @@ -56,6 +56,7 @@ go_library( "//pkg/unet", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) @@ -80,5 +81,6 @@ go_test( "//pkg/tcpip", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/host/control.go b/pkg/sentry/fs/host/control.go index 0d8d36afa..e53998be1 100644 --- a/pkg/sentry/fs/host/control.go +++ b/pkg/sentry/fs/host/control.go @@ -15,8 +15,7 @@ package host import ( - "syscall" - + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/sentry/fs" "gvisor.dev/gvisor/pkg/sentry/socket/control" @@ -59,7 +58,7 @@ func (c *scmRights) Clone() transport.RightsControlMessage { // Release implements transport.RightsControlMessage.Release. func (c *scmRights) Release(ctx context.Context) { for _, fd := range c.fds { - syscall.Close(fd) + unix.Close(fd) } c.fds = nil } @@ -71,7 +70,7 @@ func fdsToFiles(ctx context.Context, fds []int) []*fs.File { for _, fd := range fds { // Get flags. We do it here because they may be modified // by subsequent functions. - fileFlags, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_GETFL, 0) + fileFlags, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(fd), unix.F_GETFL, 0) if errno != 0 { ctx.Warningf("Error retrieving host FD flags: %v", error(errno)) break @@ -86,7 +85,7 @@ func fdsToFiles(ctx context.Context, fds []int) []*fs.File { // Set known flags. file.SetFlags(fs.SettableFileFlags{ - NonBlocking: fileFlags&syscall.O_NONBLOCK != 0, + NonBlocking: fileFlags&unix.O_NONBLOCK != 0, }) files = append(files, file) diff --git a/pkg/sentry/fs/host/descriptor.go b/pkg/sentry/fs/host/descriptor.go index cfdce6a74..5667b94a1 100644 --- a/pkg/sentry/fs/host/descriptor.go +++ b/pkg/sentry/fs/host/descriptor.go @@ -16,8 +16,8 @@ package host import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/fdnotifier" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/waiter" @@ -48,14 +48,14 @@ func newDescriptor(fd int, saveable bool, wouldBlock bool, queue *waiter.Queue) origFD := -1 if saveable { var err error - ownedFD, err = syscall.Dup(fd) + ownedFD, err = unix.Dup(fd) if err != nil { return nil, err } origFD = fd } if wouldBlock { - if err := syscall.SetNonblock(ownedFD, true); err != nil { + if err := unix.SetNonblock(ownedFD, true); err != nil { return nil, err } if err := fdnotifier.AddFD(int32(ownedFD), queue); err != nil { @@ -72,12 +72,12 @@ func newDescriptor(fd int, saveable bool, wouldBlock bool, queue *waiter.Queue) // initAfterLoad initializes the value of the descriptor after Load. func (d *descriptor) initAfterLoad(id uint64, queue *waiter.Queue) error { var err error - d.value, err = syscall.Dup(d.origFD) + d.value, err = unix.Dup(d.origFD) if err != nil { return fmt.Errorf("failed to dup restored fd %d: %v", d.origFD, err) } if d.wouldBlock { - if err := syscall.SetNonblock(d.value, true); err != nil { + if err := unix.SetNonblock(d.value, true); err != nil { return err } if err := fdnotifier.AddFD(int32(d.value), queue); err != nil { @@ -92,7 +92,7 @@ func (d *descriptor) Release() { if d.wouldBlock { fdnotifier.RemoveFD(int32(d.value)) } - if err := syscall.Close(d.value); err != nil { + if err := unix.Close(d.value); err != nil { log.Warningf("error closing fd %d: %v", d.value, err) } d.value = -1 diff --git a/pkg/sentry/fs/host/descriptor_test.go b/pkg/sentry/fs/host/descriptor_test.go index d8e4605b6..cb809ab2d 100644 --- a/pkg/sentry/fs/host/descriptor_test.go +++ b/pkg/sentry/fs/host/descriptor_test.go @@ -17,9 +17,9 @@ package host import ( "io/ioutil" "path/filepath" - "syscall" "testing" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/fdnotifier" "gvisor.dev/gvisor/pkg/waiter" ) @@ -40,7 +40,7 @@ func TestDescriptorRelease(t *testing.T) { t.Fatal("ioutil.TempDir() failed:", err) } - fd, err := syscall.Open(filepath.Join(dir, "file"), syscall.O_RDWR|syscall.O_CREAT, 0666) + fd, err := unix.Open(filepath.Join(dir, "file"), unix.O_RDWR|unix.O_CREAT, 0666) if err != nil { t.Fatal("failed to open temp file:", err) } @@ -49,7 +49,7 @@ func TestDescriptorRelease(t *testing.T) { queue := &waiter.Queue{} d, err := newDescriptor(fd, tc.saveable, tc.wouldBlock, queue) if err != nil { - syscall.Close(fd) + unix.Close(fd) t.Fatalf("newDescriptor(%d, %t, %t, queue) failed, err: %v", fd, tc.saveable, tc.wouldBlock, err) } if tc.saveable { diff --git a/pkg/sentry/fs/host/file.go b/pkg/sentry/fs/host/file.go index fd4e057d8..07bd078b7 100644 --- a/pkg/sentry/fs/host/file.go +++ b/pkg/sentry/fs/host/file.go @@ -16,8 +16,8 @@ package host import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/fdnotifier" @@ -78,16 +78,16 @@ func ImportFile(ctx context.Context, fd int, isTTY bool) (*fs.File, error) { // newFileFromDonatedFD returns an fs.File from a donated FD. If the FD is // saveable, then saveable is true. func newFileFromDonatedFD(ctx context.Context, donated int, saveable, isTTY bool) (*fs.File, error) { - var s syscall.Stat_t - if err := syscall.Fstat(donated, &s); err != nil { + var s unix.Stat_t + if err := unix.Fstat(donated, &s); err != nil { return nil, err } flags, err := fileFlagsFromDonatedFD(donated) if err != nil { return nil, err } - switch s.Mode & syscall.S_IFMT { - case syscall.S_IFSOCK: + switch s.Mode & unix.S_IFMT { + case unix.S_IFSOCK: if isTTY { return nil, fmt.Errorf("cannot import host socket as TTY") } @@ -121,19 +121,19 @@ func newFileFromDonatedFD(ctx context.Context, donated int, saveable, isTTY bool } func fileFlagsFromDonatedFD(donated int) (fs.FileFlags, error) { - flags, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(donated), syscall.F_GETFL, 0) + flags, _, errno := unix.Syscall(unix.SYS_FCNTL, uintptr(donated), unix.F_GETFL, 0) if errno != 0 { log.Warningf("Failed to get file flags for donated FD %d (errno=%d)", donated, errno) - return fs.FileFlags{}, syscall.EIO + return fs.FileFlags{}, unix.EIO } - accmode := flags & syscall.O_ACCMODE + accmode := flags & unix.O_ACCMODE return fs.FileFlags{ - Direct: flags&syscall.O_DIRECT != 0, - NonBlocking: flags&syscall.O_NONBLOCK != 0, - Sync: flags&syscall.O_SYNC != 0, - Append: flags&syscall.O_APPEND != 0, - Read: accmode == syscall.O_RDONLY || accmode == syscall.O_RDWR, - Write: accmode == syscall.O_WRONLY || accmode == syscall.O_RDWR, + Direct: flags&unix.O_DIRECT != 0, + NonBlocking: flags&unix.O_NONBLOCK != 0, + Sync: flags&unix.O_SYNC != 0, + Append: flags&unix.O_APPEND != 0, + Read: accmode == unix.O_RDONLY || accmode == unix.O_RDWR, + Write: accmode == unix.O_WRONLY || accmode == unix.O_RDWR, }, nil } @@ -182,7 +182,7 @@ func (f *fileOperations) Readdir(ctx context.Context, file *fs.File, serializer func (f *fileOperations) IterateDir(ctx context.Context, d *fs.Dirent, dirCtx *fs.DirCtx, offset int) (int, error) { // We only support non-directory file descriptors that have been // imported, so just claim that this isn't a directory, even if it is. - return offset, syscall.ENOTDIR + return offset, unix.ENOTDIR } // Write implements fs.FileOperations.Write. @@ -252,7 +252,7 @@ func (f *fileOperations) Fsync(ctx context.Context, file *fs.File, start int64, } fallthrough case fs.SyncBackingStorage: - return syscall.Fsync(f.iops.fileState.FD()) + return unix.Fsync(f.iops.fileState.FD()) } panic("invalid sync type") } diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go index df4b265fa..e299b532c 100644 --- a/pkg/sentry/fs/host/inode.go +++ b/pkg/sentry/fs/host/inode.go @@ -15,8 +15,7 @@ package host import ( - "syscall" - + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/safemem" @@ -117,12 +116,12 @@ func (i *inodeFileState) SetMaskedAttributes(ctx context.Context, mask fs.AttrMa return syserror.EPERM } if mask.Perms { - if err := syscall.Fchmod(i.FD(), uint32(attr.Perms.LinuxMode())); err != nil { + if err := unix.Fchmod(i.FD(), uint32(attr.Perms.LinuxMode())); err != nil { return err } } if mask.Size { - if err := syscall.Ftruncate(i.FD(), attr.Size); err != nil { + if err := unix.Ftruncate(i.FD(), attr.Size); err != nil { return err } } @@ -142,7 +141,7 @@ func (i *inodeFileState) SetMaskedAttributes(ctx context.Context, mask fs.AttrMa // Sync implements fsutil.CachedFileObject.Sync. func (i *inodeFileState) Sync(ctx context.Context) error { - return syscall.Fsync(i.FD()) + return unix.Fsync(i.FD()) } // FD implements fsutil.CachedFileObject.FD. @@ -151,8 +150,8 @@ func (i *inodeFileState) FD() int { } func (i *inodeFileState) unstableAttr(ctx context.Context) (fs.UnstableAttr, error) { - var s syscall.Stat_t - if err := syscall.Fstat(i.FD(), &s); err != nil { + var s unix.Stat_t + if err := unix.Fstat(i.FD(), &s); err != nil { return fs.UnstableAttr{}, err } return unstableAttr(&s), nil @@ -160,7 +159,7 @@ func (i *inodeFileState) unstableAttr(ctx context.Context) (fs.UnstableAttr, err // Allocate implements fsutil.CachedFileObject.Allocate. func (i *inodeFileState) Allocate(_ context.Context, offset, length int64) error { - return syscall.Fallocate(i.FD(), 0, offset, length) + return unix.Fallocate(i.FD(), 0, offset, length) } // inodeOperations implements fs.InodeOperations. @@ -169,8 +168,8 @@ var _ fs.InodeOperations = (*inodeOperations)(nil) // newInode returns a new fs.Inode backed by the host FD. func newInode(ctx context.Context, msrc *fs.MountSource, fd int, saveable bool) (*fs.Inode, error) { // Retrieve metadata. - var s syscall.Stat_t - err := syscall.Fstat(fd, &s) + var s unix.Stat_t + err := unix.Fstat(fd, &s) if err != nil { return nil, err } @@ -324,7 +323,7 @@ func (i *inodeOperations) SetPermissions(ctx context.Context, inode *fs.Inode, f // Then just change the timestamps on the FD, the host // will synchronize the metadata update with any host // inode and page cache. - return syscall.Fchmod(i.fileState.FD(), uint32(f.LinuxMode())) == nil + return unix.Fchmod(i.fileState.FD(), uint32(f.LinuxMode())) == nil } // Otherwise update our cached metadata. return i.cachingInodeOps.SetPermissions(ctx, inode, f) @@ -350,7 +349,7 @@ func (i *inodeOperations) Truncate(ctx context.Context, inode *fs.Inode, size in // Then just change the file size on the FD, the host // will synchronize the metadata update with any host // inode and page cache. - return syscall.Ftruncate(i.fileState.FD(), size) + return unix.Ftruncate(i.fileState.FD(), size) } // Otherwise we need to go through cachingInodeOps, even if the host page // cache is in use, to invalidate private copies of truncated pages. diff --git a/pkg/sentry/fs/host/inode_state.go b/pkg/sentry/fs/host/inode_state.go index 1adbd4562..03531b7e7 100644 --- a/pkg/sentry/fs/host/inode_state.go +++ b/pkg/sentry/fs/host/inode_state.go @@ -16,8 +16,8 @@ package host import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/sentry/device" "gvisor.dev/gvisor/pkg/sentry/fs" ) @@ -30,8 +30,8 @@ func (i *inodeFileState) afterLoad() { } // Remap the inode number. - var s syscall.Stat_t - if err := syscall.Fstat(i.FD(), &s); err != nil { + var s unix.Stat_t + if err := unix.Fstat(i.FD(), &s); err != nil { panic(fs.ErrCorruption{fmt.Errorf("failed to get metadata for fd %d: %v", i.FD(), err)}) } key := device.MultiDeviceKey{ diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go index 41a23b5da..11738871b 100644 --- a/pkg/sentry/fs/host/inode_test.go +++ b/pkg/sentry/fs/host/inode_test.go @@ -15,20 +15,20 @@ package host import ( - "syscall" "testing" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/sentry/contexttest" ) // TestCloseFD verifies fds will be closed. func TestCloseFD(t *testing.T) { var p [2]int - if err := syscall.Pipe(p[0:]); err != nil { + if err := unix.Pipe(p[0:]); err != nil { t.Fatalf("Failed to create pipe %v", err) } - defer syscall.Close(p[0]) - defer syscall.Close(p[1]) + defer unix.Close(p[0]) + defer unix.Close(p[1]) // Use the write-end because we will detect if it's closed on the read end. ctx := contexttest.Context(t) @@ -39,7 +39,7 @@ func TestCloseFD(t *testing.T) { file.DecRef(ctx) s := make([]byte, 10) - if c, err := syscall.Read(p[0], s); c != 0 || err != nil { + if c, err := unix.Read(p[0], s); c != 0 || err != nil { t.Errorf("want 0, nil (EOF) from read end, got %v, %v", c, err) } } diff --git a/pkg/sentry/fs/host/ioctl_unsafe.go b/pkg/sentry/fs/host/ioctl_unsafe.go index 150ac8e19..303ea4d9b 100644 --- a/pkg/sentry/fs/host/ioctl_unsafe.go +++ b/pkg/sentry/fs/host/ioctl_unsafe.go @@ -15,9 +15,9 @@ package host import ( - "syscall" "unsafe" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" ) @@ -25,7 +25,7 @@ import ( func ioctlGetTermios(fd int) (*linux.Termios, error) { var t linux.Termios - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.TCGETS, uintptr(unsafe.Pointer(&t))) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), linux.TCGETS, uintptr(unsafe.Pointer(&t))) if errno != 0 { return nil, errno } @@ -33,7 +33,7 @@ func ioctlGetTermios(fd int) (*linux.Termios, error) { } func ioctlSetTermios(fd int, req uint64, t *linux.Termios) error { - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(unsafe.Pointer(t))) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(unsafe.Pointer(t))) if errno != 0 { return errno } @@ -42,7 +42,7 @@ func ioctlSetTermios(fd int, req uint64, t *linux.Termios) error { func ioctlGetWinsize(fd int) (*linux.Winsize, error) { var w linux.Winsize - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.TIOCGWINSZ, uintptr(unsafe.Pointer(&w))) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), linux.TIOCGWINSZ, uintptr(unsafe.Pointer(&w))) if errno != 0 { return nil, errno } @@ -50,7 +50,7 @@ func ioctlGetWinsize(fd int) (*linux.Winsize, error) { } func ioctlSetWinsize(fd int, w *linux.Winsize) error { - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), linux.TIOCSWINSZ, uintptr(unsafe.Pointer(w))) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), linux.TIOCSWINSZ, uintptr(unsafe.Pointer(w))) if errno != 0 { return errno } diff --git a/pkg/sentry/fs/host/socket.go b/pkg/sentry/fs/host/socket.go index 2b58fc52c..f2d96d1ec 100644 --- a/pkg/sentry/fs/host/socket.go +++ b/pkg/sentry/fs/host/socket.go @@ -17,8 +17,8 @@ package host import ( "fmt" "sync/atomic" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/fd" @@ -75,26 +75,26 @@ type ConnectedEndpoint struct { // init performs initialization required for creating new ConnectedEndpoints and // for restoring them. func (c *ConnectedEndpoint) init() *syserr.Error { - family, err := syscall.GetsockoptInt(c.file.FD(), syscall.SOL_SOCKET, syscall.SO_DOMAIN) + family, err := unix.GetsockoptInt(c.file.FD(), unix.SOL_SOCKET, unix.SO_DOMAIN) if err != nil { return syserr.FromError(err) } - if family != syscall.AF_UNIX { + if family != unix.AF_UNIX { // We only allow Unix sockets. return syserr.ErrInvalidEndpointState } - stype, err := syscall.GetsockoptInt(c.file.FD(), syscall.SOL_SOCKET, syscall.SO_TYPE) + stype, err := unix.GetsockoptInt(c.file.FD(), unix.SOL_SOCKET, unix.SO_TYPE) if err != nil { return syserr.FromError(err) } - if err := syscall.SetNonblock(c.file.FD(), true); err != nil { + if err := unix.SetNonblock(c.file.FD(), true); err != nil { return syserr.FromError(err) } - sndbuf, err := syscall.GetsockoptInt(c.file.FD(), syscall.SOL_SOCKET, syscall.SO_SNDBUF) + sndbuf, err := unix.GetsockoptInt(c.file.FD(), unix.SOL_SOCKET, unix.SO_SNDBUF) if err != nil { return syserr.FromError(err) } @@ -168,7 +168,7 @@ func newSocket(ctx context.Context, orgfd int, saveable bool) (*fs.File, error) srfd := -1 if saveable { var err error - ownedfd, err = syscall.Dup(orgfd) + ownedfd, err = unix.Dup(orgfd) if err != nil { return nil, err } @@ -233,7 +233,7 @@ func (c *ConnectedEndpoint) CloseSend() { c.mu.Lock() defer c.mu.Unlock() - if err := syscall.Shutdown(c.file.FD(), syscall.SHUT_WR); err != nil { + if err := unix.Shutdown(c.file.FD(), unix.SHUT_WR); err != nil { // A well-formed UDS shutdown can't fail. See // net/unix/af_unix.c:unix_shutdown. panic(fmt.Sprintf("failed write shutdown on host socket %+v: %v", c, err)) @@ -333,7 +333,7 @@ func (c *ConnectedEndpoint) CloseRecv() { c.mu.Lock() defer c.mu.Unlock() - if err := syscall.Shutdown(c.file.FD(), syscall.SHUT_RD); err != nil { + if err := unix.Shutdown(c.file.FD(), unix.SHUT_RD); err != nil { // A well-formed UDS shutdown can't fail. See // net/unix/af_unix.c:unix_shutdown. panic(fmt.Sprintf("failed read shutdown on host socket %+v: %v", c, err)) diff --git a/pkg/sentry/fs/host/socket_iovec.go b/pkg/sentry/fs/host/socket_iovec.go index 905afb50d..7380d75e7 100644 --- a/pkg/sentry/fs/host/socket_iovec.go +++ b/pkg/sentry/fs/host/socket_iovec.go @@ -15,8 +15,7 @@ package host import ( - "syscall" - + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/iovec" "gvisor.dev/gvisor/pkg/syserror" ) @@ -54,7 +53,7 @@ func copyFromMulti(dst []byte, src [][]byte) { // // If intermediate != nil, iovecs references intermediate rather than bufs and // the caller must copy to/from bufs as necessary. -func buildIovec(bufs [][]byte, maxlen int64, truncate bool) (length int64, iovecs []syscall.Iovec, intermediate []byte, err error) { +func buildIovec(bufs [][]byte, maxlen int64, truncate bool) (length int64, iovecs []unix.Iovec, intermediate []byte, err error) { var iovsRequired int for _, b := range bufs { length += int64(len(b)) @@ -78,14 +77,14 @@ func buildIovec(bufs [][]byte, maxlen int64, truncate bool) (length int64, iovec // Use a single intermediate buffer instead. b := make([]byte, stopLen) - return stopLen, []syscall.Iovec{{ + return stopLen, []unix.Iovec{{ Base: &b[0], Len: uint64(stopLen), }}, b, err } var total int64 - iovecs = make([]syscall.Iovec, 0, iovsRequired) + iovecs = make([]unix.Iovec, 0, iovsRequired) for i := range bufs { l := len(bufs[i]) if l == 0 { @@ -97,7 +96,7 @@ func buildIovec(bufs [][]byte, maxlen int64, truncate bool) (length int64, iovec stop = stopLen - total } - iovecs = append(iovecs, syscall.Iovec{ + iovecs = append(iovecs, unix.Iovec{ Base: &bufs[i][0], Len: uint64(stop), }) diff --git a/pkg/sentry/fs/host/socket_state.go b/pkg/sentry/fs/host/socket_state.go index 498018f0a..1d3e5298a 100644 --- a/pkg/sentry/fs/host/socket_state.go +++ b/pkg/sentry/fs/host/socket_state.go @@ -16,8 +16,8 @@ package host import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/fd" ) @@ -30,7 +30,7 @@ func (c *ConnectedEndpoint) beforeSave() { // afterLoad is invoked by stateify. func (c *ConnectedEndpoint) afterLoad() { - f, err := syscall.Dup(c.srfd) + f, err := unix.Dup(c.srfd) if err != nil { panic(fmt.Sprintf("failed to dup restored FD %d: %v", c.srfd, err)) } diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go index 9d58ea448..f7014b6b1 100644 --- a/pkg/sentry/fs/host/socket_test.go +++ b/pkg/sentry/fs/host/socket_test.go @@ -16,9 +16,9 @@ package host import ( "reflect" - "syscall" "testing" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/fd" "gvisor.dev/gvisor/pkg/fdnotifier" "gvisor.dev/gvisor/pkg/sentry/contexttest" @@ -40,7 +40,7 @@ var ( ) func getFl(fd int) (uint32, error) { - fl, _, err := syscall.RawSyscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_GETFL, 0) + fl, _, err := unix.RawSyscall(unix.SYS_FCNTL, uintptr(fd), unix.F_GETFL, 0) if err == 0 { return uint32(fl), nil } @@ -49,7 +49,7 @@ func getFl(fd int) (uint32, error) { func TestSocketIsBlocking(t *testing.T) { // Using socketpair here because it's already connected. - pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { t.Fatalf("host socket creation failed: %v", err) } @@ -58,13 +58,13 @@ func TestSocketIsBlocking(t *testing.T) { if err != nil { t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[0], err) } - if fl&syscall.O_NONBLOCK == syscall.O_NONBLOCK { + if fl&unix.O_NONBLOCK == unix.O_NONBLOCK { t.Fatalf("Expected socket %v to be blocking", pair[0]) } if fl, err = getFl(pair[1]); err != nil { t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[1], err) } - if fl&syscall.O_NONBLOCK == syscall.O_NONBLOCK { + if fl&unix.O_NONBLOCK == unix.O_NONBLOCK { t.Fatalf("Expected socket %v to be blocking", pair[1]) } ctx := contexttest.Context(t) @@ -77,20 +77,20 @@ func TestSocketIsBlocking(t *testing.T) { if fl, err = getFl(pair[0]); err != nil { t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[0], err) } - if fl&syscall.O_NONBLOCK != syscall.O_NONBLOCK { + if fl&unix.O_NONBLOCK != unix.O_NONBLOCK { t.Errorf("Expected socket %v to have become non-blocking", pair[0]) } if fl, err = getFl(pair[1]); err != nil { t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[1], err) } - if fl&syscall.O_NONBLOCK == syscall.O_NONBLOCK { + if fl&unix.O_NONBLOCK == unix.O_NONBLOCK { t.Errorf("Did not expect socket %v to become non-blocking", pair[1]) } } func TestSocketWritev(t *testing.T) { // Using socketpair here because it's already connected. - pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { t.Fatalf("host socket creation failed: %v", err) } @@ -113,7 +113,7 @@ func TestSocketWritev(t *testing.T) { func TestSocketWritevLen0(t *testing.T) { // Using socketpair here because it's already connected. - pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { t.Fatalf("host socket creation failed: %v", err) } @@ -135,7 +135,7 @@ func TestSocketWritevLen0(t *testing.T) { func TestSocketSendMsgLen0(t *testing.T) { // Using socketpair here because it's already connected. - pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { t.Fatalf("host socket creation failed: %v", err) } @@ -158,9 +158,9 @@ func TestSocketSendMsgLen0(t *testing.T) { } func TestListen(t *testing.T) { - pair, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { - t.Fatalf("syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) => %v", err) + t.Fatalf("unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0) => %v", err) } ctx := contexttest.Context(t) sfile1, err := newSocket(ctx, pair[0], false) @@ -186,9 +186,9 @@ func TestListen(t *testing.T) { } // Create a Unix socket, do not bind it. - sock, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + sock, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { - t.Fatalf("syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) => %v", err) + t.Fatalf("unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0) => %v", err) } sfile3, err := newSocket(ctx, sock, false) if err != nil { @@ -236,7 +236,7 @@ func TestQueuedSize(t *testing.T) { } func TestRelease(t *testing.T) { - f, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, 0) + f, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, 0) if err != nil { t.Fatal("Creating socket:", err) } diff --git a/pkg/sentry/fs/host/socket_unsafe.go b/pkg/sentry/fs/host/socket_unsafe.go index c8231e0aa..95f5d39bd 100644 --- a/pkg/sentry/fs/host/socket_unsafe.go +++ b/pkg/sentry/fs/host/socket_unsafe.go @@ -15,8 +15,9 @@ package host import ( - "syscall" "unsafe" + + "golang.org/x/sys/unix" ) // LINT.IfChange @@ -26,9 +27,9 @@ import ( // If the total length of bufs is > maxlen, fdReadVec will do a partial read // and err will indicate why the message was truncated. func fdReadVec(fd int, bufs [][]byte, control []byte, peek bool, maxlen int64) (readLen int64, msgLen int64, controlLen uint64, controlTrunc bool, err error) { - flags := uintptr(syscall.MSG_DONTWAIT | syscall.MSG_TRUNC) + flags := uintptr(unix.MSG_DONTWAIT | unix.MSG_TRUNC) if peek { - flags |= syscall.MSG_PEEK + flags |= unix.MSG_PEEK } // Always truncate the receive buffer. All socket types will truncate @@ -39,7 +40,7 @@ func fdReadVec(fd int, bufs [][]byte, control []byte, peek bool, maxlen int64) ( return 0, 0, 0, false, err } - var msg syscall.Msghdr + var msg unix.Msghdr if len(control) != 0 { msg.Control = &control[0] msg.Controllen = uint64(len(control)) @@ -50,7 +51,7 @@ func fdReadVec(fd int, bufs [][]byte, control []byte, peek bool, maxlen int64) ( msg.Iovlen = uint64(len(iovecs)) } - rawN, _, e := syscall.RawSyscall(syscall.SYS_RECVMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), flags) + rawN, _, e := unix.RawSyscall(unix.SYS_RECVMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), flags) if e != 0 { // N.B. prioritize the syscall error over the buildIovec error. return 0, 0, 0, false, e @@ -62,7 +63,7 @@ func fdReadVec(fd int, bufs [][]byte, control []byte, peek bool, maxlen int64) ( copyToMulti(bufs, intermediate) } - controlTrunc = msg.Flags&syscall.MSG_CTRUNC == syscall.MSG_CTRUNC + controlTrunc = msg.Flags&unix.MSG_CTRUNC == unix.MSG_CTRUNC if n > length { return length, n, msg.Controllen, controlTrunc, nil @@ -87,13 +88,13 @@ func fdWriteVec(fd int, bufs [][]byte, maxlen int64, truncate bool) (int64, int6 copyFromMulti(intermediate, bufs) } - var msg syscall.Msghdr + var msg unix.Msghdr if len(iovecs) > 0 { msg.Iov = &iovecs[0] msg.Iovlen = uint64(len(iovecs)) } - n, _, e := syscall.RawSyscall(syscall.SYS_SENDMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), syscall.MSG_DONTWAIT|syscall.MSG_NOSIGNAL) + n, _, e := unix.RawSyscall(unix.SYS_SENDMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), unix.MSG_DONTWAIT|unix.MSG_NOSIGNAL) if e != 0 { // N.B. prioritize the syscall error over the buildIovec error. return 0, length, e diff --git a/pkg/sentry/fs/host/util.go b/pkg/sentry/fs/host/util.go index 1b0356930..ab74724a3 100644 --- a/pkg/sentry/fs/host/util.go +++ b/pkg/sentry/fs/host/util.go @@ -16,8 +16,8 @@ package host import ( "os" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sentry/device" @@ -27,21 +27,21 @@ import ( "gvisor.dev/gvisor/pkg/syserror" ) -func nodeType(s *syscall.Stat_t) fs.InodeType { - switch x := (s.Mode & syscall.S_IFMT); x { - case syscall.S_IFLNK: +func nodeType(s *unix.Stat_t) fs.InodeType { + switch x := (s.Mode & unix.S_IFMT); x { + case unix.S_IFLNK: return fs.Symlink - case syscall.S_IFIFO: + case unix.S_IFIFO: return fs.Pipe - case syscall.S_IFCHR: + case unix.S_IFCHR: return fs.CharacterDevice - case syscall.S_IFBLK: + case unix.S_IFBLK: return fs.BlockDevice - case syscall.S_IFSOCK: + case unix.S_IFSOCK: return fs.Socket - case syscall.S_IFDIR: + case unix.S_IFDIR: return fs.Directory - case syscall.S_IFREG: + case unix.S_IFREG: return fs.RegularFile default: // This shouldn't happen, but just in case... @@ -50,12 +50,12 @@ func nodeType(s *syscall.Stat_t) fs.InodeType { } } -func wouldBlock(s *syscall.Stat_t) bool { +func wouldBlock(s *unix.Stat_t) bool { typ := nodeType(s) return typ == fs.Pipe || typ == fs.Socket || typ == fs.CharacterDevice } -func stableAttr(s *syscall.Stat_t) fs.StableAttr { +func stableAttr(s *unix.Stat_t) fs.StableAttr { return fs.StableAttr{ Type: nodeType(s), DeviceID: hostFileDevice.DeviceID(), @@ -67,14 +67,14 @@ func stableAttr(s *syscall.Stat_t) fs.StableAttr { } } -func owner(s *syscall.Stat_t) fs.FileOwner { +func owner(s *unix.Stat_t) fs.FileOwner { return fs.FileOwner{ UID: auth.KUID(s.Uid), GID: auth.KGID(s.Gid), } } -func unstableAttr(s *syscall.Stat_t) fs.UnstableAttr { +func unstableAttr(s *unix.Stat_t) fs.UnstableAttr { return fs.UnstableAttr{ Size: s.Size, Usage: s.Blocks * 512, diff --git a/pkg/sentry/fs/host/util_amd64_unsafe.go b/pkg/sentry/fs/host/util_amd64_unsafe.go index 66da6e9f5..21782f1da 100644 --- a/pkg/sentry/fs/host/util_amd64_unsafe.go +++ b/pkg/sentry/fs/host/util_amd64_unsafe.go @@ -17,18 +17,19 @@ package host import ( - "syscall" "unsafe" + + "golang.org/x/sys/unix" ) -func fstatat(fd int, name string, flags int) (syscall.Stat_t, error) { - var stat syscall.Stat_t - namePtr, err := syscall.BytePtrFromString(name) +func fstatat(fd int, name string, flags int) (unix.Stat_t, error) { + var stat unix.Stat_t + namePtr, err := unix.BytePtrFromString(name) if err != nil { return stat, err } - _, _, errno := syscall.Syscall6( - syscall.SYS_NEWFSTATAT, + _, _, errno := unix.Syscall6( + unix.SYS_NEWFSTATAT, uintptr(fd), uintptr(unsafe.Pointer(namePtr)), uintptr(unsafe.Pointer(&stat)), diff --git a/pkg/sentry/fs/host/util_arm64_unsafe.go b/pkg/sentry/fs/host/util_arm64_unsafe.go index e8cb94aeb..ed8f5242a 100644 --- a/pkg/sentry/fs/host/util_arm64_unsafe.go +++ b/pkg/sentry/fs/host/util_arm64_unsafe.go @@ -17,18 +17,19 @@ package host import ( - "syscall" "unsafe" + + "golang.org/x/sys/unix" ) -func fstatat(fd int, name string, flags int) (syscall.Stat_t, error) { - var stat syscall.Stat_t - namePtr, err := syscall.BytePtrFromString(name) +func fstatat(fd int, name string, flags int) (unix.Stat_t, error) { + var stat unix.Stat_t + namePtr, err := unix.BytePtrFromString(name) if err != nil { return stat, err } - _, _, errno := syscall.Syscall6( - syscall.SYS_FSTATAT, + _, _, errno := unix.Syscall6( + unix.SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(namePtr)), uintptr(unsafe.Pointer(&stat)), diff --git a/pkg/sentry/fs/host/util_unsafe.go b/pkg/sentry/fs/host/util_unsafe.go index 23bd35d64..3c5e3ed6d 100644 --- a/pkg/sentry/fs/host/util_unsafe.go +++ b/pkg/sentry/fs/host/util_unsafe.go @@ -15,9 +15,9 @@ package host import ( - "syscall" "unsafe" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/sentry/fs" ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time" @@ -30,8 +30,8 @@ func readLink(fd int) (string, error) { // Buffer sizing copied from os.Readlink. for l := 128; ; l *= 2 { b := make([]byte, l) - n, _, errno := syscall.Syscall6( - syscall.SYS_READLINKAT, + n, _, errno := unix.Syscall6( + unix.SYS_READLINKAT, uintptr(fd), uintptr(unsafe.Pointer(&NulByte)), // "" uintptr(unsafe.Pointer(&b[0])), @@ -46,25 +46,25 @@ func readLink(fd int) (string, error) { } } -func timespecFromTimestamp(t ktime.Time, omit, setSysTime bool) syscall.Timespec { +func timespecFromTimestamp(t ktime.Time, omit, setSysTime bool) unix.Timespec { if omit { - return syscall.Timespec{0, linux.UTIME_OMIT} + return unix.Timespec{0, linux.UTIME_OMIT} } if setSysTime { - return syscall.Timespec{0, linux.UTIME_NOW} + return unix.Timespec{0, linux.UTIME_NOW} } - return syscall.NsecToTimespec(t.Nanoseconds()) + return unix.NsecToTimespec(t.Nanoseconds()) } func setTimestamps(fd int, ts fs.TimeSpec) error { if ts.ATimeOmit && ts.MTimeOmit { return nil } - var sts [2]syscall.Timespec + var sts [2]unix.Timespec sts[0] = timespecFromTimestamp(ts.ATime, ts.ATimeOmit, ts.ATimeSetSystemTime) sts[1] = timespecFromTimestamp(ts.MTime, ts.MTimeOmit, ts.MTimeSetSystemTime) - _, _, errno := syscall.Syscall6( - syscall.SYS_UTIMENSAT, + _, _, errno := unix.Syscall6( + unix.SYS_UTIMENSAT, uintptr(fd), 0, /* path */ uintptr(unsafe.Pointer(&sts)), diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go index c143f4ce2..5925c85ea 100644 --- a/pkg/sentry/fs/host/wait_test.go +++ b/pkg/sentry/fs/host/wait_test.go @@ -15,27 +15,27 @@ package host import ( - "syscall" "testing" "time" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/sentry/contexttest" "gvisor.dev/gvisor/pkg/waiter" ) func TestWait(t *testing.T) { var fds [2]int - err := syscall.Pipe(fds[:]) + err := unix.Pipe(fds[:]) if err != nil { t.Fatalf("Unable to create pipe: %v", err) } - defer syscall.Close(fds[1]) + defer unix.Close(fds[1]) ctx := contexttest.Context(t) file, err := NewFile(ctx, fds[0]) if err != nil { - syscall.Close(fds[0]) + unix.Close(fds[0]) t.Fatalf("NewFile failed: %v", err) } @@ -56,7 +56,7 @@ func TestWait(t *testing.T) { } // Write to the pipe, so it should be writable now. - syscall.Write(fds[1], []byte{1}) + unix.Write(fds[1], []byte{1}) // Check that we get a notification. We need to yield the current thread // so that the fdnotifier can deliver notifications, so we use a diff --git a/pkg/sentry/fs/lock/BUILD b/pkg/sentry/fs/lock/BUILD index 4d3b216d8..c09d8463b 100644 --- a/pkg/sentry/fs/lock/BUILD +++ b/pkg/sentry/fs/lock/BUILD @@ -46,6 +46,7 @@ go_library( "//pkg/log", "//pkg/sync", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) @@ -57,4 +58,5 @@ go_test( "lock_test.go", ], library = ":lock", + deps = ["@org_golang_x_sys//unix:go_default_library"], ) diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go index 57686ce07..7d7a207cc 100644 --- a/pkg/sentry/fs/lock/lock.go +++ b/pkg/sentry/fs/lock/lock.go @@ -52,8 +52,8 @@ package lock import ( "fmt" "math" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/sync" @@ -456,7 +456,7 @@ func ComputeRange(start, length, offset int64) (LockRange, error) { // fcntl(2): "l_start can be a negative number provided the offset // does not lie before the start of the file" if offset < 0 { - return LockRange{}, syscall.EINVAL + return LockRange{}, unix.EINVAL } // fcntl(2): Specifying 0 for l_len has the special meaning: lock all @@ -478,10 +478,10 @@ func ComputeRange(start, length, offset int64) (LockRange, error) { // Add to offset using a negative length (subtract). offset += length if offset < 0 { - return LockRange{}, syscall.EINVAL + return LockRange{}, unix.EINVAL } if signedEnd < offset { - return LockRange{}, syscall.EOVERFLOW + return LockRange{}, unix.EOVERFLOW } // At this point signedEnd cannot be negative, // since we asserted that offset is not negative diff --git a/pkg/sentry/fs/lock/lock_range_test.go b/pkg/sentry/fs/lock/lock_range_test.go index 6221199d1..2b6f8630b 100644 --- a/pkg/sentry/fs/lock/lock_range_test.go +++ b/pkg/sentry/fs/lock/lock_range_test.go @@ -15,8 +15,9 @@ package lock import ( - "syscall" "testing" + + "golang.org/x/sys/unix" ) func TestComputeRange(t *testing.T) { @@ -56,7 +57,7 @@ func TestComputeRange(t *testing.T) { name: "zero offset, negative start", start: -4096, offset: 0, - err: syscall.EINVAL, + err: unix.EINVAL, }, { name: "large offset, negative start, positive length", @@ -77,7 +78,7 @@ func TestComputeRange(t *testing.T) { start: 0, length: -4096, offset: 0, - err: syscall.EINVAL, + err: unix.EINVAL, }, { name: "large offset, zero start, negative length", @@ -112,7 +113,7 @@ func TestComputeRange(t *testing.T) { start: -1024, length: -1024, offset: -1024, - err: syscall.EINVAL, + err: unix.EINVAL, }, { name: "offset, start, and length equal, all positive", diff --git a/pkg/sentry/fs/mounts.go b/pkg/sentry/fs/mounts.go index d741c4339..243098a09 100644 --- a/pkg/sentry/fs/mounts.go +++ b/pkg/sentry/fs/mounts.go @@ -17,8 +17,8 @@ package fs import ( "fmt" "math" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/refs" "gvisor.dev/gvisor/pkg/sentry/kernel/auth" @@ -571,13 +571,13 @@ func (mns *MountNamespace) resolve(ctx context.Context, root, node *Dirent, rema // Make sure we didn't exhaust the traversal budget. if *remainingTraversals == 0 { target.DecRef(ctx) - return nil, syscall.ELOOP + return nil, unix.ELOOP } node.DecRef(ctx) // Drop the original reference. return target, nil - case syscall.ENOLINK: + case unix.ENOLINK: // Not a symlink. return node, nil @@ -586,7 +586,7 @@ func (mns *MountNamespace) resolve(ctx context.Context, root, node *Dirent, rema // First, check if we should traverse. if *remainingTraversals == 0 { - return nil, syscall.ELOOP + return nil, unix.ELOOP } // Read the target path. diff --git a/pkg/sentry/fs/ramfs/BUILD b/pkg/sentry/fs/ramfs/BUILD index 8ca823fb3..a51d00d86 100644 --- a/pkg/sentry/fs/ramfs/BUILD +++ b/pkg/sentry/fs/ramfs/BUILD @@ -22,6 +22,7 @@ go_library( "//pkg/syserror", "//pkg/usermem", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/sentry/fs/ramfs/dir.go b/pkg/sentry/fs/ramfs/dir.go index f4fcddecb..19990f9db 100644 --- a/pkg/sentry/fs/ramfs/dir.go +++ b/pkg/sentry/fs/ramfs/dir.go @@ -17,8 +17,8 @@ package ramfs import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/sentry/fs" @@ -378,8 +378,8 @@ func (d *Dir) Bind(ctx context.Context, dir *fs.Inode, name string, ep transport inode, err := d.createInodeOperationsCommon(ctx, name, func() (*fs.Inode, error) { return d.NewBoundEndpoint(ctx, dir, ep, perms) }) - if err == syscall.EEXIST { - return nil, syscall.EADDRINUSE + if err == unix.EEXIST { + return nil, unix.EADDRINUSE } if err != nil { return nil, err diff --git a/pkg/sentry/fs/save.go b/pkg/sentry/fs/save.go index fe5c76b44..1de9735dc 100644 --- a/pkg/sentry/fs/save.go +++ b/pkg/sentry/fs/save.go @@ -16,8 +16,8 @@ package fs import ( "fmt" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/log" ) @@ -65,7 +65,7 @@ func SaveFileFsyncError(err error) error { case nil: // We succeeded, everything is great. return nil - case syscall.EBADF, syscall.EINVAL, syscall.EROFS, syscall.ENOSYS, syscall.EPERM: + case unix.EBADF, unix.EINVAL, unix.EROFS, unix.ENOSYS, unix.EPERM: // These errors mean that the underlying node might not be syncable, // which we expect to be reported as such even from the gofer. log.Infof("failed to sync during save: %v", err) |