M gnot/trap.c => gnot/trap.c +4 -9
@@ 193,14 193,12 @@ notify(Ureg *ur)
u->svsr = ur->sr;
sp = ur->usp;
sp -= sizeof(Ureg);
- if(waserror()){
- pprint("suicide: trap in notify\n");
+ if(!okaddr((ulong)u->notify, 1, 0)
+ || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
+ pprint("suicide: bad address in notify\n");
qunlock(&u->p->debug);
pexit("Suicide", 0);
}
- validaddr((ulong)u->notify, 1, 0);
- validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0);
- poperror();
u->ureg = (void*)sp;
memmove((Ureg*)sp, ur, sizeof(Ureg));
sp -= ERRLEN;
@@ 246,14 244,11 @@ noted(Ureg *ur, ulong arg0)
memmove(ur, u->ureg, sizeof(Ureg));
switch(arg0){
case NCONT:
- if(waserror()){
+ if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
pprint("suicide: trap in noted\n");
qunlock(&u->p->debug);
goto Die;
}
- validaddr(nur->pc, 1, 0);
- validaddr(nur->usp, BY2WD, 0);
- poperror();
splhi();
qunlock(&u->p->debug);
rfnote(ur);
M pc/trap.c => pc/trap.c +4 -9
@@ 404,14 404,12 @@ notify(Ureg *ur)
u->svflags = ur->flags;
sp = ur->usp;
sp -= sizeof(Ureg);
- if(waserror()){
- pprint("suicide: trap in notify\n");
+ if(!okaddr((ulong)u->notify, 1, 0)
+ || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
+ pprint("suicide: bad address in notify\n");
qunlock(&u->p->debug);
pexit("Suicide", 0);
}
- validaddr((ulong)u->notify, 1, 0);
- validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0);
- poperror();
u->ureg = (void*)sp;
memmove((Ureg*)sp, ur, sizeof(Ureg));
sp -= ERRLEN;
@@ 459,14 457,11 @@ noted(Ureg *ur, ulong arg0)
memmove(ur, nur, sizeof(Ureg));
switch(arg0){
case NCONT:
- if(waserror()){
+ if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
pprint("suicide: trap in noted\n");
qunlock(&u->p->debug);
goto Die;
}
- validaddr(nur->pc, 1, 0); /* check for valid pc & usp */
- validaddr(nur->usp, BY2WD, 0);
- poperror();
qunlock(&u->p->debug);
return;
M port/fault.c => port/fault.c +13 -5
@@ 277,8 277,8 @@ faulterror(char *s)
/*
* Called only in a system call
*/
-void
-validaddr(ulong addr, ulong len, int write)
+int
+okaddr(ulong addr, ulong len, int write)
{
Segment *s;
@@ 293,12 293,20 @@ validaddr(ulong addr, ulong len, int write)
addr = s->top;
continue;
}
- return;
+ return 1;
}
}
+ pprint("suicide: invalid address 0x%lux in sys call pc=0x%.8lux\n", addr, userpc());
+ return 0;
+}
+
+void
+validaddr(ulong addr, ulong len, int write)
+{
+ Segment *s;
- pprint("invalid address 0x%lux in sys call pc=0x%lux", addr, userpc());
- error(Ebadarg);
+ if(!okaddr(addr, len, write))
+ pexit("Suicide", 0);
}
/*
M port/portfns.h => port/portfns.h +1 -0
@@ 147,6 147,7 @@ int nodelims(Stream*);
int notify(Ureg*);
int nrand(int);
void nullput(Queue*, Block*);
+int okaddr(ulong, ulong, int);
int openmode(ulong);
Block* padb(Block*, int);
void pageinit(void);
M power/trap.c => power/trap.c +4 -9
@@ 411,14 411,12 @@ notify(Ureg *ur)
u->svstatus = ur->status;
sp = ur->usp;
sp -= sizeof(Ureg);
- if(waserror()){
- pprint("suicide: trap in notify\n");
+ if(!okaddr((ulong)u->notify, 1, 0)
+ || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
+ pprint("suicide: bad address in notify\n");
qunlock(&u->p->debug);
pexit("Suicide", 0);
}
- validaddr((ulong)u->notify, 1, 0);
- validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0);
- poperror();
u->ureg = (void*)sp;
memmove((Ureg*)sp, ur, sizeof(Ureg));
sp -= ERRLEN;
@@ 465,14 463,11 @@ noted(Ureg **urp, ulong arg0)
(*urp)->r1 = u->svr1;
switch(arg0){
case NCONT:
- if(waserror()){
+ if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
pprint("suicide: trap in noted\n");
qunlock(&u->p->debug);
goto Die;
}
- validaddr(nur->pc, 1, 0);
- validaddr(nur->usp, BY2WD, 0);
- poperror();
splhi();
qunlock(&u->p->debug);
rfnote(urp);
M ss/trap.c => ss/trap.c +4 -9
@@ 263,14 263,12 @@ notify(Ureg *ur)
u->svpsr = ur->psr;
sp = ur->usp;
sp -= sizeof(Ureg);
- if(waserror()){
- pprint("suicide: trap in notify\n");
+ if(!okaddr((ulong)u->notify, 1, 0)
+ || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
+ pprint("suicide: bad address in notify\n");
qunlock(&u->p->debug);
pexit("Suicide", 0);
}
- validaddr((ulong)u->notify, 1, 0);
- validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0);
- poperror();
u->ureg = (void*)sp;
memmove((Ureg*)sp, ur, sizeof(Ureg));
sp -= ERRLEN;
@@ 319,14 317,11 @@ noted(Ureg **urp, ulong arg0)
(*urp)->r7 = u->svr7;
switch(arg0){
case NCONT:
- if(waserror()){
+ if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
pprint("suicide: trap in noted\n");
qunlock(&u->p->debug);
goto Die;
}
- validaddr(nur->pc, 1, 0);
- validaddr(nur->usp, BY2WD, 0);
- poperror();
splhi();
qunlock(&u->p->debug);
rfnote(urp);