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
This commit is contained in:
parent
86b914642c
commit
8211bd45bc
@ -1130,6 +1130,7 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
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 object, vm_ooffset_t offset,
|
||||
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 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
* 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 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
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;
|
||||
|
@ -307,7 +307,7 @@ long vmspace_wired_count(struct vmspace *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
|
||||
|
@ -1517,6 +1517,9 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
||||
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, vm_size_t size, vm_prot_t prot,
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user