- FrameTable: per-frame owner/use, replaces PagePool + ProcessMemory - Quota per process, page tables charged to owner - Regions for shared mem + device MMIO, torn down w/ owner - Platform: create/destroy AS, map/unmap, zero_frame; drop translate_va - RequestPages/ReleasePages/MapPage(move) checked vs kernel records - user window 0x1000..32MiB, private pts by construction - boot loader + device setup go through kernel api - kernel built in place, boot allocator bounded - isolation tests, randomized invariant test, FrameTable kani proofs - fixes: inflated release, unmapped release, dst va unchecked, heap overflow, unbounded pt alloc, unzeroed frames, double free
63 lines
2.2 KiB
Rust
63 lines
2.2 KiB
Rust
use platform::Platform;
|
|
|
|
use super::{SyscallOutcome, SyscallResult};
|
|
use crate::Kernel;
|
|
|
|
impl<P: Platform> Kernel<P> {
|
|
pub(crate) fn handle_delegate(
|
|
&mut self,
|
|
caller_pid: types::id::ProcessId,
|
|
slot: types::bounded::CapSlot,
|
|
to_endpoint: types::bounded::CapSlot,
|
|
restrict: types::permission::PermissionSet,
|
|
) -> SyscallOutcome {
|
|
let (resource, permissions) =
|
|
match self.check_cap(caller_pid, slot, types::permission::Permission::Delegate) {
|
|
Ok(cap) => (cap.resource().clone(), *cap.permissions()),
|
|
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
|
};
|
|
|
|
let restricted = permissions.restrict_to(&restrict);
|
|
|
|
let target_pid = match self.check_cap(
|
|
caller_pid,
|
|
to_endpoint,
|
|
types::permission::Permission::Execute,
|
|
) {
|
|
Ok(cap) => match cap.resource() {
|
|
domain::resource::Resource::Process(pid) => *pid,
|
|
_ => {
|
|
return SyscallOutcome::Complete(SyscallResult::Error(
|
|
domain::error::KernelError::PermissionDenied {
|
|
slot: to_endpoint,
|
|
needed: types::permission::Permission::Execute,
|
|
},
|
|
));
|
|
}
|
|
},
|
|
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
|
};
|
|
|
|
if let Err(e) = self.grant_cap(target_pid, resource, restricted) {
|
|
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
|
}
|
|
|
|
SyscallOutcome::Complete(SyscallResult::Ok)
|
|
}
|
|
|
|
pub(crate) fn handle_revoke(
|
|
&mut self,
|
|
caller_pid: types::id::ProcessId,
|
|
slot: types::bounded::CapSlot,
|
|
) -> SyscallOutcome {
|
|
let resource = match self.check_cap(caller_pid, slot, types::permission::Permission::Revoke)
|
|
{
|
|
Ok(cap) => cap.resource().clone(),
|
|
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
|
};
|
|
|
|
self.revoke_resource(&resource);
|
|
SyscallOutcome::Complete(SyscallResult::Ok)
|
|
}
|
|
}
|