diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-08-17 17:44:26 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-08-17 17:44:26 -0700 |
commit | b495ae599aeff85511449ef17bd50d656d40bc28 (patch) | |
tree | 898f459d96365eb637500ba1c17480258dd7062c /pkg/sentry/kernel/ipc/object.go | |
parent | 8f6c54c8c023d551d6d09b5428ac59fb704c7067 (diff) | |
parent | 2f1c65e7fa49ddf6debb5d8ba4a5b08e17404e2a (diff) |
Merge pull request #6262 from sudo-sturbia:msgqueue/syscalls3
PiperOrigin-RevId: 391416650
Diffstat (limited to 'pkg/sentry/kernel/ipc/object.go')
-rw-r--r-- | pkg/sentry/kernel/ipc/object.go | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/ipc/object.go b/pkg/sentry/kernel/ipc/object.go index 387b35e7e..facd157c7 100644 --- a/pkg/sentry/kernel/ipc/object.go +++ b/pkg/sentry/kernel/ipc/object.go @@ -19,6 +19,8 @@ package ipc import ( "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/context" + "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/sentry/fs" "gvisor.dev/gvisor/pkg/sentry/kernel/auth" ) @@ -113,3 +115,36 @@ func (o *Object) CheckPermissions(creds *auth.Credentials, req fs.PermMask) bool } return creds.HasCapabilityIn(linux.CAP_IPC_OWNER, o.UserNS) } + +// Set modifies attributes for an IPC object. See *ctl(IPC_SET). +// +// Precondition: Mechanism.mu must be held. +func (o *Object) Set(ctx context.Context, perm *linux.IPCPerm) error { + creds := auth.CredentialsFromContext(ctx) + uid := creds.UserNamespace.MapToKUID(auth.UID(perm.UID)) + gid := creds.UserNamespace.MapToKGID(auth.GID(perm.GID)) + if !uid.Ok() || !gid.Ok() { + // The man pages don't specify an errno for invalid uid/gid, but EINVAL + // is generally used for invalid arguments. + return linuxerr.EINVAL + } + + if !o.CheckOwnership(creds) { + // "The argument cmd has the value IPC_SET or IPC_RMID, but the + // effective user ID of the calling process is not the creator (as + // found in msg_perm.cuid) or the owner (as found in msg_perm.uid) + // of the message queue, and the caller is not privileged (Linux: + // does not have the CAP_SYS_ADMIN capability)." + return linuxerr.EPERM + } + + // User may only modify the lower 9 bits of the mode. All the other bits are + // always 0 for the underlying inode. + mode := linux.FileMode(perm.Mode & 0x1ff) + + o.Perms = fs.FilePermsFromMode(mode) + o.Owner.UID = uid + o.Owner.GID = gid + + return nil +} |