Download raw body.
Missing lock in uvm_unmap_kill_entry()
Syzkaller reported [1] an assertion when tearing down a VM space with wired
entries:
panic: kernel diagnostic assertion "uvm_page_owner_locked_p(pg, TRUE)" failed: file "/syzkaller/managers/main/kernel/sys/uvm/uvm_page.c", line 1248
Stopped at db_enter+0x25: addq $0x8,%rsp
TID PID UID PRFLAGS PFLAGS CPU COMMAND
*153883 5762 0 0x14000 0x200 0 reaper
db_enter() at db_enter+0x25 sys/arch/amd64/amd64/db_interface.c:437
panic(ffffffff8311d783) at panic+0x1cf sys/kern/subr_prf.c:198
__assert(ffffffff830d7289,ffffffff83025989,4e0,ffffffff8305b6f1) at __assert+0x29
uvm_pageunwire(fffffd8006c5df00) at uvm_pageunwire+0x1dd sys/uvm/uvm_page.c:1248
uvm_fault_unwire_locked(fffffd807aee3cb0,2a346811000,2a346c10000) at uvm_fault_unwire_locked+0x33c sys/uvm/uvm_fault.c:1774
uvm_unmap_kill_entry_withlock(fffffd807aee3cb0,fffffd807ac2dd48,0) at uvm_unmap_kill_entry_withlock+0x81 sys/uvm/uvm_map.c:1860
uvm_map_teardown(fffffd807aee3cb0) at uvm_map_teardown+0x1c7 sys/uvm/uvm_map.c:2496
uvmspace_free(fffffd807aee3cb0) at uvmspace_free+0xbd sys/uvm/uvm_map.c:3420
reaper(ffff80002a8376d0) at reaper+0x225 sys/kern/kern_exit.c:478
Wiring and unwiring a page are operations serialized by its owner lock.
Diff below prevents this panic by grabbing the lock before unwiring the
page.
ok?
[1] https://syzkaller.appspot.com/bug?extid=09beba1b131af8d8235e
Index: uvm/uvm_map.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_map.c,v
diff -u -p -r1.338 uvm_map.c
--- uvm/uvm_map.c 29 Jan 2025 15:25:31 -0000 1.338
+++ uvm/uvm_map.c 4 Feb 2025 11:10:50 -0000
@@ -1854,14 +1854,14 @@ void
uvm_unmap_kill_entry_withlock(struct vm_map *map, struct vm_map_entry *entry,
int needlock)
{
+ if (needlock)
+ uvm_map_lock_entry(entry);
+
/* Unwire removed map entry. */
if (VM_MAPENT_ISWIRED(entry)) {
entry->wired_count = 0;
uvm_fault_unwire_locked(map, entry->start, entry->end);
}
-
- if (needlock)
- uvm_map_lock_entry(entry);
/* Entry-type specific code. */
if (UVM_ET_ISHOLE(entry)) {
Missing lock in uvm_unmap_kill_entry()