summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls/linux/sys_identity.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/syscalls/linux/sys_identity.go')
-rw-r--r--pkg/sentry/syscalls/linux/sys_identity.go180
1 files changed, 180 insertions, 0 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_identity.go b/pkg/sentry/syscalls/linux/sys_identity.go
new file mode 100644
index 000000000..4fd0ed794
--- /dev/null
+++ b/pkg/sentry/syscalls/linux/sys_identity.go
@@ -0,0 +1,180 @@
+// Copyright 2018 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package linux
+
+import (
+ "gvisor.googlesource.com/gvisor/pkg/sentry/arch"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.googlesource.com/gvisor/pkg/syserror"
+)
+
+const (
+ // As NGROUPS_MAX in include/uapi/linux/limits.h.
+ maxNGroups = 65536
+)
+
+// Getuid implements the Linux syscall getuid.
+func Getuid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ c := t.Credentials()
+ ruid := c.RealKUID.In(c.UserNamespace).OrOverflow()
+ return uintptr(ruid), nil, nil
+}
+
+// Geteuid implements the Linux syscall geteuid.
+func Geteuid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ c := t.Credentials()
+ euid := c.EffectiveKUID.In(c.UserNamespace).OrOverflow()
+ return uintptr(euid), nil, nil
+}
+
+// Getresuid implements the Linux syscall getresuid.
+func Getresuid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ ruidAddr := args[0].Pointer()
+ euidAddr := args[1].Pointer()
+ suidAddr := args[2].Pointer()
+ c := t.Credentials()
+ ruid := c.RealKUID.In(c.UserNamespace).OrOverflow()
+ euid := c.EffectiveKUID.In(c.UserNamespace).OrOverflow()
+ suid := c.SavedKUID.In(c.UserNamespace).OrOverflow()
+ if _, err := t.CopyOut(ruidAddr, ruid); err != nil {
+ return 0, nil, err
+ }
+ if _, err := t.CopyOut(euidAddr, euid); err != nil {
+ return 0, nil, err
+ }
+ if _, err := t.CopyOut(suidAddr, suid); err != nil {
+ return 0, nil, err
+ }
+ return 0, nil, nil
+}
+
+// Getgid implements the Linux syscall getgid.
+func Getgid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ c := t.Credentials()
+ rgid := c.RealKGID.In(c.UserNamespace).OrOverflow()
+ return uintptr(rgid), nil, nil
+}
+
+// Getegid implements the Linux syscall getegid.
+func Getegid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ c := t.Credentials()
+ egid := c.EffectiveKGID.In(c.UserNamespace).OrOverflow()
+ return uintptr(egid), nil, nil
+}
+
+// Getresgid implements the Linux syscall getresgid.
+func Getresgid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ rgidAddr := args[0].Pointer()
+ egidAddr := args[1].Pointer()
+ sgidAddr := args[2].Pointer()
+ c := t.Credentials()
+ rgid := c.RealKGID.In(c.UserNamespace).OrOverflow()
+ egid := c.EffectiveKGID.In(c.UserNamespace).OrOverflow()
+ sgid := c.SavedKGID.In(c.UserNamespace).OrOverflow()
+ if _, err := t.CopyOut(rgidAddr, rgid); err != nil {
+ return 0, nil, err
+ }
+ if _, err := t.CopyOut(egidAddr, egid); err != nil {
+ return 0, nil, err
+ }
+ if _, err := t.CopyOut(sgidAddr, sgid); err != nil {
+ return 0, nil, err
+ }
+ return 0, nil, nil
+}
+
+// Setuid implements the Linux syscall setuid.
+func Setuid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ uid := auth.UID(args[0].Int())
+ return 0, nil, t.SetUID(uid)
+}
+
+// Setreuid implements the Linux syscall setreuid.
+func Setreuid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ ruid := auth.UID(args[0].Int())
+ euid := auth.UID(args[1].Int())
+ return 0, nil, t.SetREUID(ruid, euid)
+}
+
+// Setresuid implements the Linux syscall setreuid.
+func Setresuid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ ruid := auth.UID(args[0].Int())
+ euid := auth.UID(args[1].Int())
+ suid := auth.UID(args[2].Int())
+ return 0, nil, t.SetRESUID(ruid, euid, suid)
+}
+
+// Setgid implements the Linux syscall setgid.
+func Setgid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ gid := auth.GID(args[0].Int())
+ return 0, nil, t.SetGID(gid)
+}
+
+// Setregid implements the Linux syscall setregid.
+func Setregid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ rgid := auth.GID(args[0].Int())
+ egid := auth.GID(args[1].Int())
+ return 0, nil, t.SetREGID(rgid, egid)
+}
+
+// Setresgid implements the Linux syscall setregid.
+func Setresgid(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ rgid := auth.GID(args[0].Int())
+ egid := auth.GID(args[1].Int())
+ sgid := auth.GID(args[2].Int())
+ return 0, nil, t.SetRESGID(rgid, egid, sgid)
+}
+
+// Getgroups implements the Linux syscall getgroups.
+func Getgroups(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ size := int(args[0].Int())
+ if size < 0 {
+ return 0, nil, syserror.EINVAL
+ }
+ kgids := t.Credentials().ExtraKGIDs
+ // "If size is zero, list is not modified, but the total number of
+ // supplementary group IDs for the process is returned." - getgroups(2)
+ if size == 0 {
+ return uintptr(len(kgids)), nil, nil
+ }
+ if size < len(kgids) {
+ return 0, nil, syserror.EINVAL
+ }
+ gids := make([]auth.GID, len(kgids))
+ for i, kgid := range kgids {
+ gids[i] = kgid.In(t.UserNamespace()).OrOverflow()
+ }
+ if _, err := t.CopyOut(args[1].Pointer(), gids); err != nil {
+ return 0, nil, err
+ }
+ return uintptr(len(gids)), nil, nil
+}
+
+// Setgroups implements the Linux syscall setgroups.
+func Setgroups(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ size := args[0].Int()
+ if size < 0 || size > maxNGroups {
+ return 0, nil, syserror.EINVAL
+ }
+ if size == 0 {
+ return 0, nil, t.SetExtraGIDs(nil)
+ }
+ gids := make([]auth.GID, size)
+ if _, err := t.CopyIn(args[1].Pointer(), &gids); err != nil {
+ return 0, nil, err
+ }
+ return 0, nil, t.SetExtraGIDs(gids)
+}