DragonFlyBSD Kernel Audit
DF-2673 / fix.diff
← back to finding ↓ download raw
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -4112,6 +4112,8 @@
 	int is_procstack;
 	int use_read_lock = 1;
 	int count;
+	vm_offset_t wire_start;
+	vm_offset_t wire_end;
 
 	/*
 	 * Find the vm
@@ -4130,6 +4132,8 @@
 		return KERN_FAILURE;
 	}
 
+	wire_start = 0;
+	wire_end = 0;
 	count = vm_map_entry_reserve(MAP_RESERVE_COUNT);
 Retry:
 	if (use_read_lock)
@@ -4271,11 +4275,15 @@
 			}
 		}
 
+		/*
+		 * NOTE: The map must be unlocked before calling
+		 * vm_map_user_wiring() (it takes the map lock itself;
+		 * calling it while holding the exclusive map lock
+		 * panics lockmgr with 'locking against myself').
+		 */
 		if (map->flags & MAP_WIREFUTURE) {
-			vm_map_user_wiring(map,
-					   next->ba.start,
-					   next->ba.end,
-					   FALSE);
+			wire_start = next->ba.start;
+			wire_end = next->ba.end;
 		}
 	}
 
@@ -4285,6 +4293,9 @@
 	else
 		vm_map_unlock(map);
 	vm_map_entry_release(count);
+	if (wire_start) {
+		vm_map_user_wiring(map, wire_start, wire_end, FALSE);
+	}
 	return (rv);
 }