Index | Thread | Search

From:
"Theo de Raadt" <deraadt@openbsd.org>
Subject:
Re: uvm_vslock_device(9) fix
To:
tech@openbsd.org
Date:
Tue, 17 Feb 2026 18:03:44 -0700

Download raw body.

Thread
This is parked until another the uvm_lock_pageq problem is solved.


Martin Pieuchot <mpi@grenadille.net> wrote:

> 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;
> > 
> > 
> 
>