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