Skip to content

[axlibc] inconsistent behaviour with ISO C on malloc #306

@WIZeaz

Description

@WIZeaz

Hi! I have audited the source code of axlibc/src/malloc.rs and found that the current implementation of malloc exhibits some behaviors that are inconsistent with the ISO C standard.

Here is the current implementation of malloc in axlibc:

/// Allocate memory and return the memory address.
///
/// Returns 0 on failure (the current implementation does not trigger an exception)
#[unsafe(no_mangle)]
pub unsafe extern "C" fn malloc(size: ctypes::size_t) -> *mut c_void {
// Allocate `(actual length) + 8`. The lowest 8 Bytes are stored in the actual allocated space size.
// This is because free(uintptr_t) has only one parameter representing the address,
// So we need to save in advance to know the size of the memory space that needs to be released
let layout = Layout::from_size_align(size + CTRL_BLK_SIZE, 8).unwrap();
unsafe {
let ptr = alloc(layout).cast::<MemoryControlBlock>();
assert!(!ptr.is_null(), "malloc failed");
ptr.write(MemoryControlBlock { size });
ptr.add(1).cast()
}
}

I believe this implementation has two inconsistencies with the ISO C specification (ref: https://en.cppreference.com/w/c/memory/malloc):

  1. Return value on allocation failure. According to ISO C, malloc must return NULL when the allocation fails. However, this implementation calls assert!(!ptr.is_null()), which causes a panic instead of returning NULL.

  2. Alignment requirements. The ISO C standard requires that a successful call to malloc return a pointer suitably aligned for any object type with fundamental alignment. According to the definition here (https://en.cppreference.com/w/c/language/object.html#Alignment),

The strictest (largest) fundamental alignment of any type is implementation-definedand equal to the alignment of max_align_t(since C11).

On most 64-bit architectures (e.g., x86_64 and AArch64), max_align_t typically has an alignment of 16 bytes.
However, the current implementation hardcodes the alignment to 8 bytes via the Layout::from_size_align(..., 8), which does not satisfy the ISO C requirement on 64-bit platforms.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions