| .. | .. |
|---|
| 34 | 34 | #include <linux/stat.h> |
|---|
| 35 | 35 | #include <linux/filter.h> |
|---|
| 36 | 36 | #include <linux/highmem.h> |
|---|
| 37 | | -#include <linux/highuid.h> |
|---|
| 38 | 37 | #include <linux/mman.h> |
|---|
| 39 | 38 | #include <linux/ipv6.h> |
|---|
| 40 | 39 | #include <linux/in.h> |
|---|
| .. | .. |
|---|
| 58 | 57 | |
|---|
| 59 | 58 | #include "compat_linux.h" |
|---|
| 60 | 59 | |
|---|
| 61 | | -/* For this source file, we want overflow handling. */ |
|---|
| 62 | | - |
|---|
| 63 | | -#undef high2lowuid |
|---|
| 64 | | -#undef high2lowgid |
|---|
| 65 | | -#undef low2highuid |
|---|
| 66 | | -#undef low2highgid |
|---|
| 67 | | -#undef SET_UID16 |
|---|
| 68 | | -#undef SET_GID16 |
|---|
| 69 | | -#undef NEW_TO_OLD_UID |
|---|
| 70 | | -#undef NEW_TO_OLD_GID |
|---|
| 71 | | -#undef SET_OLDSTAT_UID |
|---|
| 72 | | -#undef SET_OLDSTAT_GID |
|---|
| 73 | | -#undef SET_STAT_UID |
|---|
| 74 | | -#undef SET_STAT_GID |
|---|
| 75 | | - |
|---|
| 76 | | -#define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) |
|---|
| 77 | | -#define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) |
|---|
| 78 | | -#define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) |
|---|
| 79 | | -#define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) |
|---|
| 80 | | -#define SET_UID16(var, uid) var = high2lowuid(uid) |
|---|
| 81 | | -#define SET_GID16(var, gid) var = high2lowgid(gid) |
|---|
| 82 | | -#define NEW_TO_OLD_UID(uid) high2lowuid(uid) |
|---|
| 83 | | -#define NEW_TO_OLD_GID(gid) high2lowgid(gid) |
|---|
| 84 | | -#define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) |
|---|
| 85 | | -#define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) |
|---|
| 86 | | -#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) |
|---|
| 87 | | -#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) |
|---|
| 88 | | - |
|---|
| 89 | | -COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename, |
|---|
| 90 | | - u16, user, u16, group) |
|---|
| 91 | | -{ |
|---|
| 92 | | - return ksys_chown(filename, low2highuid(user), low2highgid(group)); |
|---|
| 93 | | -} |
|---|
| 94 | | - |
|---|
| 95 | | -COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *, |
|---|
| 96 | | - filename, u16, user, u16, group) |
|---|
| 97 | | -{ |
|---|
| 98 | | - return ksys_lchown(filename, low2highuid(user), low2highgid(group)); |
|---|
| 99 | | -} |
|---|
| 100 | | - |
|---|
| 101 | | -COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group) |
|---|
| 102 | | -{ |
|---|
| 103 | | - return ksys_fchown(fd, low2highuid(user), low2highgid(group)); |
|---|
| 104 | | -} |
|---|
| 105 | | - |
|---|
| 106 | | -COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid) |
|---|
| 107 | | -{ |
|---|
| 108 | | - return sys_setregid(low2highgid(rgid), low2highgid(egid)); |
|---|
| 109 | | -} |
|---|
| 110 | | - |
|---|
| 111 | | -COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid) |
|---|
| 112 | | -{ |
|---|
| 113 | | - return sys_setgid(low2highgid(gid)); |
|---|
| 114 | | -} |
|---|
| 115 | | - |
|---|
| 116 | | -COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid) |
|---|
| 117 | | -{ |
|---|
| 118 | | - return sys_setreuid(low2highuid(ruid), low2highuid(euid)); |
|---|
| 119 | | -} |
|---|
| 120 | | - |
|---|
| 121 | | -COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid) |
|---|
| 122 | | -{ |
|---|
| 123 | | - return sys_setuid(low2highuid(uid)); |
|---|
| 124 | | -} |
|---|
| 125 | | - |
|---|
| 126 | | -COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid) |
|---|
| 127 | | -{ |
|---|
| 128 | | - return sys_setresuid(low2highuid(ruid), low2highuid(euid), |
|---|
| 129 | | - low2highuid(suid)); |
|---|
| 130 | | -} |
|---|
| 131 | | - |
|---|
| 132 | | -COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp, |
|---|
| 133 | | - u16 __user *, euidp, u16 __user *, suidp) |
|---|
| 134 | | -{ |
|---|
| 135 | | - const struct cred *cred = current_cred(); |
|---|
| 136 | | - int retval; |
|---|
| 137 | | - u16 ruid, euid, suid; |
|---|
| 138 | | - |
|---|
| 139 | | - ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid)); |
|---|
| 140 | | - euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid)); |
|---|
| 141 | | - suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid)); |
|---|
| 142 | | - |
|---|
| 143 | | - if (!(retval = put_user(ruid, ruidp)) && |
|---|
| 144 | | - !(retval = put_user(euid, euidp))) |
|---|
| 145 | | - retval = put_user(suid, suidp); |
|---|
| 146 | | - |
|---|
| 147 | | - return retval; |
|---|
| 148 | | -} |
|---|
| 149 | | - |
|---|
| 150 | | -COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid) |
|---|
| 151 | | -{ |
|---|
| 152 | | - return sys_setresgid(low2highgid(rgid), low2highgid(egid), |
|---|
| 153 | | - low2highgid(sgid)); |
|---|
| 154 | | -} |
|---|
| 155 | | - |
|---|
| 156 | | -COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp, |
|---|
| 157 | | - u16 __user *, egidp, u16 __user *, sgidp) |
|---|
| 158 | | -{ |
|---|
| 159 | | - const struct cred *cred = current_cred(); |
|---|
| 160 | | - int retval; |
|---|
| 161 | | - u16 rgid, egid, sgid; |
|---|
| 162 | | - |
|---|
| 163 | | - rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid)); |
|---|
| 164 | | - egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid)); |
|---|
| 165 | | - sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid)); |
|---|
| 166 | | - |
|---|
| 167 | | - if (!(retval = put_user(rgid, rgidp)) && |
|---|
| 168 | | - !(retval = put_user(egid, egidp))) |
|---|
| 169 | | - retval = put_user(sgid, sgidp); |
|---|
| 170 | | - |
|---|
| 171 | | - return retval; |
|---|
| 172 | | -} |
|---|
| 173 | | - |
|---|
| 174 | | -COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid) |
|---|
| 175 | | -{ |
|---|
| 176 | | - return sys_setfsuid(low2highuid(uid)); |
|---|
| 177 | | -} |
|---|
| 178 | | - |
|---|
| 179 | | -COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid) |
|---|
| 180 | | -{ |
|---|
| 181 | | - return sys_setfsgid(low2highgid(gid)); |
|---|
| 182 | | -} |
|---|
| 183 | | - |
|---|
| 184 | | -static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info) |
|---|
| 185 | | -{ |
|---|
| 186 | | - struct user_namespace *user_ns = current_user_ns(); |
|---|
| 187 | | - int i; |
|---|
| 188 | | - u16 group; |
|---|
| 189 | | - kgid_t kgid; |
|---|
| 190 | | - |
|---|
| 191 | | - for (i = 0; i < group_info->ngroups; i++) { |
|---|
| 192 | | - kgid = group_info->gid[i]; |
|---|
| 193 | | - group = (u16)from_kgid_munged(user_ns, kgid); |
|---|
| 194 | | - if (put_user(group, grouplist+i)) |
|---|
| 195 | | - return -EFAULT; |
|---|
| 196 | | - } |
|---|
| 197 | | - |
|---|
| 198 | | - return 0; |
|---|
| 199 | | -} |
|---|
| 200 | | - |
|---|
| 201 | | -static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist) |
|---|
| 202 | | -{ |
|---|
| 203 | | - struct user_namespace *user_ns = current_user_ns(); |
|---|
| 204 | | - int i; |
|---|
| 205 | | - u16 group; |
|---|
| 206 | | - kgid_t kgid; |
|---|
| 207 | | - |
|---|
| 208 | | - for (i = 0; i < group_info->ngroups; i++) { |
|---|
| 209 | | - if (get_user(group, grouplist+i)) |
|---|
| 210 | | - return -EFAULT; |
|---|
| 211 | | - |
|---|
| 212 | | - kgid = make_kgid(user_ns, (gid_t)group); |
|---|
| 213 | | - if (!gid_valid(kgid)) |
|---|
| 214 | | - return -EINVAL; |
|---|
| 215 | | - |
|---|
| 216 | | - group_info->gid[i] = kgid; |
|---|
| 217 | | - } |
|---|
| 218 | | - |
|---|
| 219 | | - return 0; |
|---|
| 220 | | -} |
|---|
| 221 | | - |
|---|
| 222 | | -COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist) |
|---|
| 223 | | -{ |
|---|
| 224 | | - const struct cred *cred = current_cred(); |
|---|
| 225 | | - int i; |
|---|
| 226 | | - |
|---|
| 227 | | - if (gidsetsize < 0) |
|---|
| 228 | | - return -EINVAL; |
|---|
| 229 | | - |
|---|
| 230 | | - get_group_info(cred->group_info); |
|---|
| 231 | | - i = cred->group_info->ngroups; |
|---|
| 232 | | - if (gidsetsize) { |
|---|
| 233 | | - if (i > gidsetsize) { |
|---|
| 234 | | - i = -EINVAL; |
|---|
| 235 | | - goto out; |
|---|
| 236 | | - } |
|---|
| 237 | | - if (groups16_to_user(grouplist, cred->group_info)) { |
|---|
| 238 | | - i = -EFAULT; |
|---|
| 239 | | - goto out; |
|---|
| 240 | | - } |
|---|
| 241 | | - } |
|---|
| 242 | | -out: |
|---|
| 243 | | - put_group_info(cred->group_info); |
|---|
| 244 | | - return i; |
|---|
| 245 | | -} |
|---|
| 246 | | - |
|---|
| 247 | | -COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist) |
|---|
| 248 | | -{ |
|---|
| 249 | | - struct group_info *group_info; |
|---|
| 250 | | - int retval; |
|---|
| 251 | | - |
|---|
| 252 | | - if (!may_setgroups()) |
|---|
| 253 | | - return -EPERM; |
|---|
| 254 | | - if ((unsigned)gidsetsize > NGROUPS_MAX) |
|---|
| 255 | | - return -EINVAL; |
|---|
| 256 | | - |
|---|
| 257 | | - group_info = groups_alloc(gidsetsize); |
|---|
| 258 | | - if (!group_info) |
|---|
| 259 | | - return -ENOMEM; |
|---|
| 260 | | - retval = groups16_from_user(group_info, grouplist); |
|---|
| 261 | | - if (retval) { |
|---|
| 262 | | - put_group_info(group_info); |
|---|
| 263 | | - return retval; |
|---|
| 264 | | - } |
|---|
| 265 | | - |
|---|
| 266 | | - groups_sort(group_info); |
|---|
| 267 | | - retval = set_current_groups(group_info); |
|---|
| 268 | | - put_group_info(group_info); |
|---|
| 269 | | - |
|---|
| 270 | | - return retval; |
|---|
| 271 | | -} |
|---|
| 272 | | - |
|---|
| 273 | | -COMPAT_SYSCALL_DEFINE0(s390_getuid16) |
|---|
| 274 | | -{ |
|---|
| 275 | | - return high2lowuid(from_kuid_munged(current_user_ns(), current_uid())); |
|---|
| 276 | | -} |
|---|
| 277 | | - |
|---|
| 278 | | -COMPAT_SYSCALL_DEFINE0(s390_geteuid16) |
|---|
| 279 | | -{ |
|---|
| 280 | | - return high2lowuid(from_kuid_munged(current_user_ns(), current_euid())); |
|---|
| 281 | | -} |
|---|
| 282 | | - |
|---|
| 283 | | -COMPAT_SYSCALL_DEFINE0(s390_getgid16) |
|---|
| 284 | | -{ |
|---|
| 285 | | - return high2lowgid(from_kgid_munged(current_user_ns(), current_gid())); |
|---|
| 286 | | -} |
|---|
| 287 | | - |
|---|
| 288 | | -COMPAT_SYSCALL_DEFINE0(s390_getegid16) |
|---|
| 289 | | -{ |
|---|
| 290 | | - return high2lowgid(from_kgid_munged(current_user_ns(), current_egid())); |
|---|
| 291 | | -} |
|---|
| 292 | | - |
|---|
| 293 | 60 | #ifdef CONFIG_SYSVIPC |
|---|
| 294 | 61 | COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, |
|---|
| 295 | 62 | compat_ulong_t, third, compat_uptr_t, ptr) |
|---|
| 296 | 63 | { |
|---|
| 297 | 64 | if (call >> 16) /* hack for backward compatibility */ |
|---|
| 298 | 65 | return -EINVAL; |
|---|
| 299 | | - return compat_sys_ipc(call, first, second, third, ptr, third); |
|---|
| 66 | + return compat_ksys_ipc(call, first, second, third, ptr, third); |
|---|
| 300 | 67 | } |
|---|
| 301 | 68 | #endif |
|---|
| 302 | 69 | |
|---|