feat(kernel): shared ABI decoder+proofs, no-panic gate, syscall storm, kani on shrunk kernel

This commit is contained in:
2026-10-26 23:44:09 +01:00
parent 154599e3af
commit 130a82f50d
41 changed files with 1583 additions and 404 deletions

View File

@@ -8,21 +8,26 @@
/// always exists before it does.
pub fn descendants<const N: usize>(parents: &[Option<u16>; N], root: usize) -> [bool; N] {
let mut marked = [false; N];
if root >= N {
let Some(r) = marked.get_mut(root) else {
return marked;
}
marked[root] = true;
};
*r = true;
// Each pass extends the marked set by at least one generation of
// children; a chain in an N-node forest is at most N - 1 long.
for _ in 0..N {
let mut changed = false;
for i in 0..N {
if !marked[i]
&& let Some(p) = parents[i].map(usize::from)
&& p < N
&& marked[p]
let parent_marked = parents
.get(i)
.copied()
.flatten()
.and_then(|p| marked.get(usize::from(p)).copied())
.unwrap_or(false);
if let Some(m) = marked.get_mut(i)
&& !*m
&& parent_marked
{
marked[i] = true;
*m = true;
changed = true;
}
}

View File

@@ -101,15 +101,20 @@ impl CapabilityTable {
}
}
fn slot(&self, slot: CapSlot) -> Option<&Capability> {
self.slots.get(slot.value() as usize)?.as_ref()
}
/// Generation of an occupied slot.
pub fn slot_generation(&self, slot: CapSlot) -> Option<Generation> {
self.slots[slot.value() as usize].as_ref()?;
self.slot(slot)?;
self.generations.current(slot.value() as usize)
}
pub fn get_mut(&mut self, slot: CapSlot) -> Result<&mut Capability, KernelError> {
self.slots[slot.value() as usize]
.as_mut()
self.slots
.get_mut(slot.value() as usize)
.and_then(Option::as_mut)
.ok_or(KernelError::InvalidSlot(slot))
}
@@ -121,27 +126,28 @@ impl CapabilityTable {
}
pub fn get(&self, slot: CapSlot) -> Result<&Capability, KernelError> {
let idx = slot.value() as usize;
self.slots[idx]
.as_ref()
.ok_or(KernelError::InvalidSlot(slot))
self.slot(slot).ok_or(KernelError::InvalidSlot(slot))
}
pub fn insert(&mut self, cap: Capability) -> Result<CapSlot, KernelError> {
let idx = (0..MAX_CAPS_PER_PROCESS)
.find(|&i| self.slots[i].is_none() && self.generations.is_usable(i))
let generations = &self.generations;
let (idx, free) = self
.slots
.iter_mut()
.enumerate()
.find(|(i, s)| s.is_none() && generations.is_usable(*i))
.ok_or(KernelError::NoFreeSlot)?;
self.slots[idx] = Some(cap);
CapSlot::new(idx as u8).ok_or(KernelError::NoFreeSlot)
let slot = CapSlot::new(idx as u8).ok_or(KernelError::NoFreeSlot)?;
*free = Some(cap);
Ok(slot)
}
pub fn remove(&mut self, slot: CapSlot) -> Result<(), KernelError> {
let idx = slot.value() as usize;
if self.slots[idx].is_none() {
let taken = self.slots.get_mut(idx).and_then(Option::take);
if taken.is_none() {
return Err(KernelError::InvalidSlot(slot));
}
self.slots[idx] = None;
self.generations.advance(idx);
Ok(())
}