Change the kernel's ucred API as follows:
- crhold() returns a reference to the ucred whose refcount it bumps. - crcopy() now simply copies the credentials from one credential to another and has no return value. - a new crshared() primitive is added which returns true if a ucred's refcount is > 1 and false (0) otherwise.
This commit is contained in:
parent
698166ca55
commit
bd78cece5d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84827
@ -274,11 +274,10 @@ coda_nc_enter(dcp, name, namelen, cred, cp)
|
||||
*/
|
||||
vref(CTOV(cp));
|
||||
vref(CTOV(dcp));
|
||||
crhold(cred);
|
||||
cncp->dcp = dcp;
|
||||
cncp->cp = cp;
|
||||
cncp->namelen = namelen;
|
||||
cncp->cred = cred;
|
||||
cncp->cred = crhold(cred);
|
||||
|
||||
bcopy(name, cncp->name, (unsigned)namelen);
|
||||
|
||||
|
@ -612,8 +612,7 @@ mdsetcred(struct md_s *sc, struct ucred *cred)
|
||||
|
||||
if (sc->cred)
|
||||
crfree(sc->cred);
|
||||
crhold(cred);
|
||||
sc->cred = cred;
|
||||
sc->cred = crhold(cred);
|
||||
|
||||
/*
|
||||
* Horrible kludge to establish credentials for NFS XXX.
|
||||
|
@ -274,11 +274,10 @@ coda_nc_enter(dcp, name, namelen, cred, cp)
|
||||
*/
|
||||
vref(CTOV(cp));
|
||||
vref(CTOV(dcp));
|
||||
crhold(cred);
|
||||
cncp->dcp = dcp;
|
||||
cncp->cp = cp;
|
||||
cncp->namelen = namelen;
|
||||
cncp->cred = cred;
|
||||
cncp->cred = crhold(cred);
|
||||
|
||||
bcopy(name, cncp->name, (unsigned)namelen);
|
||||
|
||||
|
@ -720,11 +720,10 @@ spec_getpages(ap)
|
||||
bp->b_iodone = spec_getpages_iodone;
|
||||
|
||||
/* B_PHYS is not set, but it is nice to fill this in. */
|
||||
bp->b_rcred = bp->b_wcred = curthread->td_proc->p_ucred;
|
||||
if (bp->b_rcred != NOCRED)
|
||||
crhold(bp->b_rcred);
|
||||
if (bp->b_wcred != NOCRED)
|
||||
crhold(bp->b_wcred);
|
||||
KASSERT(bp->b_rcred == NOCRED, ("leaking read ucred"));
|
||||
KASSERT(bp->b_wcred == NOCRED, ("leaking write ucred"));
|
||||
bp->b_rcred = crhold(curthread->td_proc->p_ucred);
|
||||
bp->b_wcred = crhold(curthread->td_proc->p_ucred);
|
||||
bp->b_blkno = blkno;
|
||||
bp->b_lblkno = blkno;
|
||||
pbgetvp(ap->a_vp, bp);
|
||||
|
@ -223,8 +223,7 @@ union_mount(mp, path, data, ndp, td)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
um->um_cred = td->td_proc->p_ucred;
|
||||
crhold(um->um_cred);
|
||||
um->um_cred = crhold(td->td_proc->p_ucred);
|
||||
um->um_cmode = UN_DIRMODE &~ td->td_proc->p_fd->fd_cmask;
|
||||
|
||||
/*
|
||||
|
@ -588,8 +588,7 @@ fsetown(pgid, sigiop)
|
||||
sigio->sio_pgrp = pgrp;
|
||||
}
|
||||
sigio->sio_pgid = pgid;
|
||||
crhold(curthread->td_proc->p_ucred);
|
||||
sigio->sio_ucred = curthread->td_proc->p_ucred;
|
||||
sigio->sio_ucred = crhold(curthread->td_proc->p_ucred);
|
||||
sigio->sio_myref = sigiop;
|
||||
s = splhigh();
|
||||
*sigiop = sigio;
|
||||
@ -995,10 +994,9 @@ falloc(td, resultfp, resultfd)
|
||||
return (error);
|
||||
}
|
||||
fp->f_count = 1;
|
||||
fp->f_cred = p->p_ucred;
|
||||
fp->f_cred = crhold(p->p_ucred);
|
||||
fp->f_ops = &badfileops;
|
||||
fp->f_seqcount = 1;
|
||||
crhold(fp->f_cred);
|
||||
if ((fq = p->p_fd->fd_ofiles[0])) {
|
||||
LIST_INSERT_AFTER(fq, fp, f_list);
|
||||
} else {
|
||||
|
@ -471,8 +471,7 @@ fork1(td, flags, procp)
|
||||
* We start off holding one spinlock after fork: sched_lock.
|
||||
*/
|
||||
PROC_LOCK(p1);
|
||||
crhold(p1->p_ucred);
|
||||
p2->p_ucred = p1->p_ucred;
|
||||
p2->p_ucred = crhold(p1->p_ucred);
|
||||
|
||||
if (p2->p_args)
|
||||
p2->p_args->ar_ref++;
|
||||
|
@ -1586,14 +1586,15 @@ crget()
|
||||
/*
|
||||
* Claim another reference to a ucred structure.
|
||||
*/
|
||||
void
|
||||
struct ucred *
|
||||
crhold(cr)
|
||||
struct ucred *cr;
|
||||
{
|
||||
|
||||
mtx_lock(&cr->cr_mtx);
|
||||
cr->cr_ref++;
|
||||
mtx_unlock(&(cr)->cr_mtx);
|
||||
mtx_unlock(&cr->cr_mtx);
|
||||
return (cr);
|
||||
}
|
||||
|
||||
|
||||
@ -1631,23 +1632,36 @@ crfree(cr)
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy cred structure to a new one and free the old one.
|
||||
* Check to see if this ucred is shared.
|
||||
*/
|
||||
struct ucred *
|
||||
crcopy(cr)
|
||||
int
|
||||
crshared(cr)
|
||||
struct ucred *cr;
|
||||
{
|
||||
struct ucred *newcr;
|
||||
int shared;
|
||||
|
||||
mtx_lock(&cr->cr_mtx);
|
||||
if (cr->cr_ref == 1) {
|
||||
mtx_unlock(&cr->cr_mtx);
|
||||
return (cr);
|
||||
}
|
||||
shared = (cr->cr_ref > 1);
|
||||
mtx_unlock(&cr->cr_mtx);
|
||||
newcr = crdup(cr);
|
||||
crfree(cr);
|
||||
return (newcr);
|
||||
return (shared);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a ucred's contents from a template. Does not block.
|
||||
*/
|
||||
void
|
||||
crcopy(dest, src)
|
||||
struct ucred *dest, *src;
|
||||
{
|
||||
|
||||
KASSERT(crshared(dest) == 0, ("crcopy of shared ucred"));
|
||||
bcopy(&src->cr_startcopy, &dest->cr_startcopy,
|
||||
(unsigned)((caddr_t)&src->cr_endcopy -
|
||||
(caddr_t)&src->cr_startcopy));
|
||||
uihold(dest->cr_uidinfo);
|
||||
uihold(dest->cr_ruidinfo);
|
||||
if (jailed(dest))
|
||||
prison_hold(dest->cr_prison);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1659,15 +1673,8 @@ crdup(cr)
|
||||
{
|
||||
struct ucred *newcr;
|
||||
|
||||
MALLOC(newcr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
|
||||
*newcr = *cr;
|
||||
bzero(&newcr->cr_mtx, sizeof(newcr->cr_mtx));
|
||||
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;
|
||||
newcr = crget();
|
||||
crcopy(newcr, cr);
|
||||
return (newcr);
|
||||
}
|
||||
|
||||
|
@ -240,8 +240,10 @@ sonewconn3(head, connstatus, td)
|
||||
so->so_state = head->so_state | SS_NOFDREF;
|
||||
so->so_proto = head->so_proto;
|
||||
so->so_timeo = head->so_timeo;
|
||||
so->so_cred = td ? td->td_proc->p_ucred : head->so_cred;
|
||||
crhold(so->so_cred);
|
||||
if (td != NULL)
|
||||
so->so_cred = crhold(td->td_proc->p_ucred);
|
||||
else
|
||||
so->so_cred = crhold(head->so_cred);
|
||||
if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat) ||
|
||||
(*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) {
|
||||
sodealloc(so);
|
||||
|
@ -160,8 +160,7 @@ socreate(dom, aso, type, proto, td)
|
||||
TAILQ_INIT(&so->so_incomp);
|
||||
TAILQ_INIT(&so->so_comp);
|
||||
so->so_type = type;
|
||||
so->so_cred = td->td_proc->p_ucred;
|
||||
crhold(so->so_cred);
|
||||
so->so_cred = crhold(td->td_proc->p_ucred);
|
||||
so->so_proto = prp;
|
||||
error = (*prp->pr_usrreqs->pru_attach)(so, proto, td);
|
||||
if (error) {
|
||||
|
@ -240,8 +240,10 @@ sonewconn3(head, connstatus, td)
|
||||
so->so_state = head->so_state | SS_NOFDREF;
|
||||
so->so_proto = head->so_proto;
|
||||
so->so_timeo = head->so_timeo;
|
||||
so->so_cred = td ? td->td_proc->p_ucred : head->so_cred;
|
||||
crhold(so->so_cred);
|
||||
if (td != NULL)
|
||||
so->so_cred = crhold(td->td_proc->p_ucred);
|
||||
else
|
||||
so->so_cred = crhold(head->so_cred);
|
||||
if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat) ||
|
||||
(*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) {
|
||||
sodealloc(so);
|
||||
|
@ -599,11 +599,8 @@ breadn(struct vnode * vp, daddr_t blkno, int size,
|
||||
bp->b_iocmd = BIO_READ;
|
||||
bp->b_flags &= ~B_INVAL;
|
||||
bp->b_ioflags &= ~BIO_ERROR;
|
||||
if (bp->b_rcred == NOCRED) {
|
||||
if (cred != NOCRED)
|
||||
crhold(cred);
|
||||
bp->b_rcred = cred;
|
||||
}
|
||||
if (bp->b_rcred == NOCRED && cred != NOCRED)
|
||||
bp->b_rcred = crhold(cred);
|
||||
vfs_busy_pages(bp, 0);
|
||||
VOP_STRATEGY(vp, bp);
|
||||
++readwait;
|
||||
@ -621,11 +618,8 @@ breadn(struct vnode * vp, daddr_t blkno, int size,
|
||||
rabp->b_flags &= ~B_INVAL;
|
||||
rabp->b_ioflags &= ~BIO_ERROR;
|
||||
rabp->b_iocmd = BIO_READ;
|
||||
if (rabp->b_rcred == NOCRED) {
|
||||
if (cred != NOCRED)
|
||||
crhold(cred);
|
||||
rabp->b_rcred = cred;
|
||||
}
|
||||
if (rabp->b_rcred == NOCRED && cred != NOCRED)
|
||||
rabp->b_rcred = crhold(cred);
|
||||
vfs_busy_pages(rabp, 0);
|
||||
BUF_KERNPROC(rabp);
|
||||
VOP_STRATEGY(vp, rabp);
|
||||
|
@ -774,10 +774,8 @@ cluster_wbuild(vp, size, start_lbn, len)
|
||||
bp->b_op = tbp->b_op;
|
||||
bp->b_bufsize = 0;
|
||||
bp->b_npages = 0;
|
||||
if (tbp->b_wcred != NOCRED) {
|
||||
bp->b_wcred = tbp->b_wcred;
|
||||
crhold(bp->b_wcred);
|
||||
}
|
||||
if (tbp->b_wcred != NOCRED)
|
||||
bp->b_wcred = crhold(tbp->b_wcred);
|
||||
|
||||
bp->b_blkno = tbp->b_blkno;
|
||||
bp->b_lblkno = tbp->b_lblkno;
|
||||
|
@ -230,10 +230,8 @@ ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
|
||||
if (cap->owner != NCP_DEFAULT_OWNER) {
|
||||
owner = crget();
|
||||
owner->cr_uid = cap->owner;
|
||||
} else {
|
||||
owner = cred;
|
||||
crhold(owner);
|
||||
}
|
||||
} else
|
||||
owner = crhold(cred);
|
||||
MALLOC(ncp, struct ncp_conn *, sizeof(struct ncp_conn),
|
||||
M_NCPDATA, M_WAITOK | M_ZERO);
|
||||
error = 0;
|
||||
|
@ -884,10 +884,8 @@ nfs_write(struct vop_write_args *ap)
|
||||
error = EINTR;
|
||||
break;
|
||||
}
|
||||
if (bp->b_wcred == NOCRED) {
|
||||
crhold(cred);
|
||||
bp->b_wcred = cred;
|
||||
}
|
||||
if (bp->b_wcred == NOCRED)
|
||||
bp->b_wcred = crhold(cred);
|
||||
np->n_flag |= NMODIFIED;
|
||||
|
||||
/*
|
||||
@ -1207,16 +1205,12 @@ nfs_asyncio(struct buf *bp, struct ucred *cred, struct thread *td)
|
||||
}
|
||||
|
||||
if (bp->b_iocmd == BIO_READ) {
|
||||
if (bp->b_rcred == NOCRED && cred != NOCRED) {
|
||||
crhold(cred);
|
||||
bp->b_rcred = cred;
|
||||
}
|
||||
if (bp->b_rcred == NOCRED && cred != NOCRED)
|
||||
bp->b_rcred = crhold(cred);
|
||||
} else {
|
||||
bp->b_flags |= B_WRITEINPROG;
|
||||
if (bp->b_wcred == NOCRED && cred != NOCRED) {
|
||||
crhold(cred);
|
||||
bp->b_wcred = cred;
|
||||
}
|
||||
if (bp->b_wcred == NOCRED && cred != NOCRED)
|
||||
bp->b_wcred = crhold(cred);
|
||||
}
|
||||
|
||||
BUF_KERNPROC(bp);
|
||||
|
@ -2361,8 +2361,7 @@ nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
|
||||
#endif
|
||||
MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
|
||||
M_NFSREQ, M_WAITOK);
|
||||
crhold(cnp->cn_cred);
|
||||
sp->s_cred = cnp->cn_cred;
|
||||
sp->s_cred = crhold(cnp->cn_cred);
|
||||
sp->s_dvp = dvp;
|
||||
VREF(dvp);
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
*/
|
||||
struct ucred {
|
||||
u_int cr_ref; /* reference count */
|
||||
#define cr_startcopy cr_uid
|
||||
uid_t cr_uid; /* effective user id */
|
||||
uid_t cr_ruid; /* real user id */
|
||||
uid_t cr_svuid; /* saved user id */
|
||||
@ -59,6 +60,7 @@ struct ucred {
|
||||
struct uidinfo *cr_uidinfo; /* per euid resource consumption */
|
||||
struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */
|
||||
struct prison *cr_prison; /* jail(4) */
|
||||
#define cr_endcopy cr_mtx
|
||||
struct mtx cr_mtx; /* protect refcount */
|
||||
};
|
||||
#define cr_gid cr_groups[0]
|
||||
@ -87,11 +89,12 @@ 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));
|
||||
void crcopy __P((struct ucred *dest, struct ucred *src));
|
||||
struct ucred *crdup __P((struct ucred *cr));
|
||||
void crfree __P((struct ucred *cr));
|
||||
struct ucred *crget __P((void));
|
||||
void crhold __P((struct ucred *cr));
|
||||
struct ucred *crhold __P((struct ucred *cr));
|
||||
int crshared __P((struct ucred *cr));
|
||||
int groupmember __P((gid_t gid, struct ucred *cred));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -210,8 +210,7 @@ ufs_extattr_start(struct mount *mp, struct thread *td)
|
||||
|
||||
ump->um_extattr.uepm_flags |= UFS_EXTATTR_UEPM_STARTED;
|
||||
|
||||
crhold(td->td_proc->p_ucred);
|
||||
ump->um_extattr.uepm_ucred = td->td_proc->p_ucred;
|
||||
ump->um_extattr.uepm_ucred = crhold(td->td_proc->p_ucred);
|
||||
|
||||
unlock:
|
||||
ufs_extattr_uepm_unlock(ump, td);
|
||||
|
@ -422,8 +422,7 @@ quotaon(td, mp, type, fname)
|
||||
* Save the credential of the process that turned on quotas.
|
||||
* Set up the time limits for this quota.
|
||||
*/
|
||||
crhold(td->td_proc->p_ucred);
|
||||
ump->um_cred[type] = td->td_proc->p_ucred;
|
||||
ump->um_cred[type] = crhold(td->td_proc->p_ucred);
|
||||
ump->um_btime[type] = MAX_DQ_TIME;
|
||||
ump->um_itime[type] = MAX_IQ_TIME;
|
||||
if (dqget(NULLVP, 0, ump, type, &dq) == 0) {
|
||||
|
@ -1134,10 +1134,9 @@ swap_pager_getpages(object, m, count, reqpage)
|
||||
|
||||
bp->b_iocmd = BIO_READ;
|
||||
bp->b_iodone = swp_pager_async_iodone;
|
||||
bp->b_rcred = bp->b_wcred = proc0.p_ucred;
|
||||
bp->b_rcred = crhold(proc0.p_ucred);
|
||||
bp->b_wcred = crhold(proc0.p_ucred);
|
||||
bp->b_data = (caddr_t) kva;
|
||||
crhold(bp->b_rcred);
|
||||
crhold(bp->b_wcred);
|
||||
bp->b_blkno = blk - (reqpage - i);
|
||||
bp->b_bcount = PAGE_SIZE * (j - i);
|
||||
bp->b_bufsize = PAGE_SIZE * (j - i);
|
||||
@ -1386,14 +1385,12 @@ swap_pager_putpages(object, m, count, sync, rtvals)
|
||||
|
||||
pmap_qenter((vm_offset_t)bp->b_data, &m[i], n);
|
||||
|
||||
bp->b_rcred = bp->b_wcred = proc0.p_ucred;
|
||||
bp->b_rcred = crhold(proc0.p_ucred);
|
||||
bp->b_wcred = crhold(proc0.p_ucred);
|
||||
bp->b_bcount = PAGE_SIZE * n;
|
||||
bp->b_bufsize = PAGE_SIZE * n;
|
||||
bp->b_blkno = blk;
|
||||
|
||||
crhold(bp->b_rcred);
|
||||
crhold(bp->b_wcred);
|
||||
|
||||
pbgetvp(swapdev_vp, bp);
|
||||
|
||||
for (j = 0; j < n; ++j) {
|
||||
@ -2082,12 +2079,10 @@ getchainbuf(struct bio *bp, struct vnode *vp, int flags)
|
||||
nbp->b_iocmd = bp->bio_cmd;
|
||||
nbp->b_ioflags = bp->bio_flags & BIO_ORDERED;
|
||||
nbp->b_flags = flags;
|
||||
nbp->b_rcred = nbp->b_wcred = proc0.p_ucred;
|
||||
nbp->b_rcred = crhold(proc0.p_ucred);
|
||||
nbp->b_wcred = crhold(proc0.p_ucred);
|
||||
nbp->b_iodone = vm_pager_chain_iodone;
|
||||
|
||||
crhold(nbp->b_rcred);
|
||||
crhold(nbp->b_wcred);
|
||||
|
||||
if (vp)
|
||||
pbgetvp(vp, nbp);
|
||||
return(nbp);
|
||||
|
@ -434,11 +434,10 @@ vnode_pager_input_smlfs(object, m)
|
||||
/* build a minimal buffer header */
|
||||
bp->b_iocmd = BIO_READ;
|
||||
bp->b_iodone = vnode_pager_iodone;
|
||||
bp->b_rcred = bp->b_wcred = curthread->td_proc->p_ucred;
|
||||
if (bp->b_rcred != NOCRED)
|
||||
crhold(bp->b_rcred);
|
||||
if (bp->b_wcred != NOCRED)
|
||||
crhold(bp->b_wcred);
|
||||
KASSERT(bp->b_rcred == NOCRED, ("leaking read ucred"));
|
||||
KASSERT(bp->b_wcred == NOCRED, ("leaking write ucred"));
|
||||
bp->b_rcred = crhold(curthread->td_proc->p_ucred);
|
||||
bp->b_wcred = crhold(curthread->td_proc->p_ucred);
|
||||
bp->b_data = (caddr_t) kva + i * bsize;
|
||||
bp->b_blkno = fileaddr;
|
||||
pbgetvp(dp, bp);
|
||||
@ -754,11 +753,10 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
bp->b_iocmd = BIO_READ;
|
||||
bp->b_iodone = vnode_pager_iodone;
|
||||
/* B_PHYS is not set, but it is nice to fill this in */
|
||||
bp->b_rcred = bp->b_wcred = curthread->td_proc->p_ucred;
|
||||
if (bp->b_rcred != NOCRED)
|
||||
crhold(bp->b_rcred);
|
||||
if (bp->b_wcred != NOCRED)
|
||||
crhold(bp->b_wcred);
|
||||
KASSERT(bp->b_rcred == NOCRED, ("leaking read ucred"));
|
||||
KASSERT(bp->b_wcred == NOCRED, ("leaking write ucred"));
|
||||
bp->b_rcred = crhold(curthread->td_proc->p_ucred);
|
||||
bp->b_wcred = crhold(curthread->td_proc->p_ucred);
|
||||
bp->b_blkno = firstaddr;
|
||||
pbgetvp(dp, bp);
|
||||
bp->b_bcount = size;
|
||||
|
Loading…
Reference in New Issue
Block a user