diff options
author | Stefan Kempf <stefan@cvs.openbsd.org> | 2016-10-08 16:19:45 +0000 |
---|---|---|
committer | Stefan Kempf <stefan@cvs.openbsd.org> | 2016-10-08 16:19:45 +0000 |
commit | 72e80f6efc1869f01564c1235657a5cd5f319232 (patch) | |
tree | 39ed33a395eb90d73502539840a05dfdef0b00b3 | |
parent | 0b395b4df6d3d2f715c8e2273409632cb06b16e7 (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.c | 9 |
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; } |