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