summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-06-05 05:26:36 +0000
committerpeter <peter@FreeBSD.org>1999-06-05 05:26:36 +0000
commit06a6a667a6bf7a90688c9b4f6a3bac0a4f01a1c6 (patch)
tree8ba2f46dfc52862d028e863eeae51775f5a5452b
parent486459045470f6c024b357b301ce2f043f1b4eab (diff)
downloadFreeBSD-src-06a6a667a6bf7a90688c9b4f6a3bac0a4f01a1c6.zip
FreeBSD-src-06a6a667a6bf7a90688c9b4f6a3bac0a4f01a1c6.tar.gz
Fix a malloc race
Obtained from: OpenBSD (csapuntz)
-rw-r--r--sys/nfs/nfs_node.c15
-rw-r--r--sys/nfsclient/nfs_node.c15
2 files changed, 24 insertions, 6 deletions
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c
index 4c01d6f..c3958c0 100644
--- a/sys/nfs/nfs_node.c
+++ b/sys/nfs/nfs_node.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_node.c 8.6 (Berkeley) 5/22/95
- * $Id: nfs_node.c,v 1.27 1998/05/24 14:41:49 peter Exp $
+ * $Id: nfs_node.c,v 1.28 1998/09/29 23:15:25 mckusick Exp $
*/
@@ -107,12 +107,13 @@ nfs_nget(mntp, fhp, fhsize, npp)
struct nfsnode **npp;
{
struct proc *p = curproc; /* XXX */
- struct nfsnode *np;
+ struct nfsnode *np, *np2;
struct nfsnodehashhead *nhpp;
register struct vnode *vp;
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) {
@@ -161,6 +162,13 @@ 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 (mntp != NFSTOV(np)->v_mount || np2->n_fhsize != 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);
@@ -248,7 +256,8 @@ nfs_reclaim(ap)
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.
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 4c01d6f..c3958c0 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_node.c 8.6 (Berkeley) 5/22/95
- * $Id: nfs_node.c,v 1.27 1998/05/24 14:41:49 peter Exp $
+ * $Id: nfs_node.c,v 1.28 1998/09/29 23:15:25 mckusick Exp $
*/
@@ -107,12 +107,13 @@ nfs_nget(mntp, fhp, fhsize, npp)
struct nfsnode **npp;
{
struct proc *p = curproc; /* XXX */
- struct nfsnode *np;
+ struct nfsnode *np, *np2;
struct nfsnodehashhead *nhpp;
register struct vnode *vp;
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) {
@@ -161,6 +162,13 @@ 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 (mntp != NFSTOV(np)->v_mount || np2->n_fhsize != 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);
@@ -248,7 +256,8 @@ nfs_reclaim(ap)
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.
OpenPOWER on IntegriCloud