From 208f87f3873e3c4d8f644b66fbcca8c8b10fcf5b Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Sun, 7 Aug 2022 00:05:53 -0700 Subject: [PATCH] Copy up consistently for all file types if open mode is writable. Earlier, we were only copying up regular files. We were missing out device files. ensureOpenableLocked() should ensure that files are copied up if mode is writable. Without this, we violate the preconditions for openCopiedUp(). Also, without this, open(file, O_WRONLY) on a lower layer pipe returns EROFS, which is confusing because the upper layer is still writable. Now it will return EPERM which indicates that the pipe can not be copied up. PiperOrigin-RevId: 465838606 --- pkg/sentry/fsimpl/overlay/filesystem.go | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/sentry/fsimpl/overlay/filesystem.go b/pkg/sentry/fsimpl/overlay/filesystem.go index b53fa6b54..af97e324f 100644 --- a/pkg/sentry/fsimpl/overlay/filesystem.go +++ b/pkg/sentry/fsimpl/overlay/filesystem.go @@ -892,18 +892,7 @@ func (d *dentry) ensureOpenableLocked(ctx context.Context, rp *vfs.ResolvingPath if err := d.checkPermissions(rp.Credentials(), ats); err != nil { return err } - switch d.mode.Load() & linux.S_IFMT { - case linux.S_IFREG: - if ats.MayWrite() { - if err := rp.Mount().CheckBeginWrite(); err != nil { - return err - } - defer rp.Mount().EndWrite() - if err := d.copyUpLocked(ctx); err != nil { - return err - } - } - case linux.S_IFDIR: + if d.isDir() { if ats.MayWrite() { return linuxerr.EISDIR } @@ -913,8 +902,19 @@ func (d *dentry) ensureOpenableLocked(ctx context.Context, rp *vfs.ResolvingPath if opts.Flags&linux.O_DIRECT != 0 { return linuxerr.EINVAL } + return nil } - return nil + + if !ats.MayWrite() { + return nil + } + + // Copy up! + if err := rp.Mount().CheckBeginWrite(); err != nil { + return err + } + defer rp.Mount().EndWrite() + return d.copyUpLocked(ctx) } // Preconditions: If vfs.AccessTypesForOpenFlags(opts).MayWrite(), then d has