fix(kernel): length function should return 0 for invalid offsets (#635)

Fixes #634 

- Updates `extism_length` to walks the allocation list to determine
valid offsets instead of assuming the provided offset is valid

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: zshipko <zshipko@users.noreply.github.com>
This commit is contained in:
zach
2023-12-14 16:55:13 -08:00
committed by GitHub
parent 49e28892bc
commit fd95729d8d
3 changed files with 25 additions and 4 deletions

View File

@@ -306,9 +306,26 @@ impl MemoryRoot {
if !Self::pointer_in_bounds_fast(offs) {
return None;
}
let ptr = offs - core::mem::size_of::<MemoryBlock>() as u64;
let ptr = ptr as *mut MemoryBlock;
Some(&mut *ptr)
// Get the first block
let mut block = self.blocks.as_mut_ptr();
// Only loop while the block pointer is less then the current position
while (block as u64) < self.blocks.as_ptr() as u64 + offs {
let b = &mut *block;
// Get the block status, this lets us know if we are able to re-use it
let status = b.status.load(Ordering::Acquire);
if status == MemoryStatus::Active as u8 && b.data.as_ptr() as Pointer == offs {
return Some(b);
}
// Get the next block
block = b.next_ptr();
}
None
}
}

Binary file not shown.

View File

@@ -198,6 +198,10 @@ fn test_kernel_allocations() {
// 512 bytes, test block re-use + splitting
let p = extism_alloc(&mut store, instance, 512);
assert_eq!(extism_length(&mut store, instance, p), 512);
assert_eq!(extism_length(&mut store, instance, p + 1), 0);
assert_eq!(extism_length(&mut store, instance, p + 2), 0);
assert_eq!(extism_length(&mut store, instance, p + 3), 0);
assert_eq!(extism_length(&mut store, instance, p + 4), 0);
extism_free(&mut store, instance, p);
// 128 bytes, should be split off the 512 byte block
@@ -210,7 +214,7 @@ fn test_kernel_allocations() {
let r = extism_alloc(&mut store, instance, 128);
assert!(p <= r && r < p + 512);
assert!(r > p);
assert_eq!(extism_length(&mut store, instance, q), 128);
assert_eq!(extism_length(&mut store, instance, r), 128);
extism_free(&mut store, instance, q);
// 100 pages