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);
        }
 
        /*
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to