summaryrefslogtreecommitdiff
path: root/sys/src/lib9p/srv.c
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 /sys/src/lib9p/srv.c
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.
Diffstat (limited to 'sys/src/lib9p/srv.c')
-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;
}