Skip site navigation (1)Skip section navigation (2)
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>