From d674b59e530355c17c0d99afcd9786581927042c Mon Sep 17 00:00:00 2001 From: stefan Date: Thu, 14 Jul 2016 16:23:49 +0000 Subject: [PATCH] Make sure that amap slot calculation does not overflow This prevents from too small amaps being allocated by forcing the allocation of a large number of slots. Based on an analysis from Jesse Hertz and Tim Newsham. ok kettenis@ --- sys/uvm/uvm_amap.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c index c6994212886..84e56c0e3fc 100644 --- a/sys/uvm/uvm_amap.c +++ b/sys/uvm/uvm_amap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_amap.c,v 1.74 2016/07/11 08:38:49 stefan Exp $ */ +/* $OpenBSD: uvm_amap.c,v 1.75 2016/07/14 16:23:49 stefan Exp $ */ /* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */ /* @@ -272,7 +272,13 @@ amap_alloc1(int slots, int waitf, int lazyalloc) int buckets, i, n; int pwaitf = (waitf == M_WAITOK) ? PR_WAITOK : PR_NOWAIT; - chunks = roundup(slots, UVM_AMAP_CHUNK) / UVM_AMAP_CHUNK; + KASSERT(slots > 0); + + /* + * Cast to unsigned so that rounding up cannot cause integer overflow + * if slots is large. + */ + chunks = roundup((unsigned int)slots, UVM_AMAP_CHUNK) / UVM_AMAP_CHUNK; if (lazyalloc) { /* @@ -314,8 +320,6 @@ amap_alloc1(int slots, int waitf, int lazyalloc) if (amap == NULL) return(NULL); - KASSERT(slots > 0); - amap->am_ref = 1; amap->am_flags = 0; #ifdef UVM_AMAP_PPREF @@ -382,9 +386,11 @@ struct vm_amap * amap_alloc(vaddr_t sz, int waitf, int lazyalloc) { struct vm_amap *amap; - int slots; + size_t slots; AMAP_B2SLOT(slots, sz); /* load slots */ + if (slots > INT_MAX) + return (NULL); amap = amap_alloc1(slots, waitf, lazyalloc); if (amap) -- 2.20.1