diff options
34 files changed, 489 insertions, 375 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index d313925..b45aec2 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -114,7 +114,6 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt) struct tty tty; struct vmspace vmspace; struct procsig procsig; - struct pcred pcred; struct pstats pstats; struct ucred ucred; struct proc proc; @@ -127,12 +126,11 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt) _kvm_err(kd, kd->program, "can't read proc at %x", p); return (-1); } - if (KREAD(kd, (u_long)proc.p_cred, &pcred) == 0) { - kp->ki_ruid = pcred.p_ruid; - kp->ki_svuid = pcred.p_svuid; - kp->ki_rgid = pcred.p_rgid; - kp->ki_svgid = pcred.p_svgid; - (void)(KREAD(kd, (u_long)pcred.pc_ucred, &ucred)); + if (KREAD(kd, (u_long)proc.p_ucred, &ucred) == 0) { + kp->ki_ruid = ucred.cr_ruid; + kp->ki_svuid = ucred.cr_svuid; + kp->ki_rgid = ucred.cr_rgid; + kp->ki_svgid = ucred.cr_svgid; kp->ki_ngroups = ucred.cr_ngroups; bcopy(ucred.cr_groups, kp->ki_groups, NGROUPS * sizeof(gid_t)); diff --git a/sys/alpha/osf1/osf1_misc.c b/sys/alpha/osf1/osf1_misc.c index 707e640..7d9a213 100644 --- a/sys/alpha/osf1/osf1_misc.c +++ b/sys/alpha/osf1/osf1_misc.c @@ -1054,29 +1054,32 @@ osf1_setuid(p, uap) { int error; uid_t uid; - register struct pcred *pc; + struct ucred *newcred, oldcred; 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 @@ osf1_setgid(p, uap) { int error; gid_t gid; - register struct pcred *pc; + struct ucred *newcred, *oldcred; 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); } diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 6a356fb..04858f7 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -478,14 +478,14 @@ linprocfs_doprocstatus(curp, p, pfs, uio) 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"); @@ -577,7 +577,7 @@ linprocfs_doexelink(curp, p, pfs, uio) 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); diff --git a/sys/compat/linprocfs/linprocfs_misc.c b/sys/compat/linprocfs/linprocfs_misc.c index 6a356fb..04858f7 100644 --- a/sys/compat/linprocfs/linprocfs_misc.c +++ b/sys/compat/linprocfs/linprocfs_misc.c @@ -478,14 +478,14 @@ linprocfs_doprocstatus(curp, p, pfs, uio) 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"); @@ -577,7 +577,7 @@ linprocfs_doexelink(curp, p, pfs, uio) 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); diff --git a/sys/compat/linprocfs/linprocfs_vnops.c b/sys/compat/linprocfs/linprocfs_vnops.c index 2bb824e..08a5023 100644 --- a/sys/compat/linprocfs/linprocfs_vnops.c +++ b/sys/compat/linprocfs/linprocfs_vnops.c @@ -433,7 +433,7 @@ linprocfs_getattr(ap) 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); } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 2c7c9b5..64200b1 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -958,13 +958,13 @@ linux_setgroups(p, uap) struct proc *p; struct linux_setgroups_args *uap; { - struct pcred *pc; + struct ucred *newcred, *oldcred; linux_gid_t linux_gidset[NGROUPS]; gid_t *bsd_gidset; int ngrp, error; - pc = p->p_cred; ngrp = uap->gidsetsize; + oldcred = p->p_ucred; /* * cr_groups[0] holds egid. Setting the whole set from @@ -972,22 +972,22 @@ linux_setgroups(p, uap) * 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 +995,11 @@ linux_setgroups(p, uap) } } else - pc->pc_ucred->cr_ngroups = 1; + newcred->cr_ngroups = 1; setsugid(p); + p->p_ucred = newcred; + crfree(oldcred); return (0); } @@ -1006,14 +1008,14 @@ linux_getgroups(p, uap) 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 diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 1baed66..a92e8a4 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1283,7 +1283,7 @@ loop: /* * 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 @@ loop: /* * 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 diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index 912cd2a..9137e0c 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c @@ -213,10 +213,10 @@ svr4_fixup(register_t **stack_base, struct image_params *imgp) 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); diff --git a/sys/ddb/db_ps.c b/sys/ddb/db_ps.c index bccda5a..cbedb1e 100644 --- a/sys/ddb/db_ps.c +++ b/sys/ddb/db_ps.c @@ -95,7 +95,7 @@ db_ps(dummy1, dummy2, dummy3, dummy4) 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); diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c index 9620be5..0f57e49 100644 --- a/sys/fs/procfs/procfs_status.c +++ b/sys/fs/procfs/procfs_status.c @@ -153,11 +153,11 @@ procfs_dostatus(curp, p, pfs, uio) 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++) { diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index a054eb9..4ca89ac 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -403,7 +403,7 @@ procfs_getattr(ap) 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); } @@ -941,8 +941,7 @@ procfs_readlink(ap) */ 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", diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 0734ba4..de82774 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -187,10 +187,10 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) 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); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 5624720..9698983 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -85,7 +85,6 @@ void mi_startup(void); /* Should be elsewhere */ 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; @@ -333,12 +332,10 @@ proc0_init(void *dummy __unused) 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. */ @@ -394,7 +391,7 @@ proc0_init(void *dummy __unused) /* * 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) diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index 7562e31..98f2495 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -222,8 +222,8 @@ acct_process(p) 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) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index f89e413..b2cc930 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -525,8 +525,6 @@ fsetown(pgid, sigiop) 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; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index abb08fc..e3ae485 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -104,6 +104,7 @@ execve(p, uap) register struct execve_args *uap; { struct nameidata nd, *ndp; + struct ucred *newcred, *oldcred; register_t *stack_base; int error, len, i; struct image_params image_params, *imgp; @@ -274,13 +275,24 @@ interpret: } /* + * 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)) && + oldcred = p->p_ucred; + 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 +300,7 @@ interpret: * 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 +308,49 @@ interpret: /* * 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 sourses 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 (oldcred->cr_svuid != oldcred->cr_uid || + oldcred->cr_svgid != oldcred->cr_gid) { + /* + * Avoid allocating a newcred if we don't have one yet and + * the saved uid/gid update would be a noop. + */ + if (newcred == NULL) + newcred = crdup(oldcred); + change_svuid(newcred, newcred->cr_uid); + change_svgid(newcred, newcred->cr_gid); + } + if (newcred != NULL) { + PROC_LOCK(p); + p->p_ucred = newcred; + PROC_UNLOCK(p); + crfree(oldcred); + } /* * Store the vp for use in procfs diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 1af27d2..6454d11 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -516,7 +516,7 @@ loop: /* * 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 @@ -541,12 +541,8 @@ loop: /* * 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 diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 62dcc06..6774f64 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -258,7 +258,7 @@ fork1(p1, flags, procp) * 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); @@ -273,7 +273,7 @@ fork1(p1, flags, procp) * 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) { /* @@ -409,15 +409,9 @@ again: * 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++; diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index ce972bd..15b51c8 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -531,17 +531,17 @@ static int 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); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index d441144..f45ac26 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -424,15 +424,15 @@ fill_kinfo_proc(p, kp) 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 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) 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; } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index f0b4ff8..fcef6d0 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -210,7 +210,7 @@ getuid(p, uap) 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 @@ getgid(p, uap) 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 @@ getgroups(p, uap) 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,10 +427,12 @@ setuid(p, uap) struct proc *p; struct setuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t uid; + struct ucred *newcred, *oldcred; + uid_t uid; int error; + uid = uap->uid; + oldcred = p->p_ucred; /* * See if we have "permission" by POSIX 1003.1 rules. * @@ -448,17 +450,17 @@ setuid(p, uap) * change. Determined by compile options. * 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 +468,16 @@ setuid(p, uap) */ 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 +487,8 @@ setuid(p, uap) * 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 +497,12 @@ setuid(p, uap) * 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 +517,27 @@ seteuid(p, uap) struct proc *p; struct seteuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t euid; + struct ucred *newcred, *oldcred; + 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))) + oldcred = p->p_ucred; + 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,10 +552,12 @@ setgid(p, uap) struct proc *p; struct setgid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t gid; + struct ucred *newcred, *oldcred; + gid_t gid; int error; + gid = uap->gid; + oldcred = p->p_ucred; /* * See if we have "permission" by POSIX 1003.1 rules. * @@ -559,17 +569,17 @@ setgid(p, uap) * * 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 +587,16 @@ setgid(p, uap) */ 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 +606,8 @@ setgid(p, uap) * 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 +615,12 @@ setgid(p, uap) * 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 +635,23 @@ setegid(p, uap) struct proc *p; struct setegid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t egid; + struct ucred *newcred, *oldcred; + 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))) + oldcred = p->p_ucred; + 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,20 +667,21 @@ setgroups(p, uap) struct proc *p; struct setgroups_args *uap; { - register struct pcred *pc = p->p_cred; - register u_int ngrp; + struct ucred *newcred, *oldcred; + u_int ngrp; int error; - if ((error = suser_xxx(0, p, PRISON_ROOT))) - return (error); ngrp = uap->gidsetsize; + oldcred = p->p_ucred; + if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) + return (error); if (ngrp > NGROUPS) return (EINVAL); /* * 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 +689,18 @@ setgroups(p, uap) * 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 +716,35 @@ setreuid(p, uap) register struct proc *p; struct setreuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t ruid, euid; + struct ucred *newcred, *oldcred; + 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) + oldcred = p->p_ucred; + 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; + 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 +760,32 @@ setregid(p, uap) register struct proc *p; struct setregid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t rgid, egid; + struct ucred *newcred, *oldcred; + 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) + oldcred = p->p_ucred; + 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]; + 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 +809,41 @@ setresuid(p, uap) register struct proc *p; struct setresuid_args *uap; { - register struct pcred *pc = p->p_cred; - register uid_t ruid, euid, suid; + struct ucred *newcred, *oldcred; + 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) + oldcred = p->p_ucred; + 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 +865,41 @@ setresgid(p, uap) register struct proc *p; struct setresgid_args *uap; { - register struct pcred *pc = p->p_cred; - register gid_t rgid, egid, sgid; + struct ucred *newcred, *oldcred; + 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) + oldcred = p->p_ucred; + 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 +916,18 @@ getresuid(p, uap) 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 +944,18 @@ getresgid(p, uap) 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 +1011,7 @@ __setugid(p, uap) int groupmember(gid, cred) gid_t gid; - register struct ucred *cred; + struct ucred *cred; { register gid_t *gp; gid_t *egp; @@ -1038,7 +1077,7 @@ u_cansee(struct ucred *u1, struct ucred *u2) if ((error = prison_check(u1, u2))) return (error); - if (!ps_showallprocs && u1->cr_uid != u2->cr_uid) { + if (!ps_showallprocs && u1->cr_ruid != u2->cr_ruid) { if (suser_xxx(u1, NULL, PRISON_ROOT) != 0) return (ESRCH); } @@ -1113,10 +1152,10 @@ p_cansignal(struct proc *p1, struct proc *p2, int signum) * 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 +1179,9 @@ p_cansched(struct proc *p1, struct proc *p2, int *privused) 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 +1217,9 @@ p_candebug(struct proc *p1, struct proc *p2, int *privused) /* 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->pc_ucred->cr_uid || - p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_svuid || - p1->p_cred->pc_ucred->cr_uid != p2->p_cred->p_ruid || + if (p1->p_ucred->cr_uid != p2->p_ucred->cr_uid || + p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid || + p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid || p2->p_flag & P_SUGID) { if ((error = suser_xxx(0, p1, PRISON_ROOT))) return (error); @@ -1308,6 +1347,7 @@ crdup(cr) *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 +1415,99 @@ setsugid(p) } /* - * Helper function to change the effective uid of a process + * change_euid(): Change a process's effective uid. + * 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. */ 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. + * Side effects: newcred->cr_gid will be modified. + * References: newcred must be an exclusive credential reference for the + * duration of the call. */ 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. + * 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. + */ +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. + * Side effects: newcred->cr_rgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + */ +void +change_rgid(newcred, rgid) + struct ucred *newcred; + gid_t rgid; { - 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_rgid = rgid; +} + +/* + * change_svuid(): Change a process's saved uid. + * Side effects: newcred->cr_svuid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + */ +void +change_svuid(newcred, svuid) + struct ucred *newcred; + uid_t svuid; +{ + + newcred->cr_svuid = svuid; +} + +/* + * change_svgid(): Change a process's saved gid. + * Side effects: newcred->cr_svgid will be updated. + * References: newcred must be an exclusive credential reference for the + * duration of the call. + */ +void +change_svgid(newcred, svgid) + struct ucred *newcred; + gid_t svgid; +{ + + newcred->cr_svgid = svgid; } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 56837f4..ae68268 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -97,14 +97,14 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, "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, @@ -1612,7 +1612,7 @@ killproc(p, why) 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); + p->p_ucred ? p->p_ucred->cr_uid : -1, why); psignal(p, SIGKILL); } @@ -1649,7 +1649,7 @@ sigexit(p, sig) 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 { @@ -1869,8 +1869,7 @@ pgsigio(sigio, sig, checkctty) 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) { @@ -1878,7 +1877,7 @@ pgsigio(sigio, sig, checkctty) 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); diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c index 569bb6f..cf2c7da 100644 --- a/sys/kern/p1003_1b.c +++ b/sys/kern/p1003_1b.c @@ -68,16 +68,17 @@ MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B"); /* * 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 @@ int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) { /* 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; diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 33ff735..2907b4e 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -988,8 +988,8 @@ unp_internalize(control, p) 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); diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 89041a6..75d3eb7 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -1710,8 +1710,8 @@ access(p, uap) * 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); @@ -3801,7 +3801,7 @@ extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname, } 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: @@ -3914,7 +3914,7 @@ extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname, } 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: @@ -3997,7 +3997,7 @@ extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname, 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); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 89041a6..75d3eb7 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1710,8 +1710,8 @@ access(p, uap) * 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); @@ -3801,7 +3801,7 @@ extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname, } 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: @@ -3914,7 +3914,7 @@ extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname, } 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: @@ -3997,7 +3997,7 @@ extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname, 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); diff --git a/sys/nfs/nfs_lock.c b/sys/nfs/nfs_lock.c index 9fd243a..85bc9d9 100644 --- a/sys/nfs/nfs_lock.c +++ b/sys/nfs/nfs_lock.c @@ -236,9 +236,11 @@ nfslockdans(p, ansp) /* 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 This authorization check is probably not right. */ - 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 */ diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c index 9fd243a..85bc9d9 100644 --- a/sys/nfsclient/nfs_lock.c +++ b/sys/nfsclient/nfs_lock.c @@ -236,9 +236,11 @@ nfslockdans(p, ansp) /* 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 This authorization check is probably not right. */ - 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 */ diff --git a/sys/posix4/p1003_1b.c b/sys/posix4/p1003_1b.c index 569bb6f..cf2c7da 100644 --- a/sys/posix4/p1003_1b.c +++ b/sys/posix4/p1003_1b.c @@ -68,16 +68,17 @@ MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B"); /* * 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 @@ int p31b_proc(struct proc *p, pid_t pid, struct proc **pp) { /* 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; diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 273ddf1..c0cb850 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -117,7 +117,6 @@ struct sigio { 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 diff --git a/sys/sys/proc.h b/sys/sys/proc.h index d953b1d..3201669 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -156,7 +156,7 @@ struct proc { 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 @@ struct proc { #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. */ @@ -337,23 +336,6 @@ struct proc { #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 #ifdef MALLOC_DECLARE diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index c48df00..356cca2 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -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 xucred { struct proc; -void change_euid __P((struct proc *p, uid_t euid)); -void change_ruid __P((struct proc *p, uid_t ruid)); +void change_egid __P((struct ucred *newcred, gid_t egid)); +void change_euid __P((struct ucred *newcred, uid_t euid)); +void change_rgid __P((struct ucred *newcred, gid_t rgid)); +void change_ruid __P((struct ucred *newcred, uid_t ruid)); +void change_svgid __P((struct ucred *newcred, gid_t svgid)); +void change_svuid __P((struct ucred *newcred, uid_t svuid)); struct ucred *crcopy __P((struct ucred *cr)); struct ucred *crdup __P((struct ucred *cr)); void crfree __P((struct ucred *cr)); diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c index e77e9fb..817fde3 100644 --- a/sys/ufs/ufs/ufs_extattr.c +++ b/sys/ufs/ufs/ufs_extattr.c @@ -621,7 +621,7 @@ ufs_extattr_enable(struct ufsmount *ump, int attrnamespace, 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 @@ ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, * 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); diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 5c293df..6b8905b 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -108,14 +108,14 @@ ufs_quotactl(mp, cmds, uid, arg, p) 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: |