summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kempf <stefan@cvs.openbsd.org>2016-10-08 16:19:45 +0000
committerStefan Kempf <stefan@cvs.openbsd.org>2016-10-08 16:19:45 +0000
commit72e80f6efc1869f01564c1235657a5cd5f319232 (patch)
tree39ed33a395eb90d73502539840a05dfdef0b00b3
parent0b395b4df6d3d2f715c8e2273409632cb06b16e7 (diff)
Prevent infinite loops for amap allocations with >= 2^17 slots
This was caused by an integer overflow in a loop. mlarkin@ noticed the hang when trying to run a vmm(4) guest with lots of RAM.
-rw-r--r--sys/uvm/uvm_amap.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c
index 4bd2dfff36e..098dc26d312 100644
--- a/sys/uvm/uvm_amap.c
+++ b/sys/uvm/uvm_amap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_amap.c,v 1.77 2016/09/15 02:00:18 dlg Exp $ */
+/* $OpenBSD: uvm_amap.c,v 1.78 2016/10/08 16:19:44 stefan Exp $ */
/* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */
/*
@@ -264,7 +264,7 @@ amap_alloc1(int slots, int waitf, int lazyalloc)
{
struct vm_amap *amap;
struct vm_amap_chunk *chunk, *tmp;
- int chunks, chunkperbucket = 1, hashshift = 0;
+ int chunks, log_chunks, chunkperbucket = 1, hashshift = 0;
int buckets, i, n;
int pwaitf = (waitf & M_WAITOK) ? PR_WAITOK : PR_NOWAIT;
@@ -301,8 +301,11 @@ amap_alloc1(int slots, int waitf, int lazyalloc)
* for the hash buckets of all amaps to exceed the maximal
* amount of KVA memory reserved for amaps.
*/
+ for (log_chunks = 1; (chunks >> log_chunks) > 0; log_chunks++)
+ continue;
+
chunkperbucket = 1 << hashshift;
- while ((1 << chunkperbucket) * 2 <= chunks) {
+ while (chunkperbucket + 1 < log_chunks) {
hashshift++;
chunkperbucket = 1 << hashshift;
}