ref: 4364b71cccf8353dc8f65a5e0db4041f6a0a1e53
parent: 1a73b594e684623c9ea1b72141f4e70ee913740b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jan 20 12:26:39 EST 2024
kernel: make trap() handlers consistent and check for stack overflow in kenter() for all archs
--- a/sys/src/9/arm64/trap.c
+++ b/sys/src/9/arm64/trap.c
@@ -226,7 +226,6 @@
}
if(scallnr >= nsyscall || systab[scallnr] == nil){
- pprint("bad sys call number %lud pc %#p", scallnr, ureg->pc);
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
--- a/sys/src/9/bcm/trap.c
+++ b/sys/src/9/bcm/trap.c
@@ -136,20 +136,6 @@
uintptr va;
char buf[ERRMAX];
- assert(!islo());
- if(up != nil)
- rem = ((char*)ureg)-((char*)up - KSTACK);
- else
- rem = ((char*)ureg)-((char*)m+sizeof(Mach));
- if(rem < 256) {
- iprint("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux\n",
- rem, up, ureg, ureg->pc);
- delay(1000);
- dumpstack();
- panic("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux",
- rem, up, ureg, ureg->pc);
- }
-
user = kenter(ureg);
/*
* All interrupts/exceptions should be resumed at ureg->pc-4,
--- a/sys/src/9/cycv/trap.c
+++ b/sys/src/9/cycv/trap.c
@@ -237,8 +237,7 @@
startns = todget(nil);
}
- if(scallnr >= nsyscall || systab[scallnr] == 0){
- pprint("bad sys call number %lud pc %lux", scallnr, ureg->pc);
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
@@ -272,14 +271,14 @@
if(scallnr == NOTED)
noted(ureg, *((ulong *) up->s.args));
- if(scallnr != RFORK && (up->procctl || up->nnote)){
- splhi();
+ splhi();
+ if(scallnr != RFORK && (up->procctl || up->nnote))
notify(ureg);
- }
- if(up->delaysched)
+ if(up->delaysched){
sched();
+ splhi();
+ }
kexit(ureg);
- splhi();
}
int
--- a/sys/src/9/kw/syscall.c
+++ b/sys/src/9/kw/syscall.c
@@ -188,16 +188,11 @@
splx(s);
startns = todget(nil);
}
- if(scallnr >= nsyscall){
- pprint("bad sys call number %d pc %#lux\n",
- scallnr, ureg->pc);
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
up->psstate = sysctab[scallnr];
-
- /* iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */
-
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
--- a/sys/src/9/kw/trap.c
+++ b/sys/src/9/kw/trap.c
@@ -193,6 +193,7 @@
Handler *h;
Irq irq;
+ m->perf.intrts = perfticks();
clockintr = 0;
assert(sort >= 0 && sort < nelem(irqs));
@@ -369,16 +370,6 @@
u32int fsr;
uintptr va;
char buf[ERRMAX];
-
- if(up != nil)
- rem = (char*)ureg - ((char*)up - KSTACK);
- else
- rem = (char*)ureg - ((char*)m + sizeof(Mach));
- if(rem < 256) {
- dumpstack();
- panic("trap %d bytes remaining, up %#p ureg %#p at pc %#lux",
- rem, up, ureg, ureg->pc);
- }
user = kenter(ureg);
if(ureg->type == PsrMabt+1)
--- a/sys/src/9/mt7688/syscall.c
+++ b/sys/src/9/mt7688/syscall.c
@@ -42,17 +42,12 @@
ret = -1;
if(!waserror()){
+ if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)))
+ validaddr(sp, sizeof(Sargs), 0);
- if(scallnr >= nsyscall){
- iprint("bad sys call number %lud pc %#lux\n",
- scallnr, ureg->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
+ up->s = *((Sargs*)(sp)); /* spim's libc is different to mips ... */
if(up->procctl == Proc_tracesyscall){
- iprint("tracesyscall\n");
- delay(50);
syscallfmt(scallnr, ureg->pc, (va_list)up->s.args);
s = splhi();
up->procctl = Proc_stopme;
@@ -61,16 +56,11 @@
startns = todget(nil);
}
- if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)))
- validaddr(sp, sizeof(Sargs), 0);
-
- up->s = *((Sargs*)(sp)); /* spim's libc is different to mips ... */
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
up->psstate = sysctab[scallnr];
-
-// iprint("[%luX] %s: syscall %s\n", (ulong)&ureg, up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?");
-// delay(20);
-// dumpregs(ureg);
-
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
@@ -120,6 +110,7 @@
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched){
sched();
+ splhi();
}
kexit(ureg);
--- a/sys/src/9/mt7688/trap.c
+++ b/sys/src/9/mt7688/trap.c
@@ -152,19 +152,6 @@
char buf[2*ERRMAX], buf1[ERRMAX], *fpexcep;
static int dumps;
- if (up && (char *)(ur) - ((char *)up - KSTACK) < 1024 && dumps++ == 0) {
- iprint("trap: proc %ld kernel stack getting full\n", up->pid);
- dumpregs(ur);
- dumpstack();
- for(;;);
- }
- if (up == nil &&
- (char *)(ur) - (char *)m->stack < 1024 && dumps++ == 0) {
- iprint("trap: cpu%d kernel stack getting full\n", m->machno);
- dumpregs(ur);
- dumpstack();
- for(;;);
- }
user = kenter(ur);
if (ur->cause & TS)
panic("trap: tlb shutdown");
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -613,18 +613,16 @@
up->nerrlab = 0;
ret = -1;
if(!waserror()){
- if(scallnr >= nsyscall || systab[scallnr] == nil){
- pprint("bad sys call number %d pc %lux\n", scallnr, ureg->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
validaddr(sp, sizeof(Sargs)+BY2WD, 0);
up->s = *((Sargs*)(sp+BY2WD));
- up->psstate = sysctab[scallnr];
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
+ up->psstate = sysctab[scallnr];
ret = systab[scallnr](up->s.args);
poperror();
}else{
--- a/sys/src/9/omap/syscall.c
+++ b/sys/src/9/omap/syscall.c
@@ -181,21 +181,15 @@
up->nerrlab = 0;
ret = -1;
if(!waserror()){
- if(scallnr >= nsyscall){
- pprint("bad sys call number %d pc %#lux\n",
- scallnr, ureg->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
validaddr(sp, sizeof(Sargs)+BY2WD, 0);
up->s = *((Sargs*)(sp+BY2WD));
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
up->psstate = sysctab[scallnr];
-
- /* iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */
-
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
--- a/sys/src/9/omap/trap.c
+++ b/sys/src/9/omap/trap.c
@@ -451,20 +451,6 @@
uintptr va;
char buf[ERRMAX];
- splhi(); /* paranoia */
- if(up != nil)
- rem = ((char*)ureg)-((char*)up-KSTACK);
- else
- rem = ((char*)ureg)-((char*)m+sizeof(Mach));
- if(rem < 1024) {
- iprint("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux\n",
- rem, up, ureg, ureg->pc);
- delay(1000);
- dumpstack();
- panic("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux",
- rem, up, ureg, ureg->pc);
- }
-
user = kenter(ureg);
/*
* All interrupts/exceptions should be resumed at ureg->pc-4,
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -382,14 +382,11 @@
static void
debugbpt(Ureg* ureg, void*)
{
- char buf[ERRMAX];
-
if(up == 0)
panic("kernel bpt");
/* restore pc to instruction that caused the trap */
ureg->pc--;
- sprint(buf, "sys: breakpoint");
- postnote(up, 1, buf, NDebug);
+ postnote(up, 1, "sys: breakpoint", NDebug);
}
static void
@@ -500,9 +497,7 @@
startns = todget(nil);
}
- if(scallnr >= nsyscall || systab[scallnr] == 0){
- pprint("bad sys call number %lud pc %lux\n",
- scallnr, ureg->pc);
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
@@ -548,13 +543,14 @@
if(scallnr == NOTED)
noted(ureg, *((ulong*)up->s.args));
- if(scallnr!=RFORK && (up->procctl || up->nnote)){
- splhi();
+ splhi();
+ if(scallnr!=RFORK && (up->procctl || up->nnote))
notify(ureg);
- }
/* if we delayed sched because we held a lock, sched now */
- if(up->delaysched)
+ if(up->delaysched){
sched();
+ splhi();
+ }
kexit(ureg);
}
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -111,6 +111,19 @@
if(user){
up->dbgreg = ureg;
cycles(&up->kentry);
+ } else {
+ int rem;
+
+ if((uchar*)&ureg < (uchar*)ureg){
+ /* stack grows down */
+ rem = (int)((uintptr)ureg - (up!=nil? (uintptr)up - KSTACK: (uintptr)m->stack));
+ } else {
+ /* stack grows up */
+ rem = (int)((up!=nil? (uintptr)up: (uintptr)m + MACHSIZE) - (uintptr)ureg);
+ }
+ if(rem < 256)
+ panic("kenter: %d stack bytes left, up %#p ureg %#p at pc %#p",
+ rem, up, ureg, ureg->pc);
}
return user;
}
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -282,9 +282,6 @@
splhi();
if(user) {
- if (up->fpstate == FPactive && (ureg->srr1 & MSR_FP) == 0){
- postnote(up, 1, buf, NDebug);
- }
notify(ureg);
if(up->fpstate != FPactive)
ureg->srr1 &= ~MSR_FP;
@@ -600,18 +597,15 @@
up->nerrlab = 0;
ret = -1;
if(!waserror()){
- if(scallnr >= nsyscall || systab[scallnr] == nil){
- pprint("bad sys call number %d pc %lux\n", scallnr, ureg->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
validaddr(sp, sizeof(Sargs)+BY2WD, 0);
up->s = *((Sargs*)(sp+BY2WD));
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
up->psstate = sysctab[scallnr];
-
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -158,21 +158,7 @@
int ecode, user, cop, x, fpchk;
ulong fpfcr31;
char buf[2*ERRMAX], buf1[ERRMAX], *fpexcep;
- static int dumps;
- if (up && (char *)(ur) - ((char *)up - KSTACK) < 1024 && dumps++ == 0) {
- iprint("trap: proc %ld kernel stack getting full\n", up->pid);
- dumpregs(ur);
- dumpstack();
- for(;;);
- }
- if (up == nil &&
- (char *)(ur) - (char *)m->stack < 1024 && dumps++ == 0) {
- iprint("trap: cpu%d kernel stack getting full\n", m->machno);
- dumpregs(ur);
- dumpstack();
- for(;;);
- }
user = kenter(ur);
if (ur->cause & TS)
panic("trap: tlb shutdown");
@@ -662,16 +648,7 @@
up->nerrlab = 0;
ret = -1;
if(!waserror()) {
- if(scallnr >= nsyscall || systab[scallnr] == 0){
- pprint("bad sys call number %ld pc %#lux\n",
- scallnr, ur->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
if(sp & (BY2WD-1)){
- pprint("odd sp in sys call pc %#lux sp %#lux\n",
- ur->pc, ur->sp);
postnote(up, 1, "sys: odd stack", NDebug);
error(Ebadarg);
}
@@ -680,6 +657,10 @@
validaddr(sp, sizeof(Sargs)+BY2WD, 0);
up->s = *((Sargs*)(sp+BY2WD));
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
up->psstate = sysctab[scallnr];
ret = systab[scallnr]((va_list)up->s.args);
@@ -714,8 +695,10 @@
if(scallnr!=RFORK && (up->procctl || up->nnote))
notify(ur);
/* if we delayed sched because we held a lock, sched now */
- if(up->delaysched)
+ if(up->delaysched){
sched();
+ splhi();
+ }
/* replicate fpstate to ureg status */
if(up->fpstate != FPactive)
ur->status &= ~CU1;
--- a/sys/src/9/teg2/syscall.c
+++ b/sys/src/9/teg2/syscall.c
@@ -206,21 +206,15 @@
l1cache->wb(); /* system is more stable with this */
if(!waserror()){
- if(scallnr >= nsyscall){
- pprint("bad sys call number %d pc %#lux\n",
- scallnr, ureg->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
validaddr(sp, sizeof(Sargs)+BY2WD, 0);
up->s = *((Sargs*)(sp+BY2WD));
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
up->psstate = sysctab[scallnr];
-
- /* iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */
-
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
--- a/sys/src/9/teg2/trap.c
+++ b/sys/src/9/teg2/trap.c
@@ -633,12 +633,12 @@
irq(Ureg* ureg)
{
int clockintr, ack;
- uint irqno, handled, t, ticks;
+ uint irqno, handled;
Intrcpuregs *icp = (Intrcpuregs *)soc.intr;
Vctl *v;
m->intr++;
- ticks = perfticks();
+ m->perf.intrts = perfticks();
handled = 0;
ack = intack(icp);
irqno = ack & Intrmask;
@@ -677,17 +677,6 @@
iprint("cpu%d: unexpected interrupt %d, now masked\n",
m->machno, irqno);
}
- t = perfticks();
- if (0) { /* left over from another port? */
- ilock(&nintrlock);
- ninterrupt++;
- if(t < ticks)
- ninterruptticks += ticks-t;
- else
- ninterruptticks += t-ticks;
- iunlock(&nintrlock);
- }
- USED(t, ticks);
clockintr = m->inclockintr == 1;
if (irqno == Loctmrirq)
m->inclockintr--;
@@ -818,20 +807,6 @@
int user, rem;
uintptr va, ifar, ifsr;
- splhi(); /* paranoia */
- if(up != nil)
- rem = ((char*)ureg)-((char*)up-KSTACK);
- else
- rem = ((char*)ureg)-((char*)m+sizeof(Mach));
- if(rem < 1024) {
- iprint("trap: %d stack bytes left, up %#p ureg %#p m %#p cpu%d at pc %#lux\n",
- rem, up, ureg, m, m->machno, ureg->pc);
- dumpstackwithureg(ureg);
- panic("trap: %d stack bytes left, up %#p ureg %#p at pc %#lux",
- rem, up, ureg, ureg->pc);
- }
-
- m->perf.intrts = perfticks();
user = kenter(ureg);
/*
* All interrupts/exceptions should be resumed at ureg->pc-4,
--- a/sys/src/9/xen/trap.c
+++ b/sys/src/9/xen/trap.c
@@ -303,15 +303,11 @@
static void
debugbpt(Ureg* ureg, void*)
{
- char buf[ERRMAX];
- print("debugbpt\n");
if(up == 0)
panic("kernel bpt");
/* restore pc to instruction that caused the trap */
ureg->pc--;
- sprint(buf, "sys: breakpoint");
- postnote(up, 1, buf, NDebug);
- print("debugbpt for proc %lud\n", up->pid);
+ postnote(up, 1, "sys: breakpoint", NDebug);
}
static void
@@ -409,19 +405,16 @@
up->nerrlab = 0;
ret = -1;
if(!waserror()){
- if(scallnr >= nsyscall || systab[scallnr] == 0){
- pprint("bad sys call number %lud pc %lux\n",
- scallnr, ureg->pc);
- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
validaddr(sp, sizeof(Sargs)+BY2WD, 0);
up->s = *((Sargs*)(sp+BY2WD));
- up->psstate = sysctab[scallnr];
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
+ postnote(up, 1, "sys: bad sys call", NDebug);
+ error(Ebadarg);
+ }
+ up->psstate = sysctab[scallnr];
ret = systab[scallnr]((va_list)up->s.args);
poperror();
}else{
@@ -462,13 +455,14 @@
if(scallnr == NOTED)
noted(ureg, *(ulong*)(sp+BY2WD));
- if(scallnr!=RFORK && (up->procctl || up->nnote)){
- splhi();
+ splhi();
+ if(scallnr!=RFORK && (up->procctl || up->nnote))
notify(ureg);
- }
/* if we delayed sched because we held a lock, sched now */
- if(up->delaysched)
+ if(up->delaysched){
sched();
+ splhi();
+ }
INTRLOG(dprint("before kexit\n");)
kexit(ureg);
}
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -236,9 +236,7 @@
splx(s);
startns = todget(nil);
}
-
- if(scallnr >= nsyscall || systab[scallnr] == 0){
- pprint("bad sys call number %lud pc %lux", scallnr, ureg->pc);
+ if(scallnr >= nsyscall || systab[scallnr] == nil){
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
@@ -272,14 +270,14 @@
if(scallnr == NOTED)
noted(ureg, *((ulong *) up->s.args));
- if(scallnr != RFORK && (up->procctl || up->nnote)){
- splhi();
+ splhi();
+ if(scallnr != RFORK && (up->procctl || up->nnote))
notify(ureg);
- }
- if(up->delaysched)
+ if(up->delaysched){
sched();
+ splhi();
+ }
kexit(ureg);
- splhi();
}
int