1 /* $NetBSD: linux32_uid16.c,v 1.2 2008/11/19 18:36:04 ad Exp $ */
2 
3 /*-
4  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
5  * Copyright (c) 2008 Nicolas Joly, all rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Emmanuel Dreyfus
18  * 4. The name of the author may not be used to endorse or promote
19  *    products derived from this software without specific prior written
20  *    permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS''
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: linux32_uid16.c,v 1.2 2008/11/19 18:36:04 ad Exp $");
37 
38 #include <sys/param.h>
39 #include <sys/proc.h>
40 #include <sys/kauth.h>
41 
42 #include <compat/netbsd32/netbsd32.h>
43 
44 #include <compat/linux/common/linux_types.h>
45 #include <compat/linux/common/linux_signal.h>
46 #include <compat/linux/common/linux_ipc.h>
47 #include <compat/linux/common/linux_sem.h>
48 #include <compat/linux/linux_syscallargs.h>
49 
50 #include <compat/linux32/common/linux32_types.h>
51 #include <compat/linux32/common/linux32_signal.h>
52 #include <compat/linux32/common/linux32_machdep.h>
53 #include <compat/linux32/linux32_syscallargs.h>
54 
55 #define LINUX32TOBSD_UID(u) \
56 	(((u) == (linux32_uid16_t)-1) ? -1 : (u))
57 #define LINUX32TOBSD_GID(g) \
58 	(((g) == (linux32_gid16_t)-1) ? -1 : (g))
59 
60 #define BSDTOLINUX32_UID(u) \
61 	(((u) & ~0xffff) ? (linux32_uid16_t)65534 : (linux32_uid16_t)(u))
62 #define BSDTOLINUX32_GID(g) \
63 	(((g) & ~0xffff) ? (linux32_gid16_t)65534 : (linux32_gid16_t)(g))
64 
65 int
linux32_sys_chown16(struct lwp * l,const struct linux32_sys_chown16_args * uap,register_t * retval)66 linux32_sys_chown16(struct lwp *l, const struct linux32_sys_chown16_args *uap, register_t *retval)
67 {
68 	/* {
69 		syscallarg(const netbsd32_charp) path;
70 		syscallarg(linux32_uid16_t) uid;
71 		syscallarg(linux32_gid16_t) gid;
72 	} */
73         struct sys___posix_chown_args ua;
74 
75 	NETBSD32TOP_UAP(path, const char);
76 	SCARG(&ua, uid) = LINUX32TOBSD_UID(SCARG(uap, uid));
77 	SCARG(&ua, gid) = LINUX32TOBSD_GID(SCARG(uap, gid));
78 
79         return sys___posix_chown(l, &ua, retval);
80 }
81 
82 int
linux32_sys_lchown16(struct lwp * l,const struct linux32_sys_lchown16_args * uap,register_t * retval)83 linux32_sys_lchown16(struct lwp *l, const struct linux32_sys_lchown16_args *uap, register_t *retval)
84 {
85 	/* {
86 		syscallarg(const netbsd32_charp) path;
87 		syscallarg(linux32_uid16_t) uid;
88 		syscallarg(linux32_gid16_t) gid;
89 	} */
90 	struct sys___posix_lchown_args ua;
91 
92 	NETBSD32TOP_UAP(path, const char);
93 	SCARG(&ua, uid) = LINUX32TOBSD_UID(SCARG(uap, uid));
94 	SCARG(&ua, gid) = LINUX32TOBSD_GID(SCARG(uap, gid));
95 
96 	return sys___posix_lchown(l, &ua, retval);
97 }
98 
99 int
linux32_sys_fchown16(struct lwp * l,const struct linux32_sys_fchown16_args * uap,register_t * retval)100 linux32_sys_fchown16(struct lwp *l, const struct linux32_sys_fchown16_args *uap, register_t *retval)
101 {
102 	/* {
103 		syscallarg(int) fd;
104 		syscallarg(linux32_uid16_t) uid;
105 		syscallarg(linux32_gid16_t) gid;
106 	} */
107 	struct sys___posix_fchown_args ua;
108 
109 	SCARG(&ua, fd) = SCARG(uap, fd);
110 	SCARG(&ua, uid) = LINUX32TOBSD_UID(SCARG(uap, uid));
111 	SCARG(&ua, gid) = LINUX32TOBSD_GID(SCARG(uap, gid));
112 
113 	return sys___posix_fchown(l, &ua, retval);
114 }
115 
116 int
linux32_sys_getgroups16(struct lwp * l,const struct linux32_sys_getgroups16_args * uap,register_t * retval)117 linux32_sys_getgroups16(struct lwp *l, const struct linux32_sys_getgroups16_args *uap, register_t *retval)
118 {
119 	/* {
120 		syscallarg(int) gidsetsize;
121 		syscallarg(linux32_gid16p_t) gidset;
122 	} */
123 	struct linux_sys_getgroups16_args ua;
124 
125 	NETBSD32TO64_UAP(gidsetsize);
126 	NETBSD32TOP_UAP(gidset, linux_gid16_t);
127 
128 	return linux_sys_getgroups16(l, &ua, retval);
129 }
130 
131 int
linux32_sys_setgroups16(struct lwp * l,const struct linux32_sys_setgroups16_args * uap,register_t * retval)132 linux32_sys_setgroups16(struct lwp *l, const struct linux32_sys_setgroups16_args *uap, register_t *retval)
133 {
134 	/* {
135 		syscallarg(int) gidsetsize;
136 		syscallarg(linux32_gid16p_t) gidset;
137 	} */
138 	struct linux_sys_setgroups16_args ua;
139 
140 	NETBSD32TO64_UAP(gidsetsize);
141 	NETBSD32TOP_UAP(gidset, linux_gid16_t);
142 
143 	return linux_sys_setgroups16(l, &ua, retval);
144 }
145 
146 int
linux32_sys_setreuid16(struct lwp * l,const struct linux32_sys_setreuid16_args * uap,register_t * retval)147 linux32_sys_setreuid16(struct lwp *l, const struct linux32_sys_setreuid16_args *uap, register_t *retval)
148 {
149 	/* {
150 		syscallarg(linux32_uid16_t) ruid;
151 		syscallarg(linux32_uid16_t) euid;
152 	} */
153 	struct sys_setreuid_args bsa;
154 
155 	SCARG(&bsa, ruid) = LINUX32TOBSD_UID(SCARG(uap, ruid));
156 	SCARG(&bsa, euid) = LINUX32TOBSD_UID(SCARG(uap, euid));
157 
158 	return sys_setreuid(l, &bsa, retval);
159 }
160 
161 int
linux32_sys_setregid16(struct lwp * l,const struct linux32_sys_setregid16_args * uap,register_t * retval)162 linux32_sys_setregid16(struct lwp *l, const struct linux32_sys_setregid16_args *uap, register_t *retval)
163 {
164 	/* {
165 		syscallarg(linux32_gid16_t) rgid;
166 		syscallarg(linux32_gid16_t) egid;
167 	} */
168 	struct sys_setregid_args bsa;
169 
170 	SCARG(&bsa, rgid) = LINUX32TOBSD_GID(SCARG(uap, rgid));
171 	SCARG(&bsa, egid) = LINUX32TOBSD_GID(SCARG(uap, egid));
172 
173 	return sys_setregid(l, &bsa, retval);
174 }
175 
176 int
linux32_sys_setresuid16(struct lwp * l,const struct linux32_sys_setresuid16_args * uap,register_t * retval)177 linux32_sys_setresuid16(struct lwp *l, const struct linux32_sys_setresuid16_args *uap, register_t *retval)
178 {
179 	/* {
180 		syscallarg(linux32_uid16_t) ruid;
181 		syscallarg(linux32_uid16_t) euid;
182 		syscallarg(linux32_uid16_t) suid;
183 	} */
184 	struct linux32_sys_setresuid_args lsa;
185 
186 	SCARG(&lsa, ruid) = LINUX32TOBSD_UID(SCARG(uap, ruid));
187 	SCARG(&lsa, euid) = LINUX32TOBSD_UID(SCARG(uap, euid));
188 	SCARG(&lsa, suid) = LINUX32TOBSD_UID(SCARG(uap, suid));
189 
190 	return linux32_sys_setresuid(l, &lsa, retval);
191 }
192 
193 int
linux32_sys_setresgid16(struct lwp * l,const struct linux32_sys_setresgid16_args * uap,register_t * retval)194 linux32_sys_setresgid16(struct lwp *l, const struct linux32_sys_setresgid16_args *uap, register_t *retval)
195 {
196 	/* {
197 		syscallarg(linux32_gid16_t) rgid;
198 		syscallarg(linux32_gid16_t) egid;
199 		syscallarg(linux32_gid16_t) sgid;
200 	} */
201 	struct linux32_sys_setresgid_args lsa;
202 
203 	SCARG(&lsa, rgid) = LINUX32TOBSD_GID(SCARG(uap, rgid));
204 	SCARG(&lsa, egid) = LINUX32TOBSD_GID(SCARG(uap, egid));
205 	SCARG(&lsa, sgid) = LINUX32TOBSD_GID(SCARG(uap, sgid));
206 
207 	return linux32_sys_setresgid(l, &lsa, retval);
208 }
209 
210 int
linux32_sys_getresuid16(struct lwp * l,const struct linux32_sys_getresuid16_args * uap,register_t * retval)211 linux32_sys_getresuid16(struct lwp *l, const struct linux32_sys_getresuid16_args *uap, register_t *retval)
212 {
213 	/* {
214 		syscallarg(linux32_uid16p_t) ruid;
215 		syscallarg(linux32_uid16p_t) euid;
216 		syscallarg(linux32_uid16p_t) suid;
217 	} */
218 	kauth_cred_t pc = l->l_cred;
219 	int error;
220 	uid_t buid;
221 	linux32_uid16_t luid;
222 
223 	buid = kauth_cred_getuid(pc);
224 	luid = BSDTOLINUX32_UID(buid);
225 	if ((error = copyout(&luid, SCARG_P32(uap, ruid), sizeof(luid))) != 0)
226 		return error;
227 
228 	buid = kauth_cred_geteuid(pc);
229 	luid = BSDTOLINUX32_UID(buid);
230 	if ((error = copyout(&luid, SCARG_P32(uap, euid), sizeof(luid))) != 0)
231 		return error;
232 
233 	buid = kauth_cred_getsvuid(pc);
234 	luid = BSDTOLINUX32_UID(buid);
235 	return (copyout(&luid, SCARG_P32(uap, suid), sizeof(luid)));
236 }
237 
238 int
linux32_sys_getresgid16(struct lwp * l,const struct linux32_sys_getresgid16_args * uap,register_t * retval)239 linux32_sys_getresgid16(struct lwp *l, const struct linux32_sys_getresgid16_args *uap, register_t *retval)
240 {
241 	/* {
242 		syscallarg(linux32_gid16p_t) rgid;
243 		syscallarg(linux32_gid16p_t) egid;
244 		syscallarg(linux32_gid16p_t) sgid;
245 	} */
246 	kauth_cred_t pc = l->l_cred;
247 	int error;
248 	gid_t bgid;
249 	linux32_gid16_t lgid;
250 
251 	bgid = kauth_cred_getgid(pc);
252 	lgid = BSDTOLINUX32_GID(bgid);
253 	if ((error = copyout(&lgid, SCARG_P32(uap, rgid), sizeof(lgid))) != 0)
254 		return error;
255 
256 	bgid = kauth_cred_getegid(pc);
257 	lgid = BSDTOLINUX32_GID(bgid);
258 	if ((error = copyout(&lgid, SCARG_P32(uap, egid), sizeof(lgid))) != 0)
259 		return error;
260 
261 	bgid = kauth_cred_getsvgid(pc);
262 	lgid = BSDTOLINUX32_GID(bgid);
263 	return (copyout(&lgid, SCARG_P32(uap, sgid), sizeof(lgid)));
264 }
265