summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/gofer
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2021-05-25 13:19:23 -0700
committergVisor bot <gvisor-bot@google.com>2021-05-25 13:21:52 -0700
commitf7bc60603e32d630598eca4663dfd9d03be5802f (patch)
tree899fc93bffc5ecee7297dfaecb7eaff2ee924b4d /pkg/sentry/fs/gofer
parent4f2439fb0ed4a6efda2637417c7137d27e4c4d26 (diff)
setgid directories for VFS1 tmpfs, overlayfs, and goferfs
PiperOrigin-RevId: 375780659
Diffstat (limited to 'pkg/sentry/fs/gofer')
-rw-r--r--pkg/sentry/fs/gofer/file.go16
-rw-r--r--pkg/sentry/fs/gofer/inode.go18
-rw-r--r--pkg/sentry/fs/gofer/path.go20
3 files changed, 49 insertions, 5 deletions
diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go
index 819e140bc..73d80d9b5 100644
--- a/pkg/sentry/fs/gofer/file.go
+++ b/pkg/sentry/fs/gofer/file.go
@@ -237,10 +237,20 @@ func (f *fileOperations) Write(ctx context.Context, file *fs.File, src usermem.I
// and availability of a host-mappable FD.
if f.inodeOperations.session().cachePolicy.useCachingInodeOps(file.Dirent.Inode) {
n, err = f.inodeOperations.cachingInodeOps.Write(ctx, src, offset)
- } else if f.inodeOperations.fileState.hostMappable != nil {
- n, err = f.inodeOperations.fileState.hostMappable.Write(ctx, src, offset)
} else {
- n, err = src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset))
+ uattr, e := f.UnstableAttr(ctx, file)
+ if e != nil {
+ return 0, e
+ }
+ if f.inodeOperations.fileState.hostMappable != nil {
+ n, err = f.inodeOperations.fileState.hostMappable.Write(ctx, src, offset, uattr)
+ } else {
+ n, err = src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset))
+ if n > 0 && uattr.Perms.HasSetUIDOrGID() {
+ uattr.Perms.DropSetUIDAndMaybeGID()
+ f.inodeOperations.SetPermissions(ctx, file.Dirent.Inode, uattr.Perms)
+ }
+ }
}
if n == 0 {
diff --git a/pkg/sentry/fs/gofer/inode.go b/pkg/sentry/fs/gofer/inode.go
index b97635ec4..da3178527 100644
--- a/pkg/sentry/fs/gofer/inode.go
+++ b/pkg/sentry/fs/gofer/inode.go
@@ -600,11 +600,25 @@ func (i *inodeOperations) Truncate(ctx context.Context, inode *fs.Inode, length
if i.session().cachePolicy.useCachingInodeOps(inode) {
return i.cachingInodeOps.Truncate(ctx, inode, length)
}
+
+ uattr, err := i.fileState.unstableAttr(ctx)
+ if err != nil {
+ return err
+ }
+
if i.session().cachePolicy == cacheRemoteRevalidating {
- return i.fileState.hostMappable.Truncate(ctx, length)
+ return i.fileState.hostMappable.Truncate(ctx, length, uattr)
+ }
+
+ mask := p9.SetAttrMask{Size: true}
+ attr := p9.SetAttr{Size: uint64(length)}
+ if uattr.Perms.HasSetUIDOrGID() {
+ mask.Permissions = true
+ uattr.Perms.DropSetUIDAndMaybeGID()
+ attr.Permissions = p9.FileMode(uattr.Perms.LinuxMode())
}
- return i.fileState.file.setAttr(ctx, p9.SetAttrMask{Size: true}, p9.SetAttr{Size: uint64(length)})
+ return i.fileState.file.setAttr(ctx, mask, attr)
}
// GetXattr implements fs.InodeOperations.GetXattr.
diff --git a/pkg/sentry/fs/gofer/path.go b/pkg/sentry/fs/gofer/path.go
index 6b3627813..940838a44 100644
--- a/pkg/sentry/fs/gofer/path.go
+++ b/pkg/sentry/fs/gofer/path.go
@@ -130,7 +130,16 @@ func (i *inodeOperations) Create(ctx context.Context, dir *fs.Inode, name string
panic(fmt.Sprintf("Create called with unknown or unset open flags: %v", flags))
}
+ // If the parent directory has setgid enabled, change the new file's owner.
owner := fs.FileOwnerFromContext(ctx)
+ parentUattr, err := dir.UnstableAttr(ctx)
+ if err != nil {
+ return nil, err
+ }
+ if parentUattr.Perms.SetGID {
+ owner.GID = parentUattr.Owner.GID
+ }
+
hostFile, err := newFile.create(ctx, name, openFlags, p9.FileMode(perm.LinuxMode()), p9.UID(owner.UID), p9.GID(owner.GID))
if err != nil {
// Could not create the file.
@@ -225,7 +234,18 @@ func (i *inodeOperations) CreateDirectory(ctx context.Context, dir *fs.Inode, s
return syserror.ENAMETOOLONG
}
+ // If the parent directory has setgid enabled, change the new directory's
+ // owner and enable setgid.
owner := fs.FileOwnerFromContext(ctx)
+ parentUattr, err := dir.UnstableAttr(ctx)
+ if err != nil {
+ return err
+ }
+ if parentUattr.Perms.SetGID {
+ owner.GID = parentUattr.Owner.GID
+ perm.SetGID = true
+ }
+
if _, err := i.fileState.file.mkdir(ctx, s, p9.FileMode(perm.LinuxMode()), p9.UID(owner.UID), p9.GID(owner.GID)); err != nil {
return err
}