use platform::Platform; use super::{SyscallOutcome, SyscallResult}; use crate::Kernel; impl Kernel

{ 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) } }