diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-08-21 23:16:40 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-08-21 23:16:40 +0000 |
commit | 3680a39bfb0773e9391106ea92581fc96d0de473 (patch) | |
tree | 96e97bcc4ef70a35c9face4f19ab872131d78440 | |
parent | a2d43ee61df1df40b2965bc42b887f9be6728adb (diff) |
Fix malloc race in nfs_node.c
-rw-r--r-- | sys/nfs/nfs_node.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c index a2c96342b27..821450837c2 100644 --- a/sys/nfs/nfs_node.c +++ b/sys/nfs/nfs_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_node.c,v 1.11 1998/08/06 19:34:58 csapuntz Exp $ */ +/* $OpenBSD: nfs_node.c,v 1.12 1998/08/21 23:16:39 csapuntz Exp $ */ /* $NetBSD: nfs_node.c,v 1.16 1996/02/18 11:53:42 fvdl Exp $ */ /* @@ -107,13 +107,14 @@ nfs_nget(mntp, fhp, fhsize, npp) struct nfsnode **npp; { struct proc *p = curproc; /* XXX */ - register struct nfsnode *np; + register struct nfsnode *np, *np2; struct nfsnodehashhead *nhpp; register struct vnode *vp; extern int (**nfsv2_vnodeop_p)__P((void *)); struct vnode *nvp; int error; +retry: nhpp = NFSNOHASH(nfs_hash(fhp, fhsize)); loop: for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) { @@ -139,6 +140,16 @@ loop: /* * Insert the nfsnode in the hash queue for its new file handle */ + for (np2 = nhpp->lh_first; np2 != 0; np2 = np2->n_hash.le_next) { + if (vp->v_mount != NFSTOV(np2)->v_mount || + fhsize != np2->n_fhsize || + bcmp((caddr_t)fhp, (caddr_t)np2->n_fhp, fhsize)) + continue; + + vrele(vp); + goto retry; + } + LIST_INSERT_HEAD(nhpp, np, n_hash); if (fhsize > NFS_SMALLFH) { MALLOC(np->n_fhp, nfsfh_t *, fhsize, M_NFSBIGFH, M_WAITOK); @@ -207,7 +218,8 @@ nfs_reclaim(v) if (prtactive && vp->v_usecount != 0) vprint("nfs_reclaim: pushing active", vp); - LIST_REMOVE(np, n_hash); + if (np->n_hash.le_prev != NULL) + LIST_REMOVE(np, n_hash); /* * For nqnfs, take it off the timer queue as required. |