Subject: bug in uvm_fault_unwire()
To: None <tech-kern@netbsd.org>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 06/16/1999 12:25:23
Hi folks...
I think I've discovered a bug in uvm_fault_unwire(), but I think it will
be fairly straight-forward to fix.
Consider the following:
- User mlock(2)'s a buffer, to guarantee it will never become
non-resident while he is using it.
- User then does physio to that buffer. Physio calls uvm_vslock()
to lock down the pages and ensure that page faults do not happen
while the I/O is in progress (possibly in interrupt context).
- Physio does the I/O.
- Physio calls uvm_vsunlock(). This calls uvm_fault_unwire().
>>> HERE IS WHERE THE PROBLEM OCCURS <<<
uvm_fault_unwire() calls pmap_change_wiring(..., FALSE),
which now gives the pmap free reign to recycle the mapping
information for that page, which is illegal; the mapping is
still wired (due to the mlock(2)), but now access of the
page could cause a non-protection page fault (disallowed).
NOTE: This could eventually lead to a panic when the user
subsequently munlock(2)'s the buffer and the mapping info
has been recycled for use by another mapping!
I think the fix is fairly simple: Make uvm_fault_unwire() lookup the
map entry or entries for the region being unwired. Only call
pmap_change_wiring(..., FALSE) if the entry for the region is not
wired.
This affects the locking protocol for uvm_fault_unwire(), but not
too badly; only uvm_map_pageable*() will be affected in this regard.
-- Jason R. Thorpe <thorpej@nas.nasa.gov>