diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-02-11 01:49:51 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-11 01:49:51 +0000 |
commit | 03d099577c93e3e4098c85a570e41664a0d72bc0 (patch) | |
tree | ff0bb5597b26cd68a7f7b433b3e9bccba0051121 /pkg/sentry/fsimpl/kernfs | |
parent | 9994360861f68e806d4c1e2ad949015cc55d130f (diff) | |
parent | 81ea0016e62318053f97ec714967047e6191fb2b (diff) |
Merge release-20210201.0-84-g81ea0016e (automated)
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs')
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/inode_impl_util.go | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go index 8139bff76..6b890a39c 100644 --- a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go +++ b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go @@ -294,22 +294,41 @@ func (a *InodeAttrs) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *aut return err } + clearSID := false stat := opts.Stat + if stat.Mask&linux.STATX_UID != 0 { + atomic.StoreUint32(&a.uid, stat.UID) + clearSID = true + } + if stat.Mask&linux.STATX_GID != 0 { + atomic.StoreUint32(&a.gid, stat.GID) + clearSID = true + } if stat.Mask&linux.STATX_MODE != 0 { for { old := atomic.LoadUint32(&a.mode) - new := old | uint32(stat.Mode & ^uint16(linux.S_IFMT)) - if swapped := atomic.CompareAndSwapUint32(&a.mode, old, new); swapped { + ft := old & linux.S_IFMT + newMode := ft | uint32(stat.Mode & ^uint16(linux.S_IFMT)) + if clearSID { + newMode = vfs.ClearSUIDAndSGID(newMode) + } + if swapped := atomic.CompareAndSwapUint32(&a.mode, old, newMode); swapped { + clearSID = false break } } } - if stat.Mask&linux.STATX_UID != 0 { - atomic.StoreUint32(&a.uid, stat.UID) - } - if stat.Mask&linux.STATX_GID != 0 { - atomic.StoreUint32(&a.gid, stat.GID) + // We may have to clear the SUID/SGID bits, but didn't do so as part of + // STATX_MODE. + if clearSID { + for { + old := atomic.LoadUint32(&a.mode) + newMode := vfs.ClearSUIDAndSGID(old) + if swapped := atomic.CompareAndSwapUint32(&a.mode, old, newMode); swapped { + break + } + } } now := ktime.NowFromContext(ctx).Nanoseconds() |