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