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