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