From 7d3a3bf1bf5fce3f02b3106a694686c36064341b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 21 Aug 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-08-21 --- gnot/chan.c | 40 +++++++++++++++++++++++----------------- gnot/dev.c | 13 +++++-------- gnot/fault.c | 9 ++++++--- gnot/mem.h | 1 + gnot/sysfile.c | 3 ++- port/chan.c | 40 +++++++++++++++++++++++----------------- port/dev.c | 13 +++++-------- port/fault.c | 9 ++++++--- port/sysfile.c | 3 ++- power/mem.h | 2 +- 10 files changed, 74 insertions(+), 59 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index 496605e2199592f27e84dfe1e6a19c15fd14a070..8f759071cdb0c6919441d2b884367b17d3b516ec 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -432,10 +432,26 @@ namec(char *name, int amode, int omode, ulong perm) Chan *c, *nc; int t; int mntok, isdot; - char *elem = u->elem; + char *p; + char *elem; if(name[0] == 0) error(0, Enonexist); + + /* + * Make sure all of name is o.k. first byte is validated + * externally so if it's a kernel address we know it's o.k. + */ + if(!((ulong)name & KZERO)){ + p = name; + t = BY2PG-((ulong)p&(BY2PG-1)); + while(vmemchr(p, 0, t) == 0){ + p += t; + t = BY2PG; + } + } + + elem = u->elem; mntok = 1; isdot = 0; if(name[0] == '/'){ @@ -446,8 +462,6 @@ namec(char *name, int amode, int omode, ulong perm) name = skipslash(name); }else if(name[0] == '#'){ mntok = 0; - if(!((ulong)name & KZERO)) - validaddr((ulong)(name+1), 2, 0); if(name[1]=='|' || name[1]=='M') error(0, Enonexist); t = devno(name[1], 1); @@ -570,18 +584,11 @@ char* skipslash(char *name) { Again: - while(*name == '/'){ - if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) - validaddr((ulong)name+1, 1, 0); + while(*name == '/') name++; - } - if(*name == '.'){ - if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) - validaddr((ulong)name+1, 1, 0); - if(name[1]==0 || name[1]=='/'){ - name++; - goto Again; - } + if(*name=='.' && (name[1]==0 || name[1]=='/')){ + name++; + goto Again; } return name; } @@ -600,7 +607,6 @@ char isfrog[]={ * name[0] should not be a slash. * Advance name to next element in path, copying current element into elem. * Return pointer to next element, skipping slashes. - * &name[0] is known to be a valid address. */ char* nextelem(char *name, char *elem) @@ -610,9 +616,9 @@ nextelem(char *name, char *elem) if(*name == '/') error(0, Efilename); - end = vmemchr(name, 0, NAMELEN); + end = memchr(name, 0, NAMELEN); if(end == 0){ - end = vmemchr(name, '/', NAMELEN); + end = memchr(name, '/', NAMELEN); if(end == 0) error(0, Efilename); }else{ diff --git a/gnot/dev.c b/gnot/dev.c index ee50ff468959d001ab32abc344e25bea4be5ee9e..7e6c5cfc39d16315524fc245cd9ca31e5ca29dd6 100644 --- a/gnot/dev.c +++ b/gnot/dev.c @@ -143,16 +143,14 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) long devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) { - long k, l, m; + long k, m; Dir dir; k = c->offset/DIRLEN; - l = (c->offset+n)/DIRLEN; - n = 0; - for(m=k; moffset += DIRLEN; @@ -160,12 +158,11 @@ devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) case 1: convD2M(&dir, d); - n += DIRLEN; + m += DIRLEN; d += DIRLEN; - m++; break; } - return n; + return m; } Chan * diff --git a/gnot/fault.c b/gnot/fault.c index 69d3ad7a5f2c420724a3a8899a7b1d970d1864b5..f7486786c7d41e5ae5822f199601c1d33cd9a64b 100644 --- a/gnot/fault.c +++ b/gnot/fault.c @@ -104,7 +104,7 @@ fault(Ureg *ur, FFrame *f) exit(); } s = &u->p->seg[SSEG]; - if(s->o==0 || addrmaxva-4*1024*1024 || addr>=s->maxva) + if(s->o==0 || addrmaxva-USTACKSIZE || addr>=s->maxva) goto cant; /* grow stack */ o = s->o; @@ -296,8 +296,11 @@ validaddr(ulong addr, ulong len, int write) } Again: s = seg(u->p, addr); - if(s==0) - goto Err; + if(s==0){ + s = &u->p->seg[SSEG]; + if(s->o==0 || addrmaxva-USTACKSIZE || addr>=s->maxva) + goto Err; + } if(write && (s->o->flag&OWRPERM)==0) goto Err; if(addr+len > s->maxva){ diff --git a/gnot/mem.h b/gnot/mem.h index 71c8c23fedda73f91652ecac1e2f6f5a28f52677..6311cf2c1751505c1f368e0fdc7466a829b06255 100644 --- a/gnot/mem.h +++ b/gnot/mem.h @@ -95,6 +95,7 @@ #define USTKTOP (TSTKTOP-100*BY2PG) /* byte just beyond user stack */ #define KZERO KSEG /* base of kernel address space */ #define KTZERO (KZERO+BY2PG) /* first address in kernel text */ +#define USTACKSIZE (4*1024*1024) /* size of user stack */ #define NSEG 5 #define MACHSIZE 4096 diff --git a/gnot/sysfile.c b/gnot/sysfile.c index 4062f883ad458ee3efe3c203121a59f0b854a06f..532ce3990da24ad7b3420986b79777b94f86edce 100644 --- a/gnot/sysfile.c +++ b/gnot/sysfile.c @@ -148,6 +148,7 @@ unionread(Chan *c, void *va, long n) nc = (*devtab[nc->type].open)(nc, OREAD); nc->offset = c->offset; nr = (*devtab[nc->type].read)(nc, va, n); + c->offset = nc->offset; /* devdirread e.g. changes it */ close(nc); poperror(); if(nr > 0) @@ -192,7 +193,7 @@ sysread(ulong *arg) if(c->offset%DIRLEN || n==0) error(0, Ebaddirread); } - if((c->qid&CHDIR) && c->flag&CMOUNT) + if((c->qid&CHDIR) && (c->flag&CMOUNT)) n = unionread(c, (void*)arg[1], n); else n = (*devtab[c->type].read)(c, (void*)arg[1], n); diff --git a/port/chan.c b/port/chan.c index 496605e2199592f27e84dfe1e6a19c15fd14a070..8f759071cdb0c6919441d2b884367b17d3b516ec 100644 --- a/port/chan.c +++ b/port/chan.c @@ -432,10 +432,26 @@ namec(char *name, int amode, int omode, ulong perm) Chan *c, *nc; int t; int mntok, isdot; - char *elem = u->elem; + char *p; + char *elem; if(name[0] == 0) error(0, Enonexist); + + /* + * Make sure all of name is o.k. first byte is validated + * externally so if it's a kernel address we know it's o.k. + */ + if(!((ulong)name & KZERO)){ + p = name; + t = BY2PG-((ulong)p&(BY2PG-1)); + while(vmemchr(p, 0, t) == 0){ + p += t; + t = BY2PG; + } + } + + elem = u->elem; mntok = 1; isdot = 0; if(name[0] == '/'){ @@ -446,8 +462,6 @@ namec(char *name, int amode, int omode, ulong perm) name = skipslash(name); }else if(name[0] == '#'){ mntok = 0; - if(!((ulong)name & KZERO)) - validaddr((ulong)(name+1), 2, 0); if(name[1]=='|' || name[1]=='M') error(0, Enonexist); t = devno(name[1], 1); @@ -570,18 +584,11 @@ char* skipslash(char *name) { Again: - while(*name == '/'){ - if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) - validaddr((ulong)name+1, 1, 0); + while(*name == '/') name++; - } - if(*name == '.'){ - if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) - validaddr((ulong)name+1, 1, 0); - if(name[1]==0 || name[1]=='/'){ - name++; - goto Again; - } + if(*name=='.' && (name[1]==0 || name[1]=='/')){ + name++; + goto Again; } return name; } @@ -600,7 +607,6 @@ char isfrog[]={ * name[0] should not be a slash. * Advance name to next element in path, copying current element into elem. * Return pointer to next element, skipping slashes. - * &name[0] is known to be a valid address. */ char* nextelem(char *name, char *elem) @@ -610,9 +616,9 @@ nextelem(char *name, char *elem) if(*name == '/') error(0, Efilename); - end = vmemchr(name, 0, NAMELEN); + end = memchr(name, 0, NAMELEN); if(end == 0){ - end = vmemchr(name, '/', NAMELEN); + end = memchr(name, '/', NAMELEN); if(end == 0) error(0, Efilename); }else{ diff --git a/port/dev.c b/port/dev.c index ee50ff468959d001ab32abc344e25bea4be5ee9e..7e6c5cfc39d16315524fc245cd9ca31e5ca29dd6 100644 --- a/port/dev.c +++ b/port/dev.c @@ -143,16 +143,14 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) long devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) { - long k, l, m; + long k, m; Dir dir; k = c->offset/DIRLEN; - l = (c->offset+n)/DIRLEN; - n = 0; - for(m=k; moffset += DIRLEN; @@ -160,12 +158,11 @@ devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) case 1: convD2M(&dir, d); - n += DIRLEN; + m += DIRLEN; d += DIRLEN; - m++; break; } - return n; + return m; } Chan * diff --git a/port/fault.c b/port/fault.c index 9ae89c8ab25064c43eb9f3e02dc092aaa4453708..7143eec772946034d3e5ba817d33aab6f2f7b5ba 100644 --- a/port/fault.c +++ b/port/fault.c @@ -38,7 +38,7 @@ fault(Ureg *ur, int user, int code) panic("fault"); } s = &u->p->seg[SSEG]; - if(s->o==0 || addrmaxva-4*1024*1024 || addr>=s->maxva) + if(s->o==0 || addrmaxva-USTACKSIZE || addr>=s->maxva) goto cant; /* grow stack */ o = s->o; @@ -223,8 +223,11 @@ validaddr(ulong addr, ulong len, int write) } Again: s = seg(u->p, addr); - if(s==0) - goto Err; + if(s==0){ + s = &u->p->seg[SSEG]; + if(s->o==0 || addrmaxva-USTACKSIZE || addr>=s->maxva) + goto Err; + } if(write && (s->o->flag&OWRPERM)==0) goto Err; if(addr+len > s->maxva){ diff --git a/port/sysfile.c b/port/sysfile.c index 4062f883ad458ee3efe3c203121a59f0b854a06f..532ce3990da24ad7b3420986b79777b94f86edce 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -148,6 +148,7 @@ unionread(Chan *c, void *va, long n) nc = (*devtab[nc->type].open)(nc, OREAD); nc->offset = c->offset; nr = (*devtab[nc->type].read)(nc, va, n); + c->offset = nc->offset; /* devdirread e.g. changes it */ close(nc); poperror(); if(nr > 0) @@ -192,7 +193,7 @@ sysread(ulong *arg) if(c->offset%DIRLEN || n==0) error(0, Ebaddirread); } - if((c->qid&CHDIR) && c->flag&CMOUNT) + if((c->qid&CHDIR) && (c->flag&CMOUNT)) n = unionread(c, (void*)arg[1], n); else n = (*devtab[c->type].read)(c, (void*)arg[1], n); diff --git a/power/mem.h b/power/mem.h index fd5622c01840b0e005b81ba15e9c4d95bd53e70d..b344341aa5bd8e3529bf261fbd702797e69fcb8f 100644 --- a/power/mem.h +++ b/power/mem.h @@ -110,7 +110,7 @@ #define TSTKTOP (USERADDR+100*BY2PG) /* top of temporary stack */ #define KZERO KSEG0 /* base of kernel address space */ #define KTZERO (KSEG0+0x20000) /* first address in kernel text */ - +#define USTACKSIZE (4*1024*1024) /* size of user stack */ /* * Exception codes */