Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

sc-allocator: Do not panic on invalid header pointer #13925

Merged
merged 1 commit into from
Apr 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions client/allocator/src/freeing_bump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,11 @@ impl FreeingBumpHeapAllocator {

let header_ptr: u32 = match self.free_lists[order] {
Link::Ptr(header_ptr) => {
assert!(
u64::from(header_ptr + order.size() + HEADER_SIZE) <= mem.size(),
"Pointer is looked up in list of free entries, into which
only valid values are inserted; qed"
);
if (u64::from(header_ptr) + u64::from(order.size()) + u64::from(HEADER_SIZE)) >
mem.size()
{
return Err(error("Invalid header pointer detected"))
Copy link
Member

@ggwpez ggwpez Apr 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will poison the heap now. Could you please add this to the test?

I assume this is intended as per doc: Once the allocator has returned an error all subsequent requests will return an error..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will abort on the first allocation error any way.

}

// Remove this header from the free list.
let next_free = Header::read_from(mem, header_ptr)?
Expand Down Expand Up @@ -1106,4 +1106,25 @@ mod tests {

assert_eq!(3, mem.pages());
}

#[test]
fn modifying_the_header_leads_to_an_error() {
let mut mem = MemoryInstance::with_pages(1);
let mut heap = FreeingBumpHeapAllocator::new(0);

let ptr = heap.allocate(&mut mem, 5).unwrap();

heap.deallocate(&mut mem, ptr).unwrap();

Header::Free(Link::Ptr(u32::MAX - 1))
.write_into(&mut mem, u32::from(ptr) - HEADER_SIZE)
.unwrap();

heap.allocate(&mut mem, 5).unwrap();
assert!(heap
.allocate(&mut mem, 5)
.unwrap_err()
.to_string()
.contains("Invalid header pointer"));
}
}