mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Translate p9.NoUID/GID to OverflowUID/GID.
p9.NoUID/GID (== uint32(-1) == auth.NoID) is not a valid auth.KUID/KGID; in particular, using it for file ownership causes capabilities to be ineffective since file capabilities require that the file's KUID and KGID are mapped into the capability holder's user namespace [1], and auth.NoID is not mapped into any user namespace. Map p9.NoUID/GID to a different, valid KUID/KGID; in the unlikely case that an application actually using the overflow KUID/KGID attempts an operation that is consequently permitted by client permission checks, the remote operation will still fail with EPERM. Since this changes the VFS2 gofer client to no longer ignore the invalid IDs entirely, this CL both permits and requires that we change synthetic mount point creation to use root credentials. [1] See fs.Inode.CheckCapability or vfs.GenericCheckPermissions. PiperOrigin-RevId: 309856455
This commit is contained in:
@@ -75,10 +75,18 @@ func owner(mounter fs.FileOwner, valid p9.AttrMask, pattr p9.Attr) fs.FileOwner
|
||||
// task's EUID/EGID.
|
||||
owner := mounter
|
||||
if valid.UID {
|
||||
owner.UID = auth.KUID(pattr.UID)
|
||||
if pattr.UID.Ok() {
|
||||
owner.UID = auth.KUID(pattr.UID)
|
||||
} else {
|
||||
owner.UID = auth.KUID(auth.OverflowUID)
|
||||
}
|
||||
}
|
||||
if valid.GID {
|
||||
owner.GID = auth.KGID(pattr.GID)
|
||||
if pattr.GID.Ok() {
|
||||
owner.GID = auth.KGID(pattr.GID)
|
||||
} else {
|
||||
owner.GID = auth.KGID(auth.OverflowGID)
|
||||
}
|
||||
}
|
||||
return owner
|
||||
}
|
||||
|
||||
@@ -663,11 +663,11 @@ func (fs *filesystem) newDentry(ctx context.Context, file p9file, qid p9.QID, ma
|
||||
},
|
||||
}
|
||||
d.pf.dentry = d
|
||||
if mask.UID && attr.UID != auth.NoID {
|
||||
d.uid = uint32(attr.UID)
|
||||
if mask.UID {
|
||||
d.uid = dentryUIDFromP9UID(attr.UID)
|
||||
}
|
||||
if mask.GID && attr.GID != auth.NoID {
|
||||
d.gid = uint32(attr.GID)
|
||||
if mask.GID {
|
||||
d.gid = dentryGIDFromP9GID(attr.GID)
|
||||
}
|
||||
if mask.Size {
|
||||
d.size = attr.Size
|
||||
@@ -718,10 +718,10 @@ func (d *dentry) updateFromP9Attrs(mask p9.AttrMask, attr *p9.Attr) {
|
||||
atomic.StoreUint32(&d.mode, uint32(attr.Mode))
|
||||
}
|
||||
if mask.UID {
|
||||
atomic.StoreUint32(&d.uid, uint32(attr.UID))
|
||||
atomic.StoreUint32(&d.uid, dentryUIDFromP9UID(attr.UID))
|
||||
}
|
||||
if mask.GID {
|
||||
atomic.StoreUint32(&d.gid, uint32(attr.GID))
|
||||
atomic.StoreUint32(&d.gid, dentryGIDFromP9GID(attr.GID))
|
||||
}
|
||||
// There is no P9_GETATTR_* bit for I/O block size.
|
||||
if attr.BlockSize != 0 {
|
||||
@@ -939,6 +939,20 @@ func (d *dentry) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes)
|
||||
return vfs.GenericCheckPermissions(creds, ats, linux.FileMode(atomic.LoadUint32(&d.mode)), auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid)))
|
||||
}
|
||||
|
||||
func dentryUIDFromP9UID(uid p9.UID) uint32 {
|
||||
if !uid.Ok() {
|
||||
return uint32(auth.OverflowUID)
|
||||
}
|
||||
return uint32(uid)
|
||||
}
|
||||
|
||||
func dentryGIDFromP9GID(gid p9.GID) uint32 {
|
||||
if !gid.Ok() {
|
||||
return uint32(auth.OverflowGID)
|
||||
}
|
||||
return uint32(gid)
|
||||
}
|
||||
|
||||
// IncRef implements vfs.DentryImpl.IncRef.
|
||||
func (d *dentry) IncRef() {
|
||||
// d.refs may be 0 if d.fs.renameMu is locked, which serializes against
|
||||
|
||||
Reference in New Issue
Block a user