diff options
author | 2011-12-03 20:07:06 +0000 | |
---|---|---|
committer | 2011-12-03 20:07:06 +0000 | |
commit | 32007ced8c6098cdaed1ba448079532a17601274 (patch) | |
tree | fecca1cd467f9e7e01b01f399d1ca431db78d7e9 | |
parent | fussing around (diff) | |
download | wireguard-openbsd-32007ced8c6098cdaed1ba448079532a17601274.tar.xz wireguard-openbsd-32007ced8c6098cdaed1ba448079532a17601274.zip |
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.c | 10 |
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(); } |