Integer overflow in deallocation

Open
#85 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
rust

Research direction

Start at src/hole.rs around line 617 and compare the reported deallocation values with the minimized psram.rs example and the large_deallocation test. Investigate why the test does not reproduce the overflow despite using the same arena size, allocation, and alignment. Done means the reported deallocation no longer panics and a regression test covers the case.

Written by the indexing model from the issue text.

Description

Thanks for this crate!
I tried to find the size of my PSRAM by simply allocating large amounts of data with a Vec and stumbled upon an integer overflow:
When trying to free an allocation with size 1048572 and alignment 4, my program panicked at https://github.com/rust-osdev/linked-list-allocator/tree/main/src/hole.rs#L617

I added a few panics to see some variable and argument values. The panic happens with this addition arguments: 1048572 += 4294967295 where the right-hand side is usize::MAX for this architecture.

I tried on the latest release 0.10.5 first but could also reproduce on the latest main commit

Minimized example:
https://github.com/ede1998/ireplay/blob/86e2f72509eaf308c133086e1daa133819e68852/src/bin/psram.rs

I tried to reduce the case even further by writing a test in this crate but could not reproduce it that way even though I compiled and ran it with 32bit x86 instead of 64 bit to ensure that usize::MAX is the same. As far as I could tell, there should be no significant difference between my minimized example and the test in terms of code: Both init an arena of the same size and then allocate and deallocate the same number of bytes with the same alignment.

Command CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=$( nix eval --raw --impure --expr 'let pkgs = import {}; in "${pkgs.pkgsi686Linux.stdenv.cc}/bin/${pkgs.pkgsi686Linux.stdenv.cc.targetPrefix}cc"');

cargo test --target=i686-unknown-linux-gnu large_deallocation

#[test]
fn large_deallocation() {
    // static mut ARENA: [MaybeUninit<u8>; 3_000_000] = [MaybeUninit::uninit(); 3_000_000];
    // let mut heap = Heap::from_slice(unsafe { &mut ARENA });
    static mut ARENA: [u8; 3_000_000] = [0; 3_000_000];
    let mut heap = Heap::empty();
    unsafe {
        heap.init(ARENA.as_mut_ptr(), 2097152);
    }
    let layout = Layout::from_size_align(1048572, 4).unwrap();
    let data = heap
        .allocate_first_fit(layout)
        .expect("Succesful allocation");
    unsafe {
        heap.deallocate(data, layout);
    }
}
Dominant language
Rust
Stars
242
Forks
56
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rust-osdev/linked-list-allocator

All issues in rust-osdev/linked-list-allocator

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.