From: Martin Pieuchot Subject: uvm_vslock_device(9) fix To: tech@openbsd.org Date: Mon, 15 Dec 2025 18:33:31 +0100 Syzkaller managed to reproduce the "address not in map" bug that we fixed for vslock(9) some months ago: https://syzkaller.appspot.com/bug?extid=ed3d78e6268404b528d5 Diff below adapts the previous fix to uvm_vslock_device(9) and avoid an unlock/relock dance by using vm_map_downgrade(). ok? Index: uvm/uvm_glue.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_glue.c,v diff -u -p -r1.94 uvm_glue.c --- uvm/uvm_glue.c 11 Sep 2025 15:28:40 -0000 1.94 +++ uvm/uvm_glue.c 15 Dec 2025 17:18:05 -0000 @@ -152,7 +152,7 @@ uvm_vslock_device(struct proc *p, void * vaddr_t start, end, off; vaddr_t sva, va; vsize_t sz; - int error, mapv, i; + int error, i; start = trunc_page((vaddr_t)addr); end = round_page((vaddr_t)addr + len); @@ -161,17 +161,15 @@ uvm_vslock_device(struct proc *p, void * if (end <= start) return (EINVAL); - vm_map_lock_read(map); -retry: - mapv = map->timestamp; - vm_map_unlock_read(map); - - if ((error = uvm_fault_wire(map, start, end, access_type))) + vm_map_lock(map); + error = uvm_map_pageable(map, start, end, FALSE, + UVM_LK_ENTER|UVM_LK_EXIT); + if (error != 0) { + vm_map_unlock(map); return (error); + } - vm_map_lock_read(map); - if (mapv != map->timestamp) - goto retry; + vm_map_downgrade(map); npages = atop(sz); for (i = 0; i < npages; i++) { @@ -220,8 +218,8 @@ retry: out_unmap: km_free((void *)sva, sz, &kv_any, &kp_none); out_unwire: - uvm_fault_unwire_locked(map, start, end); vm_map_unlock_read(map); + uvm_map_pageable(map, start, end, TRUE, 0); return (error); } @@ -245,8 +243,8 @@ uvm_vsunlock_device(struct proc *p, void if (map) copyout(map, addr, len); - uvm_fault_unwire_locked(&p->p_vmspace->vm_map, start, end); vm_map_unlock_read(&p->p_vmspace->vm_map); + uvm_map_pageable(&p->p_vmspace->vm_map, start, end, TRUE, 0); if (!map) return;