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