-
Notifications
You must be signed in to change notification settings - Fork 423
Description
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:
arceos/ulib/axlibc/src/malloc.rs
Lines 21 to 36 in 1d61c81
| /// 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):
-
Return value on allocation failure. According to ISO C,
mallocmust return NULL when the allocation fails. However, this implementation callsassert!(!ptr.is_null()), which causes a panic instead of returning NULL. -
Alignment requirements. The ISO C standard requires that a successful call to
mallocreturn 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.