diff options
-rw-r--r-- | sys/coda/coda_namecache.c | 3 | ||||
-rw-r--r-- | sys/dev/md/md.c | 3 | ||||
-rw-r--r-- | sys/fs/coda/coda_namecache.c | 3 | ||||
-rw-r--r-- | sys/fs/specfs/spec_vnops.c | 9 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vfsops.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_descrip.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 51 | ||||
-rw-r--r-- | sys/kern/uipc_sockbuf.c | 6 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 3 | ||||
-rw-r--r-- | sys/kern/uipc_socket2.c | 6 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 14 | ||||
-rw-r--r-- | sys/kern/vfs_cluster.c | 6 | ||||
-rw-r--r-- | sys/netncp/ncp_conn.c | 6 | ||||
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 18 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 3 | ||||
-rw-r--r-- | sys/sys/ucred.h | 7 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_extattr.c | 3 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_quota.c | 3 | ||||
-rw-r--r-- | sys/vm/swap_pager.c | 17 | ||||
-rw-r--r-- | sys/vm/vnode_pager.c | 18 |
21 files changed, 85 insertions, 106 deletions
diff --git a/sys/coda/coda_namecache.c b/sys/coda/coda_namecache.c index 9dfaf19750b6..29da91aac60b 100644 --- a/sys/coda/coda_namecache.c +++ b/sys/coda/coda_namecache.c @@ -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); diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 00317f1fd8ba..0a69769bdc7f 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -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. diff --git a/sys/fs/coda/coda_namecache.c b/sys/fs/coda/coda_namecache.c index 9dfaf19750b6..29da91aac60b 100644 --- a/sys/fs/coda/coda_namecache.c +++ b/sys/fs/coda/coda_namecache.c @@ -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); diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c index 24edc69aed92..94b6c1841e34 100644 --- a/sys/fs/specfs/spec_vnops.c +++ b/sys/fs/specfs/spec_vnops.c @@ -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); diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c index 7f616cb50ffb..53c5ae68622d 100644 --- a/sys/fs/unionfs/union_vfsops.c +++ b/sys/fs/unionfs/union_vfsops.c @@ -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; /* diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index d28a798581ce..b0f9e085f36c 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -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 { diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index f5ae42cf3ec6..592ff4412708 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -471,8 +471,7 @@ again: * 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++; diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 7faf612b78fd..553b27810458 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -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); } diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index b0c23fdf84ab..c969e7dec9f9 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -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); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 65ef837df8a3..a7ac484362c7 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -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) { diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index b0c23fdf84ab..c969e7dec9f9 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -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); diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index f2a78bd0631b..510222ce690f 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -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); diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index b685740e9983..1960c2812028 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -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; diff --git a/sys/netncp/ncp_conn.c b/sys/netncp/ncp_conn.c index dc255f20ac25..fbe9b15ff072 100644 --- a/sys/netncp/ncp_conn.c +++ b/sys/netncp/ncp_conn.c @@ -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; diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index bddec5d845b5..fae952d88da6 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -884,10 +884,8 @@ again: 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 @@ again: } 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); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index ed571434a4a9..fdb0fca80390 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -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); diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index 1675bc030b00..64d9abb25a4e 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -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 */ diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c index 60dc574fdba8..a1d523fc4541 100644 --- a/sys/ufs/ufs/ufs_extattr.c +++ b/sys/ufs/ufs/ufs_extattr.c @@ -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); diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 4c10d88e0a22..f1a5835cebe9 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -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) { diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index e25a5567cad1..711a00ff35d6 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -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); diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index bad9bcf948cb..97e703924c49 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -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; |