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