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