[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/linux/linux_uid16.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  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: src/sys/compat/linux/linux_uid16.c,v 1.23 2008/03/31 12:01:19 kib Exp $");
 29 
 30 #include "opt_compat.h"
 31 
 32 #include <sys/fcntl.h>
 33 #include <sys/param.h>
 34 #include <sys/lock.h>
 35 #include <sys/malloc.h>
 36 #include <sys/mutex.h>
 37 #include <sys/priv.h>
 38 #include <sys/proc.h>
 39 #include <sys/syscallsubr.h>
 40 #include <sys/sysproto.h>
 41 #include <sys/systm.h>
 42 
 43 #ifdef COMPAT_LINUX32
 44 #include <machine/../linux32/linux.h>
 45 #include <machine/../linux32/linux32_proto.h>
 46 #else
 47 #include <machine/../linux/linux.h>
 48 #include <machine/../linux/linux_proto.h>
 49 #endif
 50 
 51 #include <compat/linux/linux_util.h>
 52 
 53 DUMMY(setfsuid16);
 54 DUMMY(setfsgid16);
 55 DUMMY(getresuid16);
 56 DUMMY(getresgid16);
 57 
 58 #define CAST_NOCHG(x)   ((x == 0xFFFF) ? -1 : x)
 59 
 60 int
 61 linux_chown16(struct thread *td, struct linux_chown16_args *args)
 62 {
 63         char *path;
 64         int error;
 65 
 66         LCONVPATHEXIST(td, args->path, &path);
 67 
 68 #ifdef DEBUG
 69         if (ldebug(chown16))
 70                 printf(ARGS(chown16, "%s, %d, %d"), path, args->uid, args->gid);
 71 #endif
 72         error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
 73             CAST_NOCHG(args->gid));
 74         LFREEPATH(path);
 75         return (error);
 76 }
 77 
 78 int
 79 linux_lchown16(struct thread *td, struct linux_lchown16_args *args)
 80 {
 81         char *path;
 82         int error;
 83 
 84         LCONVPATHEXIST(td, args->path, &path);
 85 
 86 #ifdef DEBUG
 87         if (ldebug(lchown16))
 88                 printf(ARGS(lchown16, "%s, %d, %d"), path, args->uid,
 89                     args->gid);
 90 #endif
 91         error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
 92             CAST_NOCHG(args->gid));
 93         LFREEPATH(path);
 94         return (error);
 95 }
 96 
 97 int
 98 linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
 99 {
100         struct ucred *newcred, *oldcred;
101         l_gid16_t linux_gidset[NGROUPS];
102         gid_t *bsd_gidset;
103         int ngrp, error;
104         struct proc *p;
105 
106 #ifdef DEBUG
107         if (ldebug(setgroups16))
108                 printf(ARGS(setgroups16, "%d, *"), args->gidsetsize);
109 #endif
110 
111         ngrp = args->gidsetsize;
112         if (ngrp < 0 || ngrp >= NGROUPS)
113                 return (EINVAL);
114         error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
115         if (error)
116                 return (error);
117         newcred = crget();
118         p = td->td_proc;
119         PROC_LOCK(p);
120         oldcred = p->p_ucred;
121 
122         /*
123          * cr_groups[0] holds egid. Setting the whole set from
124          * the supplied set will cause egid to be changed too.
125          * Keep cr_groups[0] unchanged to prevent that.
126          */
127 
128         if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 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 
155 int
156 linux_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 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
205  *
206  * linux_getgid16() - MP SAFE
207  * linux_getuid16() - MP SAFE
208  */
209 
210 int
211 linux_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 
218 int
219 linux_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 
226 int
227 linux_getegid16(struct thread *td, struct linux_getegid16_args *args)
228 {
229         struct getegid_args bsd;
230 
231         return (getegid(td, &bsd));
232 }
233 
234 int
235 linux_geteuid16(struct thread *td, struct linux_geteuid16_args *args)
236 {
237         struct geteuid_args bsd;
238 
239         return (geteuid(td, &bsd));
240 }
241 
242 int
243 linux_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 
251 int
252 linux_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 
260 int
261 linux_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 
270 int
271 linux_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 
280 int
281 linux_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 
291 int
292 linux_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 }
301 

Cache object: 5c577a9a5a0ccf5b2dedf8cbbdf97ac8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.