xref: /freebsd/sys/kern/kern_prot.c (revision 2b743a9e9ddc6736208dc8ca1ce06ce64ad20a19)
1 /*-
2  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3  *	The Regents of the University of California.
4  * (c) UNIX System Laboratories, Inc.
5  * Copyright (c) 2000-2001 Robert N. M. Watson.
6  * All rights reserved.
7  *
8  * All or some portions of this file are derived from material licensed
9  * to the University of California by American Telephone and Telegraph
10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11  * the permission of UNIX System Laboratories, Inc.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *	@(#)kern_prot.c	8.6 (Berkeley) 1/21/94
38  */
39 
40 /*
41  * System calls related to processes and protection
42  */
43 
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD$");
46 
47 #include "opt_compat.h"
48 #include "opt_mac.h"
49 
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/acct.h>
53 #include <sys/kdb.h>
54 #include <sys/kernel.h>
55 #include <sys/lock.h>
56 #include <sys/malloc.h>
57 #include <sys/mutex.h>
58 #include <sys/refcount.h>
59 #include <sys/sx.h>
60 #include <sys/priv.h>
61 #include <sys/proc.h>
62 #include <sys/sysproto.h>
63 #include <sys/jail.h>
64 #include <sys/pioctl.h>
65 #include <sys/resourcevar.h>
66 #include <sys/socket.h>
67 #include <sys/socketvar.h>
68 #include <sys/syscallsubr.h>
69 #include <sys/sysctl.h>
70 
71 #include <security/audit/audit.h>
72 #include <security/mac/mac_framework.h>
73 
74 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
75 
76 SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy");
77 
78 #ifndef _SYS_SYSPROTO_H_
79 struct getpid_args {
80 	int	dummy;
81 };
82 #endif
83 /*
84  * MPSAFE
85  */
86 /* ARGSUSED */
87 int
88 getpid(struct thread *td, struct getpid_args *uap)
89 {
90 	struct proc *p = td->td_proc;
91 
92 	td->td_retval[0] = p->p_pid;
93 #if defined(COMPAT_43)
94 	PROC_LOCK(p);
95 	td->td_retval[1] = p->p_pptr->p_pid;
96 	PROC_UNLOCK(p);
97 #endif
98 	return (0);
99 }
100 
101 #ifndef _SYS_SYSPROTO_H_
102 struct getppid_args {
103         int     dummy;
104 };
105 #endif
106 /*
107  * MPSAFE
108  */
109 /* ARGSUSED */
110 int
111 getppid(struct thread *td, struct getppid_args *uap)
112 {
113 	struct proc *p = td->td_proc;
114 
115 	PROC_LOCK(p);
116 	td->td_retval[0] = p->p_pptr->p_pid;
117 	PROC_UNLOCK(p);
118 	return (0);
119 }
120 
121 /*
122  * Get process group ID; note that POSIX getpgrp takes no parameter.
123  */
124 #ifndef _SYS_SYSPROTO_H_
125 struct getpgrp_args {
126         int     dummy;
127 };
128 #endif
129 /*
130  * MPSAFE
131  */
132 int
133 getpgrp(struct thread *td, struct getpgrp_args *uap)
134 {
135 	struct proc *p = td->td_proc;
136 
137 	PROC_LOCK(p);
138 	td->td_retval[0] = p->p_pgrp->pg_id;
139 	PROC_UNLOCK(p);
140 	return (0);
141 }
142 
143 /* Get an arbitary pid's process group id */
144 #ifndef _SYS_SYSPROTO_H_
145 struct getpgid_args {
146 	pid_t	pid;
147 };
148 #endif
149 /*
150  * MPSAFE
151  */
152 int
153 getpgid(struct thread *td, struct getpgid_args *uap)
154 {
155 	struct proc *p;
156 	int error;
157 
158 	if (uap->pid == 0) {
159 		p = td->td_proc;
160 		PROC_LOCK(p);
161 	} else {
162 		p = pfind(uap->pid);
163 		if (p == NULL)
164 			return (ESRCH);
165 		error = p_cansee(td, p);
166 		if (error) {
167 			PROC_UNLOCK(p);
168 			return (error);
169 		}
170 	}
171 	td->td_retval[0] = p->p_pgrp->pg_id;
172 	PROC_UNLOCK(p);
173 	return (0);
174 }
175 
176 /*
177  * Get an arbitary pid's session id.
178  */
179 #ifndef _SYS_SYSPROTO_H_
180 struct getsid_args {
181 	pid_t	pid;
182 };
183 #endif
184 /*
185  * MPSAFE
186  */
187 int
188 getsid(struct thread *td, struct getsid_args *uap)
189 {
190 	struct proc *p;
191 	int error;
192 
193 	if (uap->pid == 0) {
194 		p = td->td_proc;
195 		PROC_LOCK(p);
196 	} else {
197 		p = pfind(uap->pid);
198 		if (p == NULL)
199 			return (ESRCH);
200 		error = p_cansee(td, p);
201 		if (error) {
202 			PROC_UNLOCK(p);
203 			return (error);
204 		}
205 	}
206 	td->td_retval[0] = p->p_session->s_sid;
207 	PROC_UNLOCK(p);
208 	return (0);
209 }
210 
211 #ifndef _SYS_SYSPROTO_H_
212 struct getuid_args {
213         int     dummy;
214 };
215 #endif
216 /*
217  * MPSAFE
218  */
219 /* ARGSUSED */
220 int
221 getuid(struct thread *td, struct getuid_args *uap)
222 {
223 
224 	td->td_retval[0] = td->td_ucred->cr_ruid;
225 #if defined(COMPAT_43)
226 	td->td_retval[1] = td->td_ucred->cr_uid;
227 #endif
228 	return (0);
229 }
230 
231 #ifndef _SYS_SYSPROTO_H_
232 struct geteuid_args {
233         int     dummy;
234 };
235 #endif
236 /*
237  * MPSAFE
238  */
239 /* ARGSUSED */
240 int
241 geteuid(struct thread *td, struct geteuid_args *uap)
242 {
243 
244 	td->td_retval[0] = td->td_ucred->cr_uid;
245 	return (0);
246 }
247 
248 #ifndef _SYS_SYSPROTO_H_
249 struct getgid_args {
250         int     dummy;
251 };
252 #endif
253 /*
254  * MPSAFE
255  */
256 /* ARGSUSED */
257 int
258 getgid(struct thread *td, struct getgid_args *uap)
259 {
260 
261 	td->td_retval[0] = td->td_ucred->cr_rgid;
262 #if defined(COMPAT_43)
263 	td->td_retval[1] = td->td_ucred->cr_groups[0];
264 #endif
265 	return (0);
266 }
267 
268 /*
269  * Get effective group ID.  The "egid" is groups[0], and could be obtained
270  * via getgroups.  This syscall exists because it is somewhat painful to do
271  * correctly in a library function.
272  */
273 #ifndef _SYS_SYSPROTO_H_
274 struct getegid_args {
275         int     dummy;
276 };
277 #endif
278 /*
279  * MPSAFE
280  */
281 /* ARGSUSED */
282 int
283 getegid(struct thread *td, struct getegid_args *uap)
284 {
285 
286 	td->td_retval[0] = td->td_ucred->cr_groups[0];
287 	return (0);
288 }
289 
290 #ifndef _SYS_SYSPROTO_H_
291 struct getgroups_args {
292 	u_int	gidsetsize;
293 	gid_t	*gidset;
294 };
295 #endif
296 /*
297  * MPSAFE
298  */
299 int
300 getgroups(struct thread *td, register struct getgroups_args *uap)
301 {
302 	gid_t groups[NGROUPS];
303 	u_int ngrp;
304 	int error;
305 
306 	ngrp = MIN(uap->gidsetsize, NGROUPS);
307 	error = kern_getgroups(td, &ngrp, groups);
308 	if (error)
309 		return (error);
310 	if (uap->gidsetsize > 0)
311 		error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
312 	if (error == 0)
313 		td->td_retval[0] = ngrp;
314 	return (error);
315 }
316 
317 int
318 kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups)
319 {
320 	struct ucred *cred;
321 
322 	cred = td->td_ucred;
323 	if (*ngrp == 0) {
324 		*ngrp = cred->cr_ngroups;
325 		return (0);
326 	}
327 	if (*ngrp < cred->cr_ngroups)
328 		return (EINVAL);
329 	*ngrp = cred->cr_ngroups;
330 	bcopy(cred->cr_groups, groups, *ngrp * sizeof(gid_t));
331 	return (0);
332 }
333 
334 #ifndef _SYS_SYSPROTO_H_
335 struct setsid_args {
336         int     dummy;
337 };
338 #endif
339 /*
340  * MPSAFE
341  */
342 /* ARGSUSED */
343 int
344 setsid(register struct thread *td, struct setsid_args *uap)
345 {
346 	struct pgrp *pgrp;
347 	int error;
348 	struct proc *p = td->td_proc;
349 	struct pgrp *newpgrp;
350 	struct session *newsess;
351 
352 	error = 0;
353 	pgrp = NULL;
354 
355 	MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO);
356 	MALLOC(newsess, struct session *, sizeof(struct session), M_SESSION, M_WAITOK | M_ZERO);
357 
358 	sx_xlock(&proctree_lock);
359 
360 	if (p->p_pgid == p->p_pid || (pgrp = pgfind(p->p_pid)) != NULL) {
361 		if (pgrp != NULL)
362 			PGRP_UNLOCK(pgrp);
363 		error = EPERM;
364 	} else {
365 		(void)enterpgrp(p, p->p_pid, newpgrp, newsess);
366 		td->td_retval[0] = p->p_pid;
367 		newpgrp = NULL;
368 		newsess = NULL;
369 	}
370 
371 	sx_xunlock(&proctree_lock);
372 
373 	if (newpgrp != NULL)
374 		FREE(newpgrp, M_PGRP);
375 	if (newsess != NULL)
376 		FREE(newsess, M_SESSION);
377 
378 	return (error);
379 }
380 
381 /*
382  * set process group (setpgid/old setpgrp)
383  *
384  * caller does setpgid(targpid, targpgid)
385  *
386  * pid must be caller or child of caller (ESRCH)
387  * if a child
388  *	pid must be in same session (EPERM)
389  *	pid can't have done an exec (EACCES)
390  * if pgid != pid
391  * 	there must exist some pid in same session having pgid (EPERM)
392  * pid must not be session leader (EPERM)
393  */
394 #ifndef _SYS_SYSPROTO_H_
395 struct setpgid_args {
396 	int	pid;		/* target process id */
397 	int	pgid;		/* target pgrp id */
398 };
399 #endif
400 /*
401  * MPSAFE
402  */
403 /* ARGSUSED */
404 int
405 setpgid(struct thread *td, register struct setpgid_args *uap)
406 {
407 	struct proc *curp = td->td_proc;
408 	register struct proc *targp;	/* target process */
409 	register struct pgrp *pgrp;	/* target pgrp */
410 	int error;
411 	struct pgrp *newpgrp;
412 
413 	if (uap->pgid < 0)
414 		return (EINVAL);
415 
416 	error = 0;
417 
418 	MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO);
419 
420 	sx_xlock(&proctree_lock);
421 	if (uap->pid != 0 && uap->pid != curp->p_pid) {
422 		if ((targp = pfind(uap->pid)) == NULL) {
423 			error = ESRCH;
424 			goto done;
425 		}
426 		if (!inferior(targp)) {
427 			PROC_UNLOCK(targp);
428 			error = ESRCH;
429 			goto done;
430 		}
431 		if ((error = p_cansee(td, targp))) {
432 			PROC_UNLOCK(targp);
433 			goto done;
434 		}
435 		if (targp->p_pgrp == NULL ||
436 		    targp->p_session != curp->p_session) {
437 			PROC_UNLOCK(targp);
438 			error = EPERM;
439 			goto done;
440 		}
441 		if (targp->p_flag & P_EXEC) {
442 			PROC_UNLOCK(targp);
443 			error = EACCES;
444 			goto done;
445 		}
446 		PROC_UNLOCK(targp);
447 	} else
448 		targp = curp;
449 	if (SESS_LEADER(targp)) {
450 		error = EPERM;
451 		goto done;
452 	}
453 	if (uap->pgid == 0)
454 		uap->pgid = targp->p_pid;
455 	if ((pgrp = pgfind(uap->pgid)) == NULL) {
456 		if (uap->pgid == targp->p_pid) {
457 			error = enterpgrp(targp, uap->pgid, newpgrp,
458 			    NULL);
459 			if (error == 0)
460 				newpgrp = NULL;
461 		} else
462 			error = EPERM;
463 	} else {
464 		if (pgrp == targp->p_pgrp) {
465 			PGRP_UNLOCK(pgrp);
466 			goto done;
467 		}
468 		if (pgrp->pg_id != targp->p_pid &&
469 		    pgrp->pg_session != curp->p_session) {
470 			PGRP_UNLOCK(pgrp);
471 			error = EPERM;
472 			goto done;
473 		}
474 		PGRP_UNLOCK(pgrp);
475 		error = enterthispgrp(targp, pgrp);
476 	}
477 done:
478 	sx_xunlock(&proctree_lock);
479 	KASSERT((error == 0) || (newpgrp != NULL),
480 	    ("setpgid failed and newpgrp is NULL"));
481 	if (newpgrp != NULL)
482 		FREE(newpgrp, M_PGRP);
483 	return (error);
484 }
485 
486 /*
487  * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
488  * compatible.  It says that setting the uid/gid to euid/egid is a special
489  * case of "appropriate privilege".  Once the rules are expanded out, this
490  * basically means that setuid(nnn) sets all three id's, in all permitted
491  * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
492  * does not set the saved id - this is dangerous for traditional BSD
493  * programs.  For this reason, we *really* do not want to set
494  * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
495  */
496 #define POSIX_APPENDIX_B_4_2_2
497 
498 #ifndef _SYS_SYSPROTO_H_
499 struct setuid_args {
500 	uid_t	uid;
501 };
502 #endif
503 /*
504  * MPSAFE
505  */
506 /* ARGSUSED */
507 int
508 setuid(struct thread *td, struct setuid_args *uap)
509 {
510 	struct proc *p = td->td_proc;
511 	struct ucred *newcred, *oldcred;
512 	uid_t uid;
513 	struct uidinfo *uip;
514 	int error;
515 
516 	uid = uap->uid;
517 	AUDIT_ARG(uid, uid);
518 	newcred = crget();
519 	uip = uifind(uid);
520 	PROC_LOCK(p);
521 	oldcred = p->p_ucred;
522 
523 #ifdef MAC
524 	error = mac_check_proc_setuid(p, oldcred, uid);
525 	if (error)
526 		goto fail;
527 #endif
528 
529 	/*
530 	 * See if we have "permission" by POSIX 1003.1 rules.
531 	 *
532 	 * Note that setuid(geteuid()) is a special case of
533 	 * "appropriate privileges" in appendix B.4.2.2.  We need
534 	 * to use this clause to be compatible with traditional BSD
535 	 * semantics.  Basically, it means that "setuid(xx)" sets all
536 	 * three id's (assuming you have privs).
537 	 *
538 	 * Notes on the logic.  We do things in three steps.
539 	 * 1: We determine if the euid is going to change, and do EPERM
540 	 *    right away.  We unconditionally change the euid later if this
541 	 *    test is satisfied, simplifying that part of the logic.
542 	 * 2: We determine if the real and/or saved uids are going to
543 	 *    change.  Determined by compile options.
544 	 * 3: Change euid last. (after tests in #2 for "appropriate privs")
545 	 */
546 	if (uid != oldcred->cr_ruid &&		/* allow setuid(getuid()) */
547 #ifdef _POSIX_SAVED_IDS
548 	    uid != oldcred->cr_svuid &&		/* allow setuid(saved gid) */
549 #endif
550 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
551 	    uid != oldcred->cr_uid &&		/* allow setuid(geteuid()) */
552 #endif
553 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETUID,
554 	    SUSER_ALLOWJAIL)) != 0)
555 		goto fail;
556 
557 	/*
558 	 * Copy credentials so other references do not see our changes.
559 	 */
560 	crcopy(newcred, oldcred);
561 #ifdef _POSIX_SAVED_IDS
562 	/*
563 	 * Do we have "appropriate privileges" (are we root or uid == euid)
564 	 * If so, we are changing the real uid and/or saved uid.
565 	 */
566 	if (
567 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
568 	    uid == oldcred->cr_uid ||
569 #endif
570 	    /* We are using privs. */
571 	    priv_check_cred(oldcred, PRIV_CRED_SETUID, SUSER_ALLOWJAIL) == 0)
572 #endif
573 	{
574 		/*
575 		 * Set the real uid and transfer proc count to new user.
576 		 */
577 		if (uid != oldcred->cr_ruid) {
578 			change_ruid(newcred, uip);
579 			setsugid(p);
580 		}
581 		/*
582 		 * Set saved uid
583 		 *
584 		 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
585 		 * the security of seteuid() depends on it.  B.4.2.2 says it
586 		 * is important that we should do this.
587 		 */
588 		if (uid != oldcred->cr_svuid) {
589 			change_svuid(newcred, uid);
590 			setsugid(p);
591 		}
592 	}
593 
594 	/*
595 	 * In all permitted cases, we are changing the euid.
596 	 */
597 	if (uid != oldcred->cr_uid) {
598 		change_euid(newcred, uip);
599 		setsugid(p);
600 	}
601 	p->p_ucred = newcred;
602 	PROC_UNLOCK(p);
603 	uifree(uip);
604 	crfree(oldcred);
605 	return (0);
606 
607 fail:
608 	PROC_UNLOCK(p);
609 	uifree(uip);
610 	crfree(newcred);
611 	return (error);
612 }
613 
614 #ifndef _SYS_SYSPROTO_H_
615 struct seteuid_args {
616 	uid_t	euid;
617 };
618 #endif
619 /*
620  * MPSAFE
621  */
622 /* ARGSUSED */
623 int
624 seteuid(struct thread *td, struct seteuid_args *uap)
625 {
626 	struct proc *p = td->td_proc;
627 	struct ucred *newcred, *oldcred;
628 	uid_t euid;
629 	struct uidinfo *euip;
630 	int error;
631 
632 	euid = uap->euid;
633 	AUDIT_ARG(euid, euid);
634 	newcred = crget();
635 	euip = uifind(euid);
636 	PROC_LOCK(p);
637 	oldcred = p->p_ucred;
638 
639 #ifdef MAC
640 	error = mac_check_proc_seteuid(p, oldcred, euid);
641 	if (error)
642 		goto fail;
643 #endif
644 
645 	if (euid != oldcred->cr_ruid &&		/* allow seteuid(getuid()) */
646 	    euid != oldcred->cr_svuid &&	/* allow seteuid(saved uid) */
647 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID,
648 	    SUSER_ALLOWJAIL)) != 0)
649 		goto fail;
650 
651 	/*
652 	 * Everything's okay, do it.  Copy credentials so other references do
653 	 * not see our changes.
654 	 */
655 	crcopy(newcred, oldcred);
656 	if (oldcred->cr_uid != euid) {
657 		change_euid(newcred, euip);
658 		setsugid(p);
659 	}
660 	p->p_ucred = newcred;
661 	PROC_UNLOCK(p);
662 	uifree(euip);
663 	crfree(oldcred);
664 	return (0);
665 
666 fail:
667 	PROC_UNLOCK(p);
668 	uifree(euip);
669 	crfree(newcred);
670 	return (error);
671 }
672 
673 #ifndef _SYS_SYSPROTO_H_
674 struct setgid_args {
675 	gid_t	gid;
676 };
677 #endif
678 /*
679  * MPSAFE
680  */
681 /* ARGSUSED */
682 int
683 setgid(struct thread *td, struct setgid_args *uap)
684 {
685 	struct proc *p = td->td_proc;
686 	struct ucred *newcred, *oldcred;
687 	gid_t gid;
688 	int error;
689 
690 	gid = uap->gid;
691 	AUDIT_ARG(gid, gid);
692 	newcred = crget();
693 	PROC_LOCK(p);
694 	oldcred = p->p_ucred;
695 
696 #ifdef MAC
697 	error = mac_check_proc_setgid(p, oldcred, gid);
698 	if (error)
699 		goto fail;
700 #endif
701 
702 	/*
703 	 * See if we have "permission" by POSIX 1003.1 rules.
704 	 *
705 	 * Note that setgid(getegid()) is a special case of
706 	 * "appropriate privileges" in appendix B.4.2.2.  We need
707 	 * to use this clause to be compatible with traditional BSD
708 	 * semantics.  Basically, it means that "setgid(xx)" sets all
709 	 * three id's (assuming you have privs).
710 	 *
711 	 * For notes on the logic here, see setuid() above.
712 	 */
713 	if (gid != oldcred->cr_rgid &&		/* allow setgid(getgid()) */
714 #ifdef _POSIX_SAVED_IDS
715 	    gid != oldcred->cr_svgid &&		/* allow setgid(saved gid) */
716 #endif
717 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
718 	    gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
719 #endif
720 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETGID,
721 	    SUSER_ALLOWJAIL)) != 0)
722 		goto fail;
723 
724 	crcopy(newcred, oldcred);
725 #ifdef _POSIX_SAVED_IDS
726 	/*
727 	 * Do we have "appropriate privileges" (are we root or gid == egid)
728 	 * If so, we are changing the real uid and saved gid.
729 	 */
730 	if (
731 #ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
732 	    gid == oldcred->cr_groups[0] ||
733 #endif
734 	    /* We are using privs. */
735 	    priv_check_cred(oldcred, PRIV_CRED_SETGID, SUSER_ALLOWJAIL) == 0)
736 #endif
737 	{
738 		/*
739 		 * Set real gid
740 		 */
741 		if (oldcred->cr_rgid != gid) {
742 			change_rgid(newcred, gid);
743 			setsugid(p);
744 		}
745 		/*
746 		 * Set saved gid
747 		 *
748 		 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
749 		 * the security of setegid() depends on it.  B.4.2.2 says it
750 		 * is important that we should do this.
751 		 */
752 		if (oldcred->cr_svgid != gid) {
753 			change_svgid(newcred, gid);
754 			setsugid(p);
755 		}
756 	}
757 	/*
758 	 * In all cases permitted cases, we are changing the egid.
759 	 * Copy credentials so other references do not see our changes.
760 	 */
761 	if (oldcred->cr_groups[0] != gid) {
762 		change_egid(newcred, gid);
763 		setsugid(p);
764 	}
765 	p->p_ucred = newcred;
766 	PROC_UNLOCK(p);
767 	crfree(oldcred);
768 	return (0);
769 
770 fail:
771 	PROC_UNLOCK(p);
772 	crfree(newcred);
773 	return (error);
774 }
775 
776 #ifndef _SYS_SYSPROTO_H_
777 struct setegid_args {
778 	gid_t	egid;
779 };
780 #endif
781 /*
782  * MPSAFE
783  */
784 /* ARGSUSED */
785 int
786 setegid(struct thread *td, struct setegid_args *uap)
787 {
788 	struct proc *p = td->td_proc;
789 	struct ucred *newcred, *oldcred;
790 	gid_t egid;
791 	int error;
792 
793 	egid = uap->egid;
794 	AUDIT_ARG(egid, egid);
795 	newcred = crget();
796 	PROC_LOCK(p);
797 	oldcred = p->p_ucred;
798 
799 #ifdef MAC
800 	error = mac_check_proc_setegid(p, oldcred, egid);
801 	if (error)
802 		goto fail;
803 #endif
804 
805 	if (egid != oldcred->cr_rgid &&		/* allow setegid(getgid()) */
806 	    egid != oldcred->cr_svgid &&	/* allow setegid(saved gid) */
807 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID,
808 	    SUSER_ALLOWJAIL)) != 0)
809 		goto fail;
810 
811 	crcopy(newcred, oldcred);
812 	if (oldcred->cr_groups[0] != egid) {
813 		change_egid(newcred, egid);
814 		setsugid(p);
815 	}
816 	p->p_ucred = newcred;
817 	PROC_UNLOCK(p);
818 	crfree(oldcred);
819 	return (0);
820 
821 fail:
822 	PROC_UNLOCK(p);
823 	crfree(newcred);
824 	return (error);
825 }
826 
827 #ifndef _SYS_SYSPROTO_H_
828 struct setgroups_args {
829 	u_int	gidsetsize;
830 	gid_t	*gidset;
831 };
832 #endif
833 /*
834  * MPSAFE
835  */
836 /* ARGSUSED */
837 int
838 setgroups(struct thread *td, struct setgroups_args *uap)
839 {
840 	gid_t groups[NGROUPS];
841 	int error;
842 
843 	if (uap->gidsetsize > NGROUPS)
844 		return (EINVAL);
845 	error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t));
846 	if (error)
847 		return (error);
848 	return (kern_setgroups(td, uap->gidsetsize, groups));
849 }
850 
851 int
852 kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
853 {
854 	struct proc *p = td->td_proc;
855 	struct ucred *newcred, *oldcred;
856 	int error;
857 
858 	if (ngrp > NGROUPS)
859 		return (EINVAL);
860 	AUDIT_ARG(groupset, groups, ngrp);
861 	newcred = crget();
862 	PROC_LOCK(p);
863 	oldcred = p->p_ucred;
864 
865 #ifdef MAC
866 	error = mac_check_proc_setgroups(p, oldcred, ngrp, groups);
867 	if (error)
868 		goto fail;
869 #endif
870 
871 	error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS,
872 	    SUSER_ALLOWJAIL);
873 	if (error)
874 		goto fail;
875 
876 	/*
877 	 * XXX A little bit lazy here.  We could test if anything has
878 	 * changed before crcopy() and setting P_SUGID.
879 	 */
880 	crcopy(newcred, oldcred);
881 	if (ngrp < 1) {
882 		/*
883 		 * setgroups(0, NULL) is a legitimate way of clearing the
884 		 * groups vector on non-BSD systems (which generally do not
885 		 * have the egid in the groups[0]).  We risk security holes
886 		 * when running non-BSD software if we do not do the same.
887 		 */
888 		newcred->cr_ngroups = 1;
889 	} else {
890 		bcopy(groups, newcred->cr_groups, ngrp * sizeof(gid_t));
891 		newcred->cr_ngroups = ngrp;
892 	}
893 	setsugid(p);
894 	p->p_ucred = newcred;
895 	PROC_UNLOCK(p);
896 	crfree(oldcred);
897 	return (0);
898 
899 fail:
900 	PROC_UNLOCK(p);
901 	crfree(newcred);
902 	return (error);
903 }
904 
905 #ifndef _SYS_SYSPROTO_H_
906 struct setreuid_args {
907 	uid_t	ruid;
908 	uid_t	euid;
909 };
910 #endif
911 /*
912  * MPSAFE
913  */
914 /* ARGSUSED */
915 int
916 setreuid(register struct thread *td, struct setreuid_args *uap)
917 {
918 	struct proc *p = td->td_proc;
919 	struct ucred *newcred, *oldcred;
920 	uid_t euid, ruid;
921 	struct uidinfo *euip, *ruip;
922 	int error;
923 
924 	euid = uap->euid;
925 	ruid = uap->ruid;
926 	AUDIT_ARG(euid, euid);
927 	AUDIT_ARG(ruid, ruid);
928 	newcred = crget();
929 	euip = uifind(euid);
930 	ruip = uifind(ruid);
931 	PROC_LOCK(p);
932 	oldcred = p->p_ucred;
933 
934 #ifdef MAC
935 	error = mac_check_proc_setreuid(p, oldcred, ruid, euid);
936 	if (error)
937 		goto fail;
938 #endif
939 
940 	if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
941 	      ruid != oldcred->cr_svuid) ||
942 	     (euid != (uid_t)-1 && euid != oldcred->cr_uid &&
943 	      euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) &&
944 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID,
945 	     SUSER_ALLOWJAIL)) != 0)
946 		goto fail;
947 
948 	crcopy(newcred, oldcred);
949 	if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
950 		change_euid(newcred, euip);
951 		setsugid(p);
952 	}
953 	if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
954 		change_ruid(newcred, ruip);
955 		setsugid(p);
956 	}
957 	if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) &&
958 	    newcred->cr_svuid != newcred->cr_uid) {
959 		change_svuid(newcred, newcred->cr_uid);
960 		setsugid(p);
961 	}
962 	p->p_ucred = newcred;
963 	PROC_UNLOCK(p);
964 	uifree(ruip);
965 	uifree(euip);
966 	crfree(oldcred);
967 	return (0);
968 
969 fail:
970 	PROC_UNLOCK(p);
971 	uifree(ruip);
972 	uifree(euip);
973 	crfree(newcred);
974 	return (error);
975 }
976 
977 #ifndef _SYS_SYSPROTO_H_
978 struct setregid_args {
979 	gid_t	rgid;
980 	gid_t	egid;
981 };
982 #endif
983 /*
984  * MPSAFE
985  */
986 /* ARGSUSED */
987 int
988 setregid(register struct thread *td, struct setregid_args *uap)
989 {
990 	struct proc *p = td->td_proc;
991 	struct ucred *newcred, *oldcred;
992 	gid_t egid, rgid;
993 	int error;
994 
995 	egid = uap->egid;
996 	rgid = uap->rgid;
997 	AUDIT_ARG(egid, egid);
998 	AUDIT_ARG(rgid, rgid);
999 	newcred = crget();
1000 	PROC_LOCK(p);
1001 	oldcred = p->p_ucred;
1002 
1003 #ifdef MAC
1004 	error = mac_check_proc_setregid(p, oldcred, rgid, egid);
1005 	if (error)
1006 		goto fail;
1007 #endif
1008 
1009 	if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
1010 	    rgid != oldcred->cr_svgid) ||
1011 	     (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
1012 	     egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
1013 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID,
1014 	     SUSER_ALLOWJAIL)) != 0)
1015 		goto fail;
1016 
1017 	crcopy(newcred, oldcred);
1018 	if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
1019 		change_egid(newcred, egid);
1020 		setsugid(p);
1021 	}
1022 	if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
1023 		change_rgid(newcred, rgid);
1024 		setsugid(p);
1025 	}
1026 	if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) &&
1027 	    newcred->cr_svgid != newcred->cr_groups[0]) {
1028 		change_svgid(newcred, newcred->cr_groups[0]);
1029 		setsugid(p);
1030 	}
1031 	p->p_ucred = newcred;
1032 	PROC_UNLOCK(p);
1033 	crfree(oldcred);
1034 	return (0);
1035 
1036 fail:
1037 	PROC_UNLOCK(p);
1038 	crfree(newcred);
1039 	return (error);
1040 }
1041 
1042 /*
1043  * setresuid(ruid, euid, suid) is like setreuid except control over the
1044  * saved uid is explicit.
1045  */
1046 
1047 #ifndef _SYS_SYSPROTO_H_
1048 struct setresuid_args {
1049 	uid_t	ruid;
1050 	uid_t	euid;
1051 	uid_t	suid;
1052 };
1053 #endif
1054 /*
1055  * MPSAFE
1056  */
1057 /* ARGSUSED */
1058 int
1059 setresuid(register struct thread *td, struct setresuid_args *uap)
1060 {
1061 	struct proc *p = td->td_proc;
1062 	struct ucred *newcred, *oldcred;
1063 	uid_t euid, ruid, suid;
1064 	struct uidinfo *euip, *ruip;
1065 	int error;
1066 
1067 	euid = uap->euid;
1068 	ruid = uap->ruid;
1069 	suid = uap->suid;
1070 	AUDIT_ARG(euid, euid);
1071 	AUDIT_ARG(ruid, ruid);
1072 	AUDIT_ARG(suid, suid);
1073 	newcred = crget();
1074 	euip = uifind(euid);
1075 	ruip = uifind(ruid);
1076 	PROC_LOCK(p);
1077 	oldcred = p->p_ucred;
1078 
1079 #ifdef MAC
1080 	error = mac_check_proc_setresuid(p, oldcred, ruid, euid, suid);
1081 	if (error)
1082 		goto fail;
1083 #endif
1084 
1085 	if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
1086 	     ruid != oldcred->cr_svuid &&
1087 	      ruid != oldcred->cr_uid) ||
1088 	     (euid != (uid_t)-1 && euid != oldcred->cr_ruid &&
1089 	    euid != oldcred->cr_svuid &&
1090 	      euid != oldcred->cr_uid) ||
1091 	     (suid != (uid_t)-1 && suid != oldcred->cr_ruid &&
1092 	    suid != oldcred->cr_svuid &&
1093 	      suid != oldcred->cr_uid)) &&
1094 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID,
1095 	     SUSER_ALLOWJAIL)) != 0)
1096 		goto fail;
1097 
1098 	crcopy(newcred, oldcred);
1099 	if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
1100 		change_euid(newcred, euip);
1101 		setsugid(p);
1102 	}
1103 	if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
1104 		change_ruid(newcred, ruip);
1105 		setsugid(p);
1106 	}
1107 	if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) {
1108 		change_svuid(newcred, suid);
1109 		setsugid(p);
1110 	}
1111 	p->p_ucred = newcred;
1112 	PROC_UNLOCK(p);
1113 	uifree(ruip);
1114 	uifree(euip);
1115 	crfree(oldcred);
1116 	return (0);
1117 
1118 fail:
1119 	PROC_UNLOCK(p);
1120 	uifree(ruip);
1121 	uifree(euip);
1122 	crfree(newcred);
1123 	return (error);
1124 
1125 }
1126 
1127 /*
1128  * setresgid(rgid, egid, sgid) is like setregid except control over the
1129  * saved gid is explicit.
1130  */
1131 
1132 #ifndef _SYS_SYSPROTO_H_
1133 struct setresgid_args {
1134 	gid_t	rgid;
1135 	gid_t	egid;
1136 	gid_t	sgid;
1137 };
1138 #endif
1139 /*
1140  * MPSAFE
1141  */
1142 /* ARGSUSED */
1143 int
1144 setresgid(register struct thread *td, struct setresgid_args *uap)
1145 {
1146 	struct proc *p = td->td_proc;
1147 	struct ucred *newcred, *oldcred;
1148 	gid_t egid, rgid, sgid;
1149 	int error;
1150 
1151 	egid = uap->egid;
1152 	rgid = uap->rgid;
1153 	sgid = uap->sgid;
1154 	AUDIT_ARG(egid, egid);
1155 	AUDIT_ARG(rgid, rgid);
1156 	AUDIT_ARG(sgid, sgid);
1157 	newcred = crget();
1158 	PROC_LOCK(p);
1159 	oldcred = p->p_ucred;
1160 
1161 #ifdef MAC
1162 	error = mac_check_proc_setresgid(p, oldcred, rgid, egid, sgid);
1163 	if (error)
1164 		goto fail;
1165 #endif
1166 
1167 	if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
1168 	      rgid != oldcred->cr_svgid &&
1169 	      rgid != oldcred->cr_groups[0]) ||
1170 	     (egid != (gid_t)-1 && egid != oldcred->cr_rgid &&
1171 	      egid != oldcred->cr_svgid &&
1172 	      egid != oldcred->cr_groups[0]) ||
1173 	     (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
1174 	      sgid != oldcred->cr_svgid &&
1175 	      sgid != oldcred->cr_groups[0])) &&
1176 	    (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID,
1177 	     SUSER_ALLOWJAIL)) != 0)
1178 		goto fail;
1179 
1180 	crcopy(newcred, oldcred);
1181 	if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
1182 		change_egid(newcred, egid);
1183 		setsugid(p);
1184 	}
1185 	if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) {
1186 		change_rgid(newcred, rgid);
1187 		setsugid(p);
1188 	}
1189 	if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) {
1190 		change_svgid(newcred, sgid);
1191 		setsugid(p);
1192 	}
1193 	p->p_ucred = newcred;
1194 	PROC_UNLOCK(p);
1195 	crfree(oldcred);
1196 	return (0);
1197 
1198 fail:
1199 	PROC_UNLOCK(p);
1200 	crfree(newcred);
1201 	return (error);
1202 }
1203 
1204 #ifndef _SYS_SYSPROTO_H_
1205 struct getresuid_args {
1206 	uid_t	*ruid;
1207 	uid_t	*euid;
1208 	uid_t	*suid;
1209 };
1210 #endif
1211 /*
1212  * MPSAFE
1213  */
1214 /* ARGSUSED */
1215 int
1216 getresuid(register struct thread *td, struct getresuid_args *uap)
1217 {
1218 	struct ucred *cred;
1219 	int error1 = 0, error2 = 0, error3 = 0;
1220 
1221 	cred = td->td_ucred;
1222 	if (uap->ruid)
1223 		error1 = copyout(&cred->cr_ruid,
1224 		    uap->ruid, sizeof(cred->cr_ruid));
1225 	if (uap->euid)
1226 		error2 = copyout(&cred->cr_uid,
1227 		    uap->euid, sizeof(cred->cr_uid));
1228 	if (uap->suid)
1229 		error3 = copyout(&cred->cr_svuid,
1230 		    uap->suid, sizeof(cred->cr_svuid));
1231 	return (error1 ? error1 : error2 ? error2 : error3);
1232 }
1233 
1234 #ifndef _SYS_SYSPROTO_H_
1235 struct getresgid_args {
1236 	gid_t	*rgid;
1237 	gid_t	*egid;
1238 	gid_t	*sgid;
1239 };
1240 #endif
1241 /*
1242  * MPSAFE
1243  */
1244 /* ARGSUSED */
1245 int
1246 getresgid(register struct thread *td, struct getresgid_args *uap)
1247 {
1248 	struct ucred *cred;
1249 	int error1 = 0, error2 = 0, error3 = 0;
1250 
1251 	cred = td->td_ucred;
1252 	if (uap->rgid)
1253 		error1 = copyout(&cred->cr_rgid,
1254 		    uap->rgid, sizeof(cred->cr_rgid));
1255 	if (uap->egid)
1256 		error2 = copyout(&cred->cr_groups[0],
1257 		    uap->egid, sizeof(cred->cr_groups[0]));
1258 	if (uap->sgid)
1259 		error3 = copyout(&cred->cr_svgid,
1260 		    uap->sgid, sizeof(cred->cr_svgid));
1261 	return (error1 ? error1 : error2 ? error2 : error3);
1262 }
1263 
1264 #ifndef _SYS_SYSPROTO_H_
1265 struct issetugid_args {
1266 	int dummy;
1267 };
1268 #endif
1269 /*
1270  * MPSAFE
1271  */
1272 /* ARGSUSED */
1273 int
1274 issetugid(register struct thread *td, struct issetugid_args *uap)
1275 {
1276 	struct proc *p = td->td_proc;
1277 
1278 	/*
1279 	 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
1280 	 * we use P_SUGID because we consider changing the owners as
1281 	 * "tainting" as well.
1282 	 * This is significant for procs that start as root and "become"
1283 	 * a user without an exec - programs cannot know *everything*
1284 	 * that libc *might* have put in their data segment.
1285 	 */
1286 	PROC_LOCK(p);
1287 	td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
1288 	PROC_UNLOCK(p);
1289 	return (0);
1290 }
1291 
1292 /*
1293  * MPSAFE
1294  */
1295 int
1296 __setugid(struct thread *td, struct __setugid_args *uap)
1297 {
1298 #ifdef REGRESSION
1299 	struct proc *p;
1300 
1301 	p = td->td_proc;
1302 	switch (uap->flag) {
1303 	case 0:
1304 		PROC_LOCK(p);
1305 		p->p_flag &= ~P_SUGID;
1306 		PROC_UNLOCK(p);
1307 		return (0);
1308 	case 1:
1309 		PROC_LOCK(p);
1310 		p->p_flag |= P_SUGID;
1311 		PROC_UNLOCK(p);
1312 		return (0);
1313 	default:
1314 		return (EINVAL);
1315 	}
1316 #else /* !REGRESSION */
1317 
1318 	return (ENOSYS);
1319 #endif /* REGRESSION */
1320 }
1321 
1322 /*
1323  * Check if gid is a member of the group set.
1324  *
1325  * MPSAFE (cred must be held)
1326  */
1327 int
1328 groupmember(gid_t gid, struct ucred *cred)
1329 {
1330 	register gid_t *gp;
1331 	gid_t *egp;
1332 
1333 	egp = &(cred->cr_groups[cred->cr_ngroups]);
1334 	for (gp = cred->cr_groups; gp < egp; gp++)
1335 		if (*gp == gid)
1336 			return (1);
1337 	return (0);
1338 }
1339 
1340 /*
1341  * Test the active securelevel against a given level.  securelevel_gt()
1342  * implements (securelevel > level).  securelevel_ge() implements
1343  * (securelevel >= level).  Note that the logic is inverted -- these
1344  * functions return EPERM on "success" and 0 on "failure".
1345  *
1346  * XXXRW: Possibly since this has to do with privilege, it should move to
1347  * kern_priv.c.
1348  *
1349  * MPSAFE
1350  */
1351 int
1352 securelevel_gt(struct ucred *cr, int level)
1353 {
1354 	int active_securelevel;
1355 
1356 	active_securelevel = securelevel;
1357 	KASSERT(cr != NULL, ("securelevel_gt: null cr"));
1358 	if (cr->cr_prison != NULL)
1359 		active_securelevel = imax(cr->cr_prison->pr_securelevel,
1360 		    active_securelevel);
1361 	return (active_securelevel > level ? EPERM : 0);
1362 }
1363 
1364 int
1365 securelevel_ge(struct ucred *cr, int level)
1366 {
1367 	int active_securelevel;
1368 
1369 	active_securelevel = securelevel;
1370 	KASSERT(cr != NULL, ("securelevel_ge: null cr"));
1371 	if (cr->cr_prison != NULL)
1372 		active_securelevel = imax(cr->cr_prison->pr_securelevel,
1373 		    active_securelevel);
1374 	return (active_securelevel >= level ? EPERM : 0);
1375 }
1376 
1377 /*
1378  * 'see_other_uids' determines whether or not visibility of processes
1379  * and sockets with credentials holding different real uids is possible
1380  * using a variety of system MIBs.
1381  * XXX: data declarations should be together near the beginning of the file.
1382  */
1383 static int	see_other_uids = 1;
1384 SYSCTL_INT(_security_bsd, OID_AUTO, see_other_uids, CTLFLAG_RW,
1385     &see_other_uids, 0,
1386     "Unprivileged processes may see subjects/objects with different real uid");
1387 
1388 /*-
1389  * Determine if u1 "can see" the subject specified by u2, according to the
1390  * 'see_other_uids' policy.
1391  * Returns: 0 for permitted, ESRCH otherwise
1392  * Locks: none
1393  * References: *u1 and *u2 must not change during the call
1394  *             u1 may equal u2, in which case only one reference is required
1395  */
1396 static int
1397 cr_seeotheruids(struct ucred *u1, struct ucred *u2)
1398 {
1399 
1400 	if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) {
1401 		if (priv_check_cred(u1, PRIV_SEEOTHERUIDS, SUSER_ALLOWJAIL)
1402 		    != 0)
1403 			return (ESRCH);
1404 	}
1405 	return (0);
1406 }
1407 
1408 /*
1409  * 'see_other_gids' determines whether or not visibility of processes
1410  * and sockets with credentials holding different real gids is possible
1411  * using a variety of system MIBs.
1412  * XXX: data declarations should be together near the beginning of the file.
1413  */
1414 static int	see_other_gids = 1;
1415 SYSCTL_INT(_security_bsd, OID_AUTO, see_other_gids, CTLFLAG_RW,
1416     &see_other_gids, 0,
1417     "Unprivileged processes may see subjects/objects with different real gid");
1418 
1419 /*
1420  * Determine if u1 can "see" the subject specified by u2, according to the
1421  * 'see_other_gids' policy.
1422  * Returns: 0 for permitted, ESRCH otherwise
1423  * Locks: none
1424  * References: *u1 and *u2 must not change during the call
1425  *             u1 may equal u2, in which case only one reference is required
1426  */
1427 static int
1428 cr_seeothergids(struct ucred *u1, struct ucred *u2)
1429 {
1430 	int i, match;
1431 
1432 	if (!see_other_gids) {
1433 		match = 0;
1434 		for (i = 0; i < u1->cr_ngroups; i++) {
1435 			if (groupmember(u1->cr_groups[i], u2))
1436 				match = 1;
1437 			if (match)
1438 				break;
1439 		}
1440 		if (!match) {
1441 			if (priv_check_cred(u1, PRIV_SEEOTHERGIDS,
1442 			    SUSER_ALLOWJAIL) != 0)
1443 				return (ESRCH);
1444 		}
1445 	}
1446 	return (0);
1447 }
1448 
1449 /*-
1450  * Determine if u1 "can see" the subject specified by u2.
1451  * Returns: 0 for permitted, an errno value otherwise
1452  * Locks: none
1453  * References: *u1 and *u2 must not change during the call
1454  *             u1 may equal u2, in which case only one reference is required
1455  */
1456 int
1457 cr_cansee(struct ucred *u1, struct ucred *u2)
1458 {
1459 	int error;
1460 
1461 	if ((error = prison_check(u1, u2)))
1462 		return (error);
1463 #ifdef MAC
1464 	if ((error = mac_check_cred_visible(u1, u2)))
1465 		return (error);
1466 #endif
1467 	if ((error = cr_seeotheruids(u1, u2)))
1468 		return (error);
1469 	if ((error = cr_seeothergids(u1, u2)))
1470 		return (error);
1471 	return (0);
1472 }
1473 
1474 /*-
1475  * Determine if td "can see" the subject specified by p.
1476  * Returns: 0 for permitted, an errno value otherwise
1477  * Locks: Sufficient locks to protect p->p_ucred must be held.  td really
1478  *        should be curthread.
1479  * References: td and p must be valid for the lifetime of the call
1480  */
1481 int
1482 p_cansee(struct thread *td, struct proc *p)
1483 {
1484 
1485 	/* Wrap cr_cansee() for all functionality. */
1486 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
1487 	PROC_LOCK_ASSERT(p, MA_OWNED);
1488 	return (cr_cansee(td->td_ucred, p->p_ucred));
1489 }
1490 
1491 /*
1492  * 'conservative_signals' prevents the delivery of a broad class of
1493  * signals by unprivileged processes to processes that have changed their
1494  * credentials since the last invocation of execve().  This can prevent
1495  * the leakage of cached information or retained privileges as a result
1496  * of a common class of signal-related vulnerabilities.  However, this
1497  * may interfere with some applications that expect to be able to
1498  * deliver these signals to peer processes after having given up
1499  * privilege.
1500  */
1501 static int	conservative_signals = 1;
1502 SYSCTL_INT(_security_bsd, OID_AUTO, conservative_signals, CTLFLAG_RW,
1503     &conservative_signals, 0, "Unprivileged processes prevented from "
1504     "sending certain signals to processes whose credentials have changed");
1505 /*-
1506  * Determine whether cred may deliver the specified signal to proc.
1507  * Returns: 0 for permitted, an errno value otherwise.
1508  * Locks: A lock must be held for proc.
1509  * References: cred and proc must be valid for the lifetime of the call.
1510  */
1511 int
1512 cr_cansignal(struct ucred *cred, struct proc *proc, int signum)
1513 {
1514 	int error;
1515 
1516 	PROC_LOCK_ASSERT(proc, MA_OWNED);
1517 	/*
1518 	 * Jail semantics limit the scope of signalling to proc in the
1519 	 * same jail as cred, if cred is in jail.
1520 	 */
1521 	error = prison_check(cred, proc->p_ucred);
1522 	if (error)
1523 		return (error);
1524 #ifdef MAC
1525 	if ((error = mac_check_proc_signal(cred, proc, signum)))
1526 		return (error);
1527 #endif
1528 	if ((error = cr_seeotheruids(cred, proc->p_ucred)))
1529 		return (error);
1530 	if ((error = cr_seeothergids(cred, proc->p_ucred)))
1531 		return (error);
1532 
1533 	/*
1534 	 * UNIX signal semantics depend on the status of the P_SUGID
1535 	 * bit on the target process.  If the bit is set, then additional
1536 	 * restrictions are placed on the set of available signals.
1537 	 */
1538 	if (conservative_signals && (proc->p_flag & P_SUGID)) {
1539 		switch (signum) {
1540 		case 0:
1541 		case SIGKILL:
1542 		case SIGINT:
1543 		case SIGTERM:
1544 		case SIGALRM:
1545 		case SIGSTOP:
1546 		case SIGTTIN:
1547 		case SIGTTOU:
1548 		case SIGTSTP:
1549 		case SIGHUP:
1550 		case SIGUSR1:
1551 		case SIGUSR2:
1552 			/*
1553 			 * Generally, permit job and terminal control
1554 			 * signals.
1555 			 */
1556 			break;
1557 		default:
1558 			/* Not permitted without privilege. */
1559 			error = priv_check_cred(cred, PRIV_SIGNAL_SUGID,
1560 			    SUSER_ALLOWJAIL);
1561 			if (error)
1562 				return (error);
1563 		}
1564 	}
1565 
1566 	/*
1567 	 * Generally, the target credential's ruid or svuid must match the
1568 	 * subject credential's ruid or euid.
1569 	 */
1570 	if (cred->cr_ruid != proc->p_ucred->cr_ruid &&
1571 	    cred->cr_ruid != proc->p_ucred->cr_svuid &&
1572 	    cred->cr_uid != proc->p_ucred->cr_ruid &&
1573 	    cred->cr_uid != proc->p_ucred->cr_svuid) {
1574 		/* Not permitted without privilege. */
1575 		error = priv_check_cred(cred, PRIV_SIGNAL_DIFFCRED,
1576 		    SUSER_ALLOWJAIL);
1577 		if (error)
1578 			return (error);
1579 	}
1580 
1581 	return (0);
1582 }
1583 
1584 /*-
1585  * Determine whether td may deliver the specified signal to p.
1586  * Returns: 0 for permitted, an errno value otherwise
1587  * Locks: Sufficient locks to protect various components of td and p
1588  *        must be held.  td must be curthread, and a lock must be
1589  *        held for p.
1590  * References: td and p must be valid for the lifetime of the call
1591  */
1592 int
1593 p_cansignal(struct thread *td, struct proc *p, int signum)
1594 {
1595 
1596 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
1597 	PROC_LOCK_ASSERT(p, MA_OWNED);
1598 	if (td->td_proc == p)
1599 		return (0);
1600 
1601 	/*
1602 	 * UNIX signalling semantics require that processes in the same
1603 	 * session always be able to deliver SIGCONT to one another,
1604 	 * overriding the remaining protections.
1605 	 */
1606 	/* XXX: This will require an additional lock of some sort. */
1607 	if (signum == SIGCONT && td->td_proc->p_session == p->p_session)
1608 		return (0);
1609 	/*
1610 	 * Some compat layers use SIGTHR and higher signals for
1611 	 * communication between different kernel threads of the same
1612 	 * process, so that they expect that it's always possible to
1613 	 * deliver them, even for suid applications where cr_cansignal() can
1614 	 * deny such ability for security consideration.  It should be
1615 	 * pretty safe to do since the only way to create two processes
1616 	 * with the same p_leader is via rfork(2).
1617 	 */
1618 	if (td->td_proc->p_leader != NULL && signum >= SIGTHR &&
1619 	    signum < SIGTHR + 4 && td->td_proc->p_leader == p->p_leader)
1620 		return (0);
1621 
1622 	return (cr_cansignal(td->td_ucred, p, signum));
1623 }
1624 
1625 /*-
1626  * Determine whether td may reschedule p.
1627  * Returns: 0 for permitted, an errno value otherwise
1628  * Locks: Sufficient locks to protect various components of td and p
1629  *        must be held.  td must be curthread, and a lock must
1630  *        be held for p.
1631  * References: td and p must be valid for the lifetime of the call
1632  */
1633 int
1634 p_cansched(struct thread *td, struct proc *p)
1635 {
1636 	int error;
1637 
1638 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
1639 	PROC_LOCK_ASSERT(p, MA_OWNED);
1640 	if (td->td_proc == p)
1641 		return (0);
1642 	if ((error = prison_check(td->td_ucred, p->p_ucred)))
1643 		return (error);
1644 #ifdef MAC
1645 	if ((error = mac_check_proc_sched(td->td_ucred, p)))
1646 		return (error);
1647 #endif
1648 	if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred)))
1649 		return (error);
1650 	if ((error = cr_seeothergids(td->td_ucred, p->p_ucred)))
1651 		return (error);
1652 	if (td->td_ucred->cr_ruid != p->p_ucred->cr_ruid &&
1653 	    td->td_ucred->cr_uid != p->p_ucred->cr_ruid) {
1654 		error = priv_check_cred(td->td_ucred, PRIV_SCHED_DIFFCRED,
1655 		    SUSER_ALLOWJAIL);
1656 		if (error)
1657 			return (error);
1658 	}
1659 	return (0);
1660 }
1661 
1662 /*
1663  * The 'unprivileged_proc_debug' flag may be used to disable a variety of
1664  * unprivileged inter-process debugging services, including some procfs
1665  * functionality, ptrace(), and ktrace().  In the past, inter-process
1666  * debugging has been involved in a variety of security problems, and sites
1667  * not requiring the service might choose to disable it when hardening
1668  * systems.
1669  *
1670  * XXX: Should modifying and reading this variable require locking?
1671  * XXX: data declarations should be together near the beginning of the file.
1672  */
1673 static int	unprivileged_proc_debug = 1;
1674 SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW,
1675     &unprivileged_proc_debug, 0,
1676     "Unprivileged processes may use process debugging facilities");
1677 
1678 /*-
1679  * Determine whether td may debug p.
1680  * Returns: 0 for permitted, an errno value otherwise
1681  * Locks: Sufficient locks to protect various components of td and p
1682  *        must be held.  td must be curthread, and a lock must
1683  *        be held for p.
1684  * References: td and p must be valid for the lifetime of the call
1685  */
1686 int
1687 p_candebug(struct thread *td, struct proc *p)
1688 {
1689 	int credentialchanged, error, grpsubset, i, uidsubset;
1690 
1691 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
1692 	PROC_LOCK_ASSERT(p, MA_OWNED);
1693 	if (!unprivileged_proc_debug) {
1694 		error = priv_check_cred(td->td_ucred, PRIV_DEBUG_UNPRIV,
1695 		    SUSER_ALLOWJAIL);
1696 		if (error)
1697 			return (error);
1698 	}
1699 	if (td->td_proc == p)
1700 		return (0);
1701 	if ((error = prison_check(td->td_ucred, p->p_ucred)))
1702 		return (error);
1703 #ifdef MAC
1704 	if ((error = mac_check_proc_debug(td->td_ucred, p)))
1705 		return (error);
1706 #endif
1707 	if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred)))
1708 		return (error);
1709 	if ((error = cr_seeothergids(td->td_ucred, p->p_ucred)))
1710 		return (error);
1711 
1712 	/*
1713 	 * Is p's group set a subset of td's effective group set?  This
1714 	 * includes p's egid, group access list, rgid, and svgid.
1715 	 */
1716 	grpsubset = 1;
1717 	for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
1718 		if (!groupmember(p->p_ucred->cr_groups[i], td->td_ucred)) {
1719 			grpsubset = 0;
1720 			break;
1721 		}
1722 	}
1723 	grpsubset = grpsubset &&
1724 	    groupmember(p->p_ucred->cr_rgid, td->td_ucred) &&
1725 	    groupmember(p->p_ucred->cr_svgid, td->td_ucred);
1726 
1727 	/*
1728 	 * Are the uids present in p's credential equal to td's
1729 	 * effective uid?  This includes p's euid, svuid, and ruid.
1730 	 */
1731 	uidsubset = (td->td_ucred->cr_uid == p->p_ucred->cr_uid &&
1732 	    td->td_ucred->cr_uid == p->p_ucred->cr_svuid &&
1733 	    td->td_ucred->cr_uid == p->p_ucred->cr_ruid);
1734 
1735 	/*
1736 	 * Has the credential of the process changed since the last exec()?
1737 	 */
1738 	credentialchanged = (p->p_flag & P_SUGID);
1739 
1740 	/*
1741 	 * If p's gids aren't a subset, or the uids aren't a subset,
1742 	 * or the credential has changed, require appropriate privilege
1743 	 * for td to debug p.
1744 	 */
1745 	if (!grpsubset || !uidsubset) {
1746 		error = priv_check_cred(td->td_ucred, PRIV_DEBUG_DIFFCRED,
1747 		    SUSER_ALLOWJAIL);
1748 		if (error)
1749 			return (error);
1750 	}
1751 
1752 	if (credentialchanged) {
1753 		error = priv_check_cred(td->td_ucred, PRIV_DEBUG_SUGID,
1754 		    SUSER_ALLOWJAIL);
1755 		if (error)
1756 			return (error);
1757 	}
1758 
1759 	/* Can't trace init when securelevel > 0. */
1760 	if (p == initproc) {
1761 		error = securelevel_gt(td->td_ucred, 0);
1762 		if (error)
1763 			return (error);
1764 	}
1765 
1766 	/*
1767 	 * Can't trace a process that's currently exec'ing.
1768 	 *
1769 	 * XXX: Note, this is not a security policy decision, it's a
1770 	 * basic correctness/functionality decision.  Therefore, this check
1771 	 * should be moved to the caller's of p_candebug().
1772 	 */
1773 	if ((p->p_flag & P_INEXEC) != 0)
1774 		return (EAGAIN);
1775 
1776 	return (0);
1777 }
1778 
1779 /*-
1780  * Determine whether the subject represented by cred can "see" a socket.
1781  * Returns: 0 for permitted, ENOENT otherwise.
1782  */
1783 int
1784 cr_canseesocket(struct ucred *cred, struct socket *so)
1785 {
1786 	int error;
1787 
1788 	error = prison_check(cred, so->so_cred);
1789 	if (error)
1790 		return (ENOENT);
1791 #ifdef MAC
1792 	SOCK_LOCK(so);
1793 	error = mac_check_socket_visible(cred, so);
1794 	SOCK_UNLOCK(so);
1795 	if (error)
1796 		return (error);
1797 #endif
1798 	if (cr_seeotheruids(cred, so->so_cred))
1799 		return (ENOENT);
1800 	if (cr_seeothergids(cred, so->so_cred))
1801 		return (ENOENT);
1802 
1803 	return (0);
1804 }
1805 
1806 /*-
1807  * Determine whether td can wait for the exit of p.
1808  * Returns: 0 for permitted, an errno value otherwise
1809  * Locks: Sufficient locks to protect various components of td and p
1810  *        must be held.  td must be curthread, and a lock must
1811  *        be held for p.
1812  * References: td and p must be valid for the lifetime of the call
1813 
1814  */
1815 int
1816 p_canwait(struct thread *td, struct proc *p)
1817 {
1818 	int error;
1819 
1820 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
1821 	PROC_LOCK_ASSERT(p, MA_OWNED);
1822 	if ((error = prison_check(td->td_ucred, p->p_ucred)))
1823 		return (error);
1824 #ifdef MAC
1825 	if ((error = mac_check_proc_wait(td->td_ucred, p)))
1826 		return (error);
1827 #endif
1828 #if 0
1829 	/* XXXMAC: This could have odd effects on some shells. */
1830 	if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred)))
1831 		return (error);
1832 #endif
1833 
1834 	return (0);
1835 }
1836 
1837 /*
1838  * Allocate a zeroed cred structure.
1839  * MPSAFE
1840  */
1841 struct ucred *
1842 crget(void)
1843 {
1844 	register struct ucred *cr;
1845 
1846 	MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
1847 	refcount_init(&cr->cr_ref, 1);
1848 #ifdef MAC
1849 	mac_init_cred(cr);
1850 #endif
1851 	return (cr);
1852 }
1853 
1854 /*
1855  * Claim another reference to a ucred structure.
1856  * MPSAFE
1857  */
1858 struct ucred *
1859 crhold(struct ucred *cr)
1860 {
1861 
1862 	refcount_acquire(&cr->cr_ref);
1863 	return (cr);
1864 }
1865 
1866 /*
1867  * Free a cred structure.
1868  * Throws away space when ref count gets to 0.
1869  * MPSAFE
1870  */
1871 void
1872 crfree(struct ucred *cr)
1873 {
1874 
1875 	KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref));
1876 	KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred"));
1877 	if (refcount_release(&cr->cr_ref)) {
1878 		/*
1879 		 * Some callers of crget(), such as nfs_statfs(),
1880 		 * allocate a temporary credential, but don't
1881 		 * allocate a uidinfo structure.
1882 		 */
1883 		if (cr->cr_uidinfo != NULL)
1884 			uifree(cr->cr_uidinfo);
1885 		if (cr->cr_ruidinfo != NULL)
1886 			uifree(cr->cr_ruidinfo);
1887 		/*
1888 		 * Free a prison, if any.
1889 		 */
1890 		if (jailed(cr))
1891 			prison_free(cr->cr_prison);
1892 #ifdef MAC
1893 		mac_destroy_cred(cr);
1894 #endif
1895 		FREE(cr, M_CRED);
1896 	}
1897 }
1898 
1899 /*
1900  * Check to see if this ucred is shared.
1901  * MPSAFE
1902  */
1903 int
1904 crshared(struct ucred *cr)
1905 {
1906 
1907 	return (cr->cr_ref > 1);
1908 }
1909 
1910 /*
1911  * Copy a ucred's contents from a template.  Does not block.
1912  * MPSAFE
1913  */
1914 void
1915 crcopy(struct ucred *dest, struct ucred *src)
1916 {
1917 
1918 	KASSERT(crshared(dest) == 0, ("crcopy of shared ucred"));
1919 	bcopy(&src->cr_startcopy, &dest->cr_startcopy,
1920 	    (unsigned)((caddr_t)&src->cr_endcopy -
1921 		(caddr_t)&src->cr_startcopy));
1922 	uihold(dest->cr_uidinfo);
1923 	uihold(dest->cr_ruidinfo);
1924 	if (jailed(dest))
1925 		prison_hold(dest->cr_prison);
1926 #ifdef MAC
1927 	mac_copy_cred(src, dest);
1928 #endif
1929 }
1930 
1931 /*
1932  * Dup cred struct to a new held one.
1933  * MPSAFE
1934  */
1935 struct ucred *
1936 crdup(struct ucred *cr)
1937 {
1938 	struct ucred *newcr;
1939 
1940 	newcr = crget();
1941 	crcopy(newcr, cr);
1942 	return (newcr);
1943 }
1944 
1945 /*
1946  * Fill in a struct xucred based on a struct ucred.
1947  * MPSAFE
1948  */
1949 void
1950 cru2x(struct ucred *cr, struct xucred *xcr)
1951 {
1952 
1953 	bzero(xcr, sizeof(*xcr));
1954 	xcr->cr_version = XUCRED_VERSION;
1955 	xcr->cr_uid = cr->cr_uid;
1956 	xcr->cr_ngroups = cr->cr_ngroups;
1957 	bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1958 }
1959 
1960 /*
1961  * small routine to swap a thread's current ucred for the correct one
1962  * taken from the process.
1963  * MPSAFE
1964  */
1965 void
1966 cred_update_thread(struct thread *td)
1967 {
1968 	struct proc *p;
1969 	struct ucred *cred;
1970 
1971 	p = td->td_proc;
1972 	cred = td->td_ucred;
1973 	PROC_LOCK(p);
1974 	td->td_ucred = crhold(p->p_ucred);
1975 	PROC_UNLOCK(p);
1976 	if (cred != NULL)
1977 		crfree(cred);
1978 }
1979 
1980 /*
1981  * Get login name, if available.
1982  */
1983 #ifndef _SYS_SYSPROTO_H_
1984 struct getlogin_args {
1985 	char	*namebuf;
1986 	u_int	namelen;
1987 };
1988 #endif
1989 /*
1990  * MPSAFE
1991  */
1992 /* ARGSUSED */
1993 int
1994 getlogin(struct thread *td, struct getlogin_args *uap)
1995 {
1996 	int error;
1997 	char login[MAXLOGNAME];
1998 	struct proc *p = td->td_proc;
1999 
2000 	if (uap->namelen > MAXLOGNAME)
2001 		uap->namelen = MAXLOGNAME;
2002 	PROC_LOCK(p);
2003 	SESS_LOCK(p->p_session);
2004 	bcopy(p->p_session->s_login, login, uap->namelen);
2005 	SESS_UNLOCK(p->p_session);
2006 	PROC_UNLOCK(p);
2007 	error = copyout(login, uap->namebuf, uap->namelen);
2008 	return(error);
2009 }
2010 
2011 /*
2012  * Set login name.
2013  */
2014 #ifndef _SYS_SYSPROTO_H_
2015 struct setlogin_args {
2016 	char	*namebuf;
2017 };
2018 #endif
2019 /*
2020  * MPSAFE
2021  */
2022 /* ARGSUSED */
2023 int
2024 setlogin(struct thread *td, struct setlogin_args *uap)
2025 {
2026 	struct proc *p = td->td_proc;
2027 	int error;
2028 	char logintmp[MAXLOGNAME];
2029 
2030 	error = priv_check_cred(td->td_ucred, PRIV_PROC_SETLOGIN,
2031 	    SUSER_ALLOWJAIL);
2032 	if (error)
2033 		return (error);
2034 	error = copyinstr(uap->namebuf, logintmp, sizeof(logintmp), NULL);
2035 	if (error == ENAMETOOLONG)
2036 		error = EINVAL;
2037 	else if (!error) {
2038 		PROC_LOCK(p);
2039 		SESS_LOCK(p->p_session);
2040 		(void) memcpy(p->p_session->s_login, logintmp,
2041 		    sizeof(logintmp));
2042 		SESS_UNLOCK(p->p_session);
2043 		PROC_UNLOCK(p);
2044 	}
2045 	return (error);
2046 }
2047 
2048 void
2049 setsugid(struct proc *p)
2050 {
2051 
2052 	PROC_LOCK_ASSERT(p, MA_OWNED);
2053 	p->p_flag |= P_SUGID;
2054 	if (!(p->p_pfsflags & PF_ISUGID))
2055 		p->p_stops = 0;
2056 }
2057 
2058 /*-
2059  * Change a process's effective uid.
2060  * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified.
2061  * References: newcred must be an exclusive credential reference for the
2062  *             duration of the call.
2063  */
2064 void
2065 change_euid(struct ucred *newcred, struct uidinfo *euip)
2066 {
2067 
2068 	newcred->cr_uid = euip->ui_uid;
2069 	uihold(euip);
2070 	uifree(newcred->cr_uidinfo);
2071 	newcred->cr_uidinfo = euip;
2072 }
2073 
2074 /*-
2075  * Change a process's effective gid.
2076  * Side effects: newcred->cr_gid will be modified.
2077  * References: newcred must be an exclusive credential reference for the
2078  *             duration of the call.
2079  */
2080 void
2081 change_egid(struct ucred *newcred, gid_t egid)
2082 {
2083 
2084 	newcred->cr_groups[0] = egid;
2085 }
2086 
2087 /*-
2088  * Change a process's real uid.
2089  * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo
2090  *               will be updated, and the old and new cr_ruidinfo proc
2091  *               counts will be updated.
2092  * References: newcred must be an exclusive credential reference for the
2093  *             duration of the call.
2094  */
2095 void
2096 change_ruid(struct ucred *newcred, struct uidinfo *ruip)
2097 {
2098 
2099 	(void)chgproccnt(newcred->cr_ruidinfo, -1, 0);
2100 	newcred->cr_ruid = ruip->ui_uid;
2101 	uihold(ruip);
2102 	uifree(newcred->cr_ruidinfo);
2103 	newcred->cr_ruidinfo = ruip;
2104 	(void)chgproccnt(newcred->cr_ruidinfo, 1, 0);
2105 }
2106 
2107 /*-
2108  * Change a process's real gid.
2109  * Side effects: newcred->cr_rgid will be updated.
2110  * References: newcred must be an exclusive credential reference for the
2111  *             duration of the call.
2112  */
2113 void
2114 change_rgid(struct ucred *newcred, gid_t rgid)
2115 {
2116 
2117 	newcred->cr_rgid = rgid;
2118 }
2119 
2120 /*-
2121  * Change a process's saved uid.
2122  * Side effects: newcred->cr_svuid will be updated.
2123  * References: newcred must be an exclusive credential reference for the
2124  *             duration of the call.
2125  */
2126 void
2127 change_svuid(struct ucred *newcred, uid_t svuid)
2128 {
2129 
2130 	newcred->cr_svuid = svuid;
2131 }
2132 
2133 /*-
2134  * Change a process's saved gid.
2135  * Side effects: newcred->cr_svgid will be updated.
2136  * References: newcred must be an exclusive credential reference for the
2137  *             duration of the call.
2138  */
2139 void
2140 change_svgid(struct ucred *newcred, gid_t svgid)
2141 {
2142 
2143 	newcred->cr_svgid = svgid;
2144 }
2145