Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Feb 2012 17:29:07 +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: r231526 - head/sys/vm
Message-ID:  <201202111729.q1BHT7Io040601@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Feb 11 17:29:07 2012
New Revision: 231526
URL: http://svn.freebsd.org/changeset/base/231526

Log:
  Close a race due to dropping of the map lock between creating map entry
  for a shared mapping and marking the entry for inheritance.
  Other thread might execute vmspace_fork() in between (e.g. by fork(2)),
  resulting in the mapping becoming private.
  
  Noted and reviewed by:	alc
  MFC after:	1 week

Modified:
  head/sys/vm/vm_map.c
  head/sys/vm/vm_map.h
  head/sys/vm/vm_mmap.c

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Sat Feb 11 16:41:52 2012	(r231525)
+++ head/sys/vm/vm_map.c	Sat Feb 11 17:29:07 2012	(r231526)
@@ -1130,6 +1130,7 @@ vm_map_insert(vm_map_t map, vm_object_t 
 	vm_map_entry_t temp_entry;
 	vm_eflags_t protoeflags;
 	struct ucred *cred;
+	vm_inherit_t inheritance;
 	boolean_t charge_prev_obj;
 
 	VM_MAP_ASSERT_LOCKED(map);
@@ -1173,6 +1174,10 @@ vm_map_insert(vm_map_t map, vm_object_t 
 		protoeflags |= MAP_ENTRY_NOSYNC;
 	if (cow & MAP_DISABLE_COREDUMP)
 		protoeflags |= MAP_ENTRY_NOCOREDUMP;
+	if (cow & MAP_INHERIT_SHARE)
+		inheritance = VM_INHERIT_SHARE;
+	else
+		inheritance = VM_INHERIT_DEFAULT;
 
 	cred = NULL;
 	KASSERT((object != kmem_object && object != kernel_object) ||
@@ -1227,7 +1232,7 @@ charged:
 		 * can extend the previous map entry to include the
 		 * new range as well.
 		 */
-		if ((prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
+		if ((prev_entry->inheritance == inheritance) &&
 		    (prev_entry->protection == prot) &&
 		    (prev_entry->max_protection == max)) {
 			map->size += (end - prev_entry->end);
@@ -1276,7 +1281,7 @@ charged:
 	new_entry->offset = offset;
 	new_entry->avail_ssize = 0;
 
-	new_entry->inheritance = VM_INHERIT_DEFAULT;
+	new_entry->inheritance = inheritance;
 	new_entry->protection = prot;
 	new_entry->max_protection = max;
 	new_entry->wired_count = 0;

Modified: head/sys/vm/vm_map.h
==============================================================================
--- head/sys/vm/vm_map.h	Sat Feb 11 16:41:52 2012	(r231525)
+++ head/sys/vm/vm_map.h	Sat Feb 11 17:29:07 2012	(r231526)
@@ -307,7 +307,7 @@ long vmspace_wired_count(struct vmspace 
 /*
  * Copy-on-write flags for vm_map operations
  */
-#define MAP_UNUSED_01		0x0001
+#define MAP_INHERIT_SHARE	0x0001
 #define MAP_COPY_ON_WRITE	0x0002
 #define MAP_NOFAULT		0x0004
 #define MAP_PREFAULT		0x0008

Modified: head/sys/vm/vm_mmap.c
==============================================================================
--- head/sys/vm/vm_mmap.c	Sat Feb 11 16:41:52 2012	(r231525)
+++ head/sys/vm/vm_mmap.c	Sat Feb 11 17:29:07 2012	(r231526)
@@ -1517,6 +1517,9 @@ vm_mmap(vm_map_t map, vm_offset_t *addr,
 		docow |= MAP_DISABLE_SYNCER;
 	if (flags & MAP_NOCORE)
 		docow |= MAP_DISABLE_COREDUMP;
+	/* Shared memory is also shared with children. */
+	if (flags & MAP_SHARED)
+		docow |= MAP_INHERIT_SHARE;
 
 	if (flags & MAP_STACK)
 		rv = vm_map_stack(map, *addr, size, prot, maxprot,
@@ -1536,13 +1539,6 @@ vm_mmap(vm_map_t map, vm_offset_t *addr,
 		 * or named anonymous without other references.
 		 */
 		vm_object_deallocate(object);
-	} else if (flags & MAP_SHARED) {
-		/*
-		 * Shared memory is also shared with children.
-		 */
-		rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE);
-		if (rv != KERN_SUCCESS)
-			(void) vm_map_remove(map, *addr, *addr + size);
 	}
 
 	/*



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