diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-09-19 05:22:26 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-09-19 05:22:26 +0200 |
commit | a1b2b9b126e540007ae51e128c457a8fc924b20f (patch) | |
tree | 33dd08662ec14b376f9cf4525c825f240ecf5747 /sys/src/lib9p | |
parent | 5d8300d2ebaaba3a648d25015cadd80ddd2d016e (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')
-rw-r--r-- | sys/src/lib9p/srv.c | 24 |
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; } |