From e4f093f7b1739b0872774057932704613343db77 Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Fri, 18 Feb 2022 21:03:18 -0800 Subject: [PATCH] Fix lisafs client bugs for S/R support. - There was a bug in checking for the availability of STATX_SIZE on restore. - Make the gofer client resilient to bad open(flags). Like 9P, make lisafs default to O_RDONLY when a valid open mode is not available. PiperOrigin-RevId: 429705352 --- pkg/sentry/fsimpl/gofer/handle.go | 9 ++++++--- pkg/sentry/fsimpl/gofer/save_restore.go | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/sentry/fsimpl/gofer/handle.go b/pkg/sentry/fsimpl/gofer/handle.go index 96c7b736d..1643e0ef3 100644 --- a/pkg/sentry/fsimpl/gofer/handle.go +++ b/pkg/sentry/fsimpl/gofer/handle.go @@ -18,6 +18,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/lisafs" + "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/p9" "gvisor.dev/gvisor/pkg/safemem" "gvisor.dev/gvisor/pkg/sentry/hostfd" @@ -42,7 +43,7 @@ func openHandle(ctx context.Context, file p9file, read, write, trunc bool) (hand if err != nil { return handle{fd: -1}, err } - var flags p9.OpenFlags + flags := p9.ReadOnly switch { case read && !write: flags = p9.ReadOnly @@ -50,6 +51,8 @@ func openHandle(ctx context.Context, file p9file, read, write, trunc bool) (hand flags = p9.WriteOnly case read && write: flags = p9.ReadWrite + default: + log.Debugf("openHandle called with read = write = false. Falling back to read only FD.") } if trunc { flags |= p9.OpenTruncate @@ -71,7 +74,7 @@ func openHandle(ctx context.Context, file p9file, read, write, trunc bool) (hand // Preconditions: read || write. func openHandleLisa(ctx context.Context, fdLisa lisafs.ClientFD, read, write, trunc bool) (handle, error) { - var flags uint32 + flags := uint32(unix.O_RDONLY) switch { case read && write: flags = unix.O_RDWR @@ -80,7 +83,7 @@ func openHandleLisa(ctx context.Context, fdLisa lisafs.ClientFD, read, write, tr case write: flags = unix.O_WRONLY default: - panic("tried to open unreadable and unwritable handle") + log.Debugf("openHandleLisa called with read = write = false. Falling back to read only FD.") } if trunc { flags |= unix.O_TRUNC diff --git a/pkg/sentry/fsimpl/gofer/save_restore.go b/pkg/sentry/fsimpl/gofer/save_restore.go index 01f053999..18f8a1ea5 100644 --- a/pkg/sentry/fsimpl/gofer/save_restore.go +++ b/pkg/sentry/fsimpl/gofer/save_restore.go @@ -325,7 +325,7 @@ func (d *dentry) restoreFileLisa(ctx context.Context, inode *lisafs.Inode, opts defer d.metadataMu.Unlock() if d.isRegularFile() { if opts.ValidateFileSizes { - if inode.Stat.Mask&linux.STATX_SIZE != 0 { + if inode.Stat.Mask&linux.STATX_SIZE == 0 { return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: file size not available", genericDebugPathname(d))} } if d.size != inode.Stat.Size {