root/kernel/uid16.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SYSCALL_DEFINE3
  2. SYSCALL_DEFINE3
  3. SYSCALL_DEFINE3
  4. SYSCALL_DEFINE2
  5. SYSCALL_DEFINE1
  6. SYSCALL_DEFINE2
  7. SYSCALL_DEFINE1
  8. SYSCALL_DEFINE3
  9. SYSCALL_DEFINE3
  10. SYSCALL_DEFINE3
  11. SYSCALL_DEFINE3
  12. SYSCALL_DEFINE1
  13. SYSCALL_DEFINE1
  14. groups16_to_user
  15. groups16_from_user
  16. SYSCALL_DEFINE2
  17. SYSCALL_DEFINE2
  18. SYSCALL_DEFINE0
  19. SYSCALL_DEFINE0
  20. SYSCALL_DEFINE0
  21. SYSCALL_DEFINE0

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *      Wrapper functions for 16bit uid back compatibility. All nicely tied
   4  *      together in the faint hope we can take the out in five years time.
   5  */
   6 
   7 #include <linux/mm.h>
   8 #include <linux/mman.h>
   9 #include <linux/notifier.h>
  10 #include <linux/reboot.h>
  11 #include <linux/prctl.h>
  12 #include <linux/capability.h>
  13 #include <linux/init.h>
  14 #include <linux/highuid.h>
  15 #include <linux/security.h>
  16 #include <linux/cred.h>
  17 #include <linux/syscalls.h>
  18 
  19 #include <linux/uaccess.h>
  20 
  21 #include "uid16.h"
  22 
  23 SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
  24 {
  25         return ksys_chown(filename, low2highuid(user), low2highgid(group));
  26 }
  27 
  28 SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
  29 {
  30         return ksys_lchown(filename, low2highuid(user), low2highgid(group));
  31 }
  32 
  33 SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
  34 {
  35         return ksys_fchown(fd, low2highuid(user), low2highgid(group));
  36 }
  37 
  38 SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid)
  39 {
  40         return __sys_setregid(low2highgid(rgid), low2highgid(egid));
  41 }
  42 
  43 SYSCALL_DEFINE1(setgid16, old_gid_t, gid)
  44 {
  45         return __sys_setgid(low2highgid(gid));
  46 }
  47 
  48 SYSCALL_DEFINE2(setreuid16, old_uid_t, ruid, old_uid_t, euid)
  49 {
  50         return __sys_setreuid(low2highuid(ruid), low2highuid(euid));
  51 }
  52 
  53 SYSCALL_DEFINE1(setuid16, old_uid_t, uid)
  54 {
  55         return __sys_setuid(low2highuid(uid));
  56 }
  57 
  58 SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid)
  59 {
  60         return __sys_setresuid(low2highuid(ruid), low2highuid(euid),
  61                                  low2highuid(suid));
  62 }
  63 
  64 SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruidp, old_uid_t __user *, euidp, old_uid_t __user *, suidp)
  65 {
  66         const struct cred *cred = current_cred();
  67         int retval;
  68         old_uid_t ruid, euid, suid;
  69 
  70         ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid));
  71         euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid));
  72         suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid));
  73 
  74         if (!(retval   = put_user(ruid, ruidp)) &&
  75             !(retval   = put_user(euid, euidp)))
  76                 retval = put_user(suid, suidp);
  77 
  78         return retval;
  79 }
  80 
  81 SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid)
  82 {
  83         return __sys_setresgid(low2highgid(rgid), low2highgid(egid),
  84                                  low2highgid(sgid));
  85 }
  86 
  87 SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgidp, old_gid_t __user *, egidp, old_gid_t __user *, sgidp)
  88 {
  89         const struct cred *cred = current_cred();
  90         int retval;
  91         old_gid_t rgid, egid, sgid;
  92 
  93         rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid));
  94         egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid));
  95         sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid));
  96 
  97         if (!(retval   = put_user(rgid, rgidp)) &&
  98             !(retval   = put_user(egid, egidp)))
  99                 retval = put_user(sgid, sgidp);
 100 
 101         return retval;
 102 }
 103 
 104 SYSCALL_DEFINE1(setfsuid16, old_uid_t, uid)
 105 {
 106         return __sys_setfsuid(low2highuid(uid));
 107 }
 108 
 109 SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid)
 110 {
 111         return __sys_setfsgid(low2highgid(gid));
 112 }
 113 
 114 static int groups16_to_user(old_gid_t __user *grouplist,
 115     struct group_info *group_info)
 116 {
 117         struct user_namespace *user_ns = current_user_ns();
 118         int i;
 119         old_gid_t group;
 120         kgid_t kgid;
 121 
 122         for (i = 0; i < group_info->ngroups; i++) {
 123                 kgid = group_info->gid[i];
 124                 group = high2lowgid(from_kgid_munged(user_ns, kgid));
 125                 if (put_user(group, grouplist+i))
 126                         return -EFAULT;
 127         }
 128 
 129         return 0;
 130 }
 131 
 132 static int groups16_from_user(struct group_info *group_info,
 133     old_gid_t __user *grouplist)
 134 {
 135         struct user_namespace *user_ns = current_user_ns();
 136         int i;
 137         old_gid_t group;
 138         kgid_t kgid;
 139 
 140         for (i = 0; i < group_info->ngroups; i++) {
 141                 if (get_user(group, grouplist+i))
 142                         return  -EFAULT;
 143 
 144                 kgid = make_kgid(user_ns, low2highgid(group));
 145                 if (!gid_valid(kgid))
 146                         return -EINVAL;
 147 
 148                 group_info->gid[i] = kgid;
 149         }
 150 
 151         return 0;
 152 }
 153 
 154 SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
 155 {
 156         const struct cred *cred = current_cred();
 157         int i;
 158 
 159         if (gidsetsize < 0)
 160                 return -EINVAL;
 161 
 162         i = cred->group_info->ngroups;
 163         if (gidsetsize) {
 164                 if (i > gidsetsize) {
 165                         i = -EINVAL;
 166                         goto out;
 167                 }
 168                 if (groups16_to_user(grouplist, cred->group_info)) {
 169                         i = -EFAULT;
 170                         goto out;
 171                 }
 172         }
 173 out:
 174         return i;
 175 }
 176 
 177 SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
 178 {
 179         struct group_info *group_info;
 180         int retval;
 181 
 182         if (!may_setgroups())
 183                 return -EPERM;
 184         if ((unsigned)gidsetsize > NGROUPS_MAX)
 185                 return -EINVAL;
 186 
 187         group_info = groups_alloc(gidsetsize);
 188         if (!group_info)
 189                 return -ENOMEM;
 190         retval = groups16_from_user(group_info, grouplist);
 191         if (retval) {
 192                 put_group_info(group_info);
 193                 return retval;
 194         }
 195 
 196         groups_sort(group_info);
 197         retval = set_current_groups(group_info);
 198         put_group_info(group_info);
 199 
 200         return retval;
 201 }
 202 
 203 SYSCALL_DEFINE0(getuid16)
 204 {
 205         return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));
 206 }
 207 
 208 SYSCALL_DEFINE0(geteuid16)
 209 {
 210         return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));
 211 }
 212 
 213 SYSCALL_DEFINE0(getgid16)
 214 {
 215         return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));
 216 }
 217 
 218 SYSCALL_DEFINE0(getegid16)
 219 {
 220         return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));
 221 }

/* [<][>][^][v][top][bottom][index][help] */