shithub: gefs

Download patch

ref: d52084c4ff60b1fe4e42141550fcad78e8135365
parent: 62590a88b490f6841ab68c5455c7ced0b1124a76
author: Michael Forney <mforney@mforney.org>
date: Tue Mar 1 15:32:24 EST 2022

fs: fix invalid Dent created with partial walk

If we walked some number of components, but not the full path, we
do not need the Dent. Calling getdent here leaks a reference, and
may potentially create an invalid Dent in memory.

d.name, backed by kvbuf, may have been overwritten during a btlookup
that encounters an Oinsert followed by Odelete. If there are no
other references to the Dent for the last successful wname, this
results in the creation and leak of a Dent with an incorrect pqid-name
pair, breaking subsequent walks to that wname.

--- a/fs.c
+++ b/fs.c
@@ -870,7 +870,7 @@
 		}
 		putfid(o);
 	}
-	if(i > 0){
+	if(i > 0 && i == m->nwname){
 		dent = getdent(up, &d);
 		if(dent == nil){
 			if(f != o)
@@ -879,14 +879,12 @@
 			putfid(f);
 			return;
 		}
-		if(i == m->nwname){
-			f->qpath = r.wqid[i-1].path;
-			f->pqpath = up;
-			f->dent = dent;
-			f->duid = duid;
-			f->dgid = dgid;
-			f->dmode = dmode;
-		}
+		f->qpath = r.wqid[i-1].path;
+		f->pqpath = up;
+		f->dent = dent;
+		f->duid = duid;
+		f->dgid = dgid;
+		f->dmode = dmode;
 	}
 	respond(m, &r);
 	putfid(f);