xmalloc: guard against integer overflow
authorJan Beulich <jbeulich@suse.com>
Thu, 5 Mar 2020 10:34:30 +0000 (11:34 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 5 Mar 2020 10:34:30 +0000 (11:34 +0100)
There are hypercall handling paths (EFI ones are what this was found
with) needing to allocate buffers of a caller specified size. This is
generally fine, as our page allocator enforces an upper bound on all
allocations. However, certain extremely large sizes could, when adding
in allocator overhead, result in an apparently tiny allocation size,
which would typically result in either a successful allocation, but a
severe buffer overrun when using that memory block, or in a crash right
in the allocator code.

Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
master commit: cf38b4926e2b55d1d7715cff5095a7444f5ed42d
master date: 2020-02-06 09:53:12 +0100

xen/common/xmalloc_tlsf.c

index b256dc56cfc83f5a18e30bc4b7b63daf2b6077b7..987e377cbb53aac6d3ba02fe69d8ad223091f86d 100644 (file)
@@ -388,7 +388,17 @@ void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool)
         pool->init_region = region;
     }
 
-    size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
+    if ( size < MIN_BLOCK_SIZE )
+        size = MIN_BLOCK_SIZE;
+    else
+    {
+        tmp_size = ROUNDUP_SIZE(size);
+        /* Guard against overflow. */
+        if ( tmp_size < size )
+            return NULL;
+        size = tmp_size;
+    }
+
     /* Rounding up the requested size and calculating fl and sl */
 
     spin_lock(&pool->lock);
@@ -583,6 +593,10 @@ void *_xmalloc(unsigned long size, unsigned long align)
         align = MEM_ALIGN;
     size += align - MEM_ALIGN;
 
+    /* Guard against overflow. */
+    if ( size < align - MEM_ALIGN )
+        return NULL;
+
     if ( !xenpool )
         tlsf_init();