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
This commit is contained in:
Ayush Ranjan
2022-08-07 00:08:24 -07:00
committed by gVisor bot
parent 0d7a1d0711
commit 208f87f387
+13 -13
View File
@@ -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