From owner-freebsd-arch Wed May 29 15:15:11 2002 Delivered-To: freebsd-arch@freebsd.org Received: from InterJet.dellroad.org (adsl-63-194-81-26.dsl.snfc21.pacbell.net [63.194.81.26]) by hub.freebsd.org (Postfix) with ESMTP id 2575637B400 for ; Wed, 29 May 2002 15:15:04 -0700 (PDT) Received: from arch20m.dellroad.org (arch20m.dellroad.org [10.1.1.20]) by InterJet.dellroad.org (8.9.1a/8.9.1) with ESMTP id PAA42935; Wed, 29 May 2002 15:10:55 -0700 (PDT) Received: (from archie@localhost) by arch20m.dellroad.org (8.11.6/8.11.6) id g4TMA3D93662; Wed, 29 May 2002 15:10:03 -0700 (PDT) (envelope-from archie) From: Archie Cobbs Message-Id: <200205292210.g4TMA3D93662@arch20m.dellroad.org> Subject: Re: Kernel stack overflow detection? In-Reply-To: <20020529160434.P62759@locore.ca> "from Jake Burkholder at May 29, 2002 04:04:34 pm" To: Jake Burkholder Date: Wed, 29 May 2002 15:10:03 -0700 (PDT) Cc: freebsd-arch@FreeBSD.ORG X-Mailer: ELM [version 2.4ME+ PL88 (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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