Re: Reproducible panic with MAP_GUARD and security.bsd.stack_guard_page > 1

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Sun, 2 Jul 2017 01:48:29 +0300
On Sat, Jul 01, 2017 at 01:28:47PM -0400, Shawn Webb wrote:
> When running my Stack Clash PoC on a vanilla FreeBSD 12-CURRENT/amd64 VM
> and security.bsd.stack_guard_page is > 1:
> 
> https://goo.gl/photos/vZQY4B9jKJRLrNwP7
> 
> The PoC doesn't need to be run as root on vanilla FreeBSD with a default
> configuration.
I cannot make much sense from the last sentence, esp. after mention of
the setting of stack_guard_page to greater than one value in the first
sentence.

Anyway, there could be some situation where max_grow calculation overflows.
Indeed only possible when guard > 1.  Try this.

diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 114e4b34a90..9c9b781db2d 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
_at__at_ -3684,7 +3684,7 _at__at_ vm_map_growstack(vm_map_t map, vm_offset_t addr, vm_map_entry_t gap_entry)
 	struct proc *p;
 	struct vmspace *vm;
 	struct ucred *cred;
-	vm_offset_t gap_end, gap_start, grow_start;
+	vm_offset_t gap_end, gap_start, grow_start, sgp;
 	size_t grow_amount, max_grow;
 	rlim_t lmemlim, stacklim, vmemlim;
 	int rv, rv1;
_at__at_ -3727,8 +3727,11 _at__at_ retry:
 	} else {
 		return (KERN_FAILURE);
 	}
-	max_grow = gap_entry->end - gap_entry->start - stack_guard_page *
-	    PAGE_SIZE;
+	sgp = stack_guard_page * PAGE_SIZE;
+	max_grow = gap_entry->end - gap_entry->start;
+	if (max_grow < sgp)
+		return (KERN_NO_SPACE);
+	max_grow -= sgp;
 	if (grow_amount > max_grow)
 		return (KERN_NO_SPACE);
 
Received on Sat Jul 01 2017 - 20:48:36 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:12 UTC