mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Lower layer files that can not be copied up are not writable.
Make access(W_OK) return EACCES in overlayfs if file exists only on lower layer and can not be copied up. Earlier, access(W_OK) was succeeding but operations that cause copy-up (like open(WR_ONLY)) were failing. This is likely to confuse applications. PiperOrigin-RevId: 465818314
This commit is contained in:
@@ -31,6 +31,18 @@ func (d *dentry) isCopiedUp() bool {
|
||||
return d.copiedUp.Load() != 0
|
||||
}
|
||||
|
||||
func (d *dentry) canBeCopiedUp() bool {
|
||||
ftype := d.mode.Load() & linux.S_IFMT
|
||||
switch ftype {
|
||||
case linux.S_IFREG, linux.S_IFDIR, linux.S_IFLNK, linux.S_IFBLK, linux.S_IFCHR:
|
||||
// Can be copied-up.
|
||||
return true
|
||||
default:
|
||||
// Can't be copied-up.
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// copyUpLocked ensures that d exists on the upper layer, i.e. d.upperVD.Ok().
|
||||
//
|
||||
// Preconditions: filesystem.renameMu must be locked.
|
||||
@@ -48,12 +60,7 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
|
||||
// credentials from context rather an take an explicit creds parameter.
|
||||
ctx = auth.ContextWithCredentials(ctx, d.fs.creds)
|
||||
|
||||
ftype := d.mode.Load() & linux.S_IFMT
|
||||
switch ftype {
|
||||
case linux.S_IFREG, linux.S_IFDIR, linux.S_IFLNK, linux.S_IFBLK, linux.S_IFCHR:
|
||||
// Can be copied-up.
|
||||
default:
|
||||
// Can't be copied-up.
|
||||
if !d.canBeCopiedUp() {
|
||||
return linuxerr.EPERM
|
||||
}
|
||||
|
||||
@@ -92,6 +99,7 @@ func (d *dentry) copyUpMaybeSyntheticMountpointLocked(ctx context.Context, forSy
|
||||
}
|
||||
|
||||
// Perform copy-up.
|
||||
ftype := d.mode.Load() & linux.S_IFMT
|
||||
newpop := vfs.PathOperation{
|
||||
Root: d.parent.upperVD,
|
||||
Start: d.parent.upperVD,
|
||||
|
||||
@@ -585,9 +585,18 @@ func (fs *filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
|
||||
if err := d.checkPermissions(creds, ats); err != nil {
|
||||
return err
|
||||
}
|
||||
if ats.MayWrite() && rp.Mount().ReadOnly() {
|
||||
if !ats.MayWrite() {
|
||||
// Not requesting write permission. Allow it.
|
||||
return nil
|
||||
}
|
||||
if rp.Mount().ReadOnly() {
|
||||
return linuxerr.EROFS
|
||||
}
|
||||
if !d.upperVD.Ok() && !d.canBeCopiedUp() {
|
||||
// A lower layer file that can not be copied up, can not be written to.
|
||||
// Error out here. Don't give the application false hopes.
|
||||
return linuxerr.EACCES
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user