summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorchs <chs@NetBSD.org>2019-08-05 17:36:42 +0000
committerchs <chs@NetBSD.org>2019-08-05 17:36:42 +0000
commit05db12c848fc17ec237fe72cd4b666ee39fc1be6 (patch)
treefc6200ec29f0bc4743a18679a29d596b4637671c /sys
parentf754bc380f2e7c36ed1221221c969ea075a4d9e1 (diff)
fix two bugs reported in
https://syzkaller.appspot.com/bug?id=8840dce484094a926e1ec388ffb83acb2fa291c9 - in uvm_fault_check(), if the map entry is wired, handle the fault the same way that we would handle UVM_FAULT_WIRE. faulting on wired mappings is valid if the mapped object was truncated and then later grown again. - in uvm_fault_unwire_locked(), we must hold the locks for the vm_map_entry while calling pmap_extract() in order to avoid races with the mapped object being truncated while we are unwiring it. Reported-by: syzbot+2e0ae2fc35ab7301c7b8@syzkaller.appspotmail.com
Diffstat (limited to 'sys')
-rw-r--r--sys/uvm/uvm_fault.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c
index 42a8862dedd..426b66f62cf 100644
--- a/sys/uvm/uvm_fault.c
+++ b/sys/uvm/uvm_fault.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.206 2019/05/28 08:59:35 msaitoh Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.207 2019/08/05 17:36:42 chs Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.206 2019/05/28 08:59:35 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.207 2019/08/05 17:36:42 chs Exp $");
#include "opt_uvmhist.h"
@@ -996,8 +996,11 @@ uvm_fault_check(
*/
flt->enter_prot = ufi->entry->protection;
- if (VM_MAPENT_ISWIRED(ufi->entry))
+ if (VM_MAPENT_ISWIRED(ufi->entry)) {
flt->wire_mapping = true;
+ flt->wire_paging = true;
+ flt->narrow = true;
+ }
if (flt->wire_mapping) {
flt->access_type = flt->enter_prot; /* full access for wired */
@@ -2437,8 +2440,6 @@ uvm_fault_unwire_locked(struct vm_map *map, vaddr_t start, vaddr_t end)
oentry = NULL;
for (va = start; va < end; va += PAGE_SIZE) {
- if (pmap_extract(pmap, va, &pa) == false)
- continue;
/*
* find the map entry for the current address.
@@ -2469,6 +2470,9 @@ uvm_fault_unwire_locked(struct vm_map *map, vaddr_t start, vaddr_t end)
* if the entry is no longer wired, tell the pmap.
*/
+ if (!pmap_extract(pmap, va, &pa))
+ continue;
+
if (VM_MAPENT_ISWIRED(entry) == 0)
pmap_unwire(pmap, va);