diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2014-04-05 17:18:01 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2014-04-05 17:18:01 +0000 |
commit | 19161018813038fd466d9743673d9e9b14006270 (patch) | |
tree | 34194820bea9d3804e2461e9bfaea6baf56e8b98 /sys/uvm | |
parent | 723036786b137a0daa94e7096a6fc2d95abb9706 (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.c | 9 |
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. */ |