summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-09-19 05:22:26 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2014-09-19 05:22:26 +0200
commita1b2b9b126e540007ae51e128c457a8fc924b20f (patch)
tree33dd08662ec14b376f9cf4525c825f240ecf5747
parent5d8300d2ebaaba3a648d25015cadd80ddd2d016e (diff)
lib9p: fix nil dereference crash in remove for directory permission check
file->parent can be nil when the file has been previously removed. removefile() deals with this, so skip the permission check in that case and let removefile() error out.
-rw-r--r--sys/src/lib9p/srv.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c
index 4b91b86ce..3f93ed9fb 100644
--- a/sys/src/lib9p/srv.c
+++ b/sys/src/lib9p/srv.c
@@ -365,6 +365,23 @@ rwalk(Req *r, char *error)
}
}
+static int
+dirwritable(Fid *fid)
+{
+ File *f;
+
+ f = fid->file;
+ if(f){
+ rlock(f);
+ if(f->parent && !hasperm(f->parent, fid->uid, AWRITE)){
+ runlock(f);
+ return 0;
+ }
+ runlock(f);
+ }
+ return 1;
+}
+
static void
sopen(Srv *srv, Req *r)
{
@@ -410,9 +427,7 @@ sopen(Srv *srv, Req *r)
respond(r, Eperm);
return;
}
- /* BUG RACE */
- if((r->ifcall.mode&ORCLOSE)
- && !hasperm(r->fid->file->parent, r->fid->uid, AWRITE)){
+ if((r->ifcall.mode&ORCLOSE) && !dirwritable(r->fid)){
respond(r, Eperm);
return;
}
@@ -574,8 +589,7 @@ sremove(Srv *srv, Req *r)
respond(r, Eunknownfid);
return;
}
- /* BUG RACE */
- if(r->fid->file && !hasperm(r->fid->file->parent, r->fid->uid, AWRITE)){
+ if(!dirwritable(r->fid)){
respond(r, Eperm);
return;
}