xref: /dragonfly/sys/kern/kern_prot.c (revision 28c26f7e)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)kern_prot.c	8.6 (Berkeley) 1/21/94
39  * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $
40  * $DragonFly: src/sys/kern/kern_prot.c,v 1.29 2008/02/16 15:53:39 matthias Exp $
41  */
42 
43 /*
44  * System calls related to processes and protection
45  */
46 
47 #include "opt_compat.h"
48 
49 #include <sys/param.h>
50 #include <sys/acct.h>
51 #include <sys/systm.h>
52 #include <sys/sysproto.h>
53 #include <sys/kernel.h>
54 #include <sys/lock.h>
55 #include <sys/proc.h>
56 #include <sys/priv.h>
57 #include <sys/malloc.h>
58 #include <sys/pioctl.h>
59 #include <sys/resourcevar.h>
60 #include <sys/jail.h>
61 #include <sys/lockf.h>
62 #include <sys/spinlock.h>
63 
64 #include <sys/thread2.h>
65 #include <sys/spinlock2.h>
66 
67 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
68 
69 /*
70  * NOT MP SAFE due to p_pptr access
71  */
72 /* ARGSUSED */
73 int
74 sys_getpid(struct getpid_args *uap)
75 {
76 	struct proc *p = curproc;
77 
78 	uap->sysmsg_fds[0] = p->p_pid;
79 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
80 	uap->sysmsg_fds[1] = p->p_pptr->p_pid;
81 #endif
82 	return (0);
83 }
84 
85 /* ARGSUSED */
86 int
87 sys_getppid(struct getppid_args *uap)
88 {
89 	struct proc *p = curproc;
90 
91 	uap->sysmsg_result = p->p_pptr->p_pid;
92 	return (0);
93 }
94 
95 /* ARGSUSED */
96 int
97 sys_lwp_gettid(struct lwp_gettid_args *uap)
98 {
99 	struct lwp *lp = curthread->td_lwp;
100 
101 	uap->sysmsg_result = lp->lwp_tid;
102 	return (0);
103 }
104 
105 /*
106  * Get process group ID; note that POSIX getpgrp takes no parameter
107  *
108  * MP SAFE
109  */
110 int
111 sys_getpgrp(struct getpgrp_args *uap)
112 {
113 	struct proc *p = curproc;
114 
115 	uap->sysmsg_result = p->p_pgrp->pg_id;
116 	return (0);
117 }
118 
119 /*
120  * Get an arbitrary pid's process group id
121  */
122 int
123 sys_getpgid(struct getpgid_args *uap)
124 {
125 	struct proc *p = curproc;
126 	struct proc *pt;
127 
128 	pt = p;
129 	if (uap->pid == 0)
130 		goto found;
131 
132 	if ((pt = pfind(uap->pid)) == 0)
133 		return ESRCH;
134 found:
135 	uap->sysmsg_result = pt->p_pgrp->pg_id;
136 	return 0;
137 }
138 
139 /*
140  * Get an arbitrary pid's session id.
141  */
142 int
143 sys_getsid(struct getsid_args *uap)
144 {
145 	struct proc *p = curproc;
146 	struct proc *pt;
147 
148 	pt = p;
149 	if (uap->pid == 0)
150 		goto found;
151 
152 	if ((pt = pfind(uap->pid)) == 0)
153 		return ESRCH;
154 found:
155 	uap->sysmsg_result = pt->p_session->s_sid;
156 	return 0;
157 }
158 
159 
160 /*
161  * getuid() - MP SAFE
162  */
163 /* ARGSUSED */
164 int
165 sys_getuid(struct getuid_args *uap)
166 {
167 	struct proc *p = curproc;
168 
169 	uap->sysmsg_fds[0] = p->p_ucred->cr_ruid;
170 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
171 	uap->sysmsg_fds[1] = p->p_ucred->cr_uid;
172 #endif
173 	return (0);
174 }
175 
176 /*
177  * geteuid() - MP SAFE
178  */
179 /* ARGSUSED */
180 int
181 sys_geteuid(struct geteuid_args *uap)
182 {
183 	struct proc *p = curproc;
184 
185 	uap->sysmsg_result = p->p_ucred->cr_uid;
186 	return (0);
187 }
188 
189 /*
190  * getgid() - MP SAFE
191  */
192 /* ARGSUSED */
193 int
194 sys_getgid(struct getgid_args *uap)
195 {
196 	struct proc *p = curproc;
197 
198 	uap->sysmsg_fds[0] = p->p_ucred->cr_rgid;
199 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
200 	uap->sysmsg_fds[1] = p->p_ucred->cr_groups[0];
201 #endif
202 	return (0);
203 }
204 
205 /*
206  * Get effective group ID.  The "egid" is groups[0], and could be obtained
207  * via getgroups.  This syscall exists because it is somewhat painful to do
208  * correctly in a library function.
209  *
210  * MP SAFE
211  */
212 /* ARGSUSED */
213 int
214 sys_getegid(struct getegid_args *uap)
215 {
216 	struct proc *p = curproc;
217 
218 	uap->sysmsg_result = p->p_ucred->cr_groups[0];
219 	return (0);
220 }
221 
222 int
223 sys_getgroups(struct getgroups_args *uap)
224 {
225 	struct proc *p = curproc;
226 	struct ucred *cr;
227 	u_int ngrp;
228 	int error;
229 
230 	if (p == NULL)				/* API enforcement */
231 		return(EPERM);
232 	cr = p->p_ucred;
233 
234 	if ((ngrp = uap->gidsetsize) == 0) {
235 		uap->sysmsg_result = cr->cr_ngroups;
236 		return (0);
237 	}
238 	if (ngrp < cr->cr_ngroups)
239 		return (EINVAL);
240 	ngrp = cr->cr_ngroups;
241 	if ((error = copyout((caddr_t)cr->cr_groups,
242 	    (caddr_t)uap->gidset, ngrp * sizeof(gid_t))))
243 		return (error);
244 	uap->sysmsg_result = ngrp;
245 	return (0);
246 }
247 
248 /* ARGSUSED */
249 int
250 sys_setsid(struct setsid_args *uap)
251 {
252 	struct proc *p = curproc;
253 
254 	if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
255 		return (EPERM);
256 	} else {
257 		(void)enterpgrp(p, p->p_pid, 1);
258 		uap->sysmsg_result = p->p_pid;
259 		return (0);
260 	}
261 }
262 
263 /*
264  * set process group (setpgid/old setpgrp)
265  *
266  * caller does setpgid(targpid, targpgid)
267  *
268  * pid must be caller or child of caller (ESRCH)
269  * if a child
270  *	pid must be in same session (EPERM)
271  *	pid can't have done an exec (EACCES)
272  * if pgid != pid
273  * 	there must exist some pid in same session having pgid (EPERM)
274  * pid must not be session leader (EPERM)
275  */
276 /* ARGSUSED */
277 int
278 sys_setpgid(struct setpgid_args *uap)
279 {
280 	struct proc *curp = curproc;
281 	struct proc *targp;		/* target process */
282 	struct pgrp *pgrp;		/* target pgrp */
283 
284 	if (uap->pgid < 0)
285 		return (EINVAL);
286 	if (uap->pid != 0 && uap->pid != curp->p_pid) {
287 		if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
288 			return (ESRCH);
289 		if (targp->p_pgrp == NULL ||  targp->p_session != curp->p_session)
290 			return (EPERM);
291 		if (targp->p_flag & P_EXEC)
292 			return (EACCES);
293 	} else
294 		targp = curp;
295 	if (SESS_LEADER(targp))
296 		return (EPERM);
297 	if (uap->pgid == 0)
298 		uap->pgid = targp->p_pid;
299 	else if (uap->pgid != targp->p_pid)
300 		if ((pgrp = pgfind(uap->pgid)) == 0 ||
301 	            pgrp->pg_session != curp->p_session)
302 			return (EPERM);
303 	return (enterpgrp(targp, uap->pgid, 0));
304 }
305 
306 /*
307  * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
308  * compatible.  It says that setting the uid/gid to euid/egid is a special
309  * case of "appropriate privilege".  Once the rules are expanded out, this
310  * basically means that setuid(nnn) sets all three id's, in all permitted
311  * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
312  * does not set the saved id - this is dangerous for traditional BSD
313  * programs.  For this reason, we *really* do not want to set
314  * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
315  */
316 #define POSIX_APPENDIX_B_4_2_2
317 
318 /* ARGSUSED */
319 int
320 sys_setuid(struct setuid_args *uap)
321 {
322 	struct proc *p = curproc;
323 	struct ucred *cr;
324 	uid_t uid;
325 	int error;
326 
327 	if (p == NULL)				/* API enforcement */
328 		return(EPERM);
329 	cr = p->p_ucred;
330 
331 	/*
332 	 * See if we have "permission" by POSIX 1003.1 rules.
333 	 *
334 	 * Note that setuid(geteuid()) is a special case of
335 	 * "appropriate privileges" in appendix B.4.2.2.  We need
336 	 * to use this clause to be compatible with traditional BSD
337 	 * semantics.  Basically, it means that "setuid(xx)" sets all
338 	 * three id's (assuming you have privs).
339 	 *
340 	 * Notes on the logic.  We do things in three steps.
341 	 * 1: We determine if the euid is going to change, and do EPERM
342 	 *    right away.  We unconditionally change the euid later if this
343 	 *    test is satisfied, simplifying that part of the logic.
344 	 * 2: We determine if the real and/or saved uid's are going to
345 	 *    change.  Determined by compile options.
346 	 * 3: Change euid last. (after tests in #2 for "appropriate privs")
347 	 */
348 	uid = uap->uid;
349 	if (uid != cr->cr_ruid &&		/* allow setuid(getuid()) */
350 #ifdef _POSIX_SAVED_IDS
351 	    uid != crc->cr_svuid &&		/* allow setuid(saved gid) */
352 #endif
353 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
354 	    uid != cr->cr_uid &&	/* allow setuid(geteuid()) */
355 #endif
356 	    (error = priv_check_cred(cr, PRIV_CRED_SETUID, 0)))
357 		return (error);
358 
359 #ifdef _POSIX_SAVED_IDS
360 	/*
361 	 * Do we have "appropriate privileges" (are we root or uid == euid)
362 	 * If so, we are changing the real uid and/or saved uid.
363 	 */
364 	if (
365 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
366 	    uid == cr->cr_uid ||
367 #endif
368 	    priv_check_cred(cr, PRIV_CRED_SETUID, 0) == 0) /* we are using privs */
369 #endif
370 	{
371 		/*
372 		 * Set the real uid and transfer proc count to new user.
373 		 */
374 		if (uid != cr->cr_ruid) {
375 			cr = change_ruid(uid);
376 			setsugid();
377 		}
378 		/*
379 		 * Set saved uid
380 		 *
381 		 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
382 		 * the security of seteuid() depends on it.  B.4.2.2 says it
383 		 * is important that we should do this.
384 		 */
385 		if (cr->cr_svuid != uid) {
386 			cr = cratom(&p->p_ucred);
387 			cr->cr_svuid = uid;
388 			setsugid();
389 		}
390 	}
391 
392 	/*
393 	 * In all permitted cases, we are changing the euid.
394 	 * Copy credentials so other references do not see our changes.
395 	 */
396 	if (cr->cr_uid != uid) {
397 		change_euid(uid);
398 		setsugid();
399 	}
400 	return (0);
401 }
402 
403 /* ARGSUSED */
404 int
405 sys_seteuid(struct seteuid_args *uap)
406 {
407 	struct proc *p = curproc;
408 	struct ucred *cr;
409 	uid_t euid;
410 	int error;
411 
412 	if (p == NULL)				/* API enforcement */
413 		return(EPERM);
414 
415 	cr = p->p_ucred;
416 	euid = uap->euid;
417 	if (euid != cr->cr_ruid &&		/* allow seteuid(getuid()) */
418 	    euid != cr->cr_svuid &&		/* allow seteuid(saved uid) */
419 	    (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0)))
420 		return (error);
421 	/*
422 	 * Everything's okay, do it.  Copy credentials so other references do
423 	 * not see our changes.
424 	 */
425 	if (cr->cr_uid != euid) {
426 		change_euid(euid);
427 		setsugid();
428 	}
429 	return (0);
430 }
431 
432 /* ARGSUSED */
433 int
434 sys_setgid(struct setgid_args *uap)
435 {
436 	struct proc *p = curproc;
437 	struct ucred *cr;
438 	gid_t gid;
439 	int error;
440 
441 	if (p == NULL)				/* API enforcement */
442 		return(EPERM);
443 	cr = p->p_ucred;
444 
445 	/*
446 	 * See if we have "permission" by POSIX 1003.1 rules.
447 	 *
448 	 * Note that setgid(getegid()) is a special case of
449 	 * "appropriate privileges" in appendix B.4.2.2.  We need
450 	 * to use this clause to be compatible with traditional BSD
451 	 * semantics.  Basically, it means that "setgid(xx)" sets all
452 	 * three id's (assuming you have privs).
453 	 *
454 	 * For notes on the logic here, see setuid() above.
455 	 */
456 	gid = uap->gid;
457 	if (gid != cr->cr_rgid &&		/* allow setgid(getgid()) */
458 #ifdef _POSIX_SAVED_IDS
459 	    gid != cr->cr_svgid &&		/* allow setgid(saved gid) */
460 #endif
461 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
462 	    gid != cr->cr_groups[0] && /* allow setgid(getegid()) */
463 #endif
464 	    (error = priv_check_cred(cr, PRIV_CRED_SETGID, 0)))
465 		return (error);
466 
467 #ifdef _POSIX_SAVED_IDS
468 	/*
469 	 * Do we have "appropriate privileges" (are we root or gid == egid)
470 	 * If so, we are changing the real uid and saved gid.
471 	 */
472 	if (
473 #ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
474 	    gid == cr->cr_groups[0] ||
475 #endif
476 	    priv_check_cred(cr, PRIV_CRED_SETGID, 0) == 0) /* we are using privs */
477 #endif
478 	{
479 		/*
480 		 * Set real gid
481 		 */
482 		if (cr->cr_rgid != gid) {
483 			cr = cratom(&p->p_ucred);
484 			cr->cr_rgid = gid;
485 			setsugid();
486 		}
487 		/*
488 		 * Set saved gid
489 		 *
490 		 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
491 		 * the security of setegid() depends on it.  B.4.2.2 says it
492 		 * is important that we should do this.
493 		 */
494 		if (cr->cr_svgid != gid) {
495 			cr = cratom(&p->p_ucred);
496 			cr->cr_svgid = gid;
497 			setsugid();
498 		}
499 	}
500 	/*
501 	 * In all cases permitted cases, we are changing the egid.
502 	 * Copy credentials so other references do not see our changes.
503 	 */
504 	if (cr->cr_groups[0] != gid) {
505 		cr = cratom(&p->p_ucred);
506 		cr->cr_groups[0] = gid;
507 		setsugid();
508 	}
509 	return (0);
510 }
511 
512 /* ARGSUSED */
513 int
514 sys_setegid(struct setegid_args *uap)
515 {
516 	struct proc *p = curproc;
517 	struct ucred *cr;
518 	gid_t egid;
519 	int error;
520 
521 	if (p == NULL)				/* API enforcement */
522 		return(EPERM);
523 	cr = p->p_ucred;
524 
525 	egid = uap->egid;
526 	if (egid != cr->cr_rgid &&		/* allow setegid(getgid()) */
527 	    egid != cr->cr_svgid &&		/* allow setegid(saved gid) */
528 	    (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0)))
529 		return (error);
530 	if (cr->cr_groups[0] != egid) {
531 		cr = cratom(&p->p_ucred);
532 		cr->cr_groups[0] = egid;
533 		setsugid();
534 	}
535 	return (0);
536 }
537 
538 /* ARGSUSED */
539 int
540 sys_setgroups(struct setgroups_args *uap)
541 {
542 	struct proc *p = curproc;
543 	struct ucred *cr;
544 	u_int ngrp;
545 	int error;
546 
547 	if (p == NULL)				/* API enforcement */
548 		return(EPERM);
549 	cr = p->p_ucred;
550 
551 	if ((error = priv_check_cred(cr, PRIV_CRED_SETGROUPS, 0)))
552 		return (error);
553 	ngrp = uap->gidsetsize;
554 	if (ngrp > NGROUPS)
555 		return (EINVAL);
556 	/*
557 	 * XXX A little bit lazy here.  We could test if anything has
558 	 * changed before cratom() and setting P_SUGID.
559 	 */
560 	cr = cratom(&p->p_ucred);
561 	if (ngrp < 1) {
562 		/*
563 		 * setgroups(0, NULL) is a legitimate way of clearing the
564 		 * groups vector on non-BSD systems (which generally do not
565 		 * have the egid in the groups[0]).  We risk security holes
566 		 * when running non-BSD software if we do not do the same.
567 		 */
568 		cr->cr_ngroups = 1;
569 	} else {
570 		if ((error = copyin((caddr_t)uap->gidset,
571 		    (caddr_t)cr->cr_groups, ngrp * sizeof(gid_t))))
572 			return (error);
573 		cr->cr_ngroups = ngrp;
574 	}
575 	setsugid();
576 	return (0);
577 }
578 
579 /* ARGSUSED */
580 int
581 sys_setreuid(struct setreuid_args *uap)
582 {
583 	struct proc *p = curproc;
584 	struct ucred *cr;
585 	uid_t ruid, euid;
586 	int error;
587 
588 	if (p == NULL)				/* API enforcement */
589 		return(EPERM);
590 	cr = p->p_ucred;
591 
592 	ruid = uap->ruid;
593 	euid = uap->euid;
594 	if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid) ||
595 	     (euid != (uid_t)-1 && euid != cr->cr_uid &&
596 	     euid != cr->cr_ruid && euid != cr->cr_svuid)) &&
597 	    (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0)
598 		return (error);
599 
600 	if (euid != (uid_t)-1 && cr->cr_uid != euid) {
601 		cr = change_euid(euid);
602 		setsugid();
603 	}
604 	if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
605 		cr = change_ruid(ruid);
606 		setsugid();
607 	}
608 	if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) &&
609 	    cr->cr_svuid != cr->cr_uid) {
610 		cr = cratom(&p->p_ucred);
611 		cr->cr_svuid = cr->cr_uid;
612 		setsugid();
613 	}
614 	return (0);
615 }
616 
617 /* ARGSUSED */
618 int
619 sys_setregid(struct setregid_args *uap)
620 {
621 	struct proc *p = curproc;
622 	struct ucred *cr;
623 	gid_t rgid, egid;
624 	int error;
625 
626 	if (p == NULL)				/* API enforcement */
627 		return(EPERM);
628 	cr = p->p_ucred;
629 
630 	rgid = uap->rgid;
631 	egid = uap->egid;
632 	if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid) ||
633 	     (egid != (gid_t)-1 && egid != cr->cr_groups[0] &&
634 	     egid != cr->cr_rgid && egid != cr->cr_svgid)) &&
635 	    (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0)
636 		return (error);
637 
638 	if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
639 		cr = cratom(&p->p_ucred);
640 		cr->cr_groups[0] = egid;
641 		setsugid();
642 	}
643 	if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
644 		cr = cratom(&p->p_ucred);
645 		cr->cr_rgid = rgid;
646 		setsugid();
647 	}
648 	if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) &&
649 	    cr->cr_svgid != cr->cr_groups[0]) {
650 		cr = cratom(&p->p_ucred);
651 		cr->cr_svgid = cr->cr_groups[0];
652 		setsugid();
653 	}
654 	return (0);
655 }
656 
657 /*
658  * setresuid(ruid, euid, suid) is like setreuid except control over the
659  * saved uid is explicit.
660  */
661 
662 /* ARGSUSED */
663 int
664 sys_setresuid(struct setresuid_args *uap)
665 {
666 	struct proc *p = curproc;
667 	struct ucred *cr;
668 	uid_t ruid, euid, suid;
669 	int error;
670 
671 	cr = p->p_ucred;
672 	ruid = uap->ruid;
673 	euid = uap->euid;
674 	suid = uap->suid;
675 	if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid &&
676 	      ruid != cr->cr_uid) ||
677 	     (euid != (uid_t)-1 && euid != cr->cr_ruid && euid != cr->cr_svuid &&
678 	      euid != cr->cr_uid) ||
679 	     (suid != (uid_t)-1 && suid != cr->cr_ruid && suid != cr->cr_svuid &&
680 	      suid != cr->cr_uid)) &&
681 	    (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0)
682 		return (error);
683 	if (euid != (uid_t)-1 && cr->cr_uid != euid) {
684 		cr = change_euid(euid);
685 		setsugid();
686 	}
687 	if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
688 		cr = change_ruid(ruid);
689 		setsugid();
690 	}
691 	if (suid != (uid_t)-1 && cr->cr_svuid != suid) {
692 		cr = cratom(&p->p_ucred);
693 		cr->cr_svuid = suid;
694 		setsugid();
695 	}
696 	return (0);
697 }
698 
699 /*
700  * setresgid(rgid, egid, sgid) is like setregid except control over the
701  * saved gid is explicit.
702  */
703 
704 /* ARGSUSED */
705 int
706 sys_setresgid(struct setresgid_args *uap)
707 {
708 	struct proc *p = curproc;
709 	struct ucred *cr;
710 	gid_t rgid, egid, sgid;
711 	int error;
712 
713 	cr = p->p_ucred;
714 	rgid = uap->rgid;
715 	egid = uap->egid;
716 	sgid = uap->sgid;
717 	if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid &&
718 	      rgid != cr->cr_groups[0]) ||
719 	     (egid != (gid_t)-1 && egid != cr->cr_rgid && egid != cr->cr_svgid &&
720 	      egid != cr->cr_groups[0]) ||
721 	     (sgid != (gid_t)-1 && sgid != cr->cr_rgid && sgid != cr->cr_svgid &&
722 	      sgid != cr->cr_groups[0])) &&
723 	    (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0)
724 		return (error);
725 
726 	if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
727 		cr = cratom(&p->p_ucred);
728 		cr->cr_groups[0] = egid;
729 		setsugid();
730 	}
731 	if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
732 		cr = cratom(&p->p_ucred);
733 		cr->cr_rgid = rgid;
734 		setsugid();
735 	}
736 	if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) {
737 		cr = cratom(&p->p_ucred);
738 		cr->cr_svgid = sgid;
739 		setsugid();
740 	}
741 	return (0);
742 }
743 
744 /* ARGSUSED */
745 int
746 sys_getresuid(struct getresuid_args *uap)
747 {
748 	struct proc *p = curproc;
749 	struct ucred *cr = p->p_ucred;
750 	int error1 = 0, error2 = 0, error3 = 0;
751 
752 	if (uap->ruid)
753 		error1 = copyout((caddr_t)&cr->cr_ruid,
754 		    (caddr_t)uap->ruid, sizeof(cr->cr_ruid));
755 	if (uap->euid)
756 		error2 = copyout((caddr_t)&cr->cr_uid,
757 		    (caddr_t)uap->euid, sizeof(cr->cr_uid));
758 	if (uap->suid)
759 		error3 = copyout((caddr_t)&cr->cr_svuid,
760 		    (caddr_t)uap->suid, sizeof(cr->cr_svuid));
761 	return error1 ? error1 : (error2 ? error2 : error3);
762 }
763 
764 /* ARGSUSED */
765 int
766 sys_getresgid(struct getresgid_args *uap)
767 {
768 	struct proc *p = curproc;
769 	struct ucred *cr = p->p_ucred;
770 	int error1 = 0, error2 = 0, error3 = 0;
771 
772 	if (uap->rgid)
773 		error1 = copyout((caddr_t)&cr->cr_rgid,
774 		    (caddr_t)uap->rgid, sizeof(cr->cr_rgid));
775 	if (uap->egid)
776 		error2 = copyout((caddr_t)&cr->cr_groups[0],
777 		    (caddr_t)uap->egid, sizeof(cr->cr_groups[0]));
778 	if (uap->sgid)
779 		error3 = copyout((caddr_t)&cr->cr_svgid,
780 		    (caddr_t)uap->sgid, sizeof(cr->cr_svgid));
781 	return error1 ? error1 : (error2 ? error2 : error3);
782 }
783 
784 
785 /* ARGSUSED */
786 int
787 sys_issetugid(struct issetugid_args *uap)
788 {
789 	struct proc *p = curproc;
790 	/*
791 	 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
792 	 * we use P_SUGID because we consider changing the owners as
793 	 * "tainting" as well.
794 	 * This is significant for procs that start as root and "become"
795 	 * a user without an exec - programs cannot know *everything*
796 	 * that libc *might* have put in their data segment.
797 	 */
798 	uap->sysmsg_result = (p->p_flag & P_SUGID) ? 1 : 0;
799 	return (0);
800 }
801 
802 /*
803  * Check if gid is a member of the group set.
804  */
805 int
806 groupmember(gid_t gid, struct ucred *cred)
807 {
808 	gid_t *gp;
809 	gid_t *egp;
810 
811 	egp = &(cred->cr_groups[cred->cr_ngroups]);
812 	for (gp = cred->cr_groups; gp < egp; gp++) {
813 		if (*gp == gid)
814 			return (1);
815 	}
816 	return (0);
817 }
818 
819 /*
820  * Test whether the specified credentials have the privilege
821  * in question.
822  *
823  * A kernel thread without a process context is assumed to have
824  * the privilege in question.  In situations where the caller always
825  * expect a cred to exist, the cred should be passed separately and
826  * priv_check_cred() should be used instead of priv_check().
827  *
828  * Returns 0 or error.
829  *
830  * MPSAFE
831  */
832 int
833 priv_check(struct thread *td, int priv)
834 {
835 	struct proc *p = td->td_proc;
836 
837 	if (p != NULL) {
838 		return priv_check_cred(p->p_ucred, priv, 0);
839 	} else {
840 		return (0);
841 	}
842 }
843 
844 /*
845  * Check a credential for privilege.
846  *
847  * A non-null credential is expected unless NULL_CRED_OKAY is set.
848  *
849  * MPSAFE
850  */
851 int
852 priv_check_cred(struct ucred *cred, int priv, int flags)
853 {
854 	int error;
855 
856 	KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege"));
857 
858 	KASSERT(cred != NULL || flags & NULL_CRED_OKAY,
859 		("priv_check_cred: NULL cred!"));
860 
861 	if (cred == NULL) {
862 		if (flags & NULL_CRED_OKAY)
863 			return (0);
864 		else
865 			return (EPERM);
866 	}
867 	if (cred->cr_uid != 0)
868 		return (EPERM);
869 
870 	error = prison_priv_check(cred, priv);
871 	if (error)
872 		return (error);
873 
874 	/* NOTE: accounting for suser access (p_acflag/ASU) removed */
875 	return (0);
876 }
877 
878 /*
879  * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
880  */
881 int
882 p_trespass(struct ucred *cr1, struct ucred *cr2)
883 {
884 	if (cr1 == cr2)
885 		return (0);
886 	if (!PRISON_CHECK(cr1, cr2))
887 		return (ESRCH);
888 	if (cr1->cr_ruid == cr2->cr_ruid)
889 		return (0);
890 	if (cr1->cr_uid == cr2->cr_ruid)
891 		return (0);
892 	if (cr1->cr_ruid == cr2->cr_uid)
893 		return (0);
894 	if (cr1->cr_uid == cr2->cr_uid)
895 		return (0);
896 	if (priv_check_cred(cr1, PRIV_PROC_TRESPASS, 0) == 0)
897 		return (0);
898 	return (EPERM);
899 }
900 
901 /*
902  * MPSAFE
903  */
904 static __inline void
905 _crinit(struct ucred *cr)
906 {
907 	cr->cr_ref = 1;
908 	spin_init(&cr->cr_spin);
909 }
910 
911 /*
912  * MPSAFE
913  */
914 void
915 crinit(struct ucred *cr)
916 {
917 	bzero(cr, sizeof(*cr));
918 	_crinit(cr);
919 }
920 
921 /*
922  * Allocate a zeroed cred structure.
923  *
924  * MPSAFE
925  */
926 struct ucred *
927 crget(void)
928 {
929 	struct ucred *cr;
930 
931 	cr = kmalloc(sizeof(*cr), M_CRED, M_WAITOK|M_ZERO);
932 	_crinit(cr);
933 	return (cr);
934 }
935 
936 /*
937  * Claim another reference to a ucred structure.  Can be used with special
938  * creds.
939  *
940  * It must be possible to call this routine with spinlocks held, meaning
941  * that this routine itself cannot obtain a spinlock.
942  *
943  * MPSAFE
944  */
945 struct ucred *
946 crhold(struct ucred *cr)
947 {
948 	if (cr != NOCRED && cr != FSCRED)
949 		atomic_add_int(&cr->cr_ref, 1);
950 	return(cr);
951 }
952 
953 /*
954  * Drop a reference from the cred structure, free it if the reference count
955  * reaches 0.
956  *
957  * NOTE: because we used atomic_add_int() above, without a spinlock, we
958  * must also use atomic_subtract_int() below.  A spinlock is required
959  * in crfree() to handle multiple callers racing the refcount to 0.
960  *
961  * MPALMOSTSAFE - acquires mplock on 1->0 transition of ref count
962  */
963 void
964 crfree(struct ucred *cr)
965 {
966 	if (cr->cr_ref <= 0)
967 		panic("Freeing already free credential! %p", cr);
968 	spin_lock_wr(&cr->cr_spin);
969 	atomic_subtract_int(&cr->cr_ref, 1);
970 	if (cr->cr_ref == 0) {
971 		spin_unlock_wr(&cr->cr_spin);
972 		/*
973 		 * Some callers of crget(), such as nfs_statfs(),
974 		 * allocate a temporary credential, but don't
975 		 * allocate a uidinfo structure.
976 		 */
977 		get_mplock();
978 		if (cr->cr_uidinfo != NULL) {
979 			uidrop(cr->cr_uidinfo);
980 			cr->cr_uidinfo = NULL;
981 		}
982 		if (cr->cr_ruidinfo != NULL) {
983 			uidrop(cr->cr_ruidinfo);
984 			cr->cr_ruidinfo = NULL;
985 		}
986 
987 		/*
988 		 * Destroy empty prisons
989 		 */
990 		if (jailed(cr))
991 			prison_free(cr->cr_prison);
992 		cr->cr_prison = NULL;	/* safety */
993 
994 		FREE((caddr_t)cr, M_CRED);
995 		rel_mplock();
996 	} else {
997 		spin_unlock_wr(&cr->cr_spin);
998 	}
999 }
1000 
1001 /*
1002  * Atomize a cred structure so it can be modified without polluting
1003  * other references to it.
1004  */
1005 struct ucred *
1006 cratom(struct ucred **pcr)
1007 {
1008 	struct ucred *oldcr;
1009 	struct ucred *newcr;
1010 
1011 	oldcr = *pcr;
1012 	if (oldcr->cr_ref == 1)
1013 		return (oldcr);
1014 	newcr = crget();
1015 	*newcr = *oldcr;
1016 	if (newcr->cr_uidinfo)
1017 		uihold(newcr->cr_uidinfo);
1018 	if (newcr->cr_ruidinfo)
1019 		uihold(newcr->cr_ruidinfo);
1020 	if (jailed(newcr))
1021 		prison_hold(newcr->cr_prison);
1022 	newcr->cr_ref = 1;
1023 	crfree(oldcr);
1024 	*pcr = newcr;
1025 	return (newcr);
1026 }
1027 
1028 #if 0	/* no longer used but keep around for a little while */
1029 /*
1030  * Copy cred structure to a new one and free the old one.
1031  */
1032 struct ucred *
1033 crcopy(struct ucred *cr)
1034 {
1035 	struct ucred *newcr;
1036 
1037 	if (cr->cr_ref == 1)
1038 		return (cr);
1039 	newcr = crget();
1040 	*newcr = *cr;
1041 	if (newcr->cr_uidinfo)
1042 		uihold(newcr->cr_uidinfo);
1043 	if (newcr->cr_ruidinfo)
1044 		uihold(newcr->cr_ruidinfo);
1045 	if (jailed(newcr))
1046 		prison_hold(newcr->cr_prison);
1047 	newcr->cr_ref = 1;
1048 	crfree(cr);
1049 	return (newcr);
1050 }
1051 #endif
1052 
1053 /*
1054  * Dup cred struct to a new held one.
1055  */
1056 struct ucred *
1057 crdup(struct ucred *cr)
1058 {
1059 	struct ucred *newcr;
1060 
1061 	newcr = crget();
1062 	*newcr = *cr;
1063 	if (newcr->cr_uidinfo)
1064 		uihold(newcr->cr_uidinfo);
1065 	if (newcr->cr_ruidinfo)
1066 		uihold(newcr->cr_ruidinfo);
1067 	if (jailed(newcr))
1068 		prison_hold(newcr->cr_prison);
1069 	newcr->cr_ref = 1;
1070 	return (newcr);
1071 }
1072 
1073 /*
1074  * Fill in a struct xucred based on a struct ucred.
1075  */
1076 void
1077 cru2x(struct ucred *cr, struct xucred *xcr)
1078 {
1079 
1080 	bzero(xcr, sizeof(*xcr));
1081 	xcr->cr_version = XUCRED_VERSION;
1082 	xcr->cr_uid = cr->cr_uid;
1083 	xcr->cr_ngroups = cr->cr_ngroups;
1084 	bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1085 }
1086 
1087 /*
1088  * Get login name, if available.
1089  */
1090 /* ARGSUSED */
1091 int
1092 sys_getlogin(struct getlogin_args *uap)
1093 {
1094 	struct proc *p = curproc;
1095 
1096 	if (uap->namelen > MAXLOGNAME)
1097 		uap->namelen = MAXLOGNAME;
1098 	return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1099 	    (caddr_t) uap->namebuf, uap->namelen));
1100 }
1101 
1102 /*
1103  * Set login name.
1104  */
1105 /* ARGSUSED */
1106 int
1107 sys_setlogin(struct setlogin_args *uap)
1108 {
1109 	struct proc *p = curproc;
1110 	int error;
1111 	char logintmp[MAXLOGNAME];
1112 
1113 	KKASSERT(p != NULL);
1114 	if ((error = priv_check_cred(p->p_ucred, PRIV_PROC_SETLOGIN, 0)))
1115 		return (error);
1116 	error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
1117 	    sizeof(logintmp), NULL);
1118 	if (error == ENAMETOOLONG)
1119 		error = EINVAL;
1120 	else if (!error)
1121 		(void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1122 		    sizeof(logintmp));
1123 	return (error);
1124 }
1125 
1126 void
1127 setsugid(void)
1128 {
1129 	struct proc *p = curproc;
1130 
1131 	KKASSERT(p != NULL);
1132 	p->p_flag |= P_SUGID;
1133 	if (!(p->p_pfsflags & PF_ISUGID))
1134 		p->p_stops = 0;
1135 }
1136 
1137 /*
1138  * Helper function to change the effective uid of a process
1139  */
1140 struct ucred *
1141 change_euid(uid_t euid)
1142 {
1143 	struct	proc *p = curproc;
1144 	struct	ucred *cr;
1145 
1146 	KKASSERT(p != NULL);
1147 	lf_count_adjust(p, 0);
1148 	cr = cratom(&p->p_ucred);
1149 	cr->cr_uid = euid;
1150 	uireplace(&cr->cr_uidinfo, uifind(euid));
1151 	lf_count_adjust(p, 1);
1152 	return (cr);
1153 }
1154 
1155 /*
1156  * Helper function to change the real uid of a process
1157  *
1158  * The per-uid process count for this process is transfered from
1159  * the old uid to the new uid.
1160  */
1161 struct ucred *
1162 change_ruid(uid_t ruid)
1163 {
1164 	struct	proc *p = curproc;
1165 	struct	ucred *cr;
1166 
1167 	KKASSERT(p != NULL);
1168 
1169 	cr = cratom(&p->p_ucred);
1170 	chgproccnt(cr->cr_ruidinfo, -1, 0);
1171 	cr->cr_ruid = ruid;
1172 	uireplace(&cr->cr_ruidinfo, uifind(ruid));
1173 	chgproccnt(cr->cr_ruidinfo, 1, 0);
1174 	return (cr);
1175 }
1176