summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2014-04-05 17:18:01 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2014-04-05 17:18:01 +0000
commit19161018813038fd466d9743673d9e9b14006270 (patch)
tree34194820bea9d3804e2461e9bfaea6baf56e8b98 /sys/uvm
parent723036786b137a0daa94e7096a6fc2d95abb9706 (diff)
Fix logic error and prevent theoretical infinite loop in the worst case scenario
in uvm_pmr_rootupdate(). Issue spotted and fix provided by Kieran Devlin.
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_pmemrange.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c
index 94dc842baa5..3eb24f4b5f8 100644
--- a/sys/uvm/uvm_pmemrange.c
+++ b/sys/uvm/uvm_pmemrange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pmemrange.c,v 1.38 2014/03/21 21:39:36 miod Exp $ */
+/* $OpenBSD: uvm_pmemrange.c,v 1.39 2014/04/05 17:18:00 miod Exp $ */
/*
* Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl>
@@ -1645,7 +1645,7 @@ uvm_pmr_rootupdate(struct uvm_pmemrange *pmr, struct vm_page *init_root,
* Cache the lower page, so we can page-walk later.
*/
low = root;
- low_next = RB_RIGHT(low, objt);
+ low_next = RB_LEFT(low, objt);
while (low_next != NULL && PMR_INTERSECTS_WITH(
atop(VM_PAGE_TO_PHYS(low_next)),
atop(VM_PAGE_TO_PHYS(low_next)) + low_next->fpgsz,
@@ -1653,9 +1653,12 @@ uvm_pmr_rootupdate(struct uvm_pmemrange *pmr, struct vm_page *init_root,
low = low_next;
if (uvm_pmr_pg_to_memtype(low) == memtype)
return low;
- low_next = RB_RIGHT(low, objt);
+ low_next = RB_LEFT(low, objt);
}
+ if (low == high)
+ return NULL;
+
/*
* Ack, no hits. Walk the address tree until to find something usable.
*/