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