github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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  	"github.com/SagerNet/gvisor/pkg/errors/linuxerr"
    19  	"github.com/SagerNet/gvisor/pkg/sentry/arch"
    20  	"github.com/SagerNet/gvisor/pkg/sentry/kernel"
    21  	"github.com/SagerNet/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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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  }