untrusted comment: signature from openbsd 5.9 base secret key RWQJVNompF3pwYa4tzI4bSrxrywOVRNvU/IRnMfm6wb0LNoTFJeyeZOe45Rj6x7kOPs4jMtFRuCzaT4wPqDKUSXPaDbrEv2tqAM= OpenBSD 5.9 errata 20, Jul 14, 2016: Unchecked parameters and integer overflows in the amap allocation routines could cause malloc(9) to either not allocate enough memory, leading to memory corruption, or to trigger a "malloc: allocation too large" panic. Apply by doing: signify -Vep /etc/signify/openbsd-59-base.pub -x 020_amap.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a kernel: cd /usr/src/sys/arch/`machine`/conf KK=`sysctl -n kern.osversion | cut -d# -f1` config $KK cd ../compile/$KK make make install Index: sys/arch/amd64/amd64/vmm.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v retrieving revision 1.38 diff -u -p -r1.38 vmm.c --- sys/arch/amd64/amd64/vmm.c 23 Feb 2016 17:17:31 -0000 1.38 +++ sys/arch/amd64/amd64/vmm.c 14 Jul 2016 15:21:07 -0000 @@ -1016,7 +1016,7 @@ vm_impl_init_vmx(struct vm *vm) PROT_READ | PROT_WRITE | PROT_EXEC, MAP_INHERIT_NONE, MADV_NORMAL, - UVM_FLAG_FIXED | UVM_FLAG_OVERLAY)); + UVM_FLAG_FIXED)); if (ret) { printf("vm_impl_init_vmx: uvm_mapanon failed (%d)\n", ret); /* uvm_map_deallocate calls pmap_destroy for us */ Index: sys/uvm/uvm_amap.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_amap.c,v retrieving revision 1.59 diff -u -p -r1.59 uvm_amap.c --- sys/uvm/uvm_amap.c 21 Aug 2015 16:04:35 -0000 1.59 +++ sys/uvm/uvm_amap.c 14 Jul 2016 15:21:09 -0000 @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -165,15 +166,29 @@ static inline struct vm_amap * amap_alloc1(int slots, int padslots, int waitf) { struct vm_amap *amap; - int totalslots; + size_t totalslots = (size_t)slots + padslots; amap = pool_get(&uvm_amap_pool, (waitf == M_WAITOK) ? PR_WAITOK : PR_NOWAIT); if (amap == NULL) return(NULL); - totalslots = malloc_roundup((slots + padslots) * MALLOC_SLOT_UNIT) / + /* + * Make sure that totalslots * MALLOC_SLOT_UNIT is within + * a size_t, AND: since malloc_roundup may round its argument + * to a multiple of the PAGE_SIZE, make sure that malloc_roundup + * cannot wrap totalslots * MALLOC_SLOT_UNIT to zero. + */ + if (totalslots >= (trunc_page(SIZE_MAX) / MALLOC_SLOT_UNIT)) + return (NULL); + + totalslots = malloc_roundup(totalslots * MALLOC_SLOT_UNIT) / MALLOC_SLOT_UNIT; + if (totalslots > INT_MAX) + return (NULL); + + KASSERT(totalslots > 0); + amap->am_ref = 1; amap->am_flags = 0; #ifdef UVM_AMAP_PPREF @@ -183,7 +198,7 @@ amap_alloc1(int slots, int padslots, int amap->am_nslot = slots; amap->am_nused = 0; - amap->am_slots = malloc(totalslots * MALLOC_SLOT_UNIT, M_UVMAMAP, + amap->am_slots = mallocarray(totalslots, MALLOC_SLOT_UNIT, M_UVMAMAP, waitf); if (amap->am_slots == NULL) goto fail1; @@ -210,10 +225,14 @@ struct vm_amap * amap_alloc(vaddr_t sz, vaddr_t padsz, int waitf) { struct vm_amap *amap; - int slots, padslots; + size_t slots, padslots; AMAP_B2SLOT(slots, sz); /* load slots */ AMAP_B2SLOT(padslots, padsz); + + /* Ensure that slots + padslots <= INT_MAX */ + if (slots > INT_MAX || padslots > INT_MAX - slots) + return (NULL); amap = amap_alloc1(slots, padslots, waitf); if (amap) {