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.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
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 $
43 * System calls related to processes and protection
46 #include "opt_compat.h"
48 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/sysproto.h>
52 #include <sys/kernel.h>
56 #include <sys/malloc.h>
57 #include <sys/pioctl.h>
58 #include <sys/resourcevar.h>
60 #include <sys/lockf.h>
61 #include <sys/spinlock.h>
63 #include <sys/thread2.h>
64 #include <sys/spinlock2.h>
66 static MALLOC_DEFINE(M_CRED
, "cred", "credentials");
69 sys_getpid(struct getpid_args
*uap
)
71 struct proc
*p
= curproc
;
73 uap
->sysmsg_fds
[0] = p
->p_pid
;
74 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
75 lwkt_gettoken(&proc_token
);
76 uap
->sysmsg_fds
[1] = p
->p_pptr
->p_pid
;
77 lwkt_reltoken(&proc_token
);
83 sys_getppid(struct getppid_args
*uap
)
85 struct proc
*p
= curproc
;
87 lwkt_gettoken(&proc_token
);
88 uap
->sysmsg_result
= p
->p_pptr
->p_pid
;
89 lwkt_reltoken(&proc_token
);
98 sys_lwp_gettid(struct lwp_gettid_args
*uap
)
100 struct lwp
*lp
= curthread
->td_lwp
;
102 uap
->sysmsg_result
= lp
->lwp_tid
;
107 * Get process group ID; note that POSIX getpgrp takes no parameter
112 sys_getpgrp(struct getpgrp_args
*uap
)
114 struct proc
*p
= curproc
;
116 uap
->sysmsg_result
= p
->p_pgrp
->pg_id
;
121 * Get an arbitrary pid's process group id
124 sys_getpgid(struct getpgid_args
*uap
)
126 struct proc
*p
= curproc
;
136 pt
= pfind(uap
->pid
);
140 /* XXX MPSAFE on pgrp? */
142 uap
->sysmsg_result
= pt
->p_pgrp
->pg_id
;
149 * Get an arbitrary pid's session id.
152 sys_getsid(struct getsid_args
*uap
)
154 struct proc
*p
= curproc
;
164 pt
= pfind(uap
->pid
);
169 uap
->sysmsg_result
= pt
->p_session
->s_sid
;
182 sys_getuid(struct getuid_args
*uap
)
184 struct ucred
*cred
= curthread
->td_ucred
;
186 uap
->sysmsg_fds
[0] = cred
->cr_ruid
;
187 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
188 uap
->sysmsg_fds
[1] = cred
->cr_uid
;
199 sys_geteuid(struct geteuid_args
*uap
)
201 struct ucred
*cred
= curthread
->td_ucred
;
203 uap
->sysmsg_result
= cred
->cr_uid
;
213 sys_getgid(struct getgid_args
*uap
)
215 struct ucred
*cred
= curthread
->td_ucred
;
217 uap
->sysmsg_fds
[0] = cred
->cr_rgid
;
218 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
219 uap
->sysmsg_fds
[1] = cred
->cr_groups
[0];
225 * Get effective group ID. The "egid" is groups[0], and could be obtained
226 * via getgroups. This syscall exists because it is somewhat painful to do
227 * correctly in a library function.
232 sys_getegid(struct getegid_args
*uap
)
234 struct ucred
*cred
= curthread
->td_ucred
;
236 uap
->sysmsg_result
= cred
->cr_groups
[0];
244 sys_getgroups(struct getgroups_args
*uap
)
250 cr
= curthread
->td_ucred
;
251 if ((ngrp
= uap
->gidsetsize
) == 0) {
252 uap
->sysmsg_result
= cr
->cr_ngroups
;
255 if (ngrp
< cr
->cr_ngroups
)
257 ngrp
= cr
->cr_ngroups
;
258 error
= copyout((caddr_t
)cr
->cr_groups
,
259 (caddr_t
)uap
->gidset
, ngrp
* sizeof(gid_t
));
261 uap
->sysmsg_result
= ngrp
;
266 sys_setsid(struct setsid_args
*uap
)
268 struct proc
*p
= curproc
;
269 struct pgrp
*pg
= NULL
;
272 lwkt_gettoken(&p
->p_token
);
273 if (p
->p_pgid
== p
->p_pid
|| (pg
= pgfind(p
->p_pid
)) != NULL
) {
278 enterpgrp(p
, p
->p_pid
, 1);
279 uap
->sysmsg_result
= p
->p_pid
;
282 lwkt_reltoken(&p
->p_token
);
287 * set process group (setpgid/old setpgrp)
289 * caller does setpgid(targpid, targpgid)
291 * pid must be caller or child of caller (ESRCH)
293 * pid must be in same session (EPERM)
294 * pid can't have done an exec (EACCES)
296 * there must exist some pid in same session having pgid (EPERM)
297 * pid must not be session leader (EPERM)
300 sys_setpgid(struct setpgid_args
*uap
)
302 struct proc
*curp
= curproc
;
303 struct proc
*targp
; /* target process */
304 struct pgrp
*pgrp
= NULL
; /* target pgrp */
310 if (uap
->pid
!= 0 && uap
->pid
!= curp
->p_pid
) {
311 if ((targp
= pfind(uap
->pid
)) == NULL
|| !inferior(targp
)) {
318 lwkt_gettoken(&targp
->p_token
);
319 /* targp now referenced and its token is held */
321 if (targp
->p_pgrp
== NULL
||
322 targp
->p_session
!= curp
->p_session
) {
326 if (targp
->p_flags
& P_EXEC
) {
333 lwkt_gettoken(&targp
->p_token
);
335 if (SESS_LEADER(targp
)) {
339 if (uap
->pgid
== 0) {
340 uap
->pgid
= targp
->p_pid
;
341 } else if (uap
->pgid
!= targp
->p_pid
) {
342 if ((pgrp
= pgfind(uap
->pgid
)) == NULL
||
343 pgrp
->pg_session
!= curp
->p_session
) {
348 error
= enterpgrp(targp
, uap
->pgid
, 0);
353 lwkt_reltoken(&targp
->p_token
);
360 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
361 * compatible. It says that setting the uid/gid to euid/egid is a special
362 * case of "appropriate privilege". Once the rules are expanded out, this
363 * basically means that setuid(nnn) sets all three id's, in all permitted
364 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid())
365 * does not set the saved id - this is dangerous for traditional BSD
366 * programs. For this reason, we *really* do not want to set
367 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
369 #define POSIX_APPENDIX_B_4_2_2
372 sys_setuid(struct setuid_args
*uap
)
374 struct proc
*p
= curproc
;
379 lwkt_gettoken(&proc_token
);
383 * See if we have "permission" by POSIX 1003.1 rules.
385 * Note that setuid(geteuid()) is a special case of
386 * "appropriate privileges" in appendix B.4.2.2. We need
387 * to use this clause to be compatible with traditional BSD
388 * semantics. Basically, it means that "setuid(xx)" sets all
389 * three id's (assuming you have privs).
391 * Notes on the logic. We do things in three steps.
392 * 1: We determine if the euid is going to change, and do EPERM
393 * right away. We unconditionally change the euid later if this
394 * test is satisfied, simplifying that part of the logic.
395 * 2: We determine if the real and/or saved uid's are going to
396 * change. Determined by compile options.
397 * 3: Change euid last. (after tests in #2 for "appropriate privs")
400 if (uid
!= cr
->cr_ruid
&& /* allow setuid(getuid()) */
401 #ifdef _POSIX_SAVED_IDS
402 uid
!= crc
->cr_svuid
&& /* allow setuid(saved gid) */
404 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
405 uid
!= cr
->cr_uid
&& /* allow setuid(geteuid()) */
407 (error
= priv_check_cred(cr
, PRIV_CRED_SETUID
, 0)))
410 #ifdef _POSIX_SAVED_IDS
412 * Do we have "appropriate privileges" (are we root or uid == euid)
413 * If so, we are changing the real uid and/or saved uid.
416 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
419 priv_check_cred(cr
, PRIV_CRED_SETUID
, 0) == 0) /* we are using privs */
423 * Set the real uid and transfer proc count to new user.
425 if (uid
!= cr
->cr_ruid
) {
426 cr
= change_ruid(uid
);
432 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
433 * the security of seteuid() depends on it. B.4.2.2 says it
434 * is important that we should do this.
436 if (cr
->cr_svuid
!= uid
) {
437 cr
= cratom(&p
->p_ucred
);
444 * In all permitted cases, we are changing the euid.
445 * Copy credentials so other references do not see our changes.
447 if (cr
->cr_uid
!= uid
) {
453 lwkt_reltoken(&proc_token
);
458 sys_seteuid(struct seteuid_args
*uap
)
460 struct proc
*p
= curproc
;
465 lwkt_gettoken(&proc_token
);
468 if (euid
!= cr
->cr_ruid
&& /* allow seteuid(getuid()) */
469 euid
!= cr
->cr_svuid
&& /* allow seteuid(saved uid) */
470 (error
= priv_check_cred(cr
, PRIV_CRED_SETEUID
, 0))) {
471 lwkt_reltoken(&proc_token
);
476 * Everything's okay, do it. Copy credentials so other references do
477 * not see our changes.
479 if (cr
->cr_uid
!= euid
) {
483 lwkt_reltoken(&proc_token
);
488 sys_setgid(struct setgid_args
*uap
)
490 struct proc
*p
= curproc
;
495 lwkt_gettoken(&proc_token
);
499 * See if we have "permission" by POSIX 1003.1 rules.
501 * Note that setgid(getegid()) is a special case of
502 * "appropriate privileges" in appendix B.4.2.2. We need
503 * to use this clause to be compatible with traditional BSD
504 * semantics. Basically, it means that "setgid(xx)" sets all
505 * three id's (assuming you have privs).
507 * For notes on the logic here, see setuid() above.
510 if (gid
!= cr
->cr_rgid
&& /* allow setgid(getgid()) */
511 #ifdef _POSIX_SAVED_IDS
512 gid
!= cr
->cr_svgid
&& /* allow setgid(saved gid) */
514 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
515 gid
!= cr
->cr_groups
[0] && /* allow setgid(getegid()) */
517 (error
= priv_check_cred(cr
, PRIV_CRED_SETGID
, 0))) {
521 #ifdef _POSIX_SAVED_IDS
523 * Do we have "appropriate privileges" (are we root or gid == egid)
524 * If so, we are changing the real uid and saved gid.
527 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
528 gid
== cr
->cr_groups
[0] ||
530 priv_check_cred(cr
, PRIV_CRED_SETGID
, 0) == 0) /* we are using privs */
536 if (cr
->cr_rgid
!= gid
) {
537 cr
= cratom(&p
->p_ucred
);
544 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
545 * the security of setegid() depends on it. B.4.2.2 says it
546 * is important that we should do this.
548 if (cr
->cr_svgid
!= gid
) {
549 cr
= cratom(&p
->p_ucred
);
555 * In all cases permitted cases, we are changing the egid.
556 * Copy credentials so other references do not see our changes.
558 if (cr
->cr_groups
[0] != gid
) {
559 cr
= cratom(&p
->p_ucred
);
560 cr
->cr_groups
[0] = gid
;
565 lwkt_reltoken(&proc_token
);
570 sys_setegid(struct setegid_args
*uap
)
572 struct proc
*p
= curproc
;
577 lwkt_gettoken(&proc_token
);
580 if (egid
!= cr
->cr_rgid
&& /* allow setegid(getgid()) */
581 egid
!= cr
->cr_svgid
&& /* allow setegid(saved gid) */
582 (error
= priv_check_cred(cr
, PRIV_CRED_SETEGID
, 0))) {
585 if (cr
->cr_groups
[0] != egid
) {
586 cr
= cratom(&p
->p_ucred
);
587 cr
->cr_groups
[0] = egid
;
592 lwkt_reltoken(&proc_token
);
597 sys_setgroups(struct setgroups_args
*uap
)
599 struct proc
*p
= curproc
;
604 lwkt_gettoken(&proc_token
);
607 if ((error
= priv_check_cred(cr
, PRIV_CRED_SETGROUPS
, 0)))
609 ngrp
= uap
->gidsetsize
;
610 if (ngrp
> NGROUPS
) {
615 * XXX A little bit lazy here. We could test if anything has
616 * changed before cratom() and setting P_SUGID.
618 cr
= cratom(&p
->p_ucred
);
621 * setgroups(0, NULL) is a legitimate way of clearing the
622 * groups vector on non-BSD systems (which generally do not
623 * have the egid in the groups[0]). We risk security holes
624 * when running non-BSD software if we do not do the same.
628 error
= copyin(uap
->gidset
, cr
->cr_groups
,
629 ngrp
* sizeof(gid_t
));
632 cr
->cr_ngroups
= ngrp
;
637 lwkt_reltoken(&proc_token
);
642 sys_setreuid(struct setreuid_args
*uap
)
644 struct proc
*p
= curproc
;
649 lwkt_gettoken(&proc_token
);
654 if (((ruid
!= (uid_t
)-1 && ruid
!= cr
->cr_ruid
&& ruid
!= cr
->cr_svuid
) ||
655 (euid
!= (uid_t
)-1 && euid
!= cr
->cr_uid
&&
656 euid
!= cr
->cr_ruid
&& euid
!= cr
->cr_svuid
)) &&
657 (error
= priv_check_cred(cr
, PRIV_CRED_SETREUID
, 0)) != 0) {
661 if (euid
!= (uid_t
)-1 && cr
->cr_uid
!= euid
) {
662 cr
= change_euid(euid
);
665 if (ruid
!= (uid_t
)-1 && cr
->cr_ruid
!= ruid
) {
666 cr
= change_ruid(ruid
);
669 if ((ruid
!= (uid_t
)-1 || cr
->cr_uid
!= cr
->cr_ruid
) &&
670 cr
->cr_svuid
!= cr
->cr_uid
) {
671 cr
= cratom(&p
->p_ucred
);
672 cr
->cr_svuid
= cr
->cr_uid
;
677 lwkt_reltoken(&proc_token
);
682 sys_setregid(struct setregid_args
*uap
)
684 struct proc
*p
= curproc
;
689 lwkt_gettoken(&proc_token
);
694 if (((rgid
!= (gid_t
)-1 && rgid
!= cr
->cr_rgid
&& rgid
!= cr
->cr_svgid
) ||
695 (egid
!= (gid_t
)-1 && egid
!= cr
->cr_groups
[0] &&
696 egid
!= cr
->cr_rgid
&& egid
!= cr
->cr_svgid
)) &&
697 (error
= priv_check_cred(cr
, PRIV_CRED_SETREGID
, 0)) != 0) {
701 if (egid
!= (gid_t
)-1 && cr
->cr_groups
[0] != egid
) {
702 cr
= cratom(&p
->p_ucred
);
703 cr
->cr_groups
[0] = egid
;
706 if (rgid
!= (gid_t
)-1 && cr
->cr_rgid
!= rgid
) {
707 cr
= cratom(&p
->p_ucred
);
711 if ((rgid
!= (gid_t
)-1 || cr
->cr_groups
[0] != cr
->cr_rgid
) &&
712 cr
->cr_svgid
!= cr
->cr_groups
[0]) {
713 cr
= cratom(&p
->p_ucred
);
714 cr
->cr_svgid
= cr
->cr_groups
[0];
719 lwkt_reltoken(&proc_token
);
724 * setresuid(ruid, euid, suid) is like setreuid except control over the
725 * saved uid is explicit.
728 sys_setresuid(struct setresuid_args
*uap
)
730 struct proc
*p
= curproc
;
732 uid_t ruid
, euid
, suid
;
735 lwkt_gettoken(&proc_token
);
741 if (((ruid
!= (uid_t
)-1 && ruid
!= cr
->cr_ruid
&& ruid
!= cr
->cr_svuid
&&
742 ruid
!= cr
->cr_uid
) ||
743 (euid
!= (uid_t
)-1 && euid
!= cr
->cr_ruid
&& euid
!= cr
->cr_svuid
&&
744 euid
!= cr
->cr_uid
) ||
745 (suid
!= (uid_t
)-1 && suid
!= cr
->cr_ruid
&& suid
!= cr
->cr_svuid
&&
746 suid
!= cr
->cr_uid
)) &&
747 (error
= priv_check_cred(cr
, PRIV_CRED_SETRESUID
, 0)) != 0) {
750 if (euid
!= (uid_t
)-1 && cr
->cr_uid
!= euid
) {
751 cr
= change_euid(euid
);
754 if (ruid
!= (uid_t
)-1 && cr
->cr_ruid
!= ruid
) {
755 cr
= change_ruid(ruid
);
758 if (suid
!= (uid_t
)-1 && cr
->cr_svuid
!= suid
) {
759 cr
= cratom(&p
->p_ucred
);
765 lwkt_reltoken(&proc_token
);
770 * setresgid(rgid, egid, sgid) is like setregid except control over the
771 * saved gid is explicit.
774 sys_setresgid(struct setresgid_args
*uap
)
776 struct proc
*p
= curproc
;
778 gid_t rgid
, egid
, sgid
;
781 lwkt_gettoken(&proc_token
);
786 if (((rgid
!= (gid_t
)-1 && rgid
!= cr
->cr_rgid
&& rgid
!= cr
->cr_svgid
&&
787 rgid
!= cr
->cr_groups
[0]) ||
788 (egid
!= (gid_t
)-1 && egid
!= cr
->cr_rgid
&& egid
!= cr
->cr_svgid
&&
789 egid
!= cr
->cr_groups
[0]) ||
790 (sgid
!= (gid_t
)-1 && sgid
!= cr
->cr_rgid
&& sgid
!= cr
->cr_svgid
&&
791 sgid
!= cr
->cr_groups
[0])) &&
792 (error
= priv_check_cred(cr
, PRIV_CRED_SETRESGID
, 0)) != 0) {
796 if (egid
!= (gid_t
)-1 && cr
->cr_groups
[0] != egid
) {
797 cr
= cratom(&p
->p_ucred
);
798 cr
->cr_groups
[0] = egid
;
801 if (rgid
!= (gid_t
)-1 && cr
->cr_rgid
!= rgid
) {
802 cr
= cratom(&p
->p_ucred
);
806 if (sgid
!= (gid_t
)-1 && cr
->cr_svgid
!= sgid
) {
807 cr
= cratom(&p
->p_ucred
);
813 lwkt_reltoken(&proc_token
);
818 sys_getresuid(struct getresuid_args
*uap
)
820 struct proc
*p
= curproc
;
822 int error1
= 0, error2
= 0, error3
= 0;
824 lwkt_gettoken(&proc_token
);
827 error1
= copyout((caddr_t
)&cr
->cr_ruid
,
828 (caddr_t
)uap
->ruid
, sizeof(cr
->cr_ruid
));
830 error2
= copyout((caddr_t
)&cr
->cr_uid
,
831 (caddr_t
)uap
->euid
, sizeof(cr
->cr_uid
));
833 error3
= copyout((caddr_t
)&cr
->cr_svuid
,
834 (caddr_t
)uap
->suid
, sizeof(cr
->cr_svuid
));
835 lwkt_reltoken(&proc_token
);
836 return error1
? error1
: (error2
? error2
: error3
);
843 sys_getresgid(struct getresgid_args
*uap
)
846 int error1
= 0, error2
= 0, error3
= 0;
848 cr
= curthread
->td_ucred
;
850 error1
= copyout(&cr
->cr_rgid
, uap
->rgid
,
851 sizeof(cr
->cr_rgid
));
853 error2
= copyout(&cr
->cr_groups
[0], uap
->egid
,
854 sizeof(cr
->cr_groups
[0]));
856 error3
= copyout(&cr
->cr_svgid
, uap
->sgid
,
857 sizeof(cr
->cr_svgid
));
858 return error1
? error1
: (error2
? error2
: error3
);
863 * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
864 * we use P_SUGID because we consider changing the owners as
865 * "tainting" as well.
866 * This is significant for procs that start as root and "become"
867 * a user without an exec - programs cannot know *everything*
868 * that libc *might* have put in their data segment.
873 sys_issetugid(struct issetugid_args
*uap
)
875 uap
->sysmsg_result
= (curproc
->p_flags
& P_SUGID
) ? 1 : 0;
880 * Check if gid is a member of the group set.
883 groupmember(gid_t gid
, struct ucred
*cred
)
888 egp
= &(cred
->cr_groups
[cred
->cr_ngroups
]);
889 for (gp
= cred
->cr_groups
; gp
< egp
; gp
++) {
897 * Test whether the specified credentials have the privilege
900 * A kernel thread without a process context is assumed to have
901 * the privilege in question. In situations where the caller always
902 * expect a cred to exist, the cred should be passed separately and
903 * priv_check_cred() should be used instead of priv_check().
905 * Returns 0 or error.
910 priv_check(struct thread
*td
, int priv
)
912 if (td
->td_lwp
!= NULL
)
913 return priv_check_cred(td
->td_ucred
, priv
, 0);
918 * Check a credential for privilege.
920 * A non-null credential is expected unless NULL_CRED_OKAY is set.
925 priv_check_cred(struct ucred
*cred
, int priv
, int flags
)
929 KASSERT(PRIV_VALID(priv
), ("priv_check_cred: invalid privilege"));
931 KASSERT(cred
!= NULL
|| flags
& NULL_CRED_OKAY
,
932 ("priv_check_cred: NULL cred!"));
935 if (flags
& NULL_CRED_OKAY
)
940 if (cred
->cr_uid
!= 0)
943 error
= prison_priv_check(cred
, priv
);
947 /* NOTE: accounting for suser access (p_acflag/ASU) removed */
952 * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
955 p_trespass(struct ucred
*cr1
, struct ucred
*cr2
)
959 if (!PRISON_CHECK(cr1
, cr2
))
961 if (cr1
->cr_ruid
== cr2
->cr_ruid
)
963 if (cr1
->cr_uid
== cr2
->cr_ruid
)
965 if (cr1
->cr_ruid
== cr2
->cr_uid
)
967 if (cr1
->cr_uid
== cr2
->cr_uid
)
969 if (priv_check_cred(cr1
, PRIV_PROC_TRESPASS
, 0) == 0)
978 _crinit(struct ucred
*cr
)
987 crinit(struct ucred
*cr
)
989 bzero(cr
, sizeof(*cr
));
994 * Allocate a zeroed cred structure.
1003 cr
= kmalloc(sizeof(*cr
), M_CRED
, M_WAITOK
|M_ZERO
);
1009 * Claim another reference to a ucred structure. Can be used with special
1012 * It must be possible to call this routine with spinlocks held, meaning
1013 * that this routine itself cannot obtain a spinlock.
1018 crhold(struct ucred
*cr
)
1020 if (cr
!= NOCRED
&& cr
!= FSCRED
)
1021 atomic_add_int(&cr
->cr_ref
, 1);
1026 * Drop a reference from the cred structure, free it if the reference count
1029 * NOTE: because we used atomic_add_int() above, without a spinlock, we
1030 * must also use atomic_subtract_int() below. A spinlock is required
1031 * in crfree() to handle multiple callers racing the refcount to 0.
1036 crfree(struct ucred
*cr
)
1038 if (cr
->cr_ref
<= 0)
1039 panic("Freeing already free credential! %p", cr
);
1040 if (atomic_fetchadd_int(&cr
->cr_ref
, -1) == 1) {
1042 * Some callers of crget(), such as nfs_statfs(),
1043 * allocate a temporary credential, but don't
1044 * allocate a uidinfo structure.
1046 if (cr
->cr_uidinfo
!= NULL
) {
1047 uidrop(cr
->cr_uidinfo
);
1048 cr
->cr_uidinfo
= NULL
;
1050 if (cr
->cr_ruidinfo
!= NULL
) {
1051 uidrop(cr
->cr_ruidinfo
);
1052 cr
->cr_ruidinfo
= NULL
;
1056 * Destroy empty prisons
1059 prison_free(cr
->cr_prison
);
1060 cr
->cr_prison
= NULL
; /* safety */
1062 kfree((caddr_t
)cr
, M_CRED
);
1067 * Atomize a cred structure so it can be modified without polluting
1068 * other references to it.
1070 * MPSAFE (however, *pcr must be stable)
1073 cratom(struct ucred
**pcr
)
1075 struct ucred
*oldcr
;
1076 struct ucred
*newcr
;
1079 if (oldcr
->cr_ref
== 1)
1083 if (newcr
->cr_uidinfo
)
1084 uihold(newcr
->cr_uidinfo
);
1085 if (newcr
->cr_ruidinfo
)
1086 uihold(newcr
->cr_ruidinfo
);
1088 prison_hold(newcr
->cr_prison
);
1095 #if 0 /* no longer used but keep around for a little while */
1097 * Copy cred structure to a new one and free the old one.
1099 * MPSAFE (*cr must be stable)
1102 crcopy(struct ucred
*cr
)
1104 struct ucred
*newcr
;
1106 if (cr
->cr_ref
== 1)
1110 if (newcr
->cr_uidinfo
)
1111 uihold(newcr
->cr_uidinfo
);
1112 if (newcr
->cr_ruidinfo
)
1113 uihold(newcr
->cr_ruidinfo
);
1115 prison_hold(newcr
->cr_prison
);
1123 * Dup cred struct to a new held one.
1126 crdup(struct ucred
*cr
)
1128 struct ucred
*newcr
;
1132 if (newcr
->cr_uidinfo
)
1133 uihold(newcr
->cr_uidinfo
);
1134 if (newcr
->cr_ruidinfo
)
1135 uihold(newcr
->cr_ruidinfo
);
1137 prison_hold(newcr
->cr_prison
);
1143 * Fill in a struct xucred based on a struct ucred.
1146 cru2x(struct ucred
*cr
, struct xucred
*xcr
)
1149 bzero(xcr
, sizeof(*xcr
));
1150 xcr
->cr_version
= XUCRED_VERSION
;
1151 xcr
->cr_uid
= cr
->cr_uid
;
1152 xcr
->cr_ngroups
= cr
->cr_ngroups
;
1153 bcopy(cr
->cr_groups
, xcr
->cr_groups
, sizeof(cr
->cr_groups
));
1157 * Get login name, if available.
1160 sys_getlogin(struct getlogin_args
*uap
)
1162 struct proc
*p
= curproc
;
1163 char buf
[MAXLOGNAME
];
1166 if (uap
->namelen
> MAXLOGNAME
) /* namelen is unsigned */
1167 uap
->namelen
= MAXLOGNAME
;
1168 bzero(buf
, sizeof(buf
));
1169 lwkt_gettoken(&proc_token
);
1170 bcopy(p
->p_pgrp
->pg_session
->s_login
, buf
, uap
->namelen
);
1171 lwkt_reltoken(&proc_token
);
1173 error
= copyout(buf
, uap
->namebuf
, uap
->namelen
);
1181 sys_setlogin(struct setlogin_args
*uap
)
1183 struct thread
*td
= curthread
;
1186 char buf
[MAXLOGNAME
];
1189 cred
= td
->td_ucred
;
1192 if ((error
= priv_check_cred(cred
, PRIV_PROC_SETLOGIN
, 0)))
1194 bzero(buf
, sizeof(buf
));
1195 error
= copyinstr(uap
->namebuf
, buf
, sizeof(buf
), NULL
);
1196 if (error
== ENAMETOOLONG
)
1199 lwkt_gettoken(&proc_token
);
1200 memcpy(p
->p_pgrp
->pg_session
->s_login
, buf
, sizeof(buf
));
1201 lwkt_reltoken(&proc_token
);
1209 struct proc
*p
= curproc
;
1211 KKASSERT(p
!= NULL
);
1212 lwkt_gettoken(&p
->p_token
);
1213 p
->p_flags
|= P_SUGID
;
1214 if (!(p
->p_pfsflags
& PF_ISUGID
))
1216 lwkt_reltoken(&p
->p_token
);
1220 * Helper function to change the effective uid of a process
1223 change_euid(uid_t euid
)
1225 struct proc
*p
= curproc
;
1228 KKASSERT(p
!= NULL
);
1229 lf_count_adjust(p
, 0);
1230 cr
= cratom(&p
->p_ucred
);
1232 uireplace(&cr
->cr_uidinfo
, uifind(euid
));
1233 lf_count_adjust(p
, 1);
1238 * Helper function to change the real uid of a process
1240 * The per-uid process count for this process is transfered from
1241 * the old uid to the new uid.
1244 change_ruid(uid_t ruid
)
1246 struct proc
*p
= curproc
;
1249 KKASSERT(p
!= NULL
);
1251 cr
= cratom(&p
->p_ucred
);
1252 chgproccnt(cr
->cr_ruidinfo
, -1, 0);
1254 uireplace(&cr
->cr_ruidinfo
, uifind(ruid
));
1255 chgproccnt(cr
->cr_ruidinfo
, 1, 0);