Date: Wed, 29 May 2002 15:10:03 -0700 (PDT) From: Archie Cobbs <archie@dellroad.org> To: Jake Burkholder <jake@locore.ca> Cc: freebsd-arch@FreeBSD.ORG Subject: Re: Kernel stack overflow detection? Message-ID: <200205292210.g4TMA3D93662@arch20m.dellroad.org> In-Reply-To: <20020529160434.P62759@locore.ca> "from Jake Burkholder at May 29, 2002 04:04:34 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
Jake Burkholder writes: > -current just leaves the page unmapped which has the same effect > and doesn't waste a physical page for it. This is slightly eaiser > to do if the stack is moved in the u. area. I agree leaving the page unmapped makes more sense. I'm not exactly sure how to do that but below is an updated patch that attempts to.. Basically I replaced all the PG_V's and PG_MAPPED's in the previous patch with zeroes. However I think this is still wasting a page of memory. I'd appreciate someone who understands this stuff better than me taking a look at it. > I think sparc64 is the only architecture that uses a guard page > for proc0's kstack; this is worth doing in -current for i386 > at least. This patch is supposed to handle proc0 as well (the locore.s patch)... Thanks, -Archie __________________________________________________________________________ Archie Cobbs * Packet Design * http://www.packetdesign.com --- i386/i386/locore.s Thu Sep 20 02:29:23 2001 +++ i386/i386/locore.s Wed May 29 14:57:18 2002 @@ -813,9 +813,34 @@ fillkptphys($PG_RW) /* Map proc0's UPAGES in the physical way ... */ +#ifdef KSTACK_GUARD + /* + * Map the 1st and the 3rd..Nth UPAGES pages as writable and + * leave the 2nd page unmapped to detect kernel stack overflows. + * + * Because of the way fillkptphys() works we have to do this in + * three stages: 1st page RW, 2nd page unmapped, and pages 3-N RW. + */ + movl R(p0upa), %eax + movl $1, %ecx + fillkptphys($PG_RW) + + movl R(p0upa), %eax + addl $PAGE_SIZE, %eax + movl $1, %ecx + fillkptphys($0) + + movl R(p0upa), %eax + addl $PAGE_SIZE, %eax + addl $PAGE_SIZE, %eax + movl $UPAGES, %ecx + subl $2, %ecx + fillkptphys($PG_RW) +#else movl R(p0upa), %eax movl $UPAGES, %ecx fillkptphys($PG_RW) +#endif /* Map ISA hole */ movl $ISA_HOLE_START, %eax --- i386/i386/pmap.c Thu Jan 3 17:17:33 2002 +++ i386/i386/pmap.c Wed May 29 15:03:24 2002 @@ -890,7 +890,17 @@ /* * Enter the page into the kernel address space. */ +#ifdef KSTACK_GUARD + /* Make bottom page of stack area invalid */ + if (i == 1) + *(ptek + i) = VM_PAGE_TO_PHYS(m) | pgeflag; + else { + *(ptek + i) = VM_PAGE_TO_PHYS(m) + | PG_RW | PG_V | pgeflag; + } +#else *(ptek + i) = VM_PAGE_TO_PHYS(m) | PG_RW | PG_V | pgeflag; +#endif if (oldpte) { if ((oldpte & PG_G) || (cpu_class > CPUCLASS_386)) { invlpg((vm_offset_t) up + i * PAGE_SIZE); @@ -901,7 +911,15 @@ vm_page_wakeup(m); vm_page_flag_clear(m, PG_ZERO); +#ifdef KSTACK_GUARD + /* Make bottom page of stack area invalid */ + if (i == 1) + vm_page_flag_set(m, 0); + else + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); +#else vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); +#endif m->valid = VM_PAGE_BITS_ALL; } if (updateneeded) @@ -997,7 +1015,15 @@ vm_page_wire(m); vm_page_wakeup(m); +#ifdef KSTACK_GUARD + /* Make bottom page of stack area invalid */ + if (i == 1) + vm_page_flag_set(m, 0); + else + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); +#else vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); +#endif } } --- i386/include/param.h Mon Sep 24 23:14:07 2001 +++ i386/include/param.h Wed May 29 11:34:56 2002 @@ -110,7 +110,11 @@ #define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) #define IOPAGES 2 /* pages of i/o permission bitmap */ +#ifdef KSTACK_GUARD +#define UPAGES 5 /* pages of u-area + kernel stack guard */ +#else #define UPAGES 3 /* pages of u-area */ +#endif /* * Ceiling on amount of swblock kva space. --- conf/options.i386 Mon Dec 10 04:17:04 2001 +++ conf/options.i386 Wed May 29 11:32:38 2002 @@ -30,6 +30,9 @@ COMPAT_SVR4 opt_dontuse.h DEBUG_SVR4 opt_svr4.h +# Kernel stack guard +KSTACK_GUARD opt_global.h + # i386 SMP options APIC_IO opt_global.h To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200205292210.g4TMA3D93662>
