ref: d52084c4ff60b1fe4e42141550fcad78e8135365
parent: 62590a88b490f6841ab68c5455c7ced0b1124a76
author: Michael Forney <[email protected]>
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);