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