1 /* 2 * Wrapper functions for 16bit uid back compatibility. All nicely tied 3 * together in the faint hope we can take the out in five years time. 4 */ 5 6 #include <linux/mm.h> 7 #include <linux/utsname.h> 8 #include <linux/mman.h> 9 #include <linux/smp_lock.h> 10 #include <linux/notifier.h> 11 #include <linux/reboot.h> 12 #include <linux/prctl.h> 13 #include <linux/capability.h> 14 #include <linux/init.h> 15 #include <linux/highuid.h> 16 #include <linux/security.h> 17 #include <linux/syscalls.h> 18 19 #include <asm/uaccess.h> 20 21 asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) 22 { 23 return sys_chown(filename, low2highuid(user), low2highgid(group)); 24 } 25 26 asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) 27 { 28 return sys_lchown(filename, low2highuid(user), low2highgid(group)); 29 } 30 31 asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) 32 { 33 return sys_fchown(fd, low2highuid(user), low2highgid(group)); 34 } 35 36 asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) 37 { 38 return sys_setregid(low2highgid(rgid), low2highgid(egid)); 39 } 40 41 asmlinkage long sys_setgid16(old_gid_t gid) 42 { 43 return sys_setgid(low2highgid(gid)); 44 } 45 46 asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) 47 { 48 return sys_setreuid(low2highuid(ruid), low2highuid(euid)); 49 } 50 51 asmlinkage long sys_setuid16(old_uid_t uid) 52 { 53 return sys_setuid(low2highuid(uid)); 54 } 55 56 asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) 57 { 58 return sys_setresuid(low2highuid(ruid), low2highuid(euid), 59 low2highuid(suid)); 60 } 61 62 asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) 63 { 64 int retval; 65 66 if (!(retval = put_user(high2lowuid(current->uid), ruid)) && 67 !(retval = put_user(high2lowuid(current->euid), euid))) 68 retval = put_user(high2lowuid(current->suid), suid); 69 70 return retval; 71 } 72 73 asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) 74 { 75 return sys_setresgid(low2highgid(rgid), low2highgid(egid), 76 low2highgid(sgid)); 77 } 78 79 asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) 80 { 81 int retval; 82 83 if (!(retval = put_user(high2lowgid(current->gid), rgid)) && 84 !(retval = put_user(high2lowgid(current->egid), egid))) 85 retval = put_user(high2lowgid(current->sgid), sgid); 86 87 return retval; 88 } 89 90 asmlinkage long sys_setfsuid16(old_uid_t uid) 91 { 92 return sys_setfsuid(low2highuid(uid)); 93 } 94 95 asmlinkage long sys_setfsgid16(old_gid_t gid) 96 { 97 return sys_setfsgid(low2highgid(gid)); 98 } 99 100 static int groups16_to_user(old_gid_t __user *grouplist, 101 struct group_info *group_info) 102 { 103 int i; 104 old_gid_t group; 105 106 for (i = 0; i < group_info->ngroups; i++) { 107 group = high2lowgid(GROUP_AT(group_info, i)); 108 if (put_user(group, grouplist+i)) 109 return -EFAULT; 110 } 111 112 return 0; 113 } 114 115 static int groups16_from_user(struct group_info *group_info, 116 old_gid_t __user *grouplist) 117 { 118 int i; 119 old_gid_t group; 120 121 for (i = 0; i < group_info->ngroups; i++) { 122 if (get_user(group, grouplist+i)) 123 return -EFAULT; 124 GROUP_AT(group_info, i) = low2highgid(group); 125 } 126 127 return 0; 128 } 129 130 asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist) 131 { 132 int i = 0; 133 134 if (gidsetsize < 0) 135 return -EINVAL; 136 137 get_group_info(current->group_info); 138 i = current->group_info->ngroups; 139 if (gidsetsize) { 140 if (i > gidsetsize) { 141 i = -EINVAL; 142 goto out; 143 } 144 if (groups16_to_user(grouplist, current->group_info)) { 145 i = -EFAULT; 146 goto out; 147 } 148 } 149 out: 150 put_group_info(current->group_info); 151 return i; 152 } 153 154 asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist) 155 { 156 struct group_info *group_info; 157 int retval; 158 159 if (!capable(CAP_SETGID)) 160 return -EPERM; 161 if ((unsigned)gidsetsize > NGROUPS_MAX) 162 return -EINVAL; 163 164 group_info = groups_alloc(gidsetsize); 165 if (!group_info) 166 return -ENOMEM; 167 retval = groups16_from_user(group_info, grouplist); 168 if (retval) { 169 put_group_info(group_info); 170 return retval; 171 } 172 173 retval = set_current_groups(group_info); 174 put_group_info(group_info); 175 176 return retval; 177 } 178 179 asmlinkage long sys_getuid16(void) 180 { 181 return high2lowuid(current->uid); 182 } 183 184 asmlinkage long sys_geteuid16(void) 185 { 186 return high2lowuid(current->euid); 187 } 188 189 asmlinkage long sys_getgid16(void) 190 { 191 return high2lowgid(current->gid); 192 } 193 194 asmlinkage long sys_getegid16(void) 195 { 196 return high2lowgid(current->egid); 197 } 198