diff options
author | grehan <grehan@FreeBSD.org> | 2004-07-23 05:33:24 +0000 |
---|---|---|
committer | grehan <grehan@FreeBSD.org> | 2004-07-23 05:33:24 +0000 |
commit | aa7eec1b492ac8e2f8e78f641829f125fb5b4531 (patch) | |
tree | 1a1bf3d446fdccbab2d2c23181b65f1908ee9fcb /sys/powerpc | |
parent | 64ddaac9c398132c954ed925d9b1b5595c0aedba (diff) | |
download | FreeBSD-src-aa7eec1b492ac8e2f8e78f641829f125fb5b4531.zip FreeBSD-src-aa7eec1b492ac8e2f8e78f641829f125fb5b4531.tar.gz |
Detect kernel stack excursion into guard pages. Drop into KDB
with a wired stack if this is found.
Mostly obtained from: NetBSD
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/aim/trap_subr.S | 41 | ||||
-rw-r--r-- | sys/powerpc/powerpc/trap_subr.S | 41 |
2 files changed, 72 insertions, 10 deletions
diff --git a/sys/powerpc/aim/trap_subr.S b/sys/powerpc/aim/trap_subr.S index 95f61e9..828192e 100644 --- a/sys/powerpc/aim/trap_subr.S +++ b/sys/powerpc/aim/trap_subr.S @@ -228,6 +228,15 @@ mfsprg2 %r2; /* restore r2 & r3 */ \ mfsprg3 %r3 +#ifdef KDB +/* + * Define the kdb debugger stack + */ + .data +GLOBAL(dbstk) + .space INTSTK+8 /* kdb stack */ +#endif + /* * This code gets copied to all the trap vectors * (except ISI/DSI, ALI, and the interrupts) @@ -350,6 +359,33 @@ disitrap: stw %r30,(PC_TEMPSAVE+CPUSAVE_DAR)(%r1) stw %r31,(PC_TEMPSAVE+CPUSAVE_DSISR)(%r1) +#ifdef KDB + /* Try and detect a kernel stack overflow */ + mfsrr1 %r31 + mtcr %r31 + bt 17,realtrap /* branch is user mode */ + mfsprg1 %r31 /* get old SP */ + sub. %r30,%r31,%r30 /* SP - DAR */ + bge 1f + neg %r30,%r30 /* modulo value */ +1: cmplwi %cr0,%r30,4096 /* is DAR within a page of SP? */ + bge %cr0,realtrap /* no, too far away. */ + + /* Now convert this DSI into a DDB trap. */ + GET_CPUINFO(%r1) + lwz %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* get r28 */ + stw %r30,(PC_DBSAVE +CPUSAVE_R28)(%r1) /* save r28 */ + lwz %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) /* get r29 */ + stw %r31,(PC_DBSAVE +CPUSAVE_R29)(%r1) /* save r29 */ + lwz %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) /* get r30 */ + stw %r30,(PC_DBSAVE +CPUSAVE_R30)(%r1) /* save r30 */ + lwz %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) /* get r31 */ + stw %r31,(PC_DBSAVE +CPUSAVE_R31)(%r1) /* save r31 */ + lis %r1,dbstk+INTSTK@ha /* get new SP */ + addi %r1,%r1,dbstk+INTSTK@l + b dbtrap +#endif + /* XXX need stack probe here */ realtrap: /* Test whether we already had PR set */ @@ -460,11 +496,6 @@ dbleave: /* * In case of KDB we want a separate trap catcher for it */ - .data -GLOBAL(dbstk) - .space INTSTK+8 /* kdb stack */ - - .text .globl CNAME(dblow),CNAME(dbsize) CNAME(dblow): mtsprg1 %r1 /* save SP */ diff --git a/sys/powerpc/powerpc/trap_subr.S b/sys/powerpc/powerpc/trap_subr.S index 95f61e9..828192e 100644 --- a/sys/powerpc/powerpc/trap_subr.S +++ b/sys/powerpc/powerpc/trap_subr.S @@ -228,6 +228,15 @@ mfsprg2 %r2; /* restore r2 & r3 */ \ mfsprg3 %r3 +#ifdef KDB +/* + * Define the kdb debugger stack + */ + .data +GLOBAL(dbstk) + .space INTSTK+8 /* kdb stack */ +#endif + /* * This code gets copied to all the trap vectors * (except ISI/DSI, ALI, and the interrupts) @@ -350,6 +359,33 @@ disitrap: stw %r30,(PC_TEMPSAVE+CPUSAVE_DAR)(%r1) stw %r31,(PC_TEMPSAVE+CPUSAVE_DSISR)(%r1) +#ifdef KDB + /* Try and detect a kernel stack overflow */ + mfsrr1 %r31 + mtcr %r31 + bt 17,realtrap /* branch is user mode */ + mfsprg1 %r31 /* get old SP */ + sub. %r30,%r31,%r30 /* SP - DAR */ + bge 1f + neg %r30,%r30 /* modulo value */ +1: cmplwi %cr0,%r30,4096 /* is DAR within a page of SP? */ + bge %cr0,realtrap /* no, too far away. */ + + /* Now convert this DSI into a DDB trap. */ + GET_CPUINFO(%r1) + lwz %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* get r28 */ + stw %r30,(PC_DBSAVE +CPUSAVE_R28)(%r1) /* save r28 */ + lwz %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) /* get r29 */ + stw %r31,(PC_DBSAVE +CPUSAVE_R29)(%r1) /* save r29 */ + lwz %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) /* get r30 */ + stw %r30,(PC_DBSAVE +CPUSAVE_R30)(%r1) /* save r30 */ + lwz %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) /* get r31 */ + stw %r31,(PC_DBSAVE +CPUSAVE_R31)(%r1) /* save r31 */ + lis %r1,dbstk+INTSTK@ha /* get new SP */ + addi %r1,%r1,dbstk+INTSTK@l + b dbtrap +#endif + /* XXX need stack probe here */ realtrap: /* Test whether we already had PR set */ @@ -460,11 +496,6 @@ dbleave: /* * In case of KDB we want a separate trap catcher for it */ - .data -GLOBAL(dbstk) - .space INTSTK+8 /* kdb stack */ - - .text .globl CNAME(dblow),CNAME(dbsize) CNAME(dblow): mtsprg1 %r1 /* save SP */ |