]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[malloc] Convert allocation assertions to runtime checks
authorMichael Brown <mcb30@ipxe.org>
Sun, 2 Aug 2026 11:37:57 +0000 (12:37 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sun, 2 Aug 2026 12:14:27 +0000 (13:14 +0100)
There is no way for heap_alloc_block() to be called with a size of
zero or with an alignment that is not a power of two, and so asserting
these conditions is justifiable.

However, given the criticality of memory allocation to security, it is
worth converting these to runtime checks to guard against future code
changes that could, for example, allow for a variable alignment to be
passed in without being rounded up.

Convert the zero-size assertion and the power-of-two-alignment
assertion into runtime checks, and document the reasoning.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/malloc.c

index d1a0dc5d9003e18db7f1d2045abceecdf0824c58..4fd70a962e05116e9396fda62557e20f53ba0d64 100644 (file)
@@ -277,11 +277,22 @@ static void * heap_alloc_block ( struct heap *heap, size_t size, size_t align,
        void *ptr;
 
        /* Sanity checks */
-       assert ( size != 0 );
-       assert ( ( align != 0 ) && ( ( align & ( align - 1 ) ) == 0 ) );
        valgrind_make_blocks_defined ( heap );
        check_blocks ( heap );
 
+       /* Validate inputs */
+       if ( ( size == 0 ) || ( align == 0 ) || ( align & ( align - 1 ) ) ) {
+               /* This is unreachable from any of our callers and
+                * could instead be an assertion, but we perform a
+                * runtime check anyway to guard against future
+                * possible code changes.
+                */
+               DBGC ( heap, "HEAP malformed allocation %#zx (aligned "
+                      "%#zx+%#zx)\n", size, align, offset );
+               ptr = NULL;
+               goto done;
+       }
+
        /* Limit offset to requested alignment */
        offset &= ( align - 1 );
 
@@ -293,9 +304,7 @@ static void * heap_alloc_block ( struct heap *heap, size_t size, size_t align,
        actual_size = ( ( size + offset - actual_offset + heap->align - 1 )
                        & ~( heap->align - 1 ) );
        if ( ! actual_size ) {
-               /* The requested size is not permitted to be zero.  A
-                * zero result at this point indicates that either the
-                * original requested size was zero, or that unsigned
+               /* A zero result at this point indicates that unsigned
                 * integer overflow has occurred.
                 */
                ptr = NULL;