From 81ea0016e62318053f97ec714967047e6191fb2b Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Wed, 10 Feb 2021 17:43:25 -0800 Subject: Support setgid directories in tmpfs and kernfs PiperOrigin-RevId: 356868412 --- pkg/sentry/fsimpl/kernfs/inode_impl_util.go | 33 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'pkg/sentry/fsimpl/kernfs') 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() -- cgit v1.2.3