summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2011-12-03 20:07:07 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2011-12-03 20:07:07 +0000
commit55403a401a28f52271ce6ca3d688e8b5dc55b559 (patch)
tree52828ac03d568918eed64194a522a7f65b2d60a9
parent95c0b9e2872103fd785d07a3406dda5949733feb (diff)
Be sure not to access the vm_page array out of bounds in uvm_pmr_freepages().
Among other things, this fixes early panics on hppa system which memory size is exactly 128MB. Found the hard way and reported by fries@, not reported by beck@
-rw-r--r--sys/uvm/uvm_pmemrange.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c
index 5d0678af0e5..82fdb4fc8a2 100644
--- a/sys/uvm/uvm_pmemrange.c
+++ b/sys/uvm/uvm_pmemrange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pmemrange.c,v 1.32 2011/07/08 18:25:56 ariane Exp $ */
+/* $OpenBSD: uvm_pmemrange.c,v 1.33 2011/12/03 20:07:06 miod Exp $ */
/*
* Copyright (c) 2009, 2010 Ariane van der Steldt <ariane@stack.nl>
@@ -1109,6 +1109,7 @@ uvm_pmr_freepages(struct vm_page *pg, psize_t count)
{
struct uvm_pmemrange *pmr;
psize_t i, pmr_count;
+ struct vm_page *firstpg = pg;
for (i = 0; i < count; i++) {
KASSERT(atop(VM_PAGE_TO_PHYS(&pg[i])) ==
@@ -1127,21 +1128,20 @@ uvm_pmr_freepages(struct vm_page *pg, psize_t count)
uvm_lock_fpageq();
- while (count > 0) {
+ for (i = count; i > 0; i -= pmr_count) {
pmr = uvm_pmemrange_find(atop(VM_PAGE_TO_PHYS(pg)));
KASSERT(pmr != NULL);
- pmr_count = MIN(count, pmr->high - atop(VM_PAGE_TO_PHYS(pg)));
+ pmr_count = MIN(i, pmr->high - atop(VM_PAGE_TO_PHYS(pg)));
pg->fpgsz = pmr_count;
uvm_pmr_insert(pmr, pg, 0);
uvmexp.free += pmr_count;
- count -= pmr_count;
pg += pmr_count;
}
wakeup(&uvmexp.free);
- uvm_wakeup_pla(VM_PAGE_TO_PHYS(pg), ptoa(count));
+ uvm_wakeup_pla(VM_PAGE_TO_PHYS(firstpg), ptoa(count));
uvm_unlock_fpageq();
}