xref: /dflybsd-src/sys/kern/kern_prot.c (revision 4beeb8ba8b64ebcd31d49e882f7fd21b56161c61)
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. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)kern_prot.c	8.6 (Berkeley) 1/21/94
35  * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $
36  */
37 
38 /*
39  * System calls related to processes and protection
40  */
41 
42 #include <sys/param.h>
43 #include <sys/acct.h>
44 #include <sys/systm.h>
45 #include <sys/sysproto.h>
46 #include <sys/kernel.h>
47 #include <sys/lock.h>
48 #include <sys/proc.h>
49 #include <sys/priv.h>
50 #include <sys/malloc.h>
51 #include <sys/pioctl.h>
52 #include <sys/resourcevar.h>
53 #include <sys/jail.h>
54 #include <sys/lockf.h>
55 #include <sys/spinlock.h>
56 
57 #include <sys/spinlock2.h>
58 
59 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
60 
61 int
62 sys_getpid(struct getpid_args *uap)
63 {
64 	struct proc *p = curproc;
65 
66 	uap->sysmsg_fds[0] = p->p_pid;
67 	return (0);
68 }
69 
70 int
71 sys_getppid(struct getppid_args *uap)
72 {
73 	struct proc *p = curproc;
74 
75 	uap->sysmsg_result = p->p_ppid;
76 
77 	return (0);
78 }
79 
80 int
81 sys_lwp_gettid(struct lwp_gettid_args *uap)
82 {
83 	struct lwp *lp = curthread->td_lwp;
84 	uap->sysmsg_result = lp->lwp_tid;
85 	return (0);
86 }
87 
88 /*
89  * Get process group ID; note that POSIX getpgrp takes no parameter
90  */
91 int
92 sys_getpgrp(struct getpgrp_args *uap)
93 {
94 	struct proc *p = curproc;
95 
96 	lwkt_gettoken_shared(&p->p_token);
97 	uap->sysmsg_result = p->p_pgrp->pg_id;
98 	lwkt_reltoken(&p->p_token);
99 
100 	return (0);
101 }
102 
103 /*
104  * Get an arbitrary pid's process group id
105  */
106 int
107 sys_getpgid(struct getpgid_args *uap)
108 {
109 	struct proc *p = curproc;
110 	struct proc *pt;
111 	int error;
112 
113 	error = 0;
114 
115 	if (uap->pid == 0) {
116 		pt = p;
117 		PHOLD(pt);
118 	} else {
119 		pt = pfind(uap->pid);
120 		if (pt == NULL)
121 			error = ESRCH;
122 	}
123 	if (error == 0) {
124 		lwkt_gettoken_shared(&pt->p_token);
125 		uap->sysmsg_result = pt->p_pgrp->pg_id;
126 		lwkt_reltoken(&pt->p_token);
127 	}
128 	if (pt)
129 		PRELE(pt);
130 	return (error);
131 }
132 
133 /*
134  * Get an arbitrary pid's session id.
135  */
136 int
137 sys_getsid(struct getsid_args *uap)
138 {
139 	struct proc *p = curproc;
140 	struct proc *pt;
141 	int error;
142 
143 	error = 0;
144 
145 	if (uap->pid == 0) {
146 		pt = p;
147 		PHOLD(pt);
148 	} else {
149 		pt = pfind(uap->pid);
150 		if (pt == NULL)
151 			error = ESRCH;
152 	}
153 	if (error == 0)
154 		uap->sysmsg_result = pt->p_session->s_sid;
155 	if (pt)
156 		PRELE(pt);
157 	return (error);
158 }
159 
160 
161 /*
162  * getuid()
163  */
164 int
165 sys_getuid(struct getuid_args *uap)
166 {
167 	struct ucred *cred = curthread->td_ucred;
168 
169 	uap->sysmsg_fds[0] = cred->cr_ruid;
170 	return (0);
171 }
172 
173 /*
174  * geteuid()
175  */
176 int
177 sys_geteuid(struct geteuid_args *uap)
178 {
179 	struct ucred *cred = curthread->td_ucred;
180 
181 	uap->sysmsg_result = cred->cr_uid;
182 	return (0);
183 }
184 
185 /*
186  * getgid()
187  */
188 int
189 sys_getgid(struct getgid_args *uap)
190 {
191 	struct ucred *cred = curthread->td_ucred;
192 
193 	uap->sysmsg_fds[0] = cred->cr_rgid;
194 	return (0);
195 }
196 
197 /*
198  * Get effective group ID.  The "egid" is groups[0], and could be obtained
199  * via getgroups.  This syscall exists because it is somewhat painful to do
200  * correctly in a library function.
201  */
202 int
203 sys_getegid(struct getegid_args *uap)
204 {
205 	struct ucred *cred = curthread->td_ucred;
206 
207 	uap->sysmsg_result = cred->cr_groups[0];
208 	return (0);
209 }
210 
211 int
212 sys_getgroups(struct getgroups_args *uap)
213 {
214 	struct ucred *cr;
215 	u_int ngrp;
216 	int error;
217 
218 	cr = curthread->td_ucred;
219 	if ((ngrp = uap->gidsetsize) == 0) {
220 		uap->sysmsg_result = cr->cr_ngroups;
221 		return (0);
222 	}
223 	if (ngrp < cr->cr_ngroups)
224 		return (EINVAL);
225 	ngrp = cr->cr_ngroups;
226 	error = copyout((caddr_t)cr->cr_groups,
227 			(caddr_t)uap->gidset, ngrp * sizeof(gid_t));
228 	if (error == 0)
229 		uap->sysmsg_result = ngrp;
230 	return (error);
231 }
232 
233 int
234 sys_lwp_setname(struct lwp_setname_args *uap)
235 {
236 	struct proc *p = curproc;
237 	struct lwp *lp;
238 	char buf[LPMAP_MAXTHREADTITLE];
239 	int error;
240 	size_t len;
241 
242 	if (uap->name != NULL) {
243 		error = copyinstr(uap->name, buf, sizeof(buf), &len);
244 		if (error) {
245 			if (error != ENAMETOOLONG)
246 				return error;
247 			buf[sizeof(buf)-1] = 0;
248 			len = sizeof(buf) - 1;
249 		}
250 	} else {
251 		buf[0] = 0;
252 		len = 1;
253 	}
254 
255 	lwkt_gettoken(&p->p_token);
256 
257 	lp = lwpfind(p, uap->tid);
258 	if (lp) {
259 		lwkt_gettoken(&lp->lwp_token);
260 		if (lp->lwp_lpmap == NULL)
261 			lwp_usermap(lp, -1);
262 		if (lp->lwp_lpmap)
263 			bcopy(buf, lp->lwp_lpmap->thread_title, len);
264 		lwkt_reltoken(&lp->lwp_token);
265 		LWPRELE(lp);
266 		error = 0;
267 	} else {
268 		error = ESRCH;
269 	}
270 
271 	lwkt_reltoken(&p->p_token);
272 
273 	return error;
274 }
275 
276 int
277 sys_setsid(struct setsid_args *uap)
278 {
279 	struct proc *p = curproc;
280 	struct pgrp *pg = NULL;
281 	int error;
282 
283 	lwkt_gettoken(&p->p_token);
284 	if (p->p_pgid == p->p_pid || (pg = pgfind(p->p_pid)) != NULL) {
285 		error = EPERM;
286 		if (pg)
287 			pgrel(pg);
288 	} else {
289 		enterpgrp(p, p->p_pid, 1);
290 		uap->sysmsg_result = p->p_pid;
291 		error = 0;
292 	}
293 	lwkt_reltoken(&p->p_token);
294 	return (error);
295 }
296 
297 /*
298  * set process group (setpgid/old setpgrp)
299  *
300  * caller does setpgid(targpid, targpgid)
301  *
302  * pid must be caller or child of caller (ESRCH)
303  * if a child
304  *	pid must be in same session (EPERM)
305  *	pid can't have done an exec (EACCES)
306  * if pgid != pid
307  * 	there must exist some pid in same session having pgid (EPERM)
308  * pid must not be session leader (EPERM)
309  */
310 int
311 sys_setpgid(struct setpgid_args *uap)
312 {
313 	struct proc *curp = curproc;
314 	struct proc *targp;		/* target process */
315 	struct pgrp *pgrp = NULL;	/* target pgrp */
316 	int error;
317 
318 	if (uap->pgid < 0)
319 		return (EINVAL);
320 
321 	if (uap->pid != 0 && uap->pid != curp->p_pid) {
322 		if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
323 			if (targp)
324 				PRELE(targp);
325 			error = ESRCH;
326 			targp = NULL;
327 			goto done;
328 		}
329 		lwkt_gettoken(&targp->p_token);
330 		/* targp now referenced and its token is held */
331 
332 		if (targp->p_pgrp == NULL ||
333 		    targp->p_session != curp->p_session) {
334 			error = EPERM;
335 			goto done;
336 		}
337 		if (targp->p_flags & P_EXEC) {
338 			error = EACCES;
339 			goto done;
340 		}
341 	} else {
342 		targp = curp;
343 		PHOLD(targp);
344 		lwkt_gettoken(&targp->p_token);
345 	}
346 	if (SESS_LEADER(targp)) {
347 		error = EPERM;
348 		goto done;
349 	}
350 	if (uap->pgid == 0) {
351 		uap->pgid = targp->p_pid;
352 	} else if (uap->pgid != targp->p_pid) {
353 		if ((pgrp = pgfind(uap->pgid)) == NULL ||
354 	            pgrp->pg_session != curp->p_session) {
355 			error = EPERM;
356 			goto done;
357 		}
358 	}
359 	error = enterpgrp(targp, uap->pgid, 0);
360 done:
361 	if (pgrp)
362 		pgrel(pgrp);
363 	if (targp) {
364 		lwkt_reltoken(&targp->p_token);
365 		PRELE(targp);
366 	}
367 	return (error);
368 }
369 
370 /*
371  * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
372  * compatible.  It says that setting the uid/gid to euid/egid is a special
373  * case of "appropriate privilege".  Once the rules are expanded out, this
374  * basically means that setuid(nnn) sets all three id's, in all permitted
375  * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
376  * does not set the saved id - this is dangerous for traditional BSD
377  * programs.  For this reason, we *really* do not want to set
378  * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
379  */
380 #define POSIX_APPENDIX_B_4_2_2
381 
382 int
383 sys_setuid(struct setuid_args *uap)
384 {
385 	struct proc *p = curproc;
386 	struct ucred *cr;
387 	uid_t uid;
388 	int error;
389 
390 	lwkt_gettoken(&p->p_token);
391 	cr = p->p_ucred;
392 
393 	/*
394 	 * See if we have "permission" by POSIX 1003.1 rules.
395 	 *
396 	 * Note that setuid(geteuid()) is a special case of
397 	 * "appropriate privileges" in appendix B.4.2.2.  We need
398 	 * to use this clause to be compatible with traditional BSD
399 	 * semantics.  Basically, it means that "setuid(xx)" sets all
400 	 * three id's (assuming you have privs).
401 	 *
402 	 * Notes on the logic.  We do things in three steps.
403 	 * 1: We determine if the euid is going to change, and do EPERM
404 	 *    right away.  We unconditionally change the euid later if this
405 	 *    test is satisfied, simplifying that part of the logic.
406 	 * 2: We determine if the real and/or saved uid's are going to
407 	 *    change.  Determined by compile options.
408 	 * 3: Change euid last. (after tests in #2 for "appropriate privs")
409 	 */
410 	uid = uap->uid;
411 	if (uid != cr->cr_ruid &&		/* allow setuid(getuid()) */
412 #ifdef _POSIX_SAVED_IDS
413 	    uid != crc->cr_svuid &&		/* allow setuid(saved gid) */
414 #endif
415 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
416 	    uid != cr->cr_uid &&	/* allow setuid(geteuid()) */
417 #endif
418 	    (error = priv_check_cred(cr, PRIV_CRED_SETUID, 0)))
419 		goto done;
420 
421 #ifdef _POSIX_SAVED_IDS
422 	/*
423 	 * Do we have "appropriate privileges" (are we root or uid == euid)
424 	 * If so, we are changing the real uid and/or saved uid.
425 	 */
426 	if (
427 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
428 	    uid == cr->cr_uid ||
429 #endif
430 	    priv_check_cred(cr, PRIV_CRED_SETUID, 0) == 0) /* we are using privs */
431 #endif
432 	{
433 		/*
434 		 * Set the real uid and transfer proc count to new user.
435 		 */
436 		if (uid != cr->cr_ruid) {
437 			cr = change_ruid(uid);
438 			setsugid();
439 		}
440 		/*
441 		 * Set saved uid
442 		 *
443 		 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
444 		 * the security of seteuid() depends on it.  B.4.2.2 says it
445 		 * is important that we should do this.
446 		 */
447 		if (cr->cr_svuid != uid) {
448 			cr = cratom_proc(p);
449 			cr->cr_svuid = uid;
450 			setsugid();
451 		}
452 	}
453 
454 	/*
455 	 * In all permitted cases, we are changing the euid.
456 	 * Copy credentials so other references do not see our changes.
457 	 */
458 	if (cr->cr_uid != uid) {
459 		change_euid(uid);
460 		setsugid();
461 	}
462 	error = 0;
463 done:
464 	lwkt_reltoken(&p->p_token);
465 	return (error);
466 }
467 
468 int
469 sys_seteuid(struct seteuid_args *uap)
470 {
471 	struct proc *p = curproc;
472 	struct ucred *cr;
473 	uid_t euid;
474 	int error;
475 
476 	lwkt_gettoken(&p->p_token);
477 	cr = p->p_ucred;
478 	euid = uap->euid;
479 	if (euid != cr->cr_ruid &&		/* allow seteuid(getuid()) */
480 	    euid != cr->cr_svuid &&		/* allow seteuid(saved uid) */
481 	    (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0))) {
482 		lwkt_reltoken(&p->p_token);
483 		return (error);
484 	}
485 
486 	/*
487 	 * Everything's okay, do it.  Copy credentials so other references do
488 	 * not see our changes.
489 	 */
490 	if (cr->cr_uid != euid) {
491 		change_euid(euid);
492 		setsugid();
493 	}
494 	lwkt_reltoken(&p->p_token);
495 	return (0);
496 }
497 
498 int
499 sys_setgid(struct setgid_args *uap)
500 {
501 	struct proc *p = curproc;
502 	struct ucred *cr;
503 	gid_t gid;
504 	int error;
505 
506 	lwkt_gettoken(&p->p_token);
507 	cr = p->p_ucred;
508 
509 	/*
510 	 * See if we have "permission" by POSIX 1003.1 rules.
511 	 *
512 	 * Note that setgid(getegid()) is a special case of
513 	 * "appropriate privileges" in appendix B.4.2.2.  We need
514 	 * to use this clause to be compatible with traditional BSD
515 	 * semantics.  Basically, it means that "setgid(xx)" sets all
516 	 * three id's (assuming you have privs).
517 	 *
518 	 * For notes on the logic here, see setuid() above.
519 	 */
520 	gid = uap->gid;
521 	if (gid != cr->cr_rgid &&		/* allow setgid(getgid()) */
522 #ifdef _POSIX_SAVED_IDS
523 	    gid != cr->cr_svgid &&		/* allow setgid(saved gid) */
524 #endif
525 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
526 	    gid != cr->cr_groups[0] && /* allow setgid(getegid()) */
527 #endif
528 	    (error = priv_check_cred(cr, PRIV_CRED_SETGID, 0))) {
529 		goto done;
530 	}
531 
532 #ifdef _POSIX_SAVED_IDS
533 	/*
534 	 * Do we have "appropriate privileges" (are we root or gid == egid)
535 	 * If so, we are changing the real uid and saved gid.
536 	 */
537 	if (
538 #ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
539 	    gid == cr->cr_groups[0] ||
540 #endif
541 	    priv_check_cred(cr, PRIV_CRED_SETGID, 0) == 0) /* we are using privs */
542 #endif
543 	{
544 		/*
545 		 * Set real gid
546 		 */
547 		if (cr->cr_rgid != gid) {
548 			cr = cratom_proc(p);
549 			cr->cr_rgid = gid;
550 			setsugid();
551 		}
552 		/*
553 		 * Set saved gid
554 		 *
555 		 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
556 		 * the security of setegid() depends on it.  B.4.2.2 says it
557 		 * is important that we should do this.
558 		 */
559 		if (cr->cr_svgid != gid) {
560 			cr = cratom_proc(p);
561 			cr->cr_svgid = gid;
562 			setsugid();
563 		}
564 	}
565 	/*
566 	 * In all cases permitted cases, we are changing the egid.
567 	 * Copy credentials so other references do not see our changes.
568 	 */
569 	if (cr->cr_groups[0] != gid) {
570 		cr = cratom_proc(p);
571 		cr->cr_groups[0] = gid;
572 		setsugid();
573 	}
574 	error = 0;
575 done:
576 	lwkt_reltoken(&p->p_token);
577 	return (error);
578 }
579 
580 int
581 sys_setegid(struct setegid_args *uap)
582 {
583 	struct proc *p = curproc;
584 	struct ucred *cr;
585 	gid_t egid;
586 	int error;
587 
588 	lwkt_gettoken(&p->p_token);
589 	cr = p->p_ucred;
590 	egid = uap->egid;
591 	if (egid != cr->cr_rgid &&		/* allow setegid(getgid()) */
592 	    egid != cr->cr_svgid &&		/* allow setegid(saved gid) */
593 	    (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0))) {
594 		goto done;
595 	}
596 	if (cr->cr_groups[0] != egid) {
597 		cr = cratom_proc(p);
598 		cr->cr_groups[0] = egid;
599 		setsugid();
600 	}
601 	error = 0;
602 done:
603 	lwkt_reltoken(&p->p_token);
604 	return (error);
605 }
606 
607 int
608 sys_setgroups(struct setgroups_args *uap)
609 {
610 	struct proc *p = curproc;
611 	struct ucred *cr;
612 	u_int ngrp;
613 	int error;
614 
615 	lwkt_gettoken(&p->p_token);
616 	cr = p->p_ucred;
617 
618 	if ((error = priv_check_cred(cr, PRIV_CRED_SETGROUPS, 0)))
619 		goto done;
620 	ngrp = uap->gidsetsize;
621 	if (ngrp > NGROUPS) {
622 		error = EINVAL;
623 		goto done;
624 	}
625 	/*
626 	 * XXX A little bit lazy here.  We could test if anything has
627 	 * changed before cratom() and setting P_SUGID.
628 	 */
629 	cr = cratom_proc(p);
630 	if (ngrp < 1) {
631 		/*
632 		 * setgroups(0, NULL) is a legitimate way of clearing the
633 		 * groups vector on non-BSD systems (which generally do not
634 		 * have the egid in the groups[0]).  We risk security holes
635 		 * when running non-BSD software if we do not do the same.
636 		 */
637 		cr->cr_ngroups = 1;
638 	} else {
639 		error = copyin(uap->gidset, cr->cr_groups,
640 			       ngrp * sizeof(gid_t));
641 		if (error)
642 			goto done;
643 		cr->cr_ngroups = ngrp;
644 	}
645 	setsugid();
646 	error = 0;
647 done:
648 	lwkt_reltoken(&p->p_token);
649 	return (error);
650 }
651 
652 int
653 sys_setreuid(struct setreuid_args *uap)
654 {
655 	struct proc *p = curproc;
656 	struct ucred *cr;
657 	uid_t ruid, euid;
658 	int error;
659 
660 	lwkt_gettoken(&p->p_token);
661 	cr = p->p_ucred;
662 
663 	ruid = uap->ruid;
664 	euid = uap->euid;
665 	if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid &&
666 	      ruid != cr->cr_svuid) ||
667 	     (euid != (uid_t)-1 && euid != cr->cr_uid &&
668 	      euid != cr->cr_ruid && euid != cr->cr_svuid)) &&
669 	    (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0) {
670 		goto done;
671 	}
672 
673 	if (euid != (uid_t)-1 && cr->cr_uid != euid) {
674 		cr = change_euid(euid);
675 		setsugid();
676 	}
677 	if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
678 		cr = change_ruid(ruid);
679 		setsugid();
680 	}
681 	if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) &&
682 	    cr->cr_svuid != cr->cr_uid) {
683 		cr = cratom_proc(p);
684 		cr->cr_svuid = cr->cr_uid;
685 		setsugid();
686 	}
687 	error = 0;
688 done:
689 	lwkt_reltoken(&p->p_token);
690 	return (error);
691 }
692 
693 int
694 sys_setregid(struct setregid_args *uap)
695 {
696 	struct proc *p = curproc;
697 	struct ucred *cr;
698 	gid_t rgid, egid;
699 	int error;
700 
701 	lwkt_gettoken(&p->p_token);
702 	cr = p->p_ucred;
703 
704 	rgid = uap->rgid;
705 	egid = uap->egid;
706 	if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid &&
707 	      rgid != cr->cr_svgid) ||
708 	     (egid != (gid_t)-1 && egid != cr->cr_groups[0] &&
709 	      egid != cr->cr_rgid && egid != cr->cr_svgid)) &&
710 	    (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0) {
711 		goto done;
712 	}
713 
714 	if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
715 		cr = cratom_proc(p);
716 		cr->cr_groups[0] = egid;
717 		setsugid();
718 	}
719 	if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
720 		cr = cratom_proc(p);
721 		cr->cr_rgid = rgid;
722 		setsugid();
723 	}
724 	if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) &&
725 	    cr->cr_svgid != cr->cr_groups[0]) {
726 		cr = cratom_proc(p);
727 		cr->cr_svgid = cr->cr_groups[0];
728 		setsugid();
729 	}
730 	error = 0;
731 done:
732 	lwkt_reltoken(&p->p_token);
733 	return (error);
734 }
735 
736 /*
737  * setresuid(ruid, euid, suid) is like setreuid except control over the
738  * saved uid is explicit.
739  */
740 int
741 sys_setresuid(struct setresuid_args *uap)
742 {
743 	struct proc *p = curproc;
744 	struct ucred *cr;
745 	uid_t ruid, euid, suid;
746 	int error;
747 
748 	lwkt_gettoken(&p->p_token);
749 	cr = p->p_ucred;
750 
751 	ruid = uap->ruid;
752 	euid = uap->euid;
753 	suid = uap->suid;
754 	if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid &&
755 	      ruid != cr->cr_svuid && ruid != cr->cr_uid) ||
756 	     (euid != (uid_t)-1 && euid != cr->cr_ruid &&
757 	      euid != cr->cr_svuid && euid != cr->cr_uid) ||
758 	     (suid != (uid_t)-1 && suid != cr->cr_ruid &&
759 	      suid != cr->cr_svuid && suid != cr->cr_uid)) &&
760 	    (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) {
761 		goto done;
762 	}
763 	if (euid != (uid_t)-1 && cr->cr_uid != euid) {
764 		cr = change_euid(euid);
765 		setsugid();
766 	}
767 	if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
768 		cr = change_ruid(ruid);
769 		setsugid();
770 	}
771 	if (suid != (uid_t)-1 && cr->cr_svuid != suid) {
772 		cr = cratom_proc(p);
773 		cr->cr_svuid = suid;
774 		setsugid();
775 	}
776 	error = 0;
777 done:
778 	lwkt_reltoken(&p->p_token);
779 	return (error);
780 }
781 
782 /*
783  * setresgid(rgid, egid, sgid) is like setregid except control over the
784  * saved gid is explicit.
785  */
786 int
787 sys_setresgid(struct setresgid_args *uap)
788 {
789 	struct proc *p = curproc;
790 	struct ucred *cr;
791 	gid_t rgid, egid, sgid;
792 	int error;
793 
794 	lwkt_gettoken(&p->p_token);
795 	cr = p->p_ucred;
796 	rgid = uap->rgid;
797 	egid = uap->egid;
798 	sgid = uap->sgid;
799 	if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid &&
800 	      rgid != cr->cr_svgid && rgid != cr->cr_groups[0]) ||
801 	     (egid != (gid_t)-1 && egid != cr->cr_rgid &&
802 	      egid != cr->cr_svgid && egid != cr->cr_groups[0]) ||
803 	     (sgid != (gid_t)-1 && sgid != cr->cr_rgid &&
804 	      sgid != cr->cr_svgid && sgid != cr->cr_groups[0])) &&
805 	    (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) {
806 		goto done;
807 	}
808 
809 	if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
810 		cr = cratom_proc(p);
811 		cr->cr_groups[0] = egid;
812 		setsugid();
813 	}
814 	if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
815 		cr = cratom_proc(p);
816 		cr->cr_rgid = rgid;
817 		setsugid();
818 	}
819 	if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) {
820 		cr = cratom_proc(p);
821 		cr->cr_svgid = sgid;
822 		setsugid();
823 	}
824 	error = 0;
825 done:
826 	lwkt_reltoken(&p->p_token);
827 	return (error);
828 }
829 
830 int
831 sys_getresuid(struct getresuid_args *uap)
832 {
833 	struct ucred *cr;
834 	int error1 = 0, error2 = 0, error3 = 0;
835 
836 	/*
837 	 * copyout's can fault synchronously so we cannot use a shared
838 	 * token here.
839 	 */
840 	cr = curthread->td_ucred;
841 	if (uap->ruid)
842 		error1 = copyout((caddr_t)&cr->cr_ruid,
843 		    (caddr_t)uap->ruid, sizeof(cr->cr_ruid));
844 	if (uap->euid)
845 		error2 = copyout((caddr_t)&cr->cr_uid,
846 		    (caddr_t)uap->euid, sizeof(cr->cr_uid));
847 	if (uap->suid)
848 		error3 = copyout((caddr_t)&cr->cr_svuid,
849 		    (caddr_t)uap->suid, sizeof(cr->cr_svuid));
850 	return error1 ? error1 : (error2 ? error2 : error3);
851 }
852 
853 int
854 sys_getresgid(struct getresgid_args *uap)
855 {
856 	struct ucred *cr;
857 	int error1 = 0, error2 = 0, error3 = 0;
858 
859 	cr = curthread->td_ucred;
860 	if (uap->rgid)
861 		error1 = copyout(&cr->cr_rgid, uap->rgid,
862 				 sizeof(cr->cr_rgid));
863 	if (uap->egid)
864 		error2 = copyout(&cr->cr_groups[0], uap->egid,
865 				 sizeof(cr->cr_groups[0]));
866 	if (uap->sgid)
867 		error3 = copyout(&cr->cr_svgid, uap->sgid,
868 				 sizeof(cr->cr_svgid));
869 	return error1 ? error1 : (error2 ? error2 : error3);
870 }
871 
872 
873 /*
874  * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
875  * we use P_SUGID because we consider changing the owners as
876  * "tainting" as well.
877  * This is significant for procs that start as root and "become"
878  * a user without an exec - programs cannot know *everything*
879  * that libc *might* have put in their data segment.
880  */
881 int
882 sys_issetugid(struct issetugid_args *uap)
883 {
884 	uap->sysmsg_result = (curproc->p_flags & P_SUGID) ? 1 : 0;
885 	return (0);
886 }
887 
888 /*
889  * Check if gid is a member of the group set.
890  */
891 int
892 groupmember(gid_t gid, struct ucred *cred)
893 {
894 	gid_t *gp;
895 	gid_t *egp;
896 
897 	egp = &(cred->cr_groups[cred->cr_ngroups]);
898 	for (gp = cred->cr_groups; gp < egp; gp++) {
899 		if (*gp == gid)
900 			return (1);
901 	}
902 	return (0);
903 }
904 
905 /*
906  * Test whether the specified credentials have the privilege
907  * in question.
908  *
909  * A kernel thread without a process context is assumed to have
910  * the privilege in question.  In situations where the caller always
911  * expect a cred to exist, the cred should be passed separately and
912  * priv_check_cred() should be used instead of priv_check().
913  *
914  * Returns 0 or error.
915  */
916 int
917 priv_check(struct thread *td, int priv)
918 {
919 	if (td->td_lwp != NULL)
920 		return priv_check_cred(td->td_ucred, priv, 0);
921 	return (0);
922 }
923 
924 /*
925  * Check a credential for privilege.
926  *
927  * A non-null credential is expected unless NULL_CRED_OKAY is set.
928  */
929 int
930 priv_check_cred(struct ucred *cred, int priv, int flags)
931 {
932 	int error;
933 
934 	KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege"));
935 
936 	KASSERT(cred != NULL || (flags & NULL_CRED_OKAY),
937 		("priv_check_cred: NULL cred!"));
938 
939 	if (cred == NULL) {
940 		if (flags & NULL_CRED_OKAY)
941 			return (0);
942 		else
943 			return (EPERM);
944 	}
945 	if (cred->cr_uid != 0)
946 		return (EPERM);
947 
948 	error = prison_priv_check(cred, priv);
949 	if (error)
950 		return (error);
951 
952 	/* NOTE: accounting for suser access (p_acflag/ASU) removed */
953 	return (0);
954 }
955 
956 /*
957  * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
958  */
959 int
960 p_trespass(struct ucred *cr1, struct ucred *cr2)
961 {
962 	if (cr1 == cr2)
963 		return (0);
964 	if (!PRISON_CHECK(cr1, cr2))
965 		return (ESRCH);
966 	if (cr1->cr_ruid == cr2->cr_ruid)
967 		return (0);
968 	if (cr1->cr_uid == cr2->cr_ruid)
969 		return (0);
970 	if (cr1->cr_ruid == cr2->cr_uid)
971 		return (0);
972 	if (cr1->cr_uid == cr2->cr_uid)
973 		return (0);
974 	if (priv_check_cred(cr1, PRIV_PROC_TRESPASS, 0) == 0)
975 		return (0);
976 	return (EPERM);
977 }
978 
979 static __inline void
980 _crinit(struct ucred *cr)
981 {
982 	cr->cr_ref = 1;
983 }
984 
985 void
986 crinit(struct ucred *cr)
987 {
988 	bzero(cr, sizeof(*cr));
989 	_crinit(cr);
990 }
991 
992 /*
993  * Allocate a zeroed cred structure.
994  */
995 struct ucred *
996 crget(void)
997 {
998 	struct ucred *cr;
999 
1000 	cr = kmalloc(sizeof(*cr), M_CRED, M_WAITOK|M_ZERO);
1001 	_crinit(cr);
1002 	return (cr);
1003 }
1004 
1005 /*
1006  * Claim another reference to a ucred structure.  Can be used with special
1007  * creds.
1008  *
1009  * It must be possible to call this routine with spinlocks held, meaning
1010  * that this routine itself cannot obtain a spinlock.
1011  */
1012 struct ucred *
1013 crhold(struct ucred *cr)
1014 {
1015 	if (cr != NOCRED && cr != FSCRED)
1016 		atomic_add_long(&cr->cr_ref, 1);
1017 	return(cr);
1018 }
1019 
1020 /*
1021  * Drop a reference from the cred structure, free it if the reference count
1022  * reaches 0.
1023  *
1024  * NOTE: because we used atomic_add_int() above, without a spinlock, we
1025  * must also use atomic_subtract_int() below.  A spinlock is required
1026  * in crfree() to handle multiple callers racing the refcount to 0.
1027  */
1028 void
1029 crfree(struct ucred *cr)
1030 {
1031 	if (cr->cr_ref <= 0)
1032 		panic("Freeing already free credential! %p", cr);
1033 	if (atomic_fetchadd_long(&cr->cr_ref, -1) == 1) {
1034 		/*
1035 		 * Some callers of crget(), such as nfs_statfs(),
1036 		 * allocate a temporary credential, but don't
1037 		 * allocate a uidinfo structure.
1038 		 */
1039 		if (cr->cr_uidinfo != NULL) {
1040 			uidrop(cr->cr_uidinfo);
1041 			cr->cr_uidinfo = NULL;
1042 		}
1043 		if (cr->cr_ruidinfo != NULL) {
1044 			uidrop(cr->cr_ruidinfo);
1045 			cr->cr_ruidinfo = NULL;
1046 		}
1047 
1048 		/*
1049 		 * Destroy empty prisons
1050 		 */
1051 		if (jailed(cr))
1052 			prison_free(cr->cr_prison);
1053 		cr->cr_prison = NULL;	/* safety */
1054 
1055 		kfree((caddr_t)cr, M_CRED);
1056 	}
1057 }
1058 
1059 /*
1060  * Atomize a cred structure so it can be modified without polluting
1061  * other references to it.
1062  *
1063  * MPSAFE (however, *pcr must be stable)
1064  */
1065 struct ucred *
1066 cratom(struct ucred **pcr)
1067 {
1068 	struct ucred *oldcr;
1069 	struct ucred *newcr;
1070 
1071 	oldcr = *pcr;
1072 	if (oldcr->cr_ref == 1)
1073 		return (oldcr);
1074 	newcr = crget();	/* this might block */
1075 	oldcr = *pcr;		/* re-cache after potentially blocking */
1076 	*newcr = *oldcr;
1077 	uihold(newcr->cr_uidinfo);
1078 	uihold(newcr->cr_ruidinfo);
1079 	if (jailed(newcr))
1080 		prison_hold(newcr->cr_prison);
1081 	newcr->cr_ref = 1;
1082 	crfree(oldcr);
1083 	*pcr = newcr;
1084 
1085 	return (newcr);
1086 }
1087 
1088 /*
1089  * Called with a modifying token held, but must still obtain p_spin to
1090  * actually replace p_ucred to handle races against syscall entry from
1091  * other threads which cache p_ucred->td_ucred.
1092  *
1093  * (the threads will only get the spin-lock, and they only need to in
1094  *  the case where td_ucred != p_ucred so this is optimal).
1095  */
1096 struct ucred *
1097 cratom_proc(struct proc *p)
1098 {
1099 	struct ucred *oldcr;
1100 	struct ucred *newcr;
1101 
1102 	oldcr = p->p_ucred;
1103 	if (oldcr->cr_ref == 1)
1104 		return(oldcr);
1105 
1106 	newcr = crget();	/* this might block */
1107 	oldcr = p->p_ucred;	/* so re-cache oldcr (do not re-test) */
1108 	*newcr = *oldcr;
1109 	uihold(newcr->cr_uidinfo);
1110 	uihold(newcr->cr_ruidinfo);
1111 	if (jailed(newcr))
1112 		prison_hold(newcr->cr_prison);
1113 	newcr->cr_ref = 1;
1114 
1115 	spin_lock(&p->p_spin);
1116 	p->p_ucred = newcr;
1117 	spin_unlock(&p->p_spin);
1118 	crfree(oldcr);
1119 
1120 	return newcr;
1121 }
1122 
1123 /*
1124  * Dup cred struct to a new held one.
1125  */
1126 struct ucred *
1127 crdup(struct ucred *cr)
1128 {
1129 	struct ucred *newcr;
1130 
1131 	newcr = crget();
1132 	*newcr = *cr;
1133 	uihold(newcr->cr_uidinfo);
1134 	uihold(newcr->cr_ruidinfo);
1135 	if (jailed(newcr))
1136 		prison_hold(newcr->cr_prison);
1137 	newcr->cr_ref = 1;
1138 	return (newcr);
1139 }
1140 
1141 /*
1142  * Fill in a struct xucred based on a struct ucred.
1143  */
1144 void
1145 cru2x(struct ucred *cr, struct xucred *xcr)
1146 {
1147 
1148 	bzero(xcr, sizeof(*xcr));
1149 	xcr->cr_version = XUCRED_VERSION;
1150 	xcr->cr_uid = cr->cr_uid;
1151 	xcr->cr_ngroups = cr->cr_ngroups;
1152 	bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1153 }
1154 
1155 /*
1156  * Get login name, if available.
1157  */
1158 int
1159 sys_getlogin(struct getlogin_args *uap)
1160 {
1161 	struct proc *p = curproc;
1162 	char buf[MAXLOGNAME];
1163 	int error;
1164 
1165 	if (uap->namelen > MAXLOGNAME)		/* namelen is unsigned */
1166 		uap->namelen = MAXLOGNAME;
1167 	bzero(buf, sizeof(buf));
1168 	lwkt_gettoken_shared(&p->p_token);
1169 	bcopy(p->p_pgrp->pg_session->s_login, buf, uap->namelen);
1170 	lwkt_reltoken(&p->p_token);
1171 
1172 	error = copyout(buf, uap->namebuf, uap->namelen);
1173 	return (error);
1174 }
1175 
1176 /*
1177  * Set login name.
1178  */
1179 int
1180 sys_setlogin(struct setlogin_args *uap)
1181 {
1182 	struct thread *td = curthread;
1183 	struct proc *p;
1184 	struct ucred *cred;
1185 	char buf[MAXLOGNAME];
1186 	int error;
1187 
1188 	cred = td->td_ucred;
1189 	p = td->td_proc;
1190 
1191 	if ((error = priv_check_cred(cred, PRIV_PROC_SETLOGIN, 0)))
1192 		return (error);
1193 	bzero(buf, sizeof(buf));
1194 	error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL);
1195 	if (error == ENAMETOOLONG)
1196 		error = EINVAL;
1197 	if (error == 0) {
1198 		lwkt_gettoken_shared(&p->p_token);
1199 		memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf));
1200 		lwkt_reltoken(&p->p_token);
1201 	}
1202 	return (error);
1203 }
1204 
1205 void
1206 setsugid(void)
1207 {
1208 	struct proc *p = curproc;
1209 
1210 	KKASSERT(p != NULL);
1211 	lwkt_gettoken(&p->p_token);
1212 	p->p_flags |= P_SUGID;
1213 	if (!(p->p_pfsflags & PF_ISUGID))
1214 		p->p_stops = 0;
1215 	lwkt_reltoken(&p->p_token);
1216 }
1217 
1218 /*
1219  * Helper function to change the effective uid of a process
1220  */
1221 struct ucred *
1222 change_euid(uid_t euid)
1223 {
1224 	struct	proc *p = curproc;
1225 	struct	ucred *cr;
1226 
1227 	KKASSERT(p != NULL);
1228 	lf_count_adjust(p, 0);
1229 	cr = cratom_proc(p);
1230 	cr->cr_uid = euid;
1231 	uireplace(&cr->cr_uidinfo, uifind(euid));
1232 	lf_count_adjust(p, 1);
1233 	return (cr);
1234 }
1235 
1236 /*
1237  * Helper function to change the real uid of a process
1238  *
1239  * The per-uid process count for this process is transfered from
1240  * the old uid to the new uid.
1241  */
1242 struct ucred *
1243 change_ruid(uid_t ruid)
1244 {
1245 	struct	proc *p = curproc;
1246 	struct	ucred *cr;
1247 
1248 	KKASSERT(p != NULL);
1249 
1250 	cr = cratom_proc(p);
1251 	chgproccnt(cr->cr_ruidinfo, -1, 0);
1252 	cr->cr_ruid = ruid;
1253 	uireplace(&cr->cr_ruidinfo, uifind(ruid));
1254 	chgproccnt(cr->cr_ruidinfo, 1, 0);
1255 	return (cr);
1256 }
1257