kern_prot.c revision 72786
1/*
2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	@(#)kern_prot.c	8.6 (Berkeley) 1/21/94
39 * $FreeBSD: head/sys/kern/kern_prot.c 72786 2001-02-21 06:39:57Z rwatson $
40 */
41
42/*
43 * System calls related to processes and protection
44 */
45
46#include "opt_compat.h"
47
48#include <sys/param.h>
49#include <sys/acct.h>
50#include <sys/systm.h>
51#include <sys/sysproto.h>
52#include <sys/kernel.h>
53#include <sys/lock.h>
54#include <sys/proc.h>
55#include <sys/malloc.h>
56#include <sys/pioctl.h>
57#include <sys/resourcevar.h>
58#include <sys/sysctl.h>
59#include <sys/jail.h>
60
61static MALLOC_DEFINE(M_CRED, "cred", "credentials");
62
63#ifndef _SYS_SYSPROTO_H_
64struct getpid_args {
65	int	dummy;
66};
67#endif
68
69/*
70 * getpid - MP SAFE
71 */
72
73/* ARGSUSED */
74int
75getpid(p, uap)
76	struct proc *p;
77	struct getpid_args *uap;
78{
79
80	p->p_retval[0] = p->p_pid;
81#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
82	PROCTREE_LOCK(PT_SHARED);
83	p->p_retval[1] = p->p_pptr->p_pid;
84	PROCTREE_LOCK(PT_RELEASE);
85#endif
86	return (0);
87}
88
89/*
90 * getppid - MP SAFE
91 */
92
93#ifndef _SYS_SYSPROTO_H_
94struct getppid_args {
95        int     dummy;
96};
97#endif
98/* ARGSUSED */
99int
100getppid(p, uap)
101	struct proc *p;
102	struct getppid_args *uap;
103{
104
105	PROCTREE_LOCK(PT_SHARED);
106	p->p_retval[0] = p->p_pptr->p_pid;
107	PROCTREE_LOCK(PT_RELEASE);
108	return (0);
109}
110
111/*
112 * Get process group ID; note that POSIX getpgrp takes no parameter
113 *
114 * MP SAFE
115 */
116#ifndef _SYS_SYSPROTO_H_
117struct getpgrp_args {
118        int     dummy;
119};
120#endif
121
122int
123getpgrp(p, uap)
124	struct proc *p;
125	struct getpgrp_args *uap;
126{
127
128	p->p_retval[0] = p->p_pgrp->pg_id;
129	return (0);
130}
131
132/* Get an arbitary pid's process group id */
133#ifndef _SYS_SYSPROTO_H_
134struct getpgid_args {
135	pid_t	pid;
136};
137#endif
138
139int
140getpgid(p, uap)
141	struct proc *p;
142	struct getpgid_args *uap;
143{
144	struct proc *pt;
145
146	pt = p;
147	if (uap->pid == 0)
148		goto found;
149
150	if ((pt = pfind(uap->pid)) == 0)
151		return ESRCH;
152found:
153	p->p_retval[0] = pt->p_pgrp->pg_id;
154	return 0;
155}
156
157/*
158 * Get an arbitary pid's session id.
159 */
160#ifndef _SYS_SYSPROTO_H_
161struct getsid_args {
162	pid_t	pid;
163};
164#endif
165
166int
167getsid(p, uap)
168	struct proc *p;
169	struct getsid_args *uap;
170{
171	struct proc *pt;
172
173	pt = p;
174	if (uap->pid == 0)
175		goto found;
176
177	if ((pt = pfind(uap->pid)) == 0)
178		return ESRCH;
179found:
180	p->p_retval[0] = pt->p_session->s_sid;
181	return 0;
182}
183
184
185/*
186 * getuid() - MP SAFE
187 */
188#ifndef _SYS_SYSPROTO_H_
189struct getuid_args {
190        int     dummy;
191};
192#endif
193
194/* ARGSUSED */
195int
196getuid(p, uap)
197	struct proc *p;
198	struct getuid_args *uap;
199{
200
201	p->p_retval[0] = p->p_cred->p_ruid;
202#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
203	p->p_retval[1] = p->p_ucred->cr_uid;
204#endif
205	return (0);
206}
207
208/*
209 * geteuid() - MP SAFE
210 */
211#ifndef _SYS_SYSPROTO_H_
212struct geteuid_args {
213        int     dummy;
214};
215#endif
216
217/* ARGSUSED */
218int
219geteuid(p, uap)
220	struct proc *p;
221	struct geteuid_args *uap;
222{
223
224	p->p_retval[0] = p->p_ucred->cr_uid;
225	return (0);
226}
227
228/*
229 * getgid() - MP SAFE
230 */
231#ifndef _SYS_SYSPROTO_H_
232struct getgid_args {
233        int     dummy;
234};
235#endif
236
237/* ARGSUSED */
238int
239getgid(p, uap)
240	struct proc *p;
241	struct getgid_args *uap;
242{
243
244	p->p_retval[0] = p->p_cred->p_rgid;
245#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
246	p->p_retval[1] = p->p_ucred->cr_groups[0];
247#endif
248	return (0);
249}
250
251/*
252 * Get effective group ID.  The "egid" is groups[0], and could be obtained
253 * via getgroups.  This syscall exists because it is somewhat painful to do
254 * correctly in a library function.
255 */
256#ifndef _SYS_SYSPROTO_H_
257struct getegid_args {
258        int     dummy;
259};
260#endif
261
262/* ARGSUSED */
263int
264getegid(p, uap)
265	struct proc *p;
266	struct getegid_args *uap;
267{
268
269	p->p_retval[0] = p->p_ucred->cr_groups[0];
270	return (0);
271}
272
273#ifndef _SYS_SYSPROTO_H_
274struct getgroups_args {
275	u_int	gidsetsize;
276	gid_t	*gidset;
277};
278#endif
279int
280getgroups(p, uap)
281	struct proc *p;
282	register struct	getgroups_args *uap;
283{
284	register struct pcred *pc = p->p_cred;
285	register u_int ngrp;
286	int error;
287
288	if ((ngrp = uap->gidsetsize) == 0) {
289		p->p_retval[0] = pc->pc_ucred->cr_ngroups;
290		return (0);
291	}
292	if (ngrp < pc->pc_ucred->cr_ngroups)
293		return (EINVAL);
294	ngrp = pc->pc_ucred->cr_ngroups;
295	if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups,
296	    (caddr_t)uap->gidset, ngrp * sizeof(gid_t))))
297		return (error);
298	p->p_retval[0] = ngrp;
299	return (0);
300}
301
302#ifndef _SYS_SYSPROTO_H_
303struct setsid_args {
304        int     dummy;
305};
306#endif
307
308/* ARGSUSED */
309int
310setsid(p, uap)
311	register struct proc *p;
312	struct setsid_args *uap;
313{
314
315	if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
316		return (EPERM);
317	} else {
318		(void)enterpgrp(p, p->p_pid, 1);
319		p->p_retval[0] = p->p_pid;
320		return (0);
321	}
322}
323
324/*
325 * set process group (setpgid/old setpgrp)
326 *
327 * caller does setpgid(targpid, targpgid)
328 *
329 * pid must be caller or child of caller (ESRCH)
330 * if a child
331 *	pid must be in same session (EPERM)
332 *	pid can't have done an exec (EACCES)
333 * if pgid != pid
334 * 	there must exist some pid in same session having pgid (EPERM)
335 * pid must not be session leader (EPERM)
336 */
337#ifndef _SYS_SYSPROTO_H_
338struct setpgid_args {
339	int	pid;	/* target process id */
340	int	pgid;	/* target pgrp id */
341};
342#endif
343/* ARGSUSED */
344int
345setpgid(curp, uap)
346	struct proc *curp;
347	register struct setpgid_args *uap;
348{
349	register struct proc *targp;		/* target process */
350	register struct pgrp *pgrp;		/* target pgrp */
351
352	if (uap->pgid < 0)
353		return (EINVAL);
354	if (uap->pid != 0 && uap->pid != curp->p_pid) {
355		if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
356			return (ESRCH);
357		if (targp->p_pgrp == NULL ||  targp->p_session != curp->p_session)
358			return (EPERM);
359		if (targp->p_flag & P_EXEC)
360			return (EACCES);
361	} else
362		targp = curp;
363	if (SESS_LEADER(targp))
364		return (EPERM);
365	if (uap->pgid == 0)
366		uap->pgid = targp->p_pid;
367	else if (uap->pgid != targp->p_pid)
368		if ((pgrp = pgfind(uap->pgid)) == 0 ||
369	            pgrp->pg_session != curp->p_session)
370			return (EPERM);
371	return (enterpgrp(targp, uap->pgid, 0));
372}
373
374/*
375 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
376 * compatible.  It says that setting the uid/gid to euid/egid is a special
377 * case of "appropriate privilege".  Once the rules are expanded out, this
378 * basically means that setuid(nnn) sets all three id's, in all permitted
379 * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
380 * does not set the saved id - this is dangerous for traditional BSD
381 * programs.  For this reason, we *really* do not want to set
382 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
383 */
384#define POSIX_APPENDIX_B_4_2_2
385
386#ifndef _SYS_SYSPROTO_H_
387struct setuid_args {
388	uid_t	uid;
389};
390#endif
391/* ARGSUSED */
392int
393setuid(p, uap)
394	struct proc *p;
395	struct setuid_args *uap;
396{
397	register struct pcred *pc = p->p_cred;
398	register uid_t uid;
399	int error;
400
401	/*
402	 * See if we have "permission" by POSIX 1003.1 rules.
403	 *
404	 * Note that setuid(geteuid()) is a special case of
405	 * "appropriate privileges" in appendix B.4.2.2.  We need
406	 * to use this clause to be compatible with traditional BSD
407	 * semantics.  Basically, it means that "setuid(xx)" sets all
408	 * three id's (assuming you have privs).
409	 *
410	 * Notes on the logic.  We do things in three steps.
411	 * 1: We determine if the euid is going to change, and do EPERM
412	 *    right away.  We unconditionally change the euid later if this
413	 *    test is satisfied, simplifying that part of the logic.
414	 * 2: We determine if the real and/or saved uid's are going to
415	 *    change.  Determined by compile options.
416	 * 3: Change euid last. (after tests in #2 for "appropriate privs")
417	 */
418	uid = uap->uid;
419	if (uid != pc->p_ruid &&		/* allow setuid(getuid()) */
420#ifdef _POSIX_SAVED_IDS
421	    uid != pc->p_svuid &&		/* allow setuid(saved gid) */
422#endif
423#ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
424	    uid != pc->pc_ucred->cr_uid &&	/* allow setuid(geteuid()) */
425#endif
426	    (error = suser_xxx(0, p, PRISON_ROOT)))
427		return (error);
428
429#ifdef _POSIX_SAVED_IDS
430	/*
431	 * Do we have "appropriate privileges" (are we root or uid == euid)
432	 * If so, we are changing the real uid and/or saved uid.
433	 */
434	if (
435#ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
436	    uid == pc->pc_ucred->cr_uid ||
437#endif
438	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
439#endif
440	{
441		/*
442		 * Set the real uid and transfer proc count to new user.
443		 */
444		if (uid != pc->p_ruid) {
445			change_ruid(p, uid);
446			setsugid(p);
447		}
448		/*
449		 * Set saved uid
450		 *
451		 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
452		 * the security of seteuid() depends on it.  B.4.2.2 says it
453		 * is important that we should do this.
454		 */
455		if (pc->p_svuid != uid) {
456			pc->p_svuid = uid;
457			setsugid(p);
458		}
459	}
460
461	/*
462	 * In all permitted cases, we are changing the euid.
463	 * Copy credentials so other references do not see our changes.
464	 */
465	if (pc->pc_ucred->cr_uid != uid) {
466		change_euid(p, uid);
467		setsugid(p);
468	}
469	return (0);
470}
471
472#ifndef _SYS_SYSPROTO_H_
473struct seteuid_args {
474	uid_t	euid;
475};
476#endif
477/* ARGSUSED */
478int
479seteuid(p, uap)
480	struct proc *p;
481	struct seteuid_args *uap;
482{
483	register struct pcred *pc = p->p_cred;
484	register uid_t euid;
485	int error;
486
487	euid = uap->euid;
488	if (euid != pc->p_ruid &&		/* allow seteuid(getuid()) */
489	    euid != pc->p_svuid &&		/* allow seteuid(saved uid) */
490	    (error = suser_xxx(0, p, PRISON_ROOT)))
491		return (error);
492	/*
493	 * Everything's okay, do it.  Copy credentials so other references do
494	 * not see our changes.
495	 */
496	if (pc->pc_ucred->cr_uid != euid) {
497		change_euid(p, euid);
498		setsugid(p);
499	}
500	return (0);
501}
502
503#ifndef _SYS_SYSPROTO_H_
504struct setgid_args {
505	gid_t	gid;
506};
507#endif
508/* ARGSUSED */
509int
510setgid(p, uap)
511	struct proc *p;
512	struct setgid_args *uap;
513{
514	register struct pcred *pc = p->p_cred;
515	register gid_t gid;
516	int error;
517
518	/*
519	 * See if we have "permission" by POSIX 1003.1 rules.
520	 *
521	 * Note that setgid(getegid()) is a special case of
522	 * "appropriate privileges" in appendix B.4.2.2.  We need
523	 * to use this clause to be compatible with traditional BSD
524	 * semantics.  Basically, it means that "setgid(xx)" sets all
525	 * three id's (assuming you have privs).
526	 *
527	 * For notes on the logic here, see setuid() above.
528	 */
529	gid = uap->gid;
530	if (gid != pc->p_rgid &&		/* allow setgid(getgid()) */
531#ifdef _POSIX_SAVED_IDS
532	    gid != pc->p_svgid &&		/* allow setgid(saved gid) */
533#endif
534#ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
535	    gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */
536#endif
537	    (error = suser_xxx(0, p, PRISON_ROOT)))
538		return (error);
539
540#ifdef _POSIX_SAVED_IDS
541	/*
542	 * Do we have "appropriate privileges" (are we root or gid == egid)
543	 * If so, we are changing the real uid and saved gid.
544	 */
545	if (
546#ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
547	    gid == pc->pc_ucred->cr_groups[0] ||
548#endif
549	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
550#endif
551	{
552		/*
553		 * Set real gid
554		 */
555		if (pc->p_rgid != gid) {
556			pc->p_rgid = gid;
557			setsugid(p);
558		}
559		/*
560		 * Set saved gid
561		 *
562		 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
563		 * the security of setegid() depends on it.  B.4.2.2 says it
564		 * is important that we should do this.
565		 */
566		if (pc->p_svgid != gid) {
567			pc->p_svgid = gid;
568			setsugid(p);
569		}
570	}
571	/*
572	 * In all cases permitted cases, we are changing the egid.
573	 * Copy credentials so other references do not see our changes.
574	 */
575	if (pc->pc_ucred->cr_groups[0] != gid) {
576		pc->pc_ucred = crcopy(pc->pc_ucred);
577		pc->pc_ucred->cr_groups[0] = gid;
578		setsugid(p);
579	}
580	return (0);
581}
582
583#ifndef _SYS_SYSPROTO_H_
584struct setegid_args {
585	gid_t	egid;
586};
587#endif
588/* ARGSUSED */
589int
590setegid(p, uap)
591	struct proc *p;
592	struct setegid_args *uap;
593{
594	register struct pcred *pc = p->p_cred;
595	register gid_t egid;
596	int error;
597
598	egid = uap->egid;
599	if (egid != pc->p_rgid &&		/* allow setegid(getgid()) */
600	    egid != pc->p_svgid &&		/* allow setegid(saved gid) */
601	    (error = suser_xxx(0, p, PRISON_ROOT)))
602		return (error);
603	if (pc->pc_ucred->cr_groups[0] != egid) {
604		pc->pc_ucred = crcopy(pc->pc_ucred);
605		pc->pc_ucred->cr_groups[0] = egid;
606		setsugid(p);
607	}
608	return (0);
609}
610
611#ifndef _SYS_SYSPROTO_H_
612struct setgroups_args {
613	u_int	gidsetsize;
614	gid_t	*gidset;
615};
616#endif
617/* ARGSUSED */
618int
619setgroups(p, uap)
620	struct proc *p;
621	struct setgroups_args *uap;
622{
623	register struct pcred *pc = p->p_cred;
624	register u_int ngrp;
625	int error;
626
627	if ((error = suser_xxx(0, p, PRISON_ROOT)))
628		return (error);
629	ngrp = uap->gidsetsize;
630	if (ngrp > NGROUPS)
631		return (EINVAL);
632	/*
633	 * XXX A little bit lazy here.  We could test if anything has
634	 * changed before crcopy() and setting P_SUGID.
635	 */
636	pc->pc_ucred = crcopy(pc->pc_ucred);
637	if (ngrp < 1) {
638		/*
639		 * setgroups(0, NULL) is a legitimate way of clearing the
640		 * groups vector on non-BSD systems (which generally do not
641		 * have the egid in the groups[0]).  We risk security holes
642		 * when running non-BSD software if we do not do the same.
643		 */
644		pc->pc_ucred->cr_ngroups = 1;
645	} else {
646		if ((error = copyin((caddr_t)uap->gidset,
647		    (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t))))
648			return (error);
649		pc->pc_ucred->cr_ngroups = ngrp;
650	}
651	setsugid(p);
652	return (0);
653}
654
655#ifndef _SYS_SYSPROTO_H_
656struct setreuid_args {
657	uid_t	ruid;
658	uid_t	euid;
659};
660#endif
661/* ARGSUSED */
662int
663setreuid(p, uap)
664	register struct proc *p;
665	struct setreuid_args *uap;
666{
667	register struct pcred *pc = p->p_cred;
668	register uid_t ruid, euid;
669	int error;
670
671	ruid = uap->ruid;
672	euid = uap->euid;
673	if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) ||
674	     (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid &&
675	     euid != pc->p_ruid && euid != pc->p_svuid)) &&
676	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
677		return (error);
678
679	if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
680		change_euid(p, euid);
681		setsugid(p);
682	}
683	if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {
684		change_ruid(p, ruid);
685		setsugid(p);
686	}
687	if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) &&
688	    pc->p_svuid != pc->pc_ucred->cr_uid) {
689		pc->p_svuid = pc->pc_ucred->cr_uid;
690		setsugid(p);
691	}
692	return (0);
693}
694
695#ifndef _SYS_SYSPROTO_H_
696struct setregid_args {
697	gid_t	rgid;
698	gid_t	egid;
699};
700#endif
701/* ARGSUSED */
702int
703setregid(p, uap)
704	register struct proc *p;
705	struct setregid_args *uap;
706{
707	register struct pcred *pc = p->p_cred;
708	register gid_t rgid, egid;
709	int error;
710
711	rgid = uap->rgid;
712	egid = uap->egid;
713	if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) ||
714	     (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] &&
715	     egid != pc->p_rgid && egid != pc->p_svgid)) &&
716	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
717		return (error);
718
719	if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
720		pc->pc_ucred = crcopy(pc->pc_ucred);
721		pc->pc_ucred->cr_groups[0] = egid;
722		setsugid(p);
723	}
724	if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {
725		pc->p_rgid = rgid;
726		setsugid(p);
727	}
728	if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) &&
729	    pc->p_svgid != pc->pc_ucred->cr_groups[0]) {
730		pc->p_svgid = pc->pc_ucred->cr_groups[0];
731		setsugid(p);
732	}
733	return (0);
734}
735
736/*
737 * setresuid(ruid, euid, suid) is like setreuid except control over the
738 * saved uid is explicit.
739 */
740
741#ifndef _SYS_SYSPROTO_H_
742struct setresuid_args {
743	uid_t	ruid;
744	uid_t	euid;
745	uid_t	suid;
746};
747#endif
748/* ARGSUSED */
749int
750setresuid(p, uap)
751	register struct proc *p;
752	struct setresuid_args *uap;
753{
754	register struct pcred *pc = p->p_cred;
755	register uid_t ruid, euid, suid;
756	int error;
757
758	ruid = uap->ruid;
759	euid = uap->euid;
760	suid = uap->suid;
761	if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid &&
762	      ruid != pc->pc_ucred->cr_uid) ||
763	     (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid &&
764	      euid != pc->pc_ucred->cr_uid) ||
765	     (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid &&
766	      suid != pc->pc_ucred->cr_uid)) &&
767	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
768		return (error);
769	if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
770		change_euid(p, euid);
771		setsugid(p);
772	}
773	if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {
774		change_ruid(p, ruid);
775		setsugid(p);
776	}
777	if (suid != (uid_t)-1 && pc->p_svuid != suid) {
778		pc->p_svuid = suid;
779		setsugid(p);
780	}
781	return (0);
782}
783
784/*
785 * setresgid(rgid, egid, sgid) is like setregid except control over the
786 * saved gid is explicit.
787 */
788
789#ifndef _SYS_SYSPROTO_H_
790struct setresgid_args {
791	gid_t	rgid;
792	gid_t	egid;
793	gid_t	sgid;
794};
795#endif
796/* ARGSUSED */
797int
798setresgid(p, uap)
799	register struct proc *p;
800	struct setresgid_args *uap;
801{
802	register struct pcred *pc = p->p_cred;
803	register gid_t rgid, egid, sgid;
804	int error;
805
806	rgid = uap->rgid;
807	egid = uap->egid;
808	sgid = uap->sgid;
809	if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid &&
810	      rgid != pc->pc_ucred->cr_groups[0]) ||
811	     (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid &&
812	      egid != pc->pc_ucred->cr_groups[0]) ||
813	     (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid &&
814	      sgid != pc->pc_ucred->cr_groups[0])) &&
815	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
816		return (error);
817
818	if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
819		pc->pc_ucred = crcopy(pc->pc_ucred);
820		pc->pc_ucred->cr_groups[0] = egid;
821		setsugid(p);
822	}
823	if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {
824		pc->p_rgid = rgid;
825		setsugid(p);
826	}
827	if (sgid != (gid_t)-1 && pc->p_svgid != sgid) {
828		pc->p_svgid = sgid;
829		setsugid(p);
830	}
831	return (0);
832}
833
834#ifndef _SYS_SYSPROTO_H_
835struct getresuid_args {
836	uid_t	*ruid;
837	uid_t	*euid;
838	uid_t	*suid;
839};
840#endif
841/* ARGSUSED */
842int
843getresuid(p, uap)
844	register struct proc *p;
845	struct getresuid_args *uap;
846{
847	struct pcred *pc = p->p_cred;
848	int error1 = 0, error2 = 0, error3 = 0;
849
850	if (uap->ruid)
851		error1 = copyout((caddr_t)&pc->p_ruid,
852		    (caddr_t)uap->ruid, sizeof(pc->p_ruid));
853	if (uap->euid)
854		error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid,
855		    (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid));
856	if (uap->suid)
857		error3 = copyout((caddr_t)&pc->p_svuid,
858		    (caddr_t)uap->suid, sizeof(pc->p_svuid));
859	return error1 ? error1 : (error2 ? error2 : error3);
860}
861
862#ifndef _SYS_SYSPROTO_H_
863struct getresgid_args {
864	gid_t	*rgid;
865	gid_t	*egid;
866	gid_t	*sgid;
867};
868#endif
869/* ARGSUSED */
870int
871getresgid(p, uap)
872	register struct proc *p;
873	struct getresgid_args *uap;
874{
875	struct pcred *pc = p->p_cred;
876	int error1 = 0, error2 = 0, error3 = 0;
877
878	if (uap->rgid)
879		error1 = copyout((caddr_t)&pc->p_rgid,
880		    (caddr_t)uap->rgid, sizeof(pc->p_rgid));
881	if (uap->egid)
882		error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0],
883		    (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0]));
884	if (uap->sgid)
885		error3 = copyout((caddr_t)&pc->p_svgid,
886		    (caddr_t)uap->sgid, sizeof(pc->p_svgid));
887	return error1 ? error1 : (error2 ? error2 : error3);
888}
889
890
891#ifndef _SYS_SYSPROTO_H_
892struct issetugid_args {
893	int dummy;
894};
895#endif
896/* ARGSUSED */
897int
898issetugid(p, uap)
899	register struct proc *p;
900	struct issetugid_args *uap;
901{
902	/*
903	 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
904	 * we use P_SUGID because we consider changing the owners as
905	 * "tainting" as well.
906	 * This is significant for procs that start as root and "become"
907	 * a user without an exec - programs cannot know *everything*
908	 * that libc *might* have put in their data segment.
909	 */
910	p->p_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
911	return (0);
912}
913
914/*
915 * Check if gid is a member of the group set.
916 */
917int
918groupmember(gid, cred)
919	gid_t gid;
920	register struct ucred *cred;
921{
922	register gid_t *gp;
923	gid_t *egp;
924
925	egp = &(cred->cr_groups[cred->cr_ngroups]);
926	for (gp = cred->cr_groups; gp < egp; gp++)
927		if (*gp == gid)
928			return (1);
929	return (0);
930}
931
932static int suser_permitted = 1;
933
934SYSCTL_INT(_kern, OID_AUTO, suser_permitted, CTLFLAG_RW, &suser_permitted, 0,
935    "processes with uid 0 have privilege");
936
937/*
938 * Test whether the specified credentials imply "super-user"
939 * privilege; if so, and we have accounting info, set the flag
940 * indicating use of super-powers.
941 * Returns 0 or error.
942 */
943int
944suser(p)
945	struct proc *p;
946{
947	return suser_xxx(0, p, 0);
948}
949
950int
951suser_xxx(cred, proc, flag)
952	struct ucred *cred;
953	struct proc *proc;
954	int flag;
955{
956	if (!suser_permitted)
957		return (EPERM);
958	if (!cred && !proc) {
959		printf("suser_xxx(): THINK!\n");
960		return (EPERM);
961	}
962	if (!cred)
963		cred = proc->p_ucred;
964	if (cred->cr_uid != 0)
965		return (EPERM);
966	if (jailed(cred) && !(flag & PRISON_ROOT))
967		return (EPERM);
968	return (0);
969}
970
971static int
972p_cansee(struct proc *p1, struct proc *p2, int *privused)
973{
974	int error;
975
976	if (privused != NULL)
977		*privused = 0;
978
979	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
980		return (error);
981
982	if (!ps_showallprocs && p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) {
983		if (suser_xxx(NULL, p1, PRISON_ROOT) == 0) {
984			if (privused != NULL)
985				*privused = 1;
986			return (0);
987		}
988		return (ESRCH);
989	}
990
991	return (0);
992}
993
994static int
995p_cankill(struct proc *p1, struct proc *p2, int *privused)
996{
997	int error;
998
999	if (privused != NULL)
1000		*privused = 0;
1001
1002	if (p1 == p2)
1003		return (0);
1004
1005	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
1006		return (error);
1007
1008	if (p1->p_cred->p_ruid == p2->p_cred->p_ruid)
1009		return (0);
1010	if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid)
1011		return (0);
1012	/*
1013	 * XXX should a process be able to affect another process
1014	 * acting as the same uid (i.e., a userland nfsd or the like?)
1015	 */
1016	if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid)
1017		return (0);
1018	if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
1019		return (0);
1020
1021	if (!suser_xxx(0, p1, PRISON_ROOT)) {
1022		if (privused != NULL)
1023			*privused = 1;
1024		return (0);
1025	}
1026
1027#ifdef CAPABILITIES
1028	if (!cap_check_xxx(0, p1, CAP_KILL, PRISON_ROOT)) {
1029		if (privused != NULL)
1030			*privused = 1;
1031		return (0);
1032	}
1033#endif
1034
1035	return (EPERM);
1036}
1037
1038static int
1039p_cansched(struct proc *p1, struct proc *p2, int *privused)
1040{
1041	int error;
1042
1043	if (privused != NULL)
1044		*privused = 0;
1045
1046	if (p1 == p2)
1047		return (0);
1048
1049	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
1050		return (error);
1051
1052	if (p1->p_cred->p_ruid == p2->p_cred->p_ruid)
1053		return (0);
1054	if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid)
1055		return (0);
1056	/*
1057	 * XXX should a process be able to affect another process
1058	 * acting as the same uid (i.e., a userland nfsd or the like?)
1059	 */
1060	if (p1->p_cred->p_ruid == p2->p_ucred->cr_uid)
1061		return (0);
1062	if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
1063		return (0);
1064
1065	if (!suser_xxx(0, p1, PRISON_ROOT)) {
1066		if (privused != NULL)
1067			*privused = 1;
1068		return (0);
1069	}
1070
1071#ifdef CAPABILITIES
1072	if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) {
1073		if (privused != NULL)
1074			*privused = 1;
1075		return (0);
1076	}
1077#endif
1078
1079	return (EPERM);
1080}
1081
1082static int
1083p_candebug(struct proc *p1, struct proc *p2, int *privused)
1084{
1085	int error;
1086
1087	if (privused != NULL)
1088		*privused = 0;
1089
1090	/* XXX it is authorized, but semantics don't permit it */
1091	if (p1 == p2)
1092		return (0);
1093
1094	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
1095		return (error);
1096
1097	/* not owned by you, has done setuid (unless you're root) */
1098	/* add a CAP_SYS_PTRACE here? */
1099	if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid ||
1100	    p1->p_cred->p_ruid != p2->p_cred->p_ruid ||
1101	    p1->p_cred->p_svuid != p2->p_cred->p_ruid ||
1102	    p2->p_flag & P_SUGID) {
1103		if ((error = suser_xxx(0, p1, PRISON_ROOT)))
1104			return (error);
1105		if (privused != NULL)
1106			*privused = 1;
1107	}
1108
1109	/* can't trace init when securelevel > 0 */
1110	if (securelevel > 0 && p2->p_pid == 1)
1111		return (EPERM);
1112
1113	return (0);
1114}
1115
1116int
1117p_can(struct proc *p1, struct proc *p2, int operation,
1118    int *privused)
1119{
1120
1121	switch(operation) {
1122	case P_CAN_SEE:
1123		return (p_cansee(p1, p2, privused));
1124
1125	case P_CAN_KILL:
1126		return (p_cankill(p1, p2, privused));
1127
1128	case P_CAN_SCHED:
1129		return (p_cansched(p1, p2, privused));
1130
1131	case P_CAN_DEBUG:
1132		return (p_candebug(p1, p2, privused));
1133
1134	default:
1135		panic("p_can: invalid operation");
1136	}
1137}
1138
1139
1140/*
1141 * Allocate a zeroed cred structure.
1142 */
1143struct ucred *
1144crget()
1145{
1146	register struct ucred *cr;
1147
1148	MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK|M_ZERO);
1149	cr->cr_ref = 1;
1150	mtx_init(&cr->cr_mtx, "ucred", MTX_DEF);
1151	return (cr);
1152}
1153
1154/*
1155 * Claim another reference to a ucred structure
1156 */
1157void
1158crhold(cr)
1159	struct ucred *cr;
1160{
1161
1162	mtx_lock(&cr->cr_mtx);
1163	cr->cr_ref++;
1164	mtx_unlock(&(cr)->cr_mtx);
1165}
1166
1167
1168/*
1169 * Free a cred structure.
1170 * Throws away space when ref count gets to 0.
1171 */
1172void
1173crfree(cr)
1174	struct ucred *cr;
1175{
1176
1177	mtx_lock(&cr->cr_mtx);
1178	if (--cr->cr_ref == 0) {
1179		mtx_destroy(&cr->cr_mtx);
1180		/*
1181		 * Some callers of crget(), such as nfs_statfs(),
1182		 * allocate a temporary credential, but don't
1183		 * allocate a uidinfo structure.
1184		 */
1185		if (cr->cr_uidinfo != NULL)
1186			uifree(cr->cr_uidinfo);
1187		/*
1188		 * Free a prison, if any.
1189		 */
1190		if (jailed(cr))
1191			prison_free(cr->cr_prison);
1192		FREE((caddr_t)cr, M_CRED);
1193	} else {
1194		mtx_unlock(&cr->cr_mtx);
1195	}
1196}
1197
1198/*
1199 * Copy cred structure to a new one and free the old one.
1200 */
1201struct ucred *
1202crcopy(cr)
1203	struct ucred *cr;
1204{
1205	struct ucred *newcr;
1206
1207	mtx_lock(&cr->cr_mtx);
1208	if (cr->cr_ref == 1) {
1209		mtx_unlock(&cr->cr_mtx);
1210		return (cr);
1211	}
1212	mtx_unlock(&cr->cr_mtx);
1213	newcr = crdup(cr);
1214	crfree(cr);
1215	return (newcr);
1216}
1217
1218/*
1219 * Dup cred struct to a new held one.
1220 */
1221struct ucred *
1222crdup(cr)
1223	struct ucred *cr;
1224{
1225	struct ucred *newcr;
1226
1227	MALLOC(newcr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
1228	*newcr = *cr;
1229	mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF);
1230	uihold(newcr->cr_uidinfo);
1231	if (jailed(newcr))
1232		prison_hold(newcr->cr_prison);
1233	newcr->cr_ref = 1;
1234	return (newcr);
1235}
1236
1237/*
1238 * Get login name, if available.
1239 */
1240#ifndef _SYS_SYSPROTO_H_
1241struct getlogin_args {
1242	char	*namebuf;
1243	u_int	namelen;
1244};
1245#endif
1246/* ARGSUSED */
1247int
1248getlogin(p, uap)
1249	struct proc *p;
1250	struct getlogin_args *uap;
1251{
1252
1253	if (uap->namelen > MAXLOGNAME)
1254		uap->namelen = MAXLOGNAME;
1255	return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1256	    (caddr_t) uap->namebuf, uap->namelen));
1257}
1258
1259/*
1260 * Set login name.
1261 */
1262#ifndef _SYS_SYSPROTO_H_
1263struct setlogin_args {
1264	char	*namebuf;
1265};
1266#endif
1267/* ARGSUSED */
1268int
1269setlogin(p, uap)
1270	struct proc *p;
1271	struct setlogin_args *uap;
1272{
1273	int error;
1274	char logintmp[MAXLOGNAME];
1275
1276	if ((error = suser_xxx(0, p, PRISON_ROOT)))
1277		return (error);
1278	error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
1279	    sizeof(logintmp), (size_t *)0);
1280	if (error == ENAMETOOLONG)
1281		error = EINVAL;
1282	else if (!error)
1283		(void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1284		    sizeof(logintmp));
1285	return (error);
1286}
1287
1288void
1289setsugid(p)
1290	struct proc *p;
1291{
1292	p->p_flag |= P_SUGID;
1293	if (!(p->p_pfsflags & PF_ISUGID))
1294		p->p_stops = 0;
1295}
1296
1297/*
1298 * Helper function to change the effective uid of a process
1299 */
1300void
1301change_euid(p, euid)
1302	struct	proc *p;
1303	uid_t	euid;
1304{
1305	struct	pcred *pc;
1306	struct	uidinfo *uip;
1307
1308	pc = p->p_cred;
1309	/*
1310	 * crcopy is essentially a NOP if ucred has a reference count
1311	 * of 1, which is true if it has already been copied.
1312	 */
1313	pc->pc_ucred = crcopy(pc->pc_ucred);
1314	uip = pc->pc_ucred->cr_uidinfo;
1315	pc->pc_ucred->cr_uid = euid;
1316	pc->pc_ucred->cr_uidinfo = uifind(euid);
1317	uifree(uip);
1318}
1319
1320/*
1321 * Helper function to change the real uid of a process
1322 *
1323 * The per-uid process count for this process is transfered from
1324 * the old uid to the new uid.
1325 */
1326void
1327change_ruid(p, ruid)
1328	struct	proc *p;
1329	uid_t	ruid;
1330{
1331	struct	pcred *pc;
1332	struct	uidinfo *uip;
1333
1334	pc = p->p_cred;
1335	(void)chgproccnt(pc->p_uidinfo, -1, 0);
1336	uip = pc->p_uidinfo;
1337	/* It is assumed that pcred is not shared between processes */
1338	pc->p_ruid = ruid;
1339	pc->p_uidinfo = uifind(ruid);
1340	(void)chgproccnt(pc->p_uidinfo, 1, 0);
1341	uifree(uip);
1342}
1343