mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Combine file mode and isDir arguments
Updates #1035 PiperOrigin-RevId: 303021328
This commit is contained in:
committed by
gVisor bot
parent
ce0a69ea97
commit
de694e5484
@@ -287,6 +287,11 @@ func (m FileMode) ExtraBits() FileMode {
|
||||
return m &^ (PermissionsMask | FileTypeMask)
|
||||
}
|
||||
|
||||
// IsDir returns true if file type represents a directory.
|
||||
func (m FileMode) IsDir() bool {
|
||||
return m.FileType() == S_IFDIR
|
||||
}
|
||||
|
||||
// String returns a string representation of m.
|
||||
func (m FileMode) String() string {
|
||||
var s []string
|
||||
|
||||
@@ -186,7 +186,7 @@ func (in *inode) open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts *vfs.OpenOpt
|
||||
}
|
||||
|
||||
func (in *inode) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||
return vfs.GenericCheckPermissions(creds, ats, in.isDir(), uint16(in.diskInode.Mode()), in.diskInode.UID(), in.diskInode.GID())
|
||||
return vfs.GenericCheckPermissions(creds, ats, in.diskInode.Mode(), in.diskInode.UID(), in.diskInode.GID())
|
||||
}
|
||||
|
||||
// statTo writes the statx fields to the output parameter.
|
||||
|
||||
@@ -119,7 +119,7 @@ func (fs *filesystem) stepLocked(ctx context.Context, rp *vfs.ResolvingPath, d *
|
||||
if !d.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
if err := d.checkPermissions(rp.Credentials(), vfs.MayExec, true); err != nil {
|
||||
if err := d.checkPermissions(rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
afterSymlink:
|
||||
@@ -314,7 +314,7 @@ func (fs *filesystem) doCreateAt(ctx context.Context, rp *vfs.ResolvingPath, dir
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := parent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true); err != nil {
|
||||
if err := parent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
if parent.isDeleted() {
|
||||
@@ -378,7 +378,7 @@ func (fs *filesystem) unlinkAt(ctx context.Context, rp *vfs.ResolvingPath, dir b
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := parent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true); err != nil {
|
||||
if err := parent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := rp.Mount().CheckBeginWrite(); err != nil {
|
||||
@@ -512,7 +512,7 @@ func (fs *filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.checkPermissions(creds, ats, d.isDir())
|
||||
return d.checkPermissions(creds, ats)
|
||||
}
|
||||
|
||||
// GetDentryAt implements vfs.FilesystemImpl.GetDentryAt.
|
||||
@@ -528,7 +528,7 @@ func (fs *filesystem) GetDentryAt(ctx context.Context, rp *vfs.ResolvingPath, op
|
||||
if !d.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
if err := d.checkPermissions(rp.Credentials(), vfs.MayExec, true); err != nil {
|
||||
if err := d.checkPermissions(rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -624,7 +624,7 @@ afterTrailingSymlink:
|
||||
return nil, err
|
||||
}
|
||||
// Check for search permission in the parent directory.
|
||||
if err := parent.checkPermissions(rp.Credentials(), vfs.MayExec, true); err != nil {
|
||||
if err := parent.checkPermissions(rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Determine whether or not we need to create a file.
|
||||
@@ -661,7 +661,7 @@ afterTrailingSymlink:
|
||||
// Preconditions: fs.renameMu must be locked.
|
||||
func (d *dentry) openLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
|
||||
ats := vfs.AccessTypesForOpenFlags(opts)
|
||||
if err := d.checkPermissions(rp.Credentials(), ats, d.isDir()); err != nil {
|
||||
if err := d.checkPermissions(rp.Credentials(), ats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mnt := rp.Mount()
|
||||
@@ -722,7 +722,7 @@ func (d *dentry) openLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vf
|
||||
|
||||
// Preconditions: d.fs.renameMu must be locked. d.dirMu must be locked.
|
||||
func (d *dentry) createAndOpenChildLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
|
||||
if err := d.checkPermissions(rp.Credentials(), vfs.MayWrite, true); err != nil {
|
||||
if err := d.checkPermissions(rp.Credentials(), vfs.MayWrite); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if d.isDeleted() {
|
||||
@@ -884,7 +884,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := oldParent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true); err != nil {
|
||||
if err := oldParent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
vfsObj := rp.VirtualFilesystem()
|
||||
@@ -904,7 +904,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
return syserror.EINVAL
|
||||
}
|
||||
if oldParent != newParent {
|
||||
if err := renamed.checkPermissions(rp.Credentials(), vfs.MayWrite, true); err != nil {
|
||||
if err := renamed.checkPermissions(rp.Credentials(), vfs.MayWrite); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -915,7 +915,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
|
||||
if oldParent != newParent {
|
||||
if err := newParent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true); err != nil {
|
||||
if err := newParent.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
newParent.dirMu.Lock()
|
||||
|
||||
@@ -721,7 +721,8 @@ func (d *dentry) setStat(ctx context.Context, creds *auth.Credentials, stat *lin
|
||||
if stat.Mask&^(linux.STATX_MODE|linux.STATX_UID|linux.STATX_GID|linux.STATX_ATIME|linux.STATX_MTIME|linux.STATX_SIZE) != 0 {
|
||||
return syserror.EPERM
|
||||
}
|
||||
if err := vfs.CheckSetStat(ctx, creds, stat, uint16(atomic.LoadUint32(&d.mode))&^linux.S_IFMT, auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid))); err != nil {
|
||||
mode := linux.FileMode(atomic.LoadUint32(&d.mode))
|
||||
if err := vfs.CheckSetStat(ctx, creds, stat, mode, auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid))); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := mnt.CheckBeginWrite(); err != nil {
|
||||
@@ -843,8 +844,8 @@ func (d *dentry) setStat(ctx context.Context, creds *auth.Credentials, stat *lin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dentry) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes, isDir bool) error {
|
||||
return vfs.GenericCheckPermissions(creds, ats, isDir, uint16(atomic.LoadUint32(&d.mode))&0777, auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid)))
|
||||
func (d *dentry) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||
return vfs.GenericCheckPermissions(creds, ats, linux.FileMode(atomic.LoadUint32(&d.mode)), auth.KUID(atomic.LoadUint32(&d.uid)), auth.KGID(atomic.LoadUint32(&d.gid)))
|
||||
}
|
||||
|
||||
// IncRef implements vfs.DentryImpl.IncRef.
|
||||
|
||||
@@ -167,8 +167,8 @@ func fileFlagsFromHostFD(fd int) (int, error) {
|
||||
}
|
||||
|
||||
// CheckPermissions implements kernfs.Inode.
|
||||
func (i *inode) CheckPermissions(ctx context.Context, creds *auth.Credentials, atx vfs.AccessTypes) error {
|
||||
return vfs.GenericCheckPermissions(creds, atx, false /* isDir */, uint16(i.mode), i.uid, i.gid)
|
||||
func (i *inode) CheckPermissions(ctx context.Context, creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||
return vfs.GenericCheckPermissions(creds, ats, i.mode, i.uid, i.gid)
|
||||
}
|
||||
|
||||
// Mode implements kernfs.Inode.
|
||||
@@ -306,7 +306,7 @@ func (i *inode) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Cre
|
||||
if m&^(linux.STATX_MODE|linux.STATX_SIZE|linux.STATX_ATIME|linux.STATX_MTIME) != 0 {
|
||||
return syserror.EPERM
|
||||
}
|
||||
if err := vfs.CheckSetStat(ctx, creds, &s, uint16(i.Mode().Permissions()), i.uid, i.gid); err != nil {
|
||||
if err := vfs.CheckSetStat(ctx, creds, &s, i.Mode(), i.uid, i.gid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -206,8 +206,7 @@ func (fd *GenericDirectoryFD) Stat(ctx context.Context, opts vfs.StatOptions) (l
|
||||
|
||||
// SetStat implements vfs.FileDescriptionImpl.SetStat.
|
||||
func (fd *GenericDirectoryFD) SetStat(ctx context.Context, opts vfs.SetStatOptions) error {
|
||||
fs := fd.filesystem()
|
||||
creds := auth.CredentialsFromContext(ctx)
|
||||
inode := fd.vfsfd.VirtualDentry().Dentry().Impl().(*Dentry).inode
|
||||
return inode.SetStat(ctx, fs, creds, opts)
|
||||
return inode.SetStat(ctx, fd.filesystem(), creds, opts)
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ func (a *InodeAttrs) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *aut
|
||||
if opts.Stat.Mask&^(linux.STATX_MODE|linux.STATX_UID|linux.STATX_GID) != 0 {
|
||||
return syserror.EPERM
|
||||
}
|
||||
if err := vfs.CheckSetStat(ctx, creds, &opts.Stat, uint16(a.Mode().Permissions()), auth.KUID(atomic.LoadUint32(&a.uid)), auth.KGID(atomic.LoadUint32(&a.gid))); err != nil {
|
||||
if err := vfs.CheckSetStat(ctx, creds, &opts.Stat, a.Mode(), auth.KUID(atomic.LoadUint32(&a.uid)), auth.KGID(atomic.LoadUint32(&a.gid))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -273,12 +273,10 @@ func (a *InodeAttrs) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *aut
|
||||
|
||||
// CheckPermissions implements Inode.CheckPermissions.
|
||||
func (a *InodeAttrs) CheckPermissions(_ context.Context, creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||
mode := a.Mode()
|
||||
return vfs.GenericCheckPermissions(
|
||||
creds,
|
||||
ats,
|
||||
mode.FileType() == linux.ModeDirectory,
|
||||
uint16(mode),
|
||||
a.Mode(),
|
||||
auth.KUID(atomic.LoadUint32(&a.uid)),
|
||||
auth.KGID(atomic.LoadUint32(&a.gid)),
|
||||
)
|
||||
|
||||
@@ -172,14 +172,7 @@ func (i *taskOwnedInode) Stat(fs *vfs.Filesystem, opts vfs.StatOptions) (linux.S
|
||||
func (i *taskOwnedInode) CheckPermissions(_ context.Context, creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||
mode := i.Mode()
|
||||
uid, gid := i.getOwner(mode)
|
||||
return vfs.GenericCheckPermissions(
|
||||
creds,
|
||||
ats,
|
||||
mode.FileType() == linux.ModeDirectory,
|
||||
uint16(mode),
|
||||
uid,
|
||||
gid,
|
||||
)
|
||||
return vfs.GenericCheckPermissions(creds, ats, mode, uid, gid)
|
||||
}
|
||||
|
||||
func (i *taskOwnedInode) getOwner(mode linux.FileMode) (auth.KUID, auth.KGID) {
|
||||
|
||||
@@ -41,7 +41,7 @@ func stepLocked(rp *vfs.ResolvingPath, d *dentry) (*dentry, error) {
|
||||
if !d.inode.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
if err := d.inode.checkPermissions(rp.Credentials(), vfs.MayExec, true); err != nil {
|
||||
if err := d.inode.checkPermissions(rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
afterSymlink:
|
||||
@@ -125,7 +125,7 @@ func (fs *filesystem) doCreateAt(rp *vfs.ResolvingPath, dir bool, create func(pa
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true /* isDir */); err != nil {
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
name := rp.Component()
|
||||
@@ -163,7 +163,7 @@ func (fs *filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.inode.checkPermissions(creds, ats, d.inode.isDir())
|
||||
return d.inode.checkPermissions(creds, ats)
|
||||
}
|
||||
|
||||
// GetDentryAt implements vfs.FilesystemImpl.GetDentryAt.
|
||||
@@ -178,7 +178,7 @@ func (fs *filesystem) GetDentryAt(ctx context.Context, rp *vfs.ResolvingPath, op
|
||||
if !d.inode.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
if err := d.inode.checkPermissions(rp.Credentials(), vfs.MayExec, true /* isDir */); err != nil {
|
||||
if err := d.inode.checkPermissions(rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -301,7 +301,7 @@ afterTrailingSymlink:
|
||||
return nil, err
|
||||
}
|
||||
// Check for search permission in the parent directory.
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayExec, true); err != nil {
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Reject attempts to open directories with O_CREAT.
|
||||
@@ -316,7 +316,7 @@ afterTrailingSymlink:
|
||||
child, err := stepLocked(rp, parent)
|
||||
if err == syserror.ENOENT {
|
||||
// Already checked for searchability above; now check for writability.
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite, true); err != nil {
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rp.Mount().CheckBeginWrite(); err != nil {
|
||||
@@ -347,7 +347,7 @@ afterTrailingSymlink:
|
||||
func (d *dentry) open(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.OpenOptions, afterCreate bool) (*vfs.FileDescription, error) {
|
||||
ats := vfs.AccessTypesForOpenFlags(opts)
|
||||
if !afterCreate {
|
||||
if err := d.inode.checkPermissions(rp.Credentials(), ats, d.inode.isDir()); err != nil {
|
||||
if err := d.inode.checkPermissions(rp.Credentials(), ats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -428,7 +428,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
defer mnt.EndWrite()
|
||||
|
||||
oldParent := oldParentVD.Dentry().Impl().(*dentry)
|
||||
if err := oldParent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true /* isDir */); err != nil {
|
||||
if err := oldParent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
// Call vfs.Dentry.Child() instead of stepLocked() or rp.ResolveChild(),
|
||||
@@ -445,7 +445,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
if oldParent != newParent {
|
||||
// Writability is needed to change renamed's "..".
|
||||
if err := renamed.inode.checkPermissions(rp.Credentials(), vfs.MayWrite, true /* isDir */); err != nil {
|
||||
if err := renamed.inode.checkPermissions(rp.Credentials(), vfs.MayWrite); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -455,7 +455,7 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
}
|
||||
|
||||
if err := newParent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true /* isDir */); err != nil {
|
||||
if err := newParent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
replacedVFSD := newParent.vfsd.Child(newName)
|
||||
@@ -528,7 +528,7 @@ func (fs *filesystem) RmdirAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true /* isDir */); err != nil {
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
name := rp.Component()
|
||||
@@ -621,7 +621,7 @@ func (fs *filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec, true /* isDir */); err != nil {
|
||||
if err := parent.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return err
|
||||
}
|
||||
name := rp.Component()
|
||||
|
||||
@@ -245,8 +245,9 @@ func (i *inode) decRef() {
|
||||
}
|
||||
}
|
||||
|
||||
func (i *inode) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes, isDir bool) error {
|
||||
return vfs.GenericCheckPermissions(creds, ats, isDir, uint16(atomic.LoadUint32(&i.mode)), auth.KUID(atomic.LoadUint32(&i.uid)), auth.KGID(atomic.LoadUint32(&i.gid)))
|
||||
func (i *inode) checkPermissions(creds *auth.Credentials, ats vfs.AccessTypes) error {
|
||||
mode := linux.FileMode(atomic.LoadUint32(&i.mode))
|
||||
return vfs.GenericCheckPermissions(creds, ats, mode, auth.KUID(atomic.LoadUint32(&i.uid)), auth.KGID(atomic.LoadUint32(&i.gid)))
|
||||
}
|
||||
|
||||
// Go won't inline this function, and returning linux.Statx (which is quite
|
||||
@@ -299,7 +300,8 @@ func (i *inode) setStat(ctx context.Context, creds *auth.Credentials, stat *linu
|
||||
if stat.Mask&^(linux.STATX_MODE|linux.STATX_UID|linux.STATX_GID|linux.STATX_ATIME|linux.STATX_MTIME|linux.STATX_CTIME|linux.STATX_SIZE) != 0 {
|
||||
return syserror.EPERM
|
||||
}
|
||||
if err := vfs.CheckSetStat(ctx, creds, stat, uint16(atomic.LoadUint32(&i.mode))&^linux.S_IFMT, auth.KUID(atomic.LoadUint32(&i.uid)), auth.KGID(atomic.LoadUint32(&i.gid))); err != nil {
|
||||
mode := linux.FileMode(atomic.LoadUint32(&i.mode))
|
||||
if err := vfs.CheckSetStat(ctx, creds, stat, mode, auth.KUID(atomic.LoadUint32(&i.uid)), auth.KGID(atomic.LoadUint32(&i.gid))); err != nil {
|
||||
return err
|
||||
}
|
||||
i.mu.Lock()
|
||||
|
||||
@@ -83,7 +83,7 @@ func (fs *anonFilesystem) AccessAt(ctx context.Context, rp *ResolvingPath, creds
|
||||
if !rp.Done() {
|
||||
return syserror.ENOTDIR
|
||||
}
|
||||
return GenericCheckPermissions(creds, ats, false /* isDir */, anonFileMode, anonFileUID, anonFileGID)
|
||||
return GenericCheckPermissions(creds, ats, anonFileMode, anonFileUID, anonFileGID)
|
||||
}
|
||||
|
||||
// GetDentryAt implements FilesystemImpl.GetDentryAt.
|
||||
|
||||
@@ -29,9 +29,9 @@ type AccessTypes uint16
|
||||
|
||||
// Bits in AccessTypes.
|
||||
const (
|
||||
MayExec AccessTypes = 1
|
||||
MayWrite AccessTypes = 2
|
||||
MayRead AccessTypes = 4
|
||||
MayWrite = 2
|
||||
MayExec = 1
|
||||
)
|
||||
|
||||
// OnlyRead returns true if access _only_ allows read.
|
||||
@@ -56,16 +56,17 @@ func (a AccessTypes) MayExec() bool {
|
||||
|
||||
// GenericCheckPermissions checks that creds has the given access rights on a
|
||||
// file with the given permissions, UID, and GID, subject to the rules of
|
||||
// fs/namei.c:generic_permission(). isDir is true if the file is a directory.
|
||||
func GenericCheckPermissions(creds *auth.Credentials, ats AccessTypes, isDir bool, mode uint16, kuid auth.KUID, kgid auth.KGID) error {
|
||||
// fs/namei.c:generic_permission().
|
||||
func GenericCheckPermissions(creds *auth.Credentials, ats AccessTypes, mode linux.FileMode, kuid auth.KUID, kgid auth.KGID) error {
|
||||
// Check permission bits.
|
||||
perms := mode
|
||||
perms := uint16(mode.Permissions())
|
||||
if creds.EffectiveKUID == kuid {
|
||||
perms >>= 6
|
||||
} else if creds.InGroup(kgid) {
|
||||
perms >>= 3
|
||||
}
|
||||
if uint16(ats)&perms == uint16(ats) {
|
||||
// All permission bits match, access granted.
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ func GenericCheckPermissions(creds *auth.Credentials, ats AccessTypes, isDir boo
|
||||
}
|
||||
// CAP_DAC_READ_SEARCH allows the caller to read and search arbitrary
|
||||
// directories, and read arbitrary non-directory files.
|
||||
if (isDir && !ats.MayWrite()) || ats.OnlyRead() {
|
||||
if (mode.IsDir() && !ats.MayWrite()) || ats.OnlyRead() {
|
||||
if creds.HasCapability(linux.CAP_DAC_READ_SEARCH) {
|
||||
return nil
|
||||
}
|
||||
@@ -85,7 +86,7 @@ func GenericCheckPermissions(creds *auth.Credentials, ats AccessTypes, isDir boo
|
||||
// CAP_DAC_OVERRIDE allows arbitrary access to directories, read/write
|
||||
// access to non-directory files, and execute access to non-directory files
|
||||
// for which at least one execute bit is set.
|
||||
if isDir || !ats.MayExec() || (mode&0111 != 0) {
|
||||
if mode.IsDir() || !ats.MayExec() || (mode.Permissions()&0111 != 0) {
|
||||
if creds.HasCapability(linux.CAP_DAC_OVERRIDE) {
|
||||
return nil
|
||||
}
|
||||
@@ -151,7 +152,7 @@ func MayWriteFileWithOpenFlags(flags uint32) bool {
|
||||
// CheckSetStat checks that creds has permission to change the metadata of a
|
||||
// file with the given permissions, UID, and GID as specified by stat, subject
|
||||
// to the rules of Linux's fs/attr.c:setattr_prepare().
|
||||
func CheckSetStat(ctx context.Context, creds *auth.Credentials, stat *linux.Statx, mode uint16, kuid auth.KUID, kgid auth.KGID) error {
|
||||
func CheckSetStat(ctx context.Context, creds *auth.Credentials, stat *linux.Statx, mode linux.FileMode, kuid auth.KUID, kgid auth.KGID) error {
|
||||
if stat.Mask&linux.STATX_SIZE != 0 {
|
||||
limit, err := CheckLimit(ctx, 0, int64(stat.Size))
|
||||
if err != nil {
|
||||
@@ -190,11 +191,7 @@ func CheckSetStat(ctx context.Context, creds *auth.Credentials, stat *linux.Stat
|
||||
(stat.Mask&linux.STATX_CTIME != 0 && stat.Ctime.Nsec != linux.UTIME_NOW) {
|
||||
return syserror.EPERM
|
||||
}
|
||||
// isDir is irrelevant in the following call to
|
||||
// GenericCheckPermissions since ats == MayWrite means that
|
||||
// CAP_DAC_READ_SEARCH does not apply, and CAP_DAC_OVERRIDE
|
||||
// applies, regardless of isDir.
|
||||
if err := GenericCheckPermissions(creds, MayWrite, false /* isDir */, mode, kuid, kgid); err != nil {
|
||||
if err := GenericCheckPermissions(creds, MayWrite, mode, kuid, kgid); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user