From: Martin Pieuchot Subject: Re: uvm_vslock_device(9) fix To: tech@openbsd.org Date: Tue, 17 Feb 2026 09:33:19 +0100 On 15/12/25(Mon) 18:33, Martin Pieuchot wrote: > 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? Anyone? > 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; > >