#![cfg(feature = "alloc-core")]
use std::alloc::Layout;
use std::ptr;
use sefer_alloc::AllocCore;
fn exhibit_mixed_class_page(
a: &mut AllocCore,
seed_layout: Layout,
probe_layout: Layout,
) -> Option<(*mut u8, usize, usize, Layout)> {
for _ in 0..32 {
let _ = a.alloc(seed_layout);
}
for _ in 0..64 {
let p = a.alloc(probe_layout);
if p.is_null() {
continue;
}
let pm = match a.dbg_page_map_class_for(p) {
Some(c) => c,
None => continue,
};
let lc = match a.dbg_layout_class_for(probe_layout) {
Some(c) => c,
None => continue,
};
if pm != lc {
return Some((p, lc, pm, probe_layout));
}
}
None
}
#[test]
fn dealloc_uses_layout_class_not_page_map_on_mixed_class_page() {
let mut a = AllocCore::new().unwrap();
let seed_layout = Layout::from_size_align(16, 16).unwrap();
let probe_layout = Layout::from_size_align(48, 16).unwrap();
let (block, layout_class, page_map_class, block_layout) =
match exhibit_mixed_class_page(&mut a, seed_layout, probe_layout) {
Some(x) => x,
None => {
panic!(
"test precondition failed: no mixed-class page exhibited; \
the counterfactual cannot be exercised. The bump/refill \
geometry changed and this test needs a new seeding strategy."
);
}
};
assert_ne!(
layout_class, page_map_class,
"vacuous: page_map class matches Layout class"
);
let canary: u64 = 0xDE_AD_BE_EF_C0_FF_EE_11;
unsafe { ptr::write(block.add(8) as *mut u64, canary) };
a.dealloc(block, block_layout);
let mut pm_layout = None;
for bs in 1..=4096 {
let candidate = Layout::from_size_align(bs, 16).unwrap();
if a.dbg_layout_class_for(candidate) == Some(page_map_class) {
pm_layout = Some(candidate);
break;
}
}
let pm_layout = pm_layout.expect("a layout resolving to page_map_class exists in small range");
for _ in 0..256 {
let p = a.alloc(pm_layout);
assert!(!p.is_null(), "page_map-class alloc returned null");
let observed = unsafe { ptr::read(p.add(8) as *const u64) };
assert_ne!(
observed, canary,
"page_map-class alloc returned the Layout-class block — dealloc \
derived the class from page_map (the §13 mixed-class bug)"
);
}
let mut found_reuse = false;
for _ in 0..256 {
let p = a.alloc(block_layout);
assert!(!p.is_null(), "Layout-class alloc returned null");
let observed = unsafe { ptr::read(p.add(8) as *const u64) };
if observed == canary {
found_reuse = true;
break;
}
}
assert!(
found_reuse,
"the freed block did NOT resurface on a Layout-class alloc — dealloc \
did not place it in the Layout class's free list (routing bug)"
);
}
#[test]
fn dealloc_uses_layout_class_big_then_tiny_mixed_page() {
let mut a = AllocCore::new().unwrap();
let (block, layout_class, page_map_class, block_layout) = match exhibit_mixed_class_page(
&mut a,
Layout::from_size_align(1024, 16).unwrap(),
Layout::from_size_align(16, 16).unwrap(),
) {
Some(x) => x,
None => {
panic!(
"test precondition failed: no mixed-class page exhibited \
(big→tiny). The bump/refill geometry changed and this test \
needs a new seeding strategy."
);
}
};
assert_ne!(layout_class, page_map_class);
let canary: u64 = 0xCA_FE_BA_BE_12_34_56_78;
unsafe { ptr::write(block.add(8) as *mut u64, canary) };
a.dealloc(block, block_layout);
let mut pm_layout = None;
for bs in 1..=4096 {
let candidate = Layout::from_size_align(bs, 16).unwrap();
if a.dbg_layout_class_for(candidate) == Some(page_map_class) {
pm_layout = Some(candidate);
break;
}
}
let pm_layout = pm_layout.expect("a layout resolving to page_map_class exists");
for _ in 0..256 {
let p = a.alloc(pm_layout);
assert!(!p.is_null());
let observed = unsafe { ptr::read(p.add(8) as *const u64) };
assert_ne!(
observed, canary,
"page_map-class alloc returned the tiny block — dealloc used \
page_map (§13 bug)"
);
}
let mut found = false;
for _ in 0..256 {
let p = a.alloc(block_layout);
assert!(!p.is_null());
if unsafe { ptr::read(p.add(8) as *const u64) } == canary {
found = true;
break;
}
}
assert!(found, "freed block did not resurface (routing bug)");
}