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