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