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. 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.
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
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 $
39 * System calls related to processes and protection
42 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/sysproto.h>
46 #include <sys/kernel.h>
50 #include <sys/malloc.h>
51 #include <sys/pioctl.h>
52 #include <sys/resourcevar.h>
54 #include <sys/lockf.h>
55 #include <sys/spinlock.h>
57 #include <sys/spinlock2.h>
59 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
62 sys_getpid(struct getpid_args *uap)
64 struct proc *p = curproc;
66 uap->sysmsg_fds[0] = p->p_pid;
71 sys_getppid(struct getppid_args *uap)
73 struct proc *p = curproc;
75 uap->sysmsg_result = p->p_ppid;
81 sys_lwp_gettid(struct lwp_gettid_args *uap)
83 struct lwp *lp = curthread->td_lwp;
84 uap->sysmsg_result = lp->lwp_tid;
89 * Get process group ID; note that POSIX getpgrp takes no parameter
92 sys_getpgrp(struct getpgrp_args *uap)
94 struct proc *p = curproc;
96 lwkt_gettoken_shared(&p->p_token);
97 uap->sysmsg_result = p->p_pgrp->pg_id;
98 lwkt_reltoken(&p->p_token);
104 * Get an arbitrary pid's process group id
107 sys_getpgid(struct getpgid_args *uap)
109 struct proc *p = curproc;
119 pt = pfind(uap->pid);
124 lwkt_gettoken_shared(&pt->p_token);
125 uap->sysmsg_result = pt->p_pgrp->pg_id;
126 lwkt_reltoken(&pt->p_token);
134 * Get an arbitrary pid's session id.
137 sys_getsid(struct getsid_args *uap)
139 struct proc *p = curproc;
149 pt = pfind(uap->pid);
154 uap->sysmsg_result = pt->p_session->s_sid;
165 sys_getuid(struct getuid_args *uap)
167 struct ucred *cred = curthread->td_ucred;
169 uap->sysmsg_fds[0] = cred->cr_ruid;
177 sys_geteuid(struct geteuid_args *uap)
179 struct ucred *cred = curthread->td_ucred;
181 uap->sysmsg_result = cred->cr_uid;
189 sys_getgid(struct getgid_args *uap)
191 struct ucred *cred = curthread->td_ucred;
193 uap->sysmsg_fds[0] = cred->cr_rgid;
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.
203 sys_getegid(struct getegid_args *uap)
205 struct ucred *cred = curthread->td_ucred;
207 uap->sysmsg_result = cred->cr_groups[0];
212 sys_getgroups(struct getgroups_args *uap)
218 cr = curthread->td_ucred;
219 if ((ngrp = uap->gidsetsize) == 0) {
220 uap->sysmsg_result = cr->cr_ngroups;
223 if (ngrp < cr->cr_ngroups)
225 ngrp = cr->cr_ngroups;
226 error = copyout((caddr_t)cr->cr_groups,
227 (caddr_t)uap->gidset, ngrp * sizeof(gid_t));
229 uap->sysmsg_result = ngrp;
234 sys_lwp_setname(struct lwp_setname_args *uap)
236 struct proc *p = curproc;
237 char comm0[MAXCOMLEN + 1];
238 const char *comm = NULL;
242 if (uap->name != NULL) {
243 error = copyinstr(uap->name, comm0, sizeof(comm0), NULL);
245 if (error != ENAMETOOLONG)
248 comm0[MAXCOMLEN] = '\0';
252 /* Restore to the default name, i.e. process name. */
256 lwkt_gettoken(&p->p_token);
258 lp = lwp_rb_tree_RB_LOOKUP(&p->p_lwp_tree, uap->tid);
260 strlcpy(lp->lwp_thread->td_comm, comm,
261 sizeof(lp->lwp_thread->td_comm));
267 lwkt_reltoken(&p->p_token);
272 sys_setsid(struct setsid_args *uap)
274 struct proc *p = curproc;
275 struct pgrp *pg = NULL;
278 lwkt_gettoken(&p->p_token);
279 if (p->p_pgid == p->p_pid || (pg = pgfind(p->p_pid)) != NULL) {
284 enterpgrp(p, p->p_pid, 1);
285 uap->sysmsg_result = p->p_pid;
288 lwkt_reltoken(&p->p_token);
293 * set process group (setpgid/old setpgrp)
295 * caller does setpgid(targpid, targpgid)
297 * pid must be caller or child of caller (ESRCH)
299 * pid must be in same session (EPERM)
300 * pid can't have done an exec (EACCES)
302 * there must exist some pid in same session having pgid (EPERM)
303 * pid must not be session leader (EPERM)
306 sys_setpgid(struct setpgid_args *uap)
308 struct proc *curp = curproc;
309 struct proc *targp; /* target process */
310 struct pgrp *pgrp = NULL; /* target pgrp */
316 if (uap->pid != 0 && uap->pid != curp->p_pid) {
317 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
324 lwkt_gettoken(&targp->p_token);
325 /* targp now referenced and its token is held */
327 if (targp->p_pgrp == NULL ||
328 targp->p_session != curp->p_session) {
332 if (targp->p_flags & P_EXEC) {
339 lwkt_gettoken(&targp->p_token);
341 if (SESS_LEADER(targp)) {
345 if (uap->pgid == 0) {
346 uap->pgid = targp->p_pid;
347 } else if (uap->pgid != targp->p_pid) {
348 if ((pgrp = pgfind(uap->pgid)) == NULL ||
349 pgrp->pg_session != curp->p_session) {
354 error = enterpgrp(targp, uap->pgid, 0);
359 lwkt_reltoken(&targp->p_token);
366 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
367 * compatible. It says that setting the uid/gid to euid/egid is a special
368 * case of "appropriate privilege". Once the rules are expanded out, this
369 * basically means that setuid(nnn) sets all three id's, in all permitted
370 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid())
371 * does not set the saved id - this is dangerous for traditional BSD
372 * programs. For this reason, we *really* do not want to set
373 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
375 #define POSIX_APPENDIX_B_4_2_2
378 sys_setuid(struct setuid_args *uap)
380 struct proc *p = curproc;
385 lwkt_gettoken(&p->p_token);
389 * See if we have "permission" by POSIX 1003.1 rules.
391 * Note that setuid(geteuid()) is a special case of
392 * "appropriate privileges" in appendix B.4.2.2. We need
393 * to use this clause to be compatible with traditional BSD
394 * semantics. Basically, it means that "setuid(xx)" sets all
395 * three id's (assuming you have privs).
397 * Notes on the logic. We do things in three steps.
398 * 1: We determine if the euid is going to change, and do EPERM
399 * right away. We unconditionally change the euid later if this
400 * test is satisfied, simplifying that part of the logic.
401 * 2: We determine if the real and/or saved uid's are going to
402 * change. Determined by compile options.
403 * 3: Change euid last. (after tests in #2 for "appropriate privs")
406 if (uid != cr->cr_ruid && /* allow setuid(getuid()) */
407 #ifdef _POSIX_SAVED_IDS
408 uid != crc->cr_svuid && /* allow setuid(saved gid) */
410 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
411 uid != cr->cr_uid && /* allow setuid(geteuid()) */
413 (error = priv_check_cred(cr, PRIV_CRED_SETUID, 0)))
416 #ifdef _POSIX_SAVED_IDS
418 * Do we have "appropriate privileges" (are we root or uid == euid)
419 * If so, we are changing the real uid and/or saved uid.
422 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
425 priv_check_cred(cr, PRIV_CRED_SETUID, 0) == 0) /* we are using privs */
429 * Set the real uid and transfer proc count to new user.
431 if (uid != cr->cr_ruid) {
432 cr = change_ruid(uid);
438 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
439 * the security of seteuid() depends on it. B.4.2.2 says it
440 * is important that we should do this.
442 if (cr->cr_svuid != uid) {
450 * In all permitted cases, we are changing the euid.
451 * Copy credentials so other references do not see our changes.
453 if (cr->cr_uid != uid) {
459 lwkt_reltoken(&p->p_token);
464 sys_seteuid(struct seteuid_args *uap)
466 struct proc *p = curproc;
471 lwkt_gettoken(&p->p_token);
474 if (euid != cr->cr_ruid && /* allow seteuid(getuid()) */
475 euid != cr->cr_svuid && /* allow seteuid(saved uid) */
476 (error = priv_check_cred(cr, PRIV_CRED_SETEUID, 0))) {
477 lwkt_reltoken(&p->p_token);
482 * Everything's okay, do it. Copy credentials so other references do
483 * not see our changes.
485 if (cr->cr_uid != euid) {
489 lwkt_reltoken(&p->p_token);
494 sys_setgid(struct setgid_args *uap)
496 struct proc *p = curproc;
501 lwkt_gettoken(&p->p_token);
505 * See if we have "permission" by POSIX 1003.1 rules.
507 * Note that setgid(getegid()) is a special case of
508 * "appropriate privileges" in appendix B.4.2.2. We need
509 * to use this clause to be compatible with traditional BSD
510 * semantics. Basically, it means that "setgid(xx)" sets all
511 * three id's (assuming you have privs).
513 * For notes on the logic here, see setuid() above.
516 if (gid != cr->cr_rgid && /* allow setgid(getgid()) */
517 #ifdef _POSIX_SAVED_IDS
518 gid != cr->cr_svgid && /* allow setgid(saved gid) */
520 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
521 gid != cr->cr_groups[0] && /* allow setgid(getegid()) */
523 (error = priv_check_cred(cr, PRIV_CRED_SETGID, 0))) {
527 #ifdef _POSIX_SAVED_IDS
529 * Do we have "appropriate privileges" (are we root or gid == egid)
530 * If so, we are changing the real uid and saved gid.
533 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
534 gid == cr->cr_groups[0] ||
536 priv_check_cred(cr, PRIV_CRED_SETGID, 0) == 0) /* we are using privs */
542 if (cr->cr_rgid != gid) {
550 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
551 * the security of setegid() depends on it. B.4.2.2 says it
552 * is important that we should do this.
554 if (cr->cr_svgid != gid) {
561 * In all cases permitted cases, we are changing the egid.
562 * Copy credentials so other references do not see our changes.
564 if (cr->cr_groups[0] != gid) {
566 cr->cr_groups[0] = gid;
571 lwkt_reltoken(&p->p_token);
576 sys_setegid(struct setegid_args *uap)
578 struct proc *p = curproc;
583 lwkt_gettoken(&p->p_token);
586 if (egid != cr->cr_rgid && /* allow setegid(getgid()) */
587 egid != cr->cr_svgid && /* allow setegid(saved gid) */
588 (error = priv_check_cred(cr, PRIV_CRED_SETEGID, 0))) {
591 if (cr->cr_groups[0] != egid) {
593 cr->cr_groups[0] = egid;
598 lwkt_reltoken(&p->p_token);
603 sys_setgroups(struct setgroups_args *uap)
605 struct proc *p = curproc;
610 lwkt_gettoken(&p->p_token);
613 if ((error = priv_check_cred(cr, PRIV_CRED_SETGROUPS, 0)))
615 ngrp = uap->gidsetsize;
616 if (ngrp > NGROUPS) {
621 * XXX A little bit lazy here. We could test if anything has
622 * changed before cratom() and setting P_SUGID.
627 * setgroups(0, NULL) is a legitimate way of clearing the
628 * groups vector on non-BSD systems (which generally do not
629 * have the egid in the groups[0]). We risk security holes
630 * when running non-BSD software if we do not do the same.
634 error = copyin(uap->gidset, cr->cr_groups,
635 ngrp * sizeof(gid_t));
638 cr->cr_ngroups = ngrp;
643 lwkt_reltoken(&p->p_token);
648 sys_setreuid(struct setreuid_args *uap)
650 struct proc *p = curproc;
655 lwkt_gettoken(&p->p_token);
660 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid &&
661 ruid != cr->cr_svuid) ||
662 (euid != (uid_t)-1 && euid != cr->cr_uid &&
663 euid != cr->cr_ruid && euid != cr->cr_svuid)) &&
664 (error = priv_check_cred(cr, PRIV_CRED_SETREUID, 0)) != 0) {
668 if (euid != (uid_t)-1 && cr->cr_uid != euid) {
669 cr = change_euid(euid);
672 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
673 cr = change_ruid(ruid);
676 if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) &&
677 cr->cr_svuid != cr->cr_uid) {
679 cr->cr_svuid = cr->cr_uid;
684 lwkt_reltoken(&p->p_token);
689 sys_setregid(struct setregid_args *uap)
691 struct proc *p = curproc;
696 lwkt_gettoken(&p->p_token);
701 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid &&
702 rgid != cr->cr_svgid) ||
703 (egid != (gid_t)-1 && egid != cr->cr_groups[0] &&
704 egid != cr->cr_rgid && egid != cr->cr_svgid)) &&
705 (error = priv_check_cred(cr, PRIV_CRED_SETREGID, 0)) != 0) {
709 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
711 cr->cr_groups[0] = egid;
714 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
719 if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) &&
720 cr->cr_svgid != cr->cr_groups[0]) {
722 cr->cr_svgid = cr->cr_groups[0];
727 lwkt_reltoken(&p->p_token);
732 * setresuid(ruid, euid, suid) is like setreuid except control over the
733 * saved uid is explicit.
736 sys_setresuid(struct setresuid_args *uap)
738 struct proc *p = curproc;
740 uid_t ruid, euid, suid;
743 lwkt_gettoken(&p->p_token);
749 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid &&
750 ruid != cr->cr_svuid && ruid != cr->cr_uid) ||
751 (euid != (uid_t)-1 && euid != cr->cr_ruid &&
752 euid != cr->cr_svuid && euid != cr->cr_uid) ||
753 (suid != (uid_t)-1 && suid != cr->cr_ruid &&
754 suid != cr->cr_svuid && suid != cr->cr_uid)) &&
755 (error = priv_check_cred(cr, PRIV_CRED_SETRESUID, 0)) != 0) {
758 if (euid != (uid_t)-1 && cr->cr_uid != euid) {
759 cr = change_euid(euid);
762 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
763 cr = change_ruid(ruid);
766 if (suid != (uid_t)-1 && cr->cr_svuid != suid) {
773 lwkt_reltoken(&p->p_token);
778 * setresgid(rgid, egid, sgid) is like setregid except control over the
779 * saved gid is explicit.
782 sys_setresgid(struct setresgid_args *uap)
784 struct proc *p = curproc;
786 gid_t rgid, egid, sgid;
789 lwkt_gettoken(&p->p_token);
794 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid &&
795 rgid != cr->cr_svgid && rgid != cr->cr_groups[0]) ||
796 (egid != (gid_t)-1 && egid != cr->cr_rgid &&
797 egid != cr->cr_svgid && egid != cr->cr_groups[0]) ||
798 (sgid != (gid_t)-1 && sgid != cr->cr_rgid &&
799 sgid != cr->cr_svgid && sgid != cr->cr_groups[0])) &&
800 (error = priv_check_cred(cr, PRIV_CRED_SETRESGID, 0)) != 0) {
804 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
806 cr->cr_groups[0] = egid;
809 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
814 if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) {
821 lwkt_reltoken(&p->p_token);
826 sys_getresuid(struct getresuid_args *uap)
829 int error1 = 0, error2 = 0, error3 = 0;
832 * copyout's can fault synchronously so we cannot use a shared
835 cr = curthread->td_ucred;
837 error1 = copyout((caddr_t)&cr->cr_ruid,
838 (caddr_t)uap->ruid, sizeof(cr->cr_ruid));
840 error2 = copyout((caddr_t)&cr->cr_uid,
841 (caddr_t)uap->euid, sizeof(cr->cr_uid));
843 error3 = copyout((caddr_t)&cr->cr_svuid,
844 (caddr_t)uap->suid, sizeof(cr->cr_svuid));
845 return error1 ? error1 : (error2 ? error2 : error3);
849 sys_getresgid(struct getresgid_args *uap)
852 int error1 = 0, error2 = 0, error3 = 0;
854 cr = curthread->td_ucred;
856 error1 = copyout(&cr->cr_rgid, uap->rgid,
857 sizeof(cr->cr_rgid));
859 error2 = copyout(&cr->cr_groups[0], uap->egid,
860 sizeof(cr->cr_groups[0]));
862 error3 = copyout(&cr->cr_svgid, uap->sgid,
863 sizeof(cr->cr_svgid));
864 return error1 ? error1 : (error2 ? error2 : error3);
869 * NOTE: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
870 * we use P_SUGID because we consider changing the owners as
871 * "tainting" as well.
872 * This is significant for procs that start as root and "become"
873 * a user without an exec - programs cannot know *everything*
874 * that libc *might* have put in their data segment.
877 sys_issetugid(struct issetugid_args *uap)
879 uap->sysmsg_result = (curproc->p_flags & P_SUGID) ? 1 : 0;
884 * Check if gid is a member of the group set.
887 groupmember(gid_t gid, struct ucred *cred)
892 egp = &(cred->cr_groups[cred->cr_ngroups]);
893 for (gp = cred->cr_groups; gp < egp; gp++) {
901 * Test whether the specified credentials have the privilege
904 * A kernel thread without a process context is assumed to have
905 * the privilege in question. In situations where the caller always
906 * expect a cred to exist, the cred should be passed separately and
907 * priv_check_cred() should be used instead of priv_check().
909 * Returns 0 or error.
912 priv_check(struct thread *td, int priv)
914 if (td->td_lwp != NULL)
915 return priv_check_cred(td->td_ucred, priv, 0);
920 * Check a credential for privilege.
922 * 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)
975 _crinit(struct ucred *cr)
981 crinit(struct ucred *cr)
983 bzero(cr, sizeof(*cr));
988 * Allocate a zeroed cred structure.
995 cr = kmalloc(sizeof(*cr), M_CRED, M_WAITOK|M_ZERO);
1001 * Claim another reference to a ucred structure. Can be used with special
1004 * It must be possible to call this routine with spinlocks held, meaning
1005 * that this routine itself cannot obtain a spinlock.
1008 crhold(struct ucred *cr)
1010 if (cr != NOCRED && cr != FSCRED)
1011 atomic_add_long(&cr->cr_ref, 1);
1016 * Drop a reference from the cred structure, free it if the reference count
1019 * NOTE: because we used atomic_add_int() above, without a spinlock, we
1020 * must also use atomic_subtract_int() below. A spinlock is required
1021 * in crfree() to handle multiple callers racing the refcount to 0.
1024 crfree(struct ucred *cr)
1026 if (cr->cr_ref <= 0)
1027 panic("Freeing already free credential! %p", cr);
1028 if (atomic_fetchadd_long(&cr->cr_ref, -1) == 1) {
1030 * Some callers of crget(), such as nfs_statfs(),
1031 * allocate a temporary credential, but don't
1032 * allocate a uidinfo structure.
1034 if (cr->cr_uidinfo != NULL) {
1035 uidrop(cr->cr_uidinfo);
1036 cr->cr_uidinfo = NULL;
1038 if (cr->cr_ruidinfo != NULL) {
1039 uidrop(cr->cr_ruidinfo);
1040 cr->cr_ruidinfo = NULL;
1044 * Destroy empty prisons
1047 prison_free(cr->cr_prison);
1048 cr->cr_prison = NULL; /* safety */
1050 kfree((caddr_t)cr, M_CRED);
1055 * Atomize a cred structure so it can be modified without polluting
1056 * other references to it.
1058 * MPSAFE (however, *pcr must be stable)
1061 cratom(struct ucred **pcr)
1063 struct ucred *oldcr;
1064 struct ucred *newcr;
1067 if (oldcr->cr_ref == 1)
1069 newcr = crget(); /* this might block */
1070 oldcr = *pcr; /* re-cache after potentially blocking */
1072 uihold(newcr->cr_uidinfo);
1073 uihold(newcr->cr_ruidinfo);
1075 prison_hold(newcr->cr_prison);
1084 * Called with a modifying token held, but must still obtain p_spin to
1085 * actually replace p_ucred to handle races against syscall entry from
1086 * other threads which cache p_ucred->td_ucred.
1088 * (the threads will only get the spin-lock, and they only need to in
1089 * the case where td_ucred != p_ucred so this is optimal).
1092 cratom_proc(struct proc *p)
1094 struct ucred *oldcr;
1095 struct ucred *newcr;
1098 if (oldcr->cr_ref == 1)
1101 newcr = crget(); /* this might block */
1102 oldcr = p->p_ucred; /* so re-cache oldcr (do not re-test) */
1104 uihold(newcr->cr_uidinfo);
1105 uihold(newcr->cr_ruidinfo);
1107 prison_hold(newcr->cr_prison);
1110 spin_lock(&p->p_spin);
1112 spin_unlock(&p->p_spin);
1119 * Dup cred struct to a new held one.
1122 crdup(struct ucred *cr)
1124 struct ucred *newcr;
1128 uihold(newcr->cr_uidinfo);
1129 uihold(newcr->cr_ruidinfo);
1131 prison_hold(newcr->cr_prison);
1137 * Fill in a struct xucred based on a struct ucred.
1140 cru2x(struct ucred *cr, struct xucred *xcr)
1143 bzero(xcr, sizeof(*xcr));
1144 xcr->cr_version = XUCRED_VERSION;
1145 xcr->cr_uid = cr->cr_uid;
1146 xcr->cr_ngroups = cr->cr_ngroups;
1147 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1151 * Get login name, if available.
1154 sys_getlogin(struct getlogin_args *uap)
1156 struct proc *p = curproc;
1157 char buf[MAXLOGNAME];
1160 if (uap->namelen > MAXLOGNAME) /* namelen is unsigned */
1161 uap->namelen = MAXLOGNAME;
1162 bzero(buf, sizeof(buf));
1163 lwkt_gettoken_shared(&p->p_token);
1164 bcopy(p->p_pgrp->pg_session->s_login, buf, uap->namelen);
1165 lwkt_reltoken(&p->p_token);
1167 error = copyout(buf, uap->namebuf, uap->namelen);
1175 sys_setlogin(struct setlogin_args *uap)
1177 struct thread *td = curthread;
1180 char buf[MAXLOGNAME];
1183 cred = td->td_ucred;
1186 if ((error = priv_check_cred(cred, PRIV_PROC_SETLOGIN, 0)))
1188 bzero(buf, sizeof(buf));
1189 error = copyinstr(uap->namebuf, buf, sizeof(buf), NULL);
1190 if (error == ENAMETOOLONG)
1193 lwkt_gettoken_shared(&p->p_token);
1194 memcpy(p->p_pgrp->pg_session->s_login, buf, sizeof(buf));
1195 lwkt_reltoken(&p->p_token);
1203 struct proc *p = curproc;
1205 KKASSERT(p != NULL);
1206 lwkt_gettoken(&p->p_token);
1207 p->p_flags |= P_SUGID;
1208 if (!(p->p_pfsflags & PF_ISUGID))
1210 lwkt_reltoken(&p->p_token);
1214 * Helper function to change the effective uid of a process
1217 change_euid(uid_t euid)
1219 struct proc *p = curproc;
1222 KKASSERT(p != NULL);
1223 lf_count_adjust(p, 0);
1224 cr = cratom_proc(p);
1226 uireplace(&cr->cr_uidinfo, uifind(euid));
1227 lf_count_adjust(p, 1);
1232 * Helper function to change the real uid of a process
1234 * The per-uid process count for this process is transfered from
1235 * the old uid to the new uid.
1238 change_ruid(uid_t ruid)
1240 struct proc *p = curproc;
1243 KKASSERT(p != NULL);
1245 cr = cratom_proc(p);
1246 chgproccnt(cr->cr_ruidinfo, -1, 0);
1248 uireplace(&cr->cr_ruidinfo, uifind(ruid));
1249 chgproccnt(cr->cr_ruidinfo, 1, 0);