Deleted Added
full compact
linux_uid16.c (164033) linux_uid16.c (166944)
1/*-
2 * Copyright (c) 2001 The FreeBSD Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001 The FreeBSD Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/compat/linux/linux_uid16.c 164033 2006-11-06 13:42:10Z rwatson $");
28__FBSDID("$FreeBSD: head/sys/compat/linux/linux_uid16.c 166944 2007-02-24 16:49:25Z netchild $");
29
30#include "opt_compat.h"
31
32#include <sys/param.h>
33#include <sys/lock.h>
34#include <sys/malloc.h>
35#include <sys/mutex.h>
36#include <sys/priv.h>
37#include <sys/proc.h>
38#include <sys/syscallsubr.h>
39#include <sys/sysproto.h>
40#include <sys/systm.h>
41
42#ifdef COMPAT_LINUX32
43#include <machine/../linux32/linux.h>
44#include <machine/../linux32/linux32_proto.h>
45#else
46#include <machine/../linux/linux.h>
47#include <machine/../linux/linux_proto.h>
48#endif
49
50#include <compat/linux/linux_util.h>
51
52DUMMY(setfsuid16);
53DUMMY(setfsgid16);
54DUMMY(getresuid16);
55DUMMY(getresgid16);
56
57#define CAST_NOCHG(x) ((x == 0xFFFF) ? -1 : x)
58
59int
60linux_chown16(struct thread *td, struct linux_chown16_args *args)
61{
62 char *path;
63 int error;
64
65 LCONVPATHEXIST(td, args->path, &path);
66
67#ifdef DEBUG
68 if (ldebug(chown16))
69 printf(ARGS(chown16, "%s, %d, %d"), path, args->uid, args->gid);
70#endif
71 error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
72 CAST_NOCHG(args->gid));
73 LFREEPATH(path);
74 return (error);
75}
76
77int
78linux_lchown16(struct thread *td, struct linux_lchown16_args *args)
79{
80 char *path;
81 int error;
82
83 LCONVPATHEXIST(td, args->path, &path);
84
85#ifdef DEBUG
86 if (ldebug(lchown16))
87 printf(ARGS(lchown16, "%s, %d, %d"), path, args->uid,
88 args->gid);
89#endif
90 error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
91 CAST_NOCHG(args->gid));
92 LFREEPATH(path);
93 return (error);
94}
95
96int
97linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
98{
99 struct ucred *newcred, *oldcred;
100 l_gid16_t linux_gidset[NGROUPS];
101 gid_t *bsd_gidset;
102 int ngrp, error;
103 struct proc *p;
104
105#ifdef DEBUG
106 if (ldebug(setgroups16))
107 printf(ARGS(setgroups16, "%d, *"), args->gidsetsize);
108#endif
109
110 ngrp = args->gidsetsize;
111 if (ngrp < 0 || ngrp >= NGROUPS)
112 return (EINVAL);
113 error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
114 if (error)
115 return (error);
116 newcred = crget();
117 p = td->td_proc;
118 PROC_LOCK(p);
119 oldcred = p->p_ucred;
120
121 /*
122 * cr_groups[0] holds egid. Setting the whole set from
123 * the supplied set will cause egid to be changed too.
124 * Keep cr_groups[0] unchanged to prevent that.
125 */
126
127 if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS,
128 SUSER_ALLOWJAIL)) != 0) {
129 PROC_UNLOCK(p);
130 crfree(newcred);
131 return (error);
132 }
133
134 crcopy(newcred, oldcred);
135 if (ngrp > 0) {
136 newcred->cr_ngroups = ngrp + 1;
137
138 bsd_gidset = newcred->cr_groups;
139 ngrp--;
140 while (ngrp >= 0) {
141 bsd_gidset[ngrp + 1] = linux_gidset[ngrp];
142 ngrp--;
143 }
144 }
145 else
146 newcred->cr_ngroups = 1;
147
148 setsugid(td->td_proc);
149 p->p_ucred = newcred;
150 PROC_UNLOCK(p);
151 crfree(oldcred);
152 return (0);
153}
154
155int
156linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
157{
158 struct ucred *cred;
159 l_gid16_t linux_gidset[NGROUPS];
160 gid_t *bsd_gidset;
161 int bsd_gidsetsz, ngrp, error;
162
163#ifdef DEBUG
164 if (ldebug(getgroups16))
165 printf(ARGS(getgroups16, "%d, *"), args->gidsetsize);
166#endif
167
168 cred = td->td_ucred;
169 bsd_gidset = cred->cr_groups;
170 bsd_gidsetsz = cred->cr_ngroups - 1;
171
172 /*
173 * cr_groups[0] holds egid. Returning the whole set
174 * here will cause a duplicate. Exclude cr_groups[0]
175 * to prevent that.
176 */
177
178 if ((ngrp = args->gidsetsize) == 0) {
179 td->td_retval[0] = bsd_gidsetsz;
180 return (0);
181 }
182
183 if (ngrp < bsd_gidsetsz)
184 return (EINVAL);
185
186 ngrp = 0;
187 while (ngrp < bsd_gidsetsz) {
188 linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
189 ngrp++;
190 }
191
192 error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
193 if (error)
194 return (error);
195
196 td->td_retval[0] = ngrp;
197 return (0);
198}
199
200/*
201 * The FreeBSD native getgid(2) and getuid(2) also modify td->td_retval[1]
29
30#include "opt_compat.h"
31
32#include <sys/param.h>
33#include <sys/lock.h>
34#include <sys/malloc.h>
35#include <sys/mutex.h>
36#include <sys/priv.h>
37#include <sys/proc.h>
38#include <sys/syscallsubr.h>
39#include <sys/sysproto.h>
40#include <sys/systm.h>
41
42#ifdef COMPAT_LINUX32
43#include <machine/../linux32/linux.h>
44#include <machine/../linux32/linux32_proto.h>
45#else
46#include <machine/../linux/linux.h>
47#include <machine/../linux/linux_proto.h>
48#endif
49
50#include <compat/linux/linux_util.h>
51
52DUMMY(setfsuid16);
53DUMMY(setfsgid16);
54DUMMY(getresuid16);
55DUMMY(getresgid16);
56
57#define CAST_NOCHG(x) ((x == 0xFFFF) ? -1 : x)
58
59int
60linux_chown16(struct thread *td, struct linux_chown16_args *args)
61{
62 char *path;
63 int error;
64
65 LCONVPATHEXIST(td, args->path, &path);
66
67#ifdef DEBUG
68 if (ldebug(chown16))
69 printf(ARGS(chown16, "%s, %d, %d"), path, args->uid, args->gid);
70#endif
71 error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
72 CAST_NOCHG(args->gid));
73 LFREEPATH(path);
74 return (error);
75}
76
77int
78linux_lchown16(struct thread *td, struct linux_lchown16_args *args)
79{
80 char *path;
81 int error;
82
83 LCONVPATHEXIST(td, args->path, &path);
84
85#ifdef DEBUG
86 if (ldebug(lchown16))
87 printf(ARGS(lchown16, "%s, %d, %d"), path, args->uid,
88 args->gid);
89#endif
90 error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
91 CAST_NOCHG(args->gid));
92 LFREEPATH(path);
93 return (error);
94}
95
96int
97linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
98{
99 struct ucred *newcred, *oldcred;
100 l_gid16_t linux_gidset[NGROUPS];
101 gid_t *bsd_gidset;
102 int ngrp, error;
103 struct proc *p;
104
105#ifdef DEBUG
106 if (ldebug(setgroups16))
107 printf(ARGS(setgroups16, "%d, *"), args->gidsetsize);
108#endif
109
110 ngrp = args->gidsetsize;
111 if (ngrp < 0 || ngrp >= NGROUPS)
112 return (EINVAL);
113 error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
114 if (error)
115 return (error);
116 newcred = crget();
117 p = td->td_proc;
118 PROC_LOCK(p);
119 oldcred = p->p_ucred;
120
121 /*
122 * cr_groups[0] holds egid. Setting the whole set from
123 * the supplied set will cause egid to be changed too.
124 * Keep cr_groups[0] unchanged to prevent that.
125 */
126
127 if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS,
128 SUSER_ALLOWJAIL)) != 0) {
129 PROC_UNLOCK(p);
130 crfree(newcred);
131 return (error);
132 }
133
134 crcopy(newcred, oldcred);
135 if (ngrp > 0) {
136 newcred->cr_ngroups = ngrp + 1;
137
138 bsd_gidset = newcred->cr_groups;
139 ngrp--;
140 while (ngrp >= 0) {
141 bsd_gidset[ngrp + 1] = linux_gidset[ngrp];
142 ngrp--;
143 }
144 }
145 else
146 newcred->cr_ngroups = 1;
147
148 setsugid(td->td_proc);
149 p->p_ucred = newcred;
150 PROC_UNLOCK(p);
151 crfree(oldcred);
152 return (0);
153}
154
155int
156linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
157{
158 struct ucred *cred;
159 l_gid16_t linux_gidset[NGROUPS];
160 gid_t *bsd_gidset;
161 int bsd_gidsetsz, ngrp, error;
162
163#ifdef DEBUG
164 if (ldebug(getgroups16))
165 printf(ARGS(getgroups16, "%d, *"), args->gidsetsize);
166#endif
167
168 cred = td->td_ucred;
169 bsd_gidset = cred->cr_groups;
170 bsd_gidsetsz = cred->cr_ngroups - 1;
171
172 /*
173 * cr_groups[0] holds egid. Returning the whole set
174 * here will cause a duplicate. Exclude cr_groups[0]
175 * to prevent that.
176 */
177
178 if ((ngrp = args->gidsetsize) == 0) {
179 td->td_retval[0] = bsd_gidsetsz;
180 return (0);
181 }
182
183 if (ngrp < bsd_gidsetsz)
184 return (EINVAL);
185
186 ngrp = 0;
187 while (ngrp < bsd_gidsetsz) {
188 linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
189 ngrp++;
190 }
191
192 error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
193 if (error)
194 return (error);
195
196 td->td_retval[0] = ngrp;
197 return (0);
198}
199
200/*
201 * The FreeBSD native getgid(2) and getuid(2) also modify td->td_retval[1]
202 * when COMPAT_43 is defined. This globbers registers that
203 * are assumed to be preserved. The following lightweight syscalls fixes
204 * this. See also linux_getpid(2), linux_getgid(2) and linux_getuid(2) in
205 * linux_misc.c
202 * when COMPAT_43 is defined. This clobbers registers that are assumed to
203 * be preserved. The following lightweight syscalls fixes this. See also
204 * linux_getpid(2), linux_getgid(2) and linux_getuid(2) in linux_misc.c
206 *
207 * linux_getgid16() - MP SAFE
208 * linux_getuid16() - MP SAFE
209 */
210
211int
212linux_getgid16(struct thread *td, struct linux_getgid16_args *args)
213{
214
215 td->td_retval[0] = td->td_ucred->cr_rgid;
216 return (0);
217}
218
219int
220linux_getuid16(struct thread *td, struct linux_getuid16_args *args)
221{
222
223 td->td_retval[0] = td->td_ucred->cr_ruid;
224 return (0);
225}
226
227int
228linux_getegid16(struct thread *td, struct linux_getegid16_args *args)
229{
230 struct getegid_args bsd;
231
232 return (getegid(td, &bsd));
233}
234
235int
236linux_geteuid16(struct thread *td, struct linux_geteuid16_args *args)
237{
238 struct geteuid_args bsd;
239
240 return (geteuid(td, &bsd));
241}
242
243int
244linux_setgid16(struct thread *td, struct linux_setgid16_args *args)
245{
246 struct setgid_args bsd;
247
248 bsd.gid = args->gid;
249 return (setgid(td, &bsd));
250}
251
252int
253linux_setuid16(struct thread *td, struct linux_setuid16_args *args)
254{
255 struct setuid_args bsd;
256
257 bsd.uid = args->uid;
258 return (setuid(td, &bsd));
259}
260
261int
262linux_setregid16(struct thread *td, struct linux_setregid16_args *args)
263{
264 struct setregid_args bsd;
265
266 bsd.rgid = CAST_NOCHG(args->rgid);
267 bsd.egid = CAST_NOCHG(args->egid);
268 return (setregid(td, &bsd));
269}
270
271int
272linux_setreuid16(struct thread *td, struct linux_setreuid16_args *args)
273{
274 struct setreuid_args bsd;
275
276 bsd.ruid = CAST_NOCHG(args->ruid);
277 bsd.euid = CAST_NOCHG(args->euid);
278 return (setreuid(td, &bsd));
279}
280
281int
282linux_setresgid16(struct thread *td, struct linux_setresgid16_args *args)
283{
284 struct setresgid_args bsd;
285
286 bsd.rgid = CAST_NOCHG(args->rgid);
287 bsd.egid = CAST_NOCHG(args->egid);
288 bsd.sgid = CAST_NOCHG(args->sgid);
289 return (setresgid(td, &bsd));
290}
291
292int
293linux_setresuid16(struct thread *td, struct linux_setresuid16_args *args)
294{
295 struct setresuid_args bsd;
296
297 bsd.ruid = CAST_NOCHG(args->ruid);
298 bsd.euid = CAST_NOCHG(args->euid);
299 bsd.suid = CAST_NOCHG(args->suid);
300 return (setresuid(td, &bsd));
301}
205 *
206 * linux_getgid16() - MP SAFE
207 * linux_getuid16() - MP SAFE
208 */
209
210int
211linux_getgid16(struct thread *td, struct linux_getgid16_args *args)
212{
213
214 td->td_retval[0] = td->td_ucred->cr_rgid;
215 return (0);
216}
217
218int
219linux_getuid16(struct thread *td, struct linux_getuid16_args *args)
220{
221
222 td->td_retval[0] = td->td_ucred->cr_ruid;
223 return (0);
224}
225
226int
227linux_getegid16(struct thread *td, struct linux_getegid16_args *args)
228{
229 struct getegid_args bsd;
230
231 return (getegid(td, &bsd));
232}
233
234int
235linux_geteuid16(struct thread *td, struct linux_geteuid16_args *args)
236{
237 struct geteuid_args bsd;
238
239 return (geteuid(td, &bsd));
240}
241
242int
243linux_setgid16(struct thread *td, struct linux_setgid16_args *args)
244{
245 struct setgid_args bsd;
246
247 bsd.gid = args->gid;
248 return (setgid(td, &bsd));
249}
250
251int
252linux_setuid16(struct thread *td, struct linux_setuid16_args *args)
253{
254 struct setuid_args bsd;
255
256 bsd.uid = args->uid;
257 return (setuid(td, &bsd));
258}
259
260int
261linux_setregid16(struct thread *td, struct linux_setregid16_args *args)
262{
263 struct setregid_args bsd;
264
265 bsd.rgid = CAST_NOCHG(args->rgid);
266 bsd.egid = CAST_NOCHG(args->egid);
267 return (setregid(td, &bsd));
268}
269
270int
271linux_setreuid16(struct thread *td, struct linux_setreuid16_args *args)
272{
273 struct setreuid_args bsd;
274
275 bsd.ruid = CAST_NOCHG(args->ruid);
276 bsd.euid = CAST_NOCHG(args->euid);
277 return (setreuid(td, &bsd));
278}
279
280int
281linux_setresgid16(struct thread *td, struct linux_setresgid16_args *args)
282{
283 struct setresgid_args bsd;
284
285 bsd.rgid = CAST_NOCHG(args->rgid);
286 bsd.egid = CAST_NOCHG(args->egid);
287 bsd.sgid = CAST_NOCHG(args->sgid);
288 return (setresgid(td, &bsd));
289}
290
291int
292linux_setresuid16(struct thread *td, struct linux_setresuid16_args *args)
293{
294 struct setresuid_args bsd;
295
296 bsd.ruid = CAST_NOCHG(args->ruid);
297 bsd.euid = CAST_NOCHG(args->euid);
298 bsd.suid = CAST_NOCHG(args->suid);
299 return (setresuid(td, &bsd));
300}