gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/syscalls/linux/sys_identity.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linux 16 17 import ( 18 "gvisor.dev/gvisor/pkg/errors/linuxerr" 19 "gvisor.dev/gvisor/pkg/sentry/arch" 20 "gvisor.dev/gvisor/pkg/sentry/kernel" 21 "gvisor.dev/gvisor/pkg/sentry/kernel/auth" 22 ) 23 24 const ( 25 // As NGROUPS_MAX in include/uapi/linux/limits.h. 26 maxNGroups = 65536 27 ) 28 29 // Getuid implements the Linux syscall getuid. 30 func Getuid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 31 c := t.Credentials() 32 ruid := c.RealKUID.In(c.UserNamespace).OrOverflow() 33 return uintptr(ruid), nil, nil 34 } 35 36 // Geteuid implements the Linux syscall geteuid. 37 func Geteuid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 38 c := t.Credentials() 39 euid := c.EffectiveKUID.In(c.UserNamespace).OrOverflow() 40 return uintptr(euid), nil, nil 41 } 42 43 // Getresuid implements the Linux syscall getresuid. 44 func Getresuid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 45 ruidAddr := args[0].Pointer() 46 euidAddr := args[1].Pointer() 47 suidAddr := args[2].Pointer() 48 c := t.Credentials() 49 ruid := c.RealKUID.In(c.UserNamespace).OrOverflow() 50 euid := c.EffectiveKUID.In(c.UserNamespace).OrOverflow() 51 suid := c.SavedKUID.In(c.UserNamespace).OrOverflow() 52 if _, err := ruid.CopyOut(t, ruidAddr); err != nil { 53 return 0, nil, err 54 } 55 if _, err := euid.CopyOut(t, euidAddr); err != nil { 56 return 0, nil, err 57 } 58 if _, err := suid.CopyOut(t, suidAddr); err != nil { 59 return 0, nil, err 60 } 61 return 0, nil, nil 62 } 63 64 // Getgid implements the Linux syscall getgid. 65 func Getgid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 66 c := t.Credentials() 67 rgid := c.RealKGID.In(c.UserNamespace).OrOverflow() 68 return uintptr(rgid), nil, nil 69 } 70 71 // Getegid implements the Linux syscall getegid. 72 func Getegid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 73 c := t.Credentials() 74 egid := c.EffectiveKGID.In(c.UserNamespace).OrOverflow() 75 return uintptr(egid), nil, nil 76 } 77 78 // Getresgid implements the Linux syscall getresgid. 79 func Getresgid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 80 rgidAddr := args[0].Pointer() 81 egidAddr := args[1].Pointer() 82 sgidAddr := args[2].Pointer() 83 c := t.Credentials() 84 rgid := c.RealKGID.In(c.UserNamespace).OrOverflow() 85 egid := c.EffectiveKGID.In(c.UserNamespace).OrOverflow() 86 sgid := c.SavedKGID.In(c.UserNamespace).OrOverflow() 87 if _, err := rgid.CopyOut(t, rgidAddr); err != nil { 88 return 0, nil, err 89 } 90 if _, err := egid.CopyOut(t, egidAddr); err != nil { 91 return 0, nil, err 92 } 93 if _, err := sgid.CopyOut(t, sgidAddr); err != nil { 94 return 0, nil, err 95 } 96 return 0, nil, nil 97 } 98 99 // Setuid implements the Linux syscall setuid. 100 func Setuid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 101 uid := auth.UID(args[0].Int()) 102 return 0, nil, t.SetUID(uid) 103 } 104 105 // Setreuid implements the Linux syscall setreuid. 106 func Setreuid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 107 ruid := auth.UID(args[0].Int()) 108 euid := auth.UID(args[1].Int()) 109 return 0, nil, t.SetREUID(ruid, euid) 110 } 111 112 // Setresuid implements the Linux syscall setreuid. 113 func Setresuid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 114 ruid := auth.UID(args[0].Int()) 115 euid := auth.UID(args[1].Int()) 116 suid := auth.UID(args[2].Int()) 117 return 0, nil, t.SetRESUID(ruid, euid, suid) 118 } 119 120 // Setgid implements the Linux syscall setgid. 121 func Setgid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 122 gid := auth.GID(args[0].Int()) 123 return 0, nil, t.SetGID(gid) 124 } 125 126 // Setregid implements the Linux syscall setregid. 127 func Setregid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 128 rgid := auth.GID(args[0].Int()) 129 egid := auth.GID(args[1].Int()) 130 return 0, nil, t.SetREGID(rgid, egid) 131 } 132 133 // Setresgid implements the Linux syscall setregid. 134 func Setresgid(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 135 rgid := auth.GID(args[0].Int()) 136 egid := auth.GID(args[1].Int()) 137 sgid := auth.GID(args[2].Int()) 138 return 0, nil, t.SetRESGID(rgid, egid, sgid) 139 } 140 141 // Getgroups implements the Linux syscall getgroups. 142 func Getgroups(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 143 size := int(args[0].Int()) 144 if size < 0 { 145 return 0, nil, linuxerr.EINVAL 146 } 147 kgids := t.Credentials().ExtraKGIDs 148 // "If size is zero, list is not modified, but the total number of 149 // supplementary group IDs for the process is returned." - getgroups(2) 150 if size == 0 { 151 return uintptr(len(kgids)), nil, nil 152 } 153 if size < len(kgids) { 154 return 0, nil, linuxerr.EINVAL 155 } 156 gids := make([]auth.GID, len(kgids)) 157 for i, kgid := range kgids { 158 gids[i] = kgid.In(t.UserNamespace()).OrOverflow() 159 } 160 if _, err := auth.CopyGIDSliceOut(t, args[1].Pointer(), gids); err != nil { 161 return 0, nil, err 162 } 163 return uintptr(len(gids)), nil, nil 164 } 165 166 // Setgroups implements the Linux syscall setgroups. 167 func Setgroups(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { 168 size := args[0].Int() 169 if size < 0 || size > maxNGroups { 170 return 0, nil, linuxerr.EINVAL 171 } 172 if size == 0 { 173 return 0, nil, t.SetExtraGIDs(nil) 174 } 175 gids := make([]auth.GID, size) 176 if _, err := auth.CopyGIDSliceIn(t, args[1].Pointer(), gids); err != nil { 177 return 0, nil, err 178 } 179 return 0, nil, t.SetExtraGIDs(gids) 180 }