diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-06-13 12:43:15 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-06-13 12:43:15 +0200 |
commit | 1473e5d437e12c7312a859bcdfc167284ca99a4e (patch) | |
tree | f75da5ca473332f66b07f19862aa5a301a5c3910 /sys | |
parent | f92057cc3928015d676e77e846104741d8e43b05 (diff) |
lib9p: fix lib9p wstat qid.type/mode checks (fixes lock(1) for ramfs/hjfs)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/src/cmd/ramfs.c | 10 | ||||
-rw-r--r-- | sys/src/lib9p/srv.c | 37 |
2 files changed, 24 insertions, 23 deletions
diff --git a/sys/src/cmd/ramfs.c b/sys/src/cmd/ramfs.c index 1408f07d8..8d0a8624c 100644 --- a/sys/src/cmd/ramfs.c +++ b/sys/src/cmd/ramfs.c @@ -335,14 +335,8 @@ fswstat(Req *r) } if(r->d.mode != ~0){ - f->mode = (r->d.mode & ~DMDIR) | (f->mode & DMDIR); - f->qid.type = 0; - if(f->mode & DMDIR) - f->qid.type |= QTDIR; - if(f->mode & DMAPPEND) - f->qid.type |= QTAPPEND; - if(f->mode & DMEXCL) - f->qid.type |= QTEXCL; + f->mode = r->d.mode; + f->qid.type = f->mode >> 24; } if(r->d.name[0] != '\0'){ free(f->name); diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c index 3f93ed9fb..d173f92b0 100644 --- a/sys/src/lib9p/srv.c +++ b/sys/src/lib9p/srv.c @@ -682,25 +682,32 @@ swstat(Srv *srv, Req *r) respond(r, Ebaddir); return; } - if(r->d.type != (ushort)~0){ - respond(r, "wstat -- attempt to change type"); + if(r->d.qid.path != ~0 && r->d.qid.path != r->fid->qid.path){ + respond(r, "wstat -- attempt to change qid.path"); return; } - if(r->d.dev != ~0){ - respond(r, "wstat -- attempt to change dev"); + if(r->d.qid.vers != ~0 && r->d.qid.vers != r->fid->qid.vers){ + respond(r, "wstat -- attempt to change qid.vers"); return; } - if(r->d.qid.type != (uchar)~0 || r->d.qid.vers != ~0 || r->d.qid.path != ~0){ - respond(r, "wstat -- attempt to change qid"); - return; - } - if(r->d.muid && r->d.muid[0]){ - respond(r, "wstat -- attempt to change muid"); - return; - } - if(r->d.mode != ~0 && ((r->d.mode&DMDIR)>>24) != (r->fid->qid.type&QTDIR)){ - respond(r, "wstat -- attempt to change DMDIR bit"); - return; + if(r->d.mode != ~0){ + if(r->d.mode & ~(DMDIR|DMAPPEND|DMEXCL|DMTMP|0777)){ + respond(r, "wstat -- unknown bits in mode"); + return; + } + if(r->d.qid.type != (uchar)~0 && r->d.qid.type != ((r->d.mode>>24)&0xFF)){ + respond(r, "wstat -- qid.type/mode mismatch"); + return; + } + if(((r->d.mode>>24) ^ r->fid->qid.type) & ~(QTAPPEND|QTEXCL|QTTMP)){ + respond(r, "wstat -- attempt to change qid.type"); + return; + } + } else { + if(r->d.qid.type != (uchar)~0 && r->d.qid.type != r->fid->qid.type){ + respond(r, "wstat -- attempt to change qid.type"); + return; + } } srv->wstat(r); } |