1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * Wrapper functions for 16bit uid back c 4 * together in the faint hope we can take 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 *, 24 { 25 return ksys_chown(filename, low2highui 26 } 27 28 SYSCALL_DEFINE3(lchown16, const char __user *, 29 { 30 return ksys_lchown(filename, low2highu 31 } 32 33 SYSCALL_DEFINE3(fchown16, unsigned int, fd, ol 34 { 35 return ksys_fchown(fd, low2highuid(use 36 } 37 38 SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, o 39 { 40 return __sys_setregid(low2highgid(rgid 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, o 49 { 50 return __sys_setreuid(low2highuid(ruid 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, 59 { 60 return __sys_setresuid(low2highuid(rui 61 low2highuid(s 62 } 63 64 SYSCALL_DEFINE3(getresuid16, old_uid_t __user 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(cr 71 euid = high2lowuid(from_kuid_munged(cr 72 suid = high2lowuid(from_kuid_munged(cr 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, 82 { 83 return __sys_setresgid(low2highgid(rgi 84 low2highgid(s 85 } 86 87 SYSCALL_DEFINE3(getresgid16, old_gid_t __user 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(cr 94 egid = high2lowgid(from_kgid_munged(cr 95 sgid = high2lowgid(from_kgid_munged(cr 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 * 115 struct group_info *group_info) 116 { 117 struct user_namespace *user_ns = curre 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_ 125 if (put_user(group, grouplist+ 126 return -EFAULT; 127 } 128 129 return 0; 130 } 131 132 static int groups16_from_user(struct group_inf 133 old_gid_t __user *grouplist) 134 { 135 struct user_namespace *user_ns = curre 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+ 142 return -EFAULT; 143 144 kgid = make_kgid(user_ns, low2 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, 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 169 i = -EFAULT; 170 goto out; 171 } 172 } 173 out: 174 return i; 175 } 176 177 SYSCALL_DEFINE2(setgroups16, int, gidsetsize, 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 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(cu 206 } 207 208 SYSCALL_DEFINE0(geteuid16) 209 { 210 return high2lowuid(from_kuid_munged(cu 211 } 212 213 SYSCALL_DEFINE0(getgid16) 214 { 215 return high2lowgid(from_kgid_munged(cu 216 } 217 218 SYSCALL_DEFINE0(getegid16) 219 { 220 return high2lowgid(from_kgid_munged(cu 221 } 222
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.