]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 LT |
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> | |
1da177e4 | 8 | #include <linux/mman.h> |
1da177e4 LT |
9 | #include <linux/notifier.h> |
10 | #include <linux/reboot.h> | |
11 | #include <linux/prctl.h> | |
c59ede7b | 12 | #include <linux/capability.h> |
1da177e4 LT |
13 | #include <linux/init.h> |
14 | #include <linux/highuid.h> | |
15 | #include <linux/security.h> | |
5b825c3a | 16 | #include <linux/cred.h> |
1da177e4 LT |
17 | #include <linux/syscalls.h> |
18 | ||
7c0f6ba6 | 19 | #include <linux/uaccess.h> |
1da177e4 | 20 | |
e530dca5 DB |
21 | #include "uid16.h" |
22 | ||
ca013e94 | 23 | SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) |
1da177e4 | 24 | { |
55731b3c | 25 | return ksys_chown(filename, low2highuid(user), low2highgid(group)); |
1da177e4 LT |
26 | } |
27 | ||
ca013e94 | 28 | SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) |
1da177e4 | 29 | { |
55731b3c | 30 | return ksys_lchown(filename, low2highuid(user), low2highgid(group)); |
1da177e4 LT |
31 | } |
32 | ||
ca013e94 | 33 | SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group) |
1da177e4 | 34 | { |
55731b3c | 35 | return ksys_fchown(fd, low2highuid(user), low2highgid(group)); |
1da177e4 LT |
36 | } |
37 | ||
a6b42e83 | 38 | SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid) |
1da177e4 | 39 | { |
e530dca5 | 40 | return __sys_setregid(low2highgid(rgid), low2highgid(egid)); |
1da177e4 LT |
41 | } |
42 | ||
a6b42e83 | 43 | SYSCALL_DEFINE1(setgid16, old_gid_t, gid) |
1da177e4 | 44 | { |
e530dca5 | 45 | return __sys_setgid(low2highgid(gid)); |
1da177e4 LT |
46 | } |
47 | ||
a6b42e83 | 48 | SYSCALL_DEFINE2(setreuid16, old_uid_t, ruid, old_uid_t, euid) |
1da177e4 | 49 | { |
e530dca5 | 50 | return __sys_setreuid(low2highuid(ruid), low2highuid(euid)); |
1da177e4 LT |
51 | } |
52 | ||
a6b42e83 | 53 | SYSCALL_DEFINE1(setuid16, old_uid_t, uid) |
1da177e4 | 54 | { |
e530dca5 | 55 | return __sys_setuid(low2highuid(uid)); |
1da177e4 LT |
56 | } |
57 | ||
a6b42e83 | 58 | SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid) |
1da177e4 | 59 | { |
e530dca5 | 60 | return __sys_setresuid(low2highuid(ruid), low2highuid(euid), |
5a7b46b3 | 61 | low2highuid(suid)); |
1da177e4 LT |
62 | } |
63 | ||
a29c33f4 | 64 | SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruidp, old_uid_t __user *, euidp, old_uid_t __user *, suidp) |
1da177e4 | 65 | { |
86a264ab | 66 | const struct cred *cred = current_cred(); |
1da177e4 | 67 | int retval; |
a29c33f4 | 68 | old_uid_t ruid, euid, suid; |
1da177e4 | 69 | |
a29c33f4 EB |
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); | |
1da177e4 LT |
77 | |
78 | return retval; | |
79 | } | |
80 | ||
a6b42e83 | 81 | SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid) |
1da177e4 | 82 | { |
e530dca5 | 83 | return __sys_setresgid(low2highgid(rgid), low2highgid(egid), |
5a7b46b3 | 84 | low2highgid(sgid)); |
1da177e4 LT |
85 | } |
86 | ||
a29c33f4 | 87 | SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgidp, old_gid_t __user *, egidp, old_gid_t __user *, sgidp) |
1da177e4 | 88 | { |
86a264ab | 89 | const struct cred *cred = current_cred(); |
1da177e4 | 90 | int retval; |
a29c33f4 EB |
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)); | |
1da177e4 | 96 | |
a29c33f4 EB |
97 | if (!(retval = put_user(rgid, rgidp)) && |
98 | !(retval = put_user(egid, egidp))) | |
99 | retval = put_user(sgid, sgidp); | |
1da177e4 LT |
100 | |
101 | return retval; | |
102 | } | |
103 | ||
a6b42e83 | 104 | SYSCALL_DEFINE1(setfsuid16, old_uid_t, uid) |
1da177e4 | 105 | { |
e530dca5 | 106 | return __sys_setfsuid(low2highuid(uid)); |
1da177e4 LT |
107 | } |
108 | ||
a6b42e83 | 109 | SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid) |
1da177e4 | 110 | { |
e530dca5 | 111 | return __sys_setfsgid(low2highgid(gid)); |
1da177e4 LT |
112 | } |
113 | ||
114 | static int groups16_to_user(old_gid_t __user *grouplist, | |
115 | struct group_info *group_info) | |
116 | { | |
ae2975bc | 117 | struct user_namespace *user_ns = current_user_ns(); |
1da177e4 LT |
118 | int i; |
119 | old_gid_t group; | |
ae2975bc | 120 | kgid_t kgid; |
1da177e4 LT |
121 | |
122 | for (i = 0; i < group_info->ngroups; i++) { | |
81243eac | 123 | kgid = group_info->gid[i]; |
ae2975bc | 124 | group = high2lowgid(from_kgid_munged(user_ns, kgid)); |
1da177e4 LT |
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 | { | |
ae2975bc | 135 | struct user_namespace *user_ns = current_user_ns(); |
1da177e4 LT |
136 | int i; |
137 | old_gid_t group; | |
ae2975bc | 138 | kgid_t kgid; |
1da177e4 LT |
139 | |
140 | for (i = 0; i < group_info->ngroups; i++) { | |
141 | if (get_user(group, grouplist+i)) | |
142 | return -EFAULT; | |
ae2975bc EB |
143 | |
144 | kgid = make_kgid(user_ns, low2highgid(group)); | |
145 | if (!gid_valid(kgid)) | |
146 | return -EINVAL; | |
147 | ||
81243eac | 148 | group_info->gid[i] = kgid; |
1da177e4 LT |
149 | } |
150 | ||
151 | return 0; | |
152 | } | |
153 | ||
003d7ab4 | 154 | SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist) |
1da177e4 | 155 | { |
86a264ab DH |
156 | const struct cred *cred = current_cred(); |
157 | int i; | |
1da177e4 LT |
158 | |
159 | if (gidsetsize < 0) | |
160 | return -EINVAL; | |
161 | ||
86a264ab | 162 | i = cred->group_info->ngroups; |
1da177e4 LT |
163 | if (gidsetsize) { |
164 | if (i > gidsetsize) { | |
165 | i = -EINVAL; | |
166 | goto out; | |
167 | } | |
86a264ab | 168 | if (groups16_to_user(grouplist, cred->group_info)) { |
1da177e4 LT |
169 | i = -EFAULT; |
170 | goto out; | |
171 | } | |
172 | } | |
173 | out: | |
1da177e4 LT |
174 | return i; |
175 | } | |
176 | ||
003d7ab4 | 177 | SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) |
1da177e4 LT |
178 | { |
179 | struct group_info *group_info; | |
180 | int retval; | |
181 | ||
7ff4d90b | 182 | if (!may_setgroups()) |
1da177e4 LT |
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 | ||
bdcf0a42 | 196 | groups_sort(group_info); |
1da177e4 LT |
197 | retval = set_current_groups(group_info); |
198 | put_group_info(group_info); | |
199 | ||
200 | return retval; | |
201 | } | |
202 | ||
003d7ab4 | 203 | SYSCALL_DEFINE0(getuid16) |
1da177e4 | 204 | { |
a29c33f4 | 205 | return high2lowuid(from_kuid_munged(current_user_ns(), current_uid())); |
1da177e4 LT |
206 | } |
207 | ||
003d7ab4 | 208 | SYSCALL_DEFINE0(geteuid16) |
1da177e4 | 209 | { |
a29c33f4 | 210 | return high2lowuid(from_kuid_munged(current_user_ns(), current_euid())); |
1da177e4 LT |
211 | } |
212 | ||
003d7ab4 | 213 | SYSCALL_DEFINE0(getgid16) |
1da177e4 | 214 | { |
a29c33f4 | 215 | return high2lowgid(from_kgid_munged(current_user_ns(), current_gid())); |
1da177e4 LT |
216 | } |
217 | ||
003d7ab4 | 218 | SYSCALL_DEFINE0(getegid16) |
1da177e4 | 219 | { |
a29c33f4 | 220 | return high2lowgid(from_kgid_munged(current_user_ns(), current_egid())); |
1da177e4 | 221 | } |