M gnot/chan.c => gnot/chan.c +23 -17
@@ 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{
M gnot/dev.c => gnot/dev.c +5 -8
@@ 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; m<l; k++)
+ for(m=0; m<n; k++)
switch((*gen)(c, tab, ntab, k, &dir)){
case -1:
- return n;
+ return m;
case 0:
c->offset += 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 *
M gnot/fault.c => gnot/fault.c +6 -3
@@ 104,7 104,7 @@ fault(Ureg *ur, FFrame *f)
exit();
}
s = &u->p->seg[SSEG];
- if(s->o==0 || addr<s->maxva-4*1024*1024 || addr>=s->maxva)
+ if(s->o==0 || addr<s->maxva-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 || addr<s->maxva-USTACKSIZE || addr>=s->maxva)
+ goto Err;
+ }
if(write && (s->o->flag&OWRPERM)==0)
goto Err;
if(addr+len > s->maxva){
M gnot/mem.h => gnot/mem.h +1 -0
@@ 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
M gnot/sysfile.c => gnot/sysfile.c +2 -1
@@ 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);
M port/chan.c => port/chan.c +23 -17
@@ 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{
M port/dev.c => port/dev.c +5 -8
@@ 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; m<l; k++)
+ for(m=0; m<n; k++)
switch((*gen)(c, tab, ntab, k, &dir)){
case -1:
- return n;
+ return m;
case 0:
c->offset += 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 *
M port/fault.c => port/fault.c +6 -3
@@ 38,7 38,7 @@ fault(Ureg *ur, int user, int code)
panic("fault");
}
s = &u->p->seg[SSEG];
- if(s->o==0 || addr<s->maxva-4*1024*1024 || addr>=s->maxva)
+ if(s->o==0 || addr<s->maxva-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 || addr<s->maxva-USTACKSIZE || addr>=s->maxva)
+ goto Err;
+ }
if(write && (s->o->flag&OWRPERM)==0)
goto Err;
if(addr+len > s->maxva){
M port/sysfile.c => port/sysfile.c +2 -1
@@ 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);
M power/mem.h => power/mem.h +1 -1
@@ 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
*/