rcore-os / rcore-os/buddy_system_allocator
`FrameAllocator` treats zero-sized requests as real allocations and panics on zero-sized deallocation
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 145
- Forks
- 34
- PR merge metrics
- No merged PRs in 30d
Description
FrameAllocator currently does not reject zero-sized requests at the API boundary.
Relevant code:
src/frame.rs:86-89forallocsrc/frame.rs:95-98foralloc_alignedsrc/frame.rs:107-110foralloc_atsrc/frame.rs:178-181fordeallocsrc/frame.rs:186-189fordealloc_aligned
Because 0usize.next_power_of_two() == 1, a zero-sized request is internally treated as size 1.
That causes two problems:
- zero-sized allocation requests can consume a real frame
- zero-sized deallocation can panic due to
self.allocated -= size
Reproduction
Allocation side:
use buddy_system_allocator::FrameAllocator;
use core::alloc::Layout;
#[test]
fn frame_allocator_zero_sized_allocations_should_be_rejected() {
let mut frame = FrameAllocator::<8>::new();
frame.add_frame(0, 8);
// These currently succeed instead of returning None.
assert_eq!(frame.alloc(0), None);
assert_eq!(frame.alloc_at(3, 0), None);
assert_eq!(
frame.alloc_aligned(Layout::from_size_align(0, 1).unwrap()),
None,
);
// Zero-sized calls should not affect allocator state.
assert_eq!(frame.alloc(8), Some(0));
}
Deallocation side:
use buddy_system_allocator::FrameAllocator;
use core::alloc::Layout;
#[test]
fn frame_allocator_zero_sized_deallocations_should_be_noop() {
let mut frame = FrameAllocator::<8>::new();
frame.add_frame(0, 1);
// Currently panics with subtract overflow.
frame.dealloc(0, 0);
frame.dealloc_aligned(0, Layout::from_size_align(0, 1).unwrap());
assert_eq!(frame.alloc(1), Some(0));
}
Why this matters
This is not just a semantic edge case. The current behavior is inconsistent and unsafe:
- zero-sized allocation unexpectedly consumes a real resource
- zero-sized deallocation can panic
- accounting can also be polluted by these calls
alloc_aligned / dealloc_aligned are especially awkward here because a zero-sized layout can still be expanded by alignment.
Suggested fix
Handle zero-sized inputs explicitly at the public API boundary:
alloc(0)returnsNonealloc_at(_, 0)returnsNonealloc_aligned(layout)returnsNonewhenlayout.size() == 0dealloc(_, 0)is a no-opdealloc_aligned(_, layout)is a no-op whenlayout.size() == 0
Optionally, internal helpers can also add:
debug_assert!(size > 0);
But the public behavior should avoid panicking on zero-sized requests.
If it is confirmed to be a bug, I can submit a PR to help fix it.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the alloc, alloc_aligned, alloc_at, dealloc, and dealloc_aligned implementations in src/frame.rs at the line ranges listed in the issue. Run the supplied zero-sized allocation and deallocation reproductions, then verify that allocation returns None, deallocation is a no-op, and a subsequent real allocation still succeeds without consuming or corrupting allocator state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100