From owner-freebsd-audit Sat May 12 20:42:52 2001 Delivered-To: freebsd-audit@freebsd.org Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by hub.freebsd.org (Postfix) with ESMTP id A362B37B423 for ; Sat, 12 May 2001 20:41:55 -0700 (PDT) (envelope-from robert@fledge.watson.org) Received: from fledge.watson.org (robert@fledge.pr.watson.org [192.0.2.3]) by fledge.watson.org (8.11.3/8.11.3) with SMTP id f4D3fpf49857 for ; Sat, 12 May 2001 23:41:51 -0400 (EDT) (envelope-from robert@fledge.watson.org) Date: Sat, 12 May 2001 23:41:51 -0400 (EDT) From: Robert Watson X-Sender: robert@fledge.watson.org To: audit@FreeBSD.org Subject: RE: Patch to eliminate struct pcred (fwd) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Attached, please find revision 4 of the pcred merge into ucred patch. Differences from pcred.3.diff are: - add alpha/osf1 support to pcred patch, missed in previous iterations - fix bug in newcred/oldcred handling introduced in kern_exec in pcred.3.diff Otherwise the changes remain the same. I notice that one of the comments I added about the saved uid behavior is consistent with the concerns expressed by Ruslan, and I think we should revisit these after I finish the pcred merge. For now, I'm attempting to maintain consistent behavior with the pre-pcred-merge, but we should discuss this in detail and figure out whether current behavior is "right", and document it properly if so, and fix it if not. Robert N M Watson FreeBSD Core Team, TrustedBSD Project robert@fledge.watson.org NAI Labs, Safeport Network Services ? compile/GENERIC ? compile/LINT ? i386/conf/LINT Index: alpha/osf1/osf1_misc.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/osf1/osf1_misc.c,v retrieving revision 1.13 diff -u -r1.13 osf1_misc.c --- alpha/osf1/osf1_misc.c 2001/05/01 08:11:49 1.13 +++ alpha/osf1/osf1_misc.c 2001/05/13 03:23:41 @@ -1054,29 +1054,32 @@ { int error; uid_t uid; - register struct pcred *pc; + struct ucred *oldcred, *newcred; uid = SCARG(uap, uid); - pc = p->p_cred; + oldcred = p->p_ucred; if ((error = suser(p)) != 0 && - uid != pc->p_ruid && uid != pc->p_svuid) + uid != oldcred->cr_ruid && uid != oldcred->cr_svuid) return (error); + newcred = crdup(oldcred); if (error == 0) { - if (uid != pc->p_ruid) { - change_ruid(p, uid); + if (uid != oldcred->cr_ruid) { + change_ruid(newcred, uid); setsugid(p); } - if (pc->p_svuid != uid) { - pc->p_svuid = uid; + if (oldcred->cr_svuid != uid) { + change_svuid(newcred, uid); setsugid(p); } } - if (pc->pc_ucred->cr_uid != uid) { - change_euid(p, uid); + if (newcred->cr_uid != uid) { + change_euid(newcred, uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -1095,22 +1098,32 @@ { int error; gid_t gid; - register struct pcred *pc; + struct ucred *oldcred, *newcred; gid = SCARG(uap, gid); - pc = p->p_cred; + oldcred = p->p_ucred; if (((error = suser(p)) != 0 ) && - gid != pc->p_rgid && gid != pc->p_svgid) + gid != oldcred->cr_rgid && gid != oldcred->cr_svgid) return (error); - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_gid = gid; + newcred = crdup(oldcred); if (error == 0) { - pc->p_rgid = gid; - pc->p_svgid = gid; + if (gid != oldcred->cr_rgid) { + change_rgid(newcred, gid); + setsugid(p); + } + if (oldcred->cr_svgid != gid) { + change_svgid(newcred, gid); + setsugid(p); + } + } + if (newcred->cr_groups[0] != gid) { + change_egid(newcred, gid); + setsugid(p); } - setsugid(p); + p->p_ucred = newcred; + crfree(oldcred); return (0); } Index: compat/linprocfs/linprocfs_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_misc.c,v retrieving revision 1.24 diff -u -r1.24 linprocfs_misc.c --- compat/linprocfs/linprocfs_misc.c 2001/05/01 08:11:51 1.24 +++ compat/linprocfs/linprocfs_misc.c 2001/05/13 03:23:46 @@ -444,14 +444,14 @@ PROC_LOCK(p); sbuf_printf(&sb, "PPid:\t%d\n", p->p_pptr ? p->p_pptr->p_pid : 0); - sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_cred->p_ruid, + sbuf_printf(&sb, "Uid:\t%d %d %d %d\n", p->p_ucred->cr_ruid, p->p_ucred->cr_uid, - p->p_cred->p_svuid, + p->p_ucred->cr_svuid, /* FreeBSD doesn't have fsuid */ p->p_ucred->cr_uid); - sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_cred->p_rgid, + sbuf_printf(&sb, "Gid:\t%d %d %d %d\n", p->p_ucred->cr_rgid, p->p_ucred->cr_gid, - p->p_cred->p_svgid, + p->p_ucred->cr_svgid, /* FreeBSD doesn't have fsgid */ p->p_ucred->cr_gid); sbuf_cat(&sb, "Groups:\t"); @@ -543,7 +543,7 @@ char *freepath = NULL; p = PFIND(pfs->pfs_pid); - if (p == NULL || p->p_cred == NULL || p->p_ucred == NULL) { + if (p == NULL || p->p_ucred == NULL) { if (p != NULL) PROC_UNLOCK(p); printf("doexelink: pid %d disappeared\n", pfs->pfs_pid); Index: compat/linprocfs/linprocfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_vnops.c,v retrieving revision 1.23 diff -u -r1.23 linprocfs_vnops.c --- compat/linprocfs/linprocfs_vnops.c 2001/05/04 05:19:22 1.23 +++ compat/linprocfs/linprocfs_vnops.c 2001/05/13 03:23:46 @@ -432,7 +432,7 @@ procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { + if (procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } Index: compat/linux/linux_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.101 diff -u -r1.101 linux_misc.c --- compat/linux/linux_misc.c 2001/05/01 08:11:51 1.101 +++ compat/linux/linux_misc.c 2001/05/13 03:23:47 @@ -958,12 +958,11 @@ struct proc *p; struct linux_setgroups_args *uap; { - struct pcred *pc; + struct ucred *newcred, *oldcred = p->p_ucred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int ngrp, error; - pc = p->p_cred; ngrp = uap->gidsetsize; /* @@ -972,22 +971,22 @@ * Keep cr_groups[0] unchanged to prevent that. */ - if ((error = suser_xxx(NULL, p, PRISON_ROOT)) != 0) + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); if (ngrp >= NGROUPS) return (EINVAL); - pc->pc_ucred = crcopy(pc->pc_ucred); + newcred = crdup(oldcred); if (ngrp > 0) { error = copyin((caddr_t)uap->gidset, (caddr_t)linux_gidset, ngrp * sizeof(linux_gid_t)); if (error) return (error); - pc->pc_ucred->cr_ngroups = ngrp + 1; + newcred->cr_ngroups = ngrp + 1; - bsd_gidset = pc->pc_ucred->cr_groups; + bsd_gidset = newcred->cr_groups; ngrp--; while (ngrp >= 0) { bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; @@ -995,9 +994,13 @@ } } else - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; setsugid(p); + + p->p_ucred = newcred; + crfree(oldcred); + return (0); } @@ -1006,14 +1009,14 @@ struct proc *p; struct linux_getgroups_args *uap; { - struct pcred *pc; + struct ucred *cred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int bsd_gidsetsz, ngrp, error; - pc = p->p_cred; - bsd_gidset = pc->pc_ucred->cr_groups; - bsd_gidsetsz = pc->pc_ucred->cr_ngroups - 1; + cred = p->p_ucred; + bsd_gidset = cred->cr_groups; + bsd_gidsetsz = cred->cr_ngroups - 1; /* * cr_groups[0] holds egid. Returning the whole set Index: compat/svr4/svr4_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_misc.c,v retrieving revision 1.30 diff -u -r1.30 svr4_misc.c --- compat/svr4/svr4_misc.c 2001/05/01 08:11:52 1.30 +++ compat/svr4/svr4_misc.c 2001/05/13 03:23:48 @@ -1283,7 +1283,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(q->p_cred->p_uidinfo, -1, 0); + (void)chgproccnt(q->p_ucred->cr_ruidinfo, -1, 0); /* * Release reference to text vnode. @@ -1294,13 +1294,8 @@ /* * Free up credentials. */ - PROC_LOCK(q); - if (--q->p_cred->p_refcnt == 0) { - crfree(q->p_ucred); - uifree(q->p_cred->p_uidinfo); - FREE(q->p_cred, M_SUBPROC); - q->p_cred = NULL; - } + crfree(q->p_ucred); + q->p_ucred = NULL; /* * Remove unused arguments Index: compat/svr4/svr4_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/compat/svr4/svr4_sysvec.c,v retrieving revision 1.20 diff -u -r1.20 svr4_sysvec.c --- compat/svr4/svr4_sysvec.c 2001/02/24 22:20:02 1.20 +++ compat/svr4/svr4_sysvec.c 2001/05/13 03:23:48 @@ -213,10 +213,10 @@ AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); - AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); - AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); - AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); - AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); Index: ddb/db_ps.c =================================================================== RCS file: /home/ncvs/src/sys/ddb/db_ps.c,v retrieving revision 1.22 diff -u -r1.22 db_ps.c --- ddb/db_ps.c 2001/03/28 09:17:49 1.22 +++ ddb/db_ps.c 2001/05/13 03:23:50 @@ -95,7 +95,7 @@ db_printf("%5d %8p %8p %4d %5d %5d %06x %d", p->p_pid, (volatile void *)p, (void *)p->p_addr, - p->p_cred ? p->p_cred->p_ruid : 0, pp->p_pid, + p->p_ucred ? p->p_ucred->cr_ruid : 0, pp->p_pid, p->p_pgrp ? p->p_pgrp->pg_id : 0, p->p_flag, p->p_stat); if (p->p_wchan) { db_printf(" %6s %8p", p->p_wmesg, (void *)p->p_wchan); Index: i386/linux/linux_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.78 diff -u -r1.78 linux_sysvec.c --- i386/linux/linux_sysvec.c 2001/05/01 08:12:52 1.78 +++ i386/linux/linux_sysvec.c 2001/05/13 03:24:04 @@ -186,10 +186,10 @@ AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); PROC_LOCK(imgp->proc); - AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); - AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); - AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); - AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); PROC_UNLOCK(imgp->proc); AUXARGS_ENTRY(pos, AT_NULL, 0); Index: kern/init_main.c =================================================================== RCS file: /home/ncvs/src/sys/kern/init_main.c,v retrieving revision 1.168 diff -u -r1.168 init_main.c --- kern/init_main.c 2001/04/29 02:44:48 1.168 +++ kern/init_main.c 2001/05/13 03:24:05 @@ -85,7 +85,6 @@ static struct session session0; static struct pgrp pgrp0; struct proc proc0; -static struct pcred cred0; static struct procsig procsig0; static struct filedesc0 filedesc0; static struct plimit limit0; @@ -321,12 +320,10 @@ callout_init(&p->p_slpcallout, 1); /* Create credentials. */ - cred0.p_refcnt = 1; - cred0.p_uidinfo = uifind(0); - p->p_cred = &cred0; p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ p->p_ucred->cr_uidinfo = uifind(0); + p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = NULL; /* Don't jail it. */ /* Create procsig. */ @@ -380,7 +377,7 @@ /* * Charge root for one process. */ - (void)chgproccnt(cred0.p_uidinfo, 1, 0); + (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0); } SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) Index: kern/kern_acct.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_acct.c,v retrieving revision 1.33 diff -u -r1.33 kern_acct.c --- kern/kern_acct.c 2001/05/01 08:12:55 1.33 +++ kern/kern_acct.c 2001/05/13 03:24:05 @@ -222,8 +222,8 @@ acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0); /* (6) The UID and GID of the process */ - acct.ac_uid = p->p_cred->p_ruid; - acct.ac_gid = p->p_cred->p_rgid; + acct.ac_uid = p->p_ucred->cr_ruid; + acct.ac_gid = p->p_ucred->cr_rgid; /* (7) The terminal from which the process was started */ if ((p->p_flag & P_CONTROLT) && p->p_pgrp->pg_session->s_ttyp) Index: kern/kern_descrip.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.100 diff -u -r1.100 kern_descrip.c --- kern/kern_descrip.c 2001/05/01 08:12:55 1.100 +++ kern/kern_descrip.c 2001/05/13 03:24:06 @@ -525,8 +525,6 @@ sigio->sio_pgid = pgid; crhold(curproc->p_ucred); sigio->sio_ucred = curproc->p_ucred; - /* It would be convenient if p_ruid was in ucred. */ - sigio->sio_ruid = curproc->p_cred->p_ruid; sigio->sio_myref = sigiop; s = splhigh(); *sigiop = sigio; Index: kern/kern_exec.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v retrieving revision 1.126 diff -u -r1.126 kern_exec.c --- kern/kern_exec.c 2001/05/01 08:12:56 1.126 +++ kern/kern_exec.c 2001/05/13 03:24:06 @@ -104,6 +104,7 @@ register struct execve_args *uap; { struct nameidata nd, *ndp; + struct ucred *oldcred = p->p_ucred, *newcred; register_t *stack_base; int error, len, i; struct image_params image_params, *imgp; @@ -274,13 +275,23 @@ } /* + * XXX: Note, the whole execve() is incredibly racey right now + * with regards to debugging and privilege/credential management. + * In particular, it's possible to race during exec() to attach + * debugging to a process that will gain privilege. + * + * This MUST be fixed prior to any release. + */ + + /* * Implement image setuid/setgid. * * Don't honor setuid/setgid if the filesystem prohibits it or if * the process is being traced. */ - if ((((attr.va_mode & VSUID) && p->p_ucred->cr_uid != attr.va_uid) || - ((attr.va_mode & VSGID) && p->p_ucred->cr_gid != attr.va_gid)) && + newcred = NULL; + if ((((attr.va_mode & VSUID) && oldcred->cr_uid != attr.va_uid) || + ((attr.va_mode & VSGID) && oldcred->cr_gid != attr.va_gid)) && (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && (p->p_flag & P_TRACED) == 0) { PROC_UNLOCK(p); @@ -288,7 +299,7 @@ * Turn off syscall tracing for set-id programs, except for * root. */ - if (p->p_tracep && suser(p)) { + if (p->p_tracep && suser_xxx(oldcred, NULL, PRISON_ROOT)) { p->p_traceflag = 0; vrele(p->p_tracep); p->p_tracep = NULL; @@ -296,25 +307,64 @@ /* * Set the new credentials. */ - p->p_ucred = crcopy(p->p_ucred); + newcred = crdup(oldcred); if (attr.va_mode & VSUID) - change_euid(p, attr.va_uid); + change_euid(newcred, attr.va_uid); if (attr.va_mode & VSGID) - p->p_ucred->cr_gid = attr.va_gid; + change_egid(newcred, attr.va_gid); setsugid(p); setugidsafety(p); } else { - if (p->p_ucred->cr_uid == p->p_cred->p_ruid && - p->p_ucred->cr_gid == p->p_cred->p_rgid) + if (oldcred->cr_uid == oldcred->cr_ruid && + oldcred->cr_gid == oldcred->cr_rgid) p->p_flag &= ~P_SUGID; PROC_UNLOCK(p); } /* * Implement correct POSIX saved-id behavior. - */ - p->p_cred->p_svuid = p->p_ucred->cr_uid; - p->p_cred->p_svgid = p->p_ucred->cr_gid; + * + * XXX: It's not clear that the existing behavior is + * POSIX-compliant. A number of courses indicate that the saved + * uid/gid should only be updated if the new ruid is not equal to + * the old ruid, or the new euid is not equal to the old euid and + * the new euid is not equal to the old ruid. The FreeBSD code + * always updates the saved uid/gid. Also, this code uses the new + * (replaced) euid and egid as the source, which may or may not be + * the right ones to use. + */ + if (newcred != NULL) { + change_svuid(newcred, newcred->cr_uid); + change_svgid(newcred, newcred->cr_gid); + } else { + /* + * Avoid allocated a newcred if we don't have one yet and + * update would be a noop. + */ + if (oldcred->cr_svuid != oldcred->cr_uid || + oldcred->cr_svgid != oldcred->cr_gid) { + newcred = crdup(oldcred); + change_svuid(newcred, newcred->cr_uid); + change_svgid(newcred, newcred->cr_gid); + } + + } + + if (newcred != NULL) { + /* + * If the credential was updated, replace it with the + * new credential. + * + * XXX: should setsugid() be called here? + */ + struct ucred *oldcred; + + oldcred = p->p_ucred; + PROC_LOCK(p); + p->p_ucred = newcred; + PROC_UNLOCK(p); + crfree(oldcred); + } /* * Store the vp for use in procfs Index: kern/kern_exit.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v retrieving revision 1.126 diff -u -r1.126 kern_exit.c --- kern/kern_exit.c 2001/05/04 16:13:28 1.126 +++ kern/kern_exit.c 2001/05/13 03:24:07 @@ -514,7 +514,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(p->p_cred->p_uidinfo, -1, 0); + (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); /* * Release reference to text vnode @@ -539,12 +539,8 @@ /* * Free up credentials. */ - if (--p->p_cred->p_refcnt == 0) { - crfree(p->p_ucred); - uifree(p->p_cred->p_uidinfo); - FREE(p->p_cred, M_SUBPROC); - p->p_cred = NULL; - } + crfree(p->p_ucred); + p->p_ucred = NULL; /* * Remove unused arguments Index: kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.111 diff -u -r1.111 kern_fork.c --- kern/kern_fork.c 2001/05/07 18:07:29 1.111 +++ kern/kern_fork.c 2001/05/13 03:24:07 @@ -257,7 +257,7 @@ * exceed the limit. The variable nprocs is the current number of * processes, maxproc is the limit. */ - uid = p1->p_cred->p_ruid; + uid = p1->p_ucred->cr_ruid; if ((nprocs >= maxproc - 1 && uid != 0) || nprocs >= maxproc) { tablefull("proc"); return (EAGAIN); @@ -272,7 +272,7 @@ * Increment the count of procs running with this uid. Don't allow * a nonprivileged user to exceed their current limit. */ - ok = chgproccnt(p1->p_cred->p_uidinfo, 1, + ok = chgproccnt(p1->p_ucred->cr_ruidinfo, 1, (uid != 0) ? p1->p_rlimit[RLIMIT_NPROC].rlim_cur : 0); if (!ok) { /* @@ -408,15 +408,9 @@ * We start off holding one spinlock after fork: sched_lock. */ p2->p_spinlocks = 1; - PROC_UNLOCK(p2); - MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred), - M_SUBPROC, M_WAITOK); - PROC_LOCK(p2); PROC_LOCK(p1); - bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred)); - p2->p_cred->p_refcnt = 1; crhold(p1->p_ucred); - uihold(p1->p_cred->p_uidinfo); + p2->p_ucred = p1->p_ucred; if (p2->p_args) p2->p_args->ar_ref++; Index: kern/kern_ktrace.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v retrieving revision 1.52 diff -u -r1.52 kern_ktrace.c --- kern/kern_ktrace.c 2001/05/01 08:12:56 1.52 +++ kern/kern_ktrace.c 2001/05/13 03:24:08 @@ -531,17 +531,17 @@ ktrcanset(callp, targetp) struct proc *callp, *targetp; { - register struct pcred *caller = callp->p_cred; - register struct pcred *target = targetp->p_cred; + struct ucred *callcr = callp->p_ucred; + struct ucred *targetcr = targetp->p_ucred; - if (prison_check(callp->p_ucred, targetp->p_ucred)) + if (prison_check(callcr, targetcr)) return (0); - if ((caller->pc_ucred->cr_uid == target->p_ruid && - target->p_ruid == target->p_svuid && - caller->p_rgid == target->p_rgid && /* XXX */ - target->p_rgid == target->p_svgid && + if ((callcr->cr_uid == targetcr->cr_ruid && + targetcr->cr_ruid == targetcr->cr_svuid && + callcr->cr_rgid == targetcr->cr_rgid && /* XXX */ + targetcr->cr_rgid == targetcr->cr_svgid && (targetp->p_traceflag & KTRFAC_ROOT) == 0) || - caller->pc_ucred->cr_uid == 0) + !suser_xxx(callcr, NULL, PRISON_ROOT)) return (1); return (0); Index: kern/kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.93 diff -u -r1.93 kern_proc.c --- kern/kern_proc.c 2001/05/01 08:12:57 1.93 +++ kern/kern_proc.c 2001/05/13 03:24:08 @@ -424,15 +424,15 @@ kp->ki_textvp = p->p_textvp; kp->ki_fd = p->p_fd; kp->ki_vmspace = p->p_vmspace; - if (p->p_cred) { - kp->ki_uid = p->p_cred->pc_ucred->cr_uid; - kp->ki_ruid = p->p_cred->p_ruid; - kp->ki_svuid = p->p_cred->p_svuid; - kp->ki_ngroups = p->p_cred->pc_ucred->cr_ngroups; - bcopy(p->p_cred->pc_ucred->cr_groups, kp->ki_groups, + if (p->p_ucred) { + kp->ki_uid = p->p_ucred->cr_uid; + kp->ki_ruid = p->p_ucred->cr_ruid; + kp->ki_svuid = p->p_ucred->cr_svuid; + kp->ki_ngroups = p->p_ucred->cr_ngroups; + bcopy(p->p_ucred->cr_groups, kp->ki_groups, NGROUPS * sizeof(gid_t)); - kp->ki_rgid = p->p_cred->p_rgid; - kp->ki_svgid = p->p_cred->p_svgid; + kp->ki_rgid = p->p_ucred->cr_rgid; + kp->ki_svgid = p->p_ucred->cr_svgid; } if (p->p_procsig) { kp->ki_sigignore = p->p_procsig->ps_sigignore; @@ -653,7 +653,7 @@ case KERN_PROC_RUID: if (p->p_ucred == NULL || - p->p_cred->p_ruid != (uid_t)name[0]) + p->p_ucred->cr_ruid != (uid_t)name[0]) continue; break; } Index: kern/kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.89 diff -u -r1.89 kern_prot.c --- kern/kern_prot.c 2001/05/01 08:12:57 1.89 +++ kern/kern_prot.c 2001/05/13 03:24:09 @@ -210,7 +210,7 @@ struct getuid_args *uap; { - p->p_retval[0] = p->p_cred->p_ruid; + p->p_retval[0] = p->p_ucred->cr_ruid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_retval[1] = p->p_ucred->cr_uid; #endif @@ -253,7 +253,7 @@ struct getgid_args *uap; { - p->p_retval[0] = p->p_cred->p_rgid; + p->p_retval[0] = p->p_ucred->cr_rgid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_retval[1] = p->p_ucred->cr_groups[0]; #endif @@ -293,18 +293,18 @@ struct proc *p; register struct getgroups_args *uap; { - register struct pcred *pc = p->p_cred; - register u_int ngrp; + struct ucred *cred = p->p_ucred; + u_int ngrp; int error; if ((ngrp = uap->gidsetsize) == 0) { - p->p_retval[0] = pc->pc_ucred->cr_ngroups; + p->p_retval[0] = cred->cr_ngroups; return (0); } - if (ngrp < pc->pc_ucred->cr_ngroups) + if (ngrp < cred->cr_ngroups) return (EINVAL); - ngrp = pc->pc_ucred->cr_ngroups; - if ((error = copyout((caddr_t)pc->pc_ucred->cr_groups, + ngrp = cred->cr_ngroups; + if ((error = copyout((caddr_t)cred->cr_groups, (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) return (error); p->p_retval[0] = ngrp; @@ -427,7 +427,7 @@ struct proc *p; struct setuid_args *uap; { - register struct pcred *pc = p->p_cred; + struct ucred *oldcred = p->p_ucred, *newcred; register uid_t uid; int error; @@ -449,16 +449,17 @@ * 3: Change euid last. (after tests in #2 for "appropriate privs") */ uid = uap->uid; - if (uid != pc->p_ruid && /* allow setuid(getuid()) */ + if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ #ifdef _POSIX_SAVED_IDS - uid != pc->p_svuid && /* allow setuid(saved gid) */ + uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ #endif #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ - uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */ + uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ #endif - (error = suser_xxx(0, p, PRISON_ROOT))) + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + newcred = crdup(oldcred); #ifdef _POSIX_SAVED_IDS /* * Do we have "appropriate privileges" (are we root or uid == euid) @@ -466,16 +467,16 @@ */ if ( #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ - uid == pc->pc_ucred->cr_uid || + uid == oldcred->cr_uid || #endif - suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ + suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ #endif { /* * Set the real uid and transfer proc count to new user. */ - if (uid != pc->p_ruid) { - change_ruid(p, uid); + if (uid != oldcred->cr_ruid) { + change_ruid(newcred, uid); setsugid(p); } /* @@ -485,8 +486,8 @@ * the security of seteuid() depends on it. B.4.2.2 says it * is important that we should do this. */ - if (pc->p_svuid != uid) { - pc->p_svuid = uid; + if (uid != oldcred->cr_svuid) { + change_svuid(newcred, uid); setsugid(p); } } @@ -495,10 +496,12 @@ * In all permitted cases, we are changing the euid. * Copy credentials so other references do not see our changes. */ - if (pc->pc_ucred->cr_uid != uid) { - change_euid(p, uid); + if (uid != oldcred->cr_uid) { + change_euid(newcred, uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -513,23 +516,31 @@ struct proc *p; struct seteuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t euid; + struct ucred *oldcred = p->p_ucred, *newcred; + uid_t euid; int error; euid = uap->euid; - if (euid != pc->p_ruid && /* allow seteuid(getuid()) */ - euid != pc->p_svuid && /* allow seteuid(saved uid) */ - (error = suser_xxx(0, p, PRISON_ROOT))) + /* + * The new effective uid must equal the current real or saved + * uid. Appropriate privilege may override this restriction. + */ + if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ + euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + /* * Everything's okay, do it. Copy credentials so other references do * not see our changes. */ - if (pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + newcred = crdup(oldcred); + if (oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -544,7 +555,7 @@ struct proc *p; struct setgid_args *uap; { - register struct pcred *pc = p->p_cred; + struct ucred *oldcred = p->p_ucred, *newcred; register gid_t gid; int error; @@ -560,16 +571,17 @@ * For notes on the logic here, see setuid() above. */ gid = uap->gid; - if (gid != pc->p_rgid && /* allow setgid(getgid()) */ + if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ #ifdef _POSIX_SAVED_IDS - gid != pc->p_svgid && /* allow setgid(saved gid) */ + gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ #endif #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ - gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */ + gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ #endif - (error = suser_xxx(0, p, PRISON_ROOT))) + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); + newcred = crdup(oldcred); #ifdef _POSIX_SAVED_IDS /* * Do we have "appropriate privileges" (are we root or gid == egid) @@ -577,16 +589,16 @@ */ if ( #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ - gid == pc->pc_ucred->cr_groups[0] || + gid == oldcred->cr_groups[0] || #endif - suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */ + suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ #endif { /* * Set real gid */ - if (pc->p_rgid != gid) { - pc->p_rgid = gid; + if (oldcred->cr_rgid != gid) { + change_rgid(newcred, gid); setsugid(p); } /* @@ -596,8 +608,8 @@ * the security of setegid() depends on it. B.4.2.2 says it * is important that we should do this. */ - if (pc->p_svgid != gid) { - pc->p_svgid = gid; + if (oldcred->cr_svgid != gid) { + change_svgid(newcred, gid); setsugid(p); } } @@ -605,11 +617,12 @@ * In all cases permitted cases, we are changing the egid. * Copy credentials so other references do not see our changes. */ - if (pc->pc_ucred->cr_groups[0] != gid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = gid; + if (oldcred->cr_groups[0] != gid) { + change_egid(newcred, gid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -624,20 +637,27 @@ struct proc *p; struct setegid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t egid; + struct ucred *oldcred = p->p_ucred, *newcred; + gid_t egid; int error; egid = uap->egid; - if (egid != pc->p_rgid && /* allow setegid(getgid()) */ - egid != pc->p_svgid && /* allow setegid(saved gid) */ - (error = suser_xxx(0, p, PRISON_ROOT))) + /* + * The new effective gid must be equal to either the current real or + * saved gid. Appropriate privilege may override this restriction. + */ + if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ + egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ + (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); - if (pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + + newcred = crdup(oldcred); + if (oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -653,11 +673,11 @@ struct proc *p; struct setgroups_args *uap; { - register struct pcred *pc = p->p_cred; - register u_int ngrp; + struct ucred *oldcred = p->p_ucred, *newcred; + u_int ngrp; int error; - if ((error = suser_xxx(0, p, PRISON_ROOT))) + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) return (error); ngrp = uap->gidsetsize; if (ngrp > NGROUPS) @@ -666,7 +686,7 @@ * XXX A little bit lazy here. We could test if anything has * changed before crcopy() and setting P_SUGID. */ - pc->pc_ucred = crcopy(pc->pc_ucred); + newcred = crdup(oldcred); if (ngrp < 1) { /* * setgroups(0, NULL) is a legitimate way of clearing the @@ -674,14 +694,18 @@ * have the egid in the groups[0]). We risk security holes * when running non-BSD software if we do not do the same. */ - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; } else { if ((error = copyin((caddr_t)uap->gidset, - (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t)))) + (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { + crfree(newcred); return (error); - pc->pc_ucred->cr_ngroups = ngrp; + } + newcred->cr_ngroups = ngrp; } setsugid(p); + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -697,31 +721,52 @@ register struct proc *p; struct setreuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t ruid, euid; + struct ucred *oldcred = p->p_ucred, *newcred; + uid_t ruid, euid; int error; ruid = uap->ruid; euid = uap->euid; - if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) || - (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid && - euid != pc->p_ruid && euid != pc->p_svuid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + /* + * If an real uid update is requested, the requested real uid must + * be equal to the current real or saved uid. If an effective uid + * update is requested, the requested euid must be equal to the + * current effective uid, real uid, or saved uid. Appropriate + * privilege may override these restrictions. + */ + if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && + ruid != oldcred->cr_svuid) || + (euid != (uid_t)-1 && euid != oldcred->cr_uid && + euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + newcred = crdup(oldcred); + if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } - if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { - change_ruid(p, ruid); + if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { + change_ruid(newcred, ruid); setsugid(p); } - if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) && - pc->p_svuid != pc->pc_ucred->cr_uid) { - pc->p_svuid = pc->pc_ucred->cr_uid; + /* + * XXX: What is this intended to accomplish? In which cases should + * it be looking at the old values, and in which, the new values? + * + * Note current behavior is: + * If the ruid update is requested (even if the ruid is not changed) + * or the euid is not equal to the value of the ruid, a difference + * in the svuid and the euid will result in the svuid being + * updated to the new value of the euid. + */ + if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && + newcred->cr_svuid != newcred->cr_uid) { + change_svuid(newcred, newcred->cr_uid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -737,30 +782,49 @@ register struct proc *p; struct setregid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t rgid, egid; + struct ucred *oldcred = p->p_ucred, *newcred; + gid_t rgid, egid; int error; rgid = uap->rgid; egid = uap->egid; - if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) || - (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] && - egid != pc->p_rgid && egid != pc->p_svgid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + /* + * If a real gid update is requested, the requested real gid must + * be equal to the current real or saved gid. If an effective gid + * update is requested, the requested effective gid must be equal + * to the current effective gid, the current real gid, or the + * current saved gid. Apropriate privilege may override this + * restriction. + */ + if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && + rgid != oldcred->cr_svgid) || + (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && + egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + newcred = crdup(oldcred); + if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } - if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { - pc->p_rgid = rgid; + if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { + change_rgid(newcred, rgid); setsugid(p); } - if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) && - pc->p_svgid != pc->pc_ucred->cr_groups[0]) { - pc->p_svgid = pc->pc_ucred->cr_groups[0]; + /* + * XXX: What is this intended to accomplish? In which cases should + * it be looking at the old values, and in which, the new values? + * + * Note current behavior is: + * If the rgid update is requested (even if the rgid is not changed) + * or the egid is not equal to the value of the rgid, a difference + * in the svgid and the egid will result in the svuid being + * updated to the new value of the euid. + */ + if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && + newcred->cr_svgid != newcred->cr_groups[0]) { + change_svgid(newcred, newcred->cr_groups[0]); setsugid(p); } return (0); @@ -784,33 +848,40 @@ register struct proc *p; struct setresuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t ruid, euid, suid; + struct ucred *oldcred = p->p_ucred, *newcred; + uid_t ruid, euid, suid; int error; ruid = uap->ruid; euid = uap->euid; suid = uap->suid; - if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid && - ruid != pc->pc_ucred->cr_uid) || - (euid != (uid_t)-1 && euid != pc->p_ruid && euid != pc->p_svuid && - euid != pc->pc_ucred->cr_uid) || - (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid && - suid != pc->pc_ucred->cr_uid)) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && + ruid != oldcred->cr_svuid && + ruid != oldcred->cr_uid) || + (euid != (uid_t)-1 && euid != oldcred->cr_ruid && + euid != oldcred->cr_svuid && + euid != oldcred->cr_uid) || + (suid != (uid_t)-1 && suid != oldcred->cr_ruid && + suid != oldcred->cr_svuid && + suid != oldcred->cr_uid)) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) { - change_euid(p, euid); + + newcred = crdup(oldcred); + if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { + change_euid(newcred, euid); setsugid(p); } - if (ruid != (uid_t)-1 && pc->p_ruid != ruid) { - change_ruid(p, ruid); + if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { + change_ruid(newcred, ruid); setsugid(p); } - if (suid != (uid_t)-1 && pc->p_svuid != suid) { - pc->p_svuid = suid; + if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { + change_svuid(newcred, suid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -832,35 +903,40 @@ register struct proc *p; struct setresgid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t rgid, egid, sgid; + struct ucred *oldcred = p->p_ucred, *newcred; + gid_t rgid, egid, sgid; int error; rgid = uap->rgid; egid = uap->egid; sgid = uap->sgid; - if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid && - rgid != pc->pc_ucred->cr_groups[0]) || - (egid != (gid_t)-1 && egid != pc->p_rgid && egid != pc->p_svgid && - egid != pc->pc_ucred->cr_groups[0]) || - (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid && - sgid != pc->pc_ucred->cr_groups[0])) && - (error = suser_xxx(0, p, PRISON_ROOT)) != 0) + if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && + rgid != oldcred->cr_svgid && + rgid != oldcred->cr_groups[0]) || + (egid != (gid_t)-1 && egid != oldcred->cr_rgid && + egid != oldcred->cr_svgid && + egid != oldcred->cr_groups[0]) || + (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && + sgid != oldcred->cr_svgid && + sgid != oldcred->cr_groups[0])) && + (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) return (error); - if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) { - pc->pc_ucred = crcopy(pc->pc_ucred); - pc->pc_ucred->cr_groups[0] = egid; + newcred = crdup(oldcred); + if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { + change_egid(newcred, egid); setsugid(p); } - if (rgid != (gid_t)-1 && pc->p_rgid != rgid) { - pc->p_rgid = rgid; + if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { + change_rgid(newcred, rgid); setsugid(p); } - if (sgid != (gid_t)-1 && pc->p_svgid != sgid) { - pc->p_svgid = sgid; + if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { + change_svgid(newcred, sgid); setsugid(p); } + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -877,18 +953,18 @@ register struct proc *p; struct getresuid_args *uap; { - struct pcred *pc = p->p_cred; + struct ucred *cred = p->p_ucred; int error1 = 0, error2 = 0, error3 = 0; if (uap->ruid) - error1 = copyout((caddr_t)&pc->p_ruid, - (caddr_t)uap->ruid, sizeof(pc->p_ruid)); + error1 = copyout((caddr_t)&cred->cr_ruid, + (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); if (uap->euid) - error2 = copyout((caddr_t)&pc->pc_ucred->cr_uid, - (caddr_t)uap->euid, sizeof(pc->pc_ucred->cr_uid)); + error2 = copyout((caddr_t)&cred->cr_uid, + (caddr_t)uap->euid, sizeof(cred->cr_uid)); if (uap->suid) - error3 = copyout((caddr_t)&pc->p_svuid, - (caddr_t)uap->suid, sizeof(pc->p_svuid)); + error3 = copyout((caddr_t)&cred->cr_svuid, + (caddr_t)uap->suid, sizeof(cred->cr_svuid)); return error1 ? error1 : (error2 ? error2 : error3); } @@ -905,18 +981,18 @@ register struct proc *p; struct getresgid_args *uap; { - struct pcred *pc = p->p_cred; + struct ucred *cred = p->p_ucred; int error1 = 0, error2 = 0, error3 = 0; if (uap->rgid) - error1 = copyout((caddr_t)&pc->p_rgid, - (caddr_t)uap->rgid, sizeof(pc->p_rgid)); + error1 = copyout((caddr_t)&cred->cr_rgid, + (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); if (uap->egid) - error2 = copyout((caddr_t)&pc->pc_ucred->cr_groups[0], - (caddr_t)uap->egid, sizeof(pc->pc_ucred->cr_groups[0])); + error2 = copyout((caddr_t)&cred->cr_groups[0], + (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); if (uap->sgid) - error3 = copyout((caddr_t)&pc->p_svgid, - (caddr_t)uap->sgid, sizeof(pc->p_svgid)); + error3 = copyout((caddr_t)&cred->cr_svgid, + (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); return error1 ? error1 : (error2 ? error2 : error3); } @@ -972,7 +1048,7 @@ int groupmember(gid, cred) gid_t gid; - register struct ucred *cred; + struct ucred *cred; { register gid_t *gp; gid_t *egp; @@ -1113,10 +1189,10 @@ * Generally, the object credential's ruid or svuid must match the * subject credential's ruid or euid. */ - if (p1->p_cred->p_ruid != p2->p_cred->p_ruid && - p1->p_cred->p_ruid != p2->p_cred->p_svuid && - p1->p_ucred->cr_uid != p2->p_cred->p_ruid && - p1->p_ucred->cr_uid != p2->p_cred->p_svuid) { + if (p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid && + p1->p_ucred->cr_ruid != p2->p_ucred->cr_svuid && + p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid && + p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid) { /* Not permitted, try privilege. */ error = suser_xxx(NULL, p1, PRISON_ROOT); if (error) @@ -1140,9 +1216,9 @@ if ((error = prison_check(p1->p_ucred, p2->p_ucred))) return (error); - if (p1->p_cred->p_ruid == p2->p_cred->p_ruid) + if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) return (0); - if (p1->p_ucred->cr_uid == p2->p_cred->p_ruid) + if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) return (0); if (!suser_xxx(0, p1, PRISON_ROOT)) { @@ -1178,9 +1254,9 @@ /* not owned by you, has done setuid (unless you're root) */ /* add a CAP_SYS_PTRACE here? */ - if (p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || - p1->p_cred->p_ruid != p2->p_cred->p_ruid || - p1->p_cred->p_svuid != p2->p_cred->p_ruid || + if (p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid || + p1->p_ucred->cr_ruid != p2->p_ucred->cr_ruid || + p1->p_ucred->cr_svuid != p2->p_ucred->cr_ruid || p2->p_flag & P_SUGID) { if ((error = suser_xxx(0, p1, PRISON_ROOT))) return (error); @@ -1308,6 +1384,7 @@ *newcr = *cr; mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF); uihold(newcr->cr_uidinfo); + uihold(newcr->cr_ruidinfo); if (jailed(newcr)) prison_hold(newcr->cr_prison); newcr->cr_ref = 1; @@ -1375,48 +1452,123 @@ } /* - * Helper function to change the effective uid of a process + * change_euid(): Change a process's effective uid. + * Arguments: struct ucred *newcred, uid_t euid + * Returns: none + * Locks: none + * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none */ void -change_euid(p, euid) - struct proc *p; - uid_t euid; +change_euid(newcred, euid) + struct ucred *newcred; + uid_t euid; { - struct pcred *pc; - struct uidinfo *uip; - pc = p->p_cred; - /* - * crcopy is essentially a NOP if ucred has a reference count - * of 1, which is true if it has already been copied. - */ - pc->pc_ucred = crcopy(pc->pc_ucred); - uip = pc->pc_ucred->cr_uidinfo; - pc->pc_ucred->cr_uid = euid; - pc->pc_ucred->cr_uidinfo = uifind(euid); - uifree(uip); + newcred->cr_uid = euid; + uifree(newcred->cr_uidinfo); + newcred->cr_uidinfo = uifind(euid); } /* - * Helper function to change the real uid of a process - * - * The per-uid process count for this process is transfered from - * the old uid to the new uid. + * change_egid(): Change a process's effective gid. + * Arguments: struct ucred *newcred, gid_t egid + * Returns: none + * Locks: none + * Side effects: newcred->cr_gid will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none */ void -change_ruid(p, ruid) - struct proc *p; - uid_t ruid; +change_egid(newcred, egid) + struct ucred *newcred; + gid_t egid; +{ + + newcred->cr_groups[0] = egid; +} + +/* + * change_ruid(): Change a process's real uid. + * Arguments: struct ucred *newcred, uid_t ruid + * Returns: none + * Locks: none + * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo + * will be updated, and the old and new cr_ruidinfo proc + * counts will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_ruid(newcred, ruid) + struct ucred *newcred; + uid_t ruid; +{ + + (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); + newcred->cr_ruid = ruid; + uifree(newcred->cr_ruidinfo); + newcred->cr_ruidinfo = uifind(ruid); + (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); +} + +/* + * change_rgid(): Change a process's real gid. + * Arguments: struct ucred *newcred, gid_t rgid + * Returns: none + * Locks: none + * Side effects: newcred->cr_rgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_rgid(newcred, rgid) + struct ucred *newcred; + gid_t rgid; +{ + + newcred->cr_rgid = rgid; +} + +/* + * change_svuid(): Change a process's saved uid. + * Arguments: struct ucred *newcred, uid_t svuid + * Returns: none + * Locks: none + * Side effects: newcred->cr_svuid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_svuid(newcred, svuid) + struct ucred *newcred; + uid_t svuid; +{ + + newcred->cr_svuid = svuid; +} + +/* + * change_svgid(): Change a process's saved gid. + * Arguments: struct ucred *newcred, gid_t svgid + * Returns: none + * Locks: none + * Side effects: newcred->cr_svgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + * Notes: none + */ +void +change_svgid(newcred, svgid) + struct ucred *newcred; + gid_t svgid; { - struct pcred *pc; - struct uidinfo *uip; - pc = p->p_cred; - (void)chgproccnt(pc->p_uidinfo, -1, 0); - uip = pc->p_uidinfo; - /* It is assumed that pcred is not shared between processes */ - pc->p_ruid = ruid; - pc->p_uidinfo = uifind(ruid); - (void)chgproccnt(pc->p_uidinfo, 1, 0); - uifree(uip); + newcred->cr_svgid = svgid; } Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.118 diff -u -r1.118 kern_sig.c --- kern/kern_sig.c 2001/05/07 18:07:29 1.118 +++ kern/kern_sig.c 2001/05/13 03:24:11 @@ -98,14 +98,14 @@ "Log processes quitting on abnormal signals to syslog(3)"); /* - * Policy -- Can real uid ruid with ucred uc send a signal to process q? + * Policy -- Can ucred cr1 send SIGIO to process cr2? */ -#define CANSIGIO(ruid, uc, q) \ - ((uc)->cr_uid == 0 || \ - (ruid) == (q)->p_cred->p_ruid || \ - (uc)->cr_uid == (q)->p_cred->p_ruid || \ - (ruid) == (q)->p_ucred->cr_uid || \ - (uc)->cr_uid == (q)->p_ucred->cr_uid) +#define CANSIGIO(cr1, cr2) \ + ((cr1)->cr_uid == 0 || \ + (cr2)->cr_ruid == (cr2)->cr_ruid || \ + (cr2)->cr_uid == (cr2)->cr_ruid || \ + (cr2)->cr_ruid == (cr2)->cr_uid || \ + (cr2)->cr_uid == (cr2)->cr_uid) int sugid_coredump; SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, @@ -1610,8 +1610,8 @@ { CTR3(KTR_PROC, "killproc: proc %p (pid %d, %s)", p, p->p_pid, p->p_comm); - log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm, - p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, why); + log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, + p->p_comm, p->p_ucred ? p->p_ucred->cr_uid : -1, why); PROC_LOCK(p); psignal(p, SIGKILL); PROC_UNLOCK(p); @@ -1650,7 +1650,7 @@ log(LOG_INFO, "pid %d (%s), uid %d: exited on signal %d%s\n", p->p_pid, p->p_comm, - p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1, + p->p_ucred ? p->p_ucred->cr_uid : -1, sig &~ WCOREFLAG, sig & WCOREFLAG ? " (core dumped)" : ""); } else { @@ -1870,8 +1870,7 @@ if (sigio->sio_pgid > 0) { PROC_LOCK(sigio->sio_proc); - if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, - sigio->sio_proc)) + if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred)) psignal(sigio->sio_proc, sig); PROC_UNLOCK(sigio->sio_proc); } else if (sigio->sio_pgid < 0) { @@ -1879,7 +1878,7 @@ LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) { PROC_LOCK(p); - if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, p) && + if (CANSIGIO(sigio->sio_ucred, p->p_ucred) && (checkctty == 0 || (p->p_flag & P_CONTROLT))) psignal(p, sig); PROC_UNLOCK(p); Index: kern/uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.65 diff -u -r1.65 uipc_usrreq.c --- kern/uipc_usrreq.c 2001/05/01 08:12:59 1.65 +++ kern/uipc_usrreq.c 2001/05/13 03:24:12 @@ -988,8 +988,8 @@ if (cm->cmsg_type == SCM_CREDS) { cmcred = (struct cmsgcred *)(cm + 1); cmcred->cmcred_pid = p->p_pid; - cmcred->cmcred_uid = p->p_cred->p_ruid; - cmcred->cmcred_gid = p->p_cred->p_rgid; + cmcred->cmcred_uid = p->p_ucred->cr_ruid; + cmcred->cmcred_gid = p->p_ucred->cr_rgid; cmcred->cmcred_euid = p->p_ucred->cr_uid; cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups, CMGROUP_MAX); Index: kern/vfs_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.189 diff -u -r1.189 vfs_syscalls.c --- kern/vfs_syscalls.c 2001/04/29 02:44:49 1.189 +++ kern/vfs_syscalls.c 2001/05/13 03:24:14 @@ -1711,8 +1711,8 @@ * rather than to modify the potentially shared process structure. */ tmpcred = crdup(cred); - tmpcred->cr_uid = p->p_cred->p_ruid; - tmpcred->cr_groups[0] = p->p_cred->p_rgid; + tmpcred->cr_uid = cred->cr_ruid; + tmpcred->cr_groups[0] = cred->cr_rgid; p->p_ucred = tmpcred; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, SCARG(uap, path), p); @@ -3799,7 +3799,7 @@ } cnt = auio.uio_resid; error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, - p->p_cred->pc_ucred, p); + p->p_ucred, p); cnt -= auio.uio_resid; p->p_retval[0] = cnt; done: @@ -3912,7 +3912,7 @@ } cnt = auio.uio_resid; error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio, - p->p_cred->pc_ucred, p); + p->p_ucred, p); cnt -= auio.uio_resid; p->p_retval[0] = cnt; done: @@ -3995,7 +3995,7 @@ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, - p->p_cred->pc_ucred, p); + p->p_ucred, p); VOP_UNLOCK(vp, 0, p); vn_finished_write(mp); Index: miscfs/procfs/procfs_status.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_status.c,v retrieving revision 1.29 diff -u -r1.29 procfs_status.c --- miscfs/procfs/procfs_status.c 2001/05/01 08:13:09 1.29 +++ miscfs/procfs/procfs_status.c 2001/05/13 03:24:15 @@ -153,11 +153,11 @@ ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu", (u_long)cr->cr_uid, - (u_long)p->p_cred->p_ruid, - (u_long)p->p_cred->p_rgid); + (u_long)cr->cr_ruid, + (u_long)cr->cr_rgid); DOCHECK(); - /* egid (p->p_cred->p_svgid) is equal to cr_ngroups[0] + /* egid (cr->cr_svgid) is equal to cr_ngroups[0] see also getegid(2) in /sys/kern/kern_prot.c */ for (i = 0; i < cr->cr_ngroups; i++) { Index: miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.95 diff -u -r1.95 procfs_vnops.c --- miscfs/procfs/procfs_vnops.c 2001/05/01 08:13:09 1.95 +++ miscfs/procfs/procfs_vnops.c 2001/05/13 03:24:22 @@ -404,7 +404,7 @@ procp = PFIND(pfs->pfs_pid); if (procp == NULL) return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { + if (procp->p_ucred == NULL) { PROC_UNLOCK(procp); return (ENOENT); } @@ -942,8 +942,7 @@ */ case Pfile: procp = PFIND(pfs->pfs_pid); - if (procp == NULL || procp->p_cred == NULL || - procp->p_ucred == NULL) { + if (procp == NULL || procp->p_ucred == NULL) { if (procp != NULL) PROC_UNLOCK(procp); printf("procfs_readlink: pid %d disappeared\n", Index: nfs/nfs_lock.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_lock.c,v retrieving revision 1.4 diff -u -r1.4 nfs_lock.c --- nfs/nfs_lock.c 2001/05/01 08:13:14 1.4 +++ nfs/nfs_lock.c 2001/05/13 03:24:34 @@ -236,9 +236,11 @@ /* Let root, or someone who once was root (lockd generally * switches to the daemon uid once it is done setting up) make - * this call + * this call. + * + * XXX */ - if ((error = suser(p)) != 0 && p->p_cred->p_svuid != 0) + if ((error = suser(p)) != 0 && p->p_ucred->cr_svuid != 0) return (error); /* the version should match, or we're out of sync */ Index: posix4/p1003_1b.c =================================================================== RCS file: /home/ncvs/src/sys/posix4/p1003_1b.c,v retrieving revision 1.9 diff -u -r1.9 p1003_1b.c --- posix4/p1003_1b.c 2001/05/06 16:15:42 1.9 +++ posix4/p1003_1b.c 2001/05/13 03:24:35 @@ -68,16 +68,17 @@ /* * This is stolen from CANSIGNAL in kern_sig: * - * Can process p, with pcred pc, do "write flavor" operations to process q? + * Can process with credential cr1 do "write flavor" operations to credential + * cr2. This check needs to use generalized checks. */ -#define CAN_AFFECT(p, q) \ - (!suser_xxx(NULL, p, PRISON_ROOT) || \ - (p)->p_cred->pc_ruid == (q)->p_cred->p_ruid || \ - (p)->p_ucred->cr_uid == (q)->p_cred->p_ruid || \ - (p)->p_cred->pc_ruid == (q)->p_ucred->cr_uid || \ - (p)->p_ucred->cr_uid == (q)->p_ucred->cr_uid) +#define CAN_AFFECT(cr1, cr2) \ + (!suser_xxx(cr1, NULL, PRISON_ROOT) || \ + (c1)->cr_ruid == (cr2)->cr_ruid || \ + (c1)->cr_uid == (cr2)->cr_ruid || \ + (c1)->cr_ruid == (cr2)->cr_uid || \ + (c1)->cr_uid == (cr2)->cr_uid) #else -#define CAN_AFFECT(p, q) (!suser_xxx(NULL, p, PRISON_ROOT)) +#define CAN_AFFECT(cr1, cr2) (!suser_xxx(cr1, NULL, PRISON_ROOT)) #endif /* @@ -99,7 +100,7 @@ { /* Enforce permission policy. */ - if (CAN_AFFECT(p, other_proc)) + if (CAN_AFFECT(p->p_ucred, other_proc->p_ucred)) *pp = other_proc; else ret = EPERM; Index: sys/filedesc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/filedesc.h,v retrieving revision 1.26 diff -u -r1.26 filedesc.h --- sys/filedesc.h 2000/11/18 21:01:04 1.26 +++ sys/filedesc.h 2001/05/13 03:24:35 @@ -117,7 +117,6 @@ struct sigio **sio_myref; /* location of the pointer that holds * the reference to this structure */ struct ucred *sio_ucred; /* current credentials */ - uid_t sio_ruid; /* real user id */ pid_t sio_pgid; /* pgid for signals */ }; #define sio_proc sio_u.siu_proc Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.161 diff -u -r1.161 proc.h --- sys/proc.h 2001/04/27 19:28:25 1.161 +++ sys/proc.h 2001/05/13 03:24:35 @@ -156,7 +156,7 @@ LIST_ENTRY(proc) p_list; /* (d) List of all processes. */ /* substructures: */ - struct pcred *p_cred; /* (c + k) Process owner's identity. */ + struct ucred *p_ucred; /* (c + k) Process owner's identity. */ struct filedesc *p_fd; /* (b) Ptr to open files structure. */ struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */ struct plimit *p_limit; /* (m) Process limits. */ @@ -166,7 +166,6 @@ #define p_sigignore p_procsig->ps_sigignore #define p_sigcatch p_procsig->ps_sigcatch -#define p_ucred p_cred->pc_ucred #define p_rlimit p_limit->pl_rlimit int p_flag; /* (c) P_* flags. */ @@ -336,23 +335,6 @@ #define P_CAN_SEE 1 #define P_CAN_SCHED 3 #define P_CAN_DEBUG 4 - -/* - * MOVE TO ucred.h? - * - * Shareable process credentials (always resident). This includes a reference - * to the current user credentials as well as real and saved ids that may be - * used to change ids. - */ -struct pcred { - struct ucred *pc_ucred; /* Current credentials. */ - uid_t p_ruid; /* Real user id. */ - uid_t p_svuid; /* Saved effective user id. */ - gid_t p_rgid; /* Real group id. */ - gid_t p_svgid; /* Saved effective group id. */ - int p_refcnt; /* Number of references. */ - struct uidinfo *p_uidinfo; /* Per uid resource consumption. */ -}; #ifdef _KERNEL Index: sys/ucred.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ucred.h,v retrieving revision 1.23 diff -u -r1.23 ucred.h --- sys/ucred.h 2001/05/01 08:13:18 1.23 +++ sys/ucred.h 2001/05/13 03:24:35 @@ -50,9 +50,14 @@ struct ucred { u_int cr_ref; /* reference count */ uid_t cr_uid; /* effective user id */ + uid_t cr_ruid; /* real user id */ + uid_t cr_svuid; /* saved user id */ short cr_ngroups; /* number of groups */ gid_t cr_groups[NGROUPS]; /* groups */ - struct uidinfo *cr_uidinfo; /* per uid resource consumption */ + gid_t cr_rgid; /* real group id */ + gid_t cr_svgid; /* saved user id */ + struct uidinfo *cr_uidinfo; /* per euid resource consumption */ + struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */ struct prison *cr_prison; /* jail(4) */ struct mtx cr_mtx; /* protect refcount */ }; @@ -77,8 +82,12 @@ struct proc; -void change_euid __P((struct proc *p, uid_t euid)); -void change_ruid __P((struct proc *p, uid_t ruid)); +void change_euid __P((struct ucred *newcred, uid_t euid)); +void change_egid __P((struct ucred *newcred, gid_t egid)); +void change_ruid __P((struct ucred *newcred, uid_t ruid)); +void change_rgid __P((struct ucred *newcred, uid_t rgid)); +void change_svuid __P((struct ucred *newcred, uid_t svuid)); +void change_svgid __P((struct ucred *newcred, gid_t svgid)); struct ucred *crcopy __P((struct ucred *cr)); struct ucred *crdup __P((struct ucred *cr)); void crfree __P((struct ucred *cr)); Index: ufs/ufs/ufs_extattr.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_extattr.c,v retrieving revision 1.31 diff -u -r1.31 ufs_extattr.c --- ufs/ufs/ufs_extattr.c 2001/04/29 02:45:28 1.31 +++ ufs/ufs/ufs_extattr.c 2001/05/13 03:24:36 @@ -621,7 +621,7 @@ auio.uio_rw = UIO_READ; auio.uio_procp = (struct proc *) p; - VOP_LEASE(backing_vnode, p, p->p_cred->pc_ucred, LEASE_WRITE); + VOP_LEASE(backing_vnode, p, p->p_ucred, LEASE_WRITE); vn_lock(backing_vnode, LK_SHARED | LK_NOPAUSE | LK_RETRY, p); error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED, ump->um_extattr.uepm_ucred); @@ -702,7 +702,7 @@ * Processes with privilege, but in jail, are not allowed to * configure extended attributes. */ - if ((error = suser_xxx(p->p_cred->pc_ucred, p, 0))) { + if ((error = suser_xxx(p->p_ucred, p, 0))) { if (filename_vp != NULL) VOP_UNLOCK(filename_vp, 0, p); return (error); Index: ufs/ufs/ufs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vfsops.c,v retrieving revision 1.24 diff -u -r1.24 ufs_vfsops.c --- ufs/ufs/ufs_vfsops.c 2001/05/01 08:13:19 1.24 +++ ufs/ufs/ufs_vfsops.c 2001/05/13 03:24:37 @@ -108,14 +108,14 @@ int cmd, type, error; if (uid == -1) - uid = p->p_cred->p_ruid; + uid = p->p_ucred->cr_ruid; cmd = cmds >> SUBCMDSHIFT; switch (cmd) { case Q_SYNC: break; case Q_GETQUOTA: - if (uid == p->p_cred->p_ruid) + if (uid == p->p_ucred->cr_ruid) break; /* fall through */ default: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message