[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 1/3] lib/ukalloc: fix multiple issues in uk_posix_memalign_ifpages



uk_posix_memalign_ifpages might return out-of-bounds pointers when
alignment is smaller than  __PAGE_SIZE (for example align = __PAGE_SIZE / 2,
and size = __PAGE_SIZE - sizeof(size_t)).

Address this issue by reserving at least align bytes for the size
information.

This also adds support for align > __PAGE_SIZE.

Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx>

diff --git a/lib/ukalloc/alloc.c b/lib/ukalloc/alloc.c
index 708bd02..aa87274 100644
--- a/lib/ukalloc/alloc.c
+++ b/lib/ukalloc/alloc.c
@@ -235,8 +235,7 @@ int uk_posix_memalign_ifpages(struct uk_alloc *a,
 
        UK_ASSERT(a);
        if (((align - 1) & align) != 0
-           || (align % sizeof(void *)) != 0
-           || (align > __PAGE_SIZE))
+           || (align % sizeof(void *)) != 0)
                return EINVAL;
 
        if (!size) {
@@ -244,14 +243,11 @@ int uk_posix_memalign_ifpages(struct uk_alloc *a,
                return EINVAL;
        }
 
-       /* For page-aligned memory blocks, the size information is not stored
-        * immediately preceding the memory block, but instead at the
-        * beginning of the page preceeding the memory handed out via malloc.
+       /* Store size information preceeding the memory block. Since we return
+        * pointers aligned at `align` we need to reserve at least that much
+         * space for the size information.
         */
-       if (align == __PAGE_SIZE)
-               realsize = ALIGN_UP(size + __PAGE_SIZE, align);
-       else
-               realsize = ALIGN_UP(size + sizeof(order), align);
+       realsize = ALIGN_UP(size + align, align);
 
        order = uk_alloc_size_to_order(realsize);
        intptr = uk_palloc(a, order);
@@ -260,6 +256,11 @@ int uk_posix_memalign_ifpages(struct uk_alloc *a,
                return ENOMEM;
 
        *(size_t *)intptr = order;
+
+       /* This is guaranteed to stay within bounds since the next address
+         * aligned at `align` is guaranteed to be within the first `align`
+        * bytes.
+        */
        *memptr = (void *) ALIGN_UP((uintptr_t)intptr + sizeof(order), align);
        return 0;
 }
-- 
2.7.4


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.