Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Jun 2017 20:06:05 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r320339 - head/sys/vm
Message-ID:  <201706252006.v5PK65de088842@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun Jun 25 20:06:05 2017
New Revision: 320339
URL: https://svnweb.freebsd.org/changeset/base/320339

Log:
  Correctly handle small MAP_STACK requests.
  
  If mmap(2) is called with the MAP_STACK flag and the size which is
  less or equal to the initial stack mapping size plus guard,
  calculation of the mapping layout created zero-sized guard.  Attempt
  to create such entry failed in vm_map_insert(), causing the whole
  mmap(2) call to fail.
  
  Fix it by adjusting the initial mapping size to have space for
  non-empty guard.  Reject MAP_STACK requests which are shorter or equal
  to the configured guard pages size.
  
  Reported and tested by:	Manfred Antar <null@pozo.com>
  Reviewed by:	alc, markj
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/vm/vm_map.c

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Sun Jun 25 19:59:39 2017	(r320338)
+++ head/sys/vm/vm_map.c	Sun Jun 25 20:06:05 2017	(r320339)
@@ -3567,13 +3567,18 @@ out:
 	return (rv);
 }
 
+static int stack_guard_page = 1;
+SYSCTL_INT(_security_bsd, OID_AUTO, stack_guard_page, CTLFLAG_RWTUN,
+    &stack_guard_page, 0,
+    "Specifies the number of guard pages for a stack that grows");
+
 static int
 vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
     vm_size_t growsize, vm_prot_t prot, vm_prot_t max, int cow)
 {
 	vm_map_entry_t new_entry, prev_entry;
 	vm_offset_t bot, gap_bot, gap_top, top;
-	vm_size_t init_ssize;
+	vm_size_t init_ssize, sgp;
 	int orient, rv;
 
 	/*
@@ -3586,12 +3591,16 @@ vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos,
 	KASSERT(orient != (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP),
 	    ("bi-dir stack"));
 
+	sgp = (vm_size_t)stack_guard_page * PAGE_SIZE;
 	if (addrbos < vm_map_min(map) ||
 	    addrbos > vm_map_max(map) ||
-	    addrbos + max_ssize < addrbos)
+	    addrbos + max_ssize < addrbos ||
+	    sgp >= max_ssize)
 		return (KERN_NO_SPACE);
 
-	init_ssize = (max_ssize < growsize) ? max_ssize : growsize;
+	init_ssize = growsize;
+	if (max_ssize < init_ssize + sgp)
+		init_ssize = max_ssize - sgp;
 
 	/* If addr is already mapped, no go */
 	if (vm_map_lookup_entry(map, addrbos, &prev_entry))
@@ -3644,11 +3653,6 @@ vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos,
 		(void)vm_map_delete(map, bot, top);
 	return (rv);
 }
-
-static int stack_guard_page = 1;
-SYSCTL_INT(_security_bsd, OID_AUTO, stack_guard_page, CTLFLAG_RWTUN,
-    &stack_guard_page, 0,
-    "Specifies the number of guard pages for a stack that grows.");
 
 /*
  * Attempts to grow a vm stack entry.  Returns KERN_SUCCESS if we



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706252006.v5PK65de088842>