diff options
author | Ayush Ranjan <ayushranjan@google.com> | 2021-02-03 22:42:28 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-03 22:44:51 -0800 |
commit | f2c881f68498b542f21288559e3cb218673484f0 (patch) | |
tree | 32042a8f900ddb4d2b569859ab0f8a4405a7e5b6 /pkg/sentry/fsimpl/overlay | |
parent | 0dbc112979ff046e15a9616e98c4febc135ce77e (diff) |
[vfs] Make sticky bit check consistent with Linux.
Our implementation of vfs.CheckDeleteSticky was not consistent with Linux,
specifically not consistent with fs/linux.h:check_sticky().
One of the biggest differences was that the vfs implementation did not
allow the owner of the sticky directory to delete files inside it that belonged
to other users.
This change makes our implementation consistent with Linux.
Also adds an integration test to check for this. This bug is also present in
VFS1.
Updates #3027
PiperOrigin-RevId: 355557425
Diffstat (limited to 'pkg/sentry/fsimpl/overlay')
-rw-r--r-- | pkg/sentry/fsimpl/overlay/filesystem.go | 6 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/overlay/overlay.go | 10 |
2 files changed, 13 insertions, 3 deletions
diff --git a/pkg/sentry/fsimpl/overlay/filesystem.go b/pkg/sentry/fsimpl/overlay/filesystem.go index e46f593c7..b36031291 100644 --- a/pkg/sentry/fsimpl/overlay/filesystem.go +++ b/pkg/sentry/fsimpl/overlay/filesystem.go @@ -1068,7 +1068,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa if err != nil { return err } - if err := vfs.CheckDeleteSticky(creds, linux.FileMode(atomic.LoadUint32(&oldParent.mode)), auth.KUID(atomic.LoadUint32(&renamed.uid))); err != nil { + if err := oldParent.mayDelete(creds, renamed); err != nil { return err } if renamed.isDir() { @@ -1317,7 +1317,7 @@ func (fs *filesystem) RmdirAt(ctx context.Context, rp *vfs.ResolvingPath) error if !child.isDir() { return syserror.ENOTDIR } - if err := vfs.CheckDeleteSticky(rp.Credentials(), linux.FileMode(atomic.LoadUint32(&parent.mode)), auth.KUID(atomic.LoadUint32(&child.uid))); err != nil { + if err := parent.mayDelete(rp.Credentials(), child); err != nil { return err } child.dirMu.Lock() @@ -1584,7 +1584,7 @@ func (fs *filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error if child.isDir() { return syserror.EISDIR } - if err := vfs.CheckDeleteSticky(rp.Credentials(), linux.FileMode(parentMode), auth.KUID(atomic.LoadUint32(&child.uid))); err != nil { + if err := parent.mayDelete(rp.Credentials(), child); err != nil { return err } if err := vfsObj.PrepareDeleteDentry(mntns, &child.vfsd); err != nil { diff --git a/pkg/sentry/fsimpl/overlay/overlay.go b/pkg/sentry/fsimpl/overlay/overlay.go index 082fa6504..acd3684c6 100644 --- a/pkg/sentry/fsimpl/overlay/overlay.go +++ b/pkg/sentry/fsimpl/overlay/overlay.go @@ -760,6 +760,16 @@ func (d *dentry) updateAfterSetStatLocked(opts *vfs.SetStatOptions) { } } +func (d *dentry) mayDelete(creds *auth.Credentials, child *dentry) error { + return vfs.CheckDeleteSticky( + creds, + linux.FileMode(atomic.LoadUint32(&d.mode)), + auth.KUID(atomic.LoadUint32(&d.uid)), + auth.KUID(atomic.LoadUint32(&child.uid)), + auth.KGID(atomic.LoadUint32(&child.gid)), + ) +} + // fileDescription is embedded by overlay implementations of // vfs.FileDescriptionImpl. // |