diff options
author | cinap_lenrek <cinap_lenrek@rei2.9hal> | 2012-02-08 00:00:42 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@rei2.9hal> | 2012-02-08 00:00:42 +0100 |
commit | 022fd02b9632b0ca3ddd9547730446dd222ab93d (patch) | |
tree | ec2f051174546017bf0a7cdc88004728c083bf4c /sys/src | |
parent | d970ed6a5a243c2ec69857b69382b79eaaad1e87 (diff) |
fix endless devwalk loops caused by genbuf truncation
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/port/devenv.c | 5 | ||||
-rw-r--r-- | sys/src/9/port/devshr.c | 18 | ||||
-rw-r--r-- | sys/src/9/port/devsrv.c | 39 |
3 files changed, 38 insertions, 24 deletions
diff --git a/sys/src/9/port/devenv.c b/sys/src/9/port/devenv.c index e93a95139..0bb26dcf8 100644 --- a/sys/src/9/port/devenv.c +++ b/sys/src/9/port/devenv.c @@ -48,7 +48,7 @@ envgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp) else if(s < eg->nent) e = eg->ent[s]; - if(e == 0) { + if(e == 0 || (strlen(e->name) >= sizeof(up->genbuf))) { runlock(eg); return -1; } @@ -147,6 +147,9 @@ envcreate(Chan *c, char *name, int omode, ulong) if(c->qid.type != QTDIR) error(Eperm); + if(strlen(name) >= sizeof(up->genbuf)) + error(Egreg); + omode = openmode(omode); eg = envgrp(c); diff --git a/sys/src/9/port/devshr.c b/sys/src/9/port/devshr.c index ddab43d0b..f6ef0ae9a 100644 --- a/sys/src/9/port/devshr.c +++ b/sys/src/9/port/devshr.c @@ -298,13 +298,13 @@ shrgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) sch = tosch(c); switch(sch->level){ default: - error(Egreg); + return -1; case Qroot: case Qcroot: qlock(&shrslk); for(shr = shrs; shr && s; shr = shr->next) s--; - if(shr == nil){ + if(shr == nil || (strlen(shr->name) >= sizeof(up->genbuf))){ qunlock(&shrslk); return -1; } @@ -323,11 +323,11 @@ shrgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) rlock(&h->lock); for(m = h->mount; m && s; m = m->next) s--; - if(m == nil){ + mpt = tompt(m); + if(m == nil || (strlen(mpt->name) >= sizeof(up->genbuf))){ runlock(&h->lock); return -1; } - mpt = tompt(m); kstrcpy(up->genbuf, mpt->name, sizeof up->genbuf); devdir(c, shrqid(Qcmpt, mpt->id), up->genbuf, 0, mpt->owner, mpt->perm, dp); runlock(&h->lock); @@ -460,7 +460,8 @@ shrcreate(Chan *c, char *name, int omode, ulong perm) case Qcroot: if((perm & DMDIR) == 0 || openmode(omode) != OREAD) error(Eperm); - + if(strlen(name) >= sizeof(up->genbuf)) + error(Egreg); qlock(&shrslk); if(waserror()){ qunlock(&shrslk); @@ -497,6 +498,9 @@ shrcreate(Chan *c, char *name, int omode, ulong perm) error(Eperm); devpermcheck(shr->owner, shr->perm, ORDWR); + if(strlen(name) >= sizeof(up->genbuf)) + error(Egreg); + h = &shr->umh; wlock(&h->lock); if(waserror()){ @@ -652,14 +656,14 @@ shrwstat(Chan *c, uchar *dp, int n) if(d.name && *d.name && strcmp(ent->name, d.name) != 0) { if(strchr(d.name, '/') != nil) error(Ebadchar); + if(strlen(d.name) >= sizeof(up->genbuf)) + error(Egreg); kstrdup(&ent->name, d.name); } poperror(); free(strs); switch(sch->level){ - default: - error(Egreg); case Qcshr: poperror(); qunlock(&shrslk); diff --git a/sys/src/9/port/devsrv.c b/sys/src/9/port/devsrv.c index 4426d1e00..adde67b9b 100644 --- a/sys/src/9/port/devsrv.c +++ b/sys/src/9/port/devsrv.c @@ -21,8 +21,18 @@ static QLock srvlk; static Srv *srv; static int qidpath; +static Srv* +srvlookup(char *name, ulong qidpath) +{ + Srv *sp; + for(sp = srv; sp; sp = sp->link) + if(sp->path == qidpath || (name && strcmp(sp->name, name) == 0)) + return sp; + return nil; +} + static int -srvgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) +srvgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp) { Srv *sp; Qid q; @@ -33,14 +43,16 @@ srvgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) } qlock(&srvlk); - for(sp = srv; sp && s; sp = sp->link) - s--; - - if(sp == 0) { + if(name) + sp = srvlookup(name, -1); + else { + for(sp = srv; sp && s; sp = sp->link) + s--; + } + if(sp == 0 || (strlen(sp->name) >= sizeof(up->genbuf))) { qunlock(&srvlk); return -1; } - mkqid(&q, sp->path, 0, QTFILE); /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); @@ -67,16 +79,6 @@ srvwalk(Chan *c, Chan *nc, char **name, int nname) return devwalk(c, nc, name, nname, 0, 0, srvgen); } -static Srv* -srvlookup(char *name, ulong qidpath) -{ - Srv *sp; - for(sp = srv; sp; sp = sp->link) - if(sp->path == qidpath || (name && strcmp(sp->name, name) == 0)) - return sp; - return nil; -} - static int srvstat(Chan *c, uchar *db, int n) { @@ -145,6 +147,9 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) if(openmode(omode) != OWRITE) error(Eperm); + if(strlen(name) >= sizeof(up->genbuf)) + error(Egreg); + sp = smalloc(sizeof *sp); sname = smalloc(strlen(name)+1); @@ -260,6 +265,8 @@ srvwstat(Chan *c, uchar *dp, int n) if(d.name && *d.name && strcmp(sp->name, d.name) != 0) { if(strchr(d.name, '/') != nil) error(Ebadchar); + if(strlen(d.name) >= sizeof(up->genbuf)) + error(Egreg); kstrdup(&sp->name, d.name); } qunlock(&srvlk); |