73 lines
2.3 KiB
Rust
73 lines
2.3 KiB
Rust
use super::*;
|
|
use crate::{SyscallOutcome, SyscallResult};
|
|
use domain::syscall::Syscall;
|
|
use types::address::DataRef;
|
|
use types::bounded::CapSlot;
|
|
use types::permission::PermissionSet;
|
|
|
|
#[test]
|
|
fn delegate_without_delegate_permission_fails() {
|
|
let (mut k, _) = kernel_with_process();
|
|
// slot 0 has ProcessCreate cap — no Delegate permission
|
|
let outcome = k.handle_syscall(Syscall::Delegate {
|
|
slot: CapSlot::new(0).unwrap(),
|
|
to_endpoint: CapSlot::new(1).unwrap(),
|
|
permissions: PermissionSet::empty(),
|
|
});
|
|
assert!(matches!(
|
|
outcome,
|
|
SyscallOutcome::Complete(SyscallResult::Error(_))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn delegate_with_valid_cap_succeeds() {
|
|
let (mut k, pid) = kernel_with_process();
|
|
|
|
// Create a second process to delegate to
|
|
let target_slot = match k.handle_syscall(Syscall::CreateProcess {
|
|
create_cap: CapSlot::new(0).unwrap(),
|
|
image: DataRef::empty(),
|
|
}) {
|
|
SyscallOutcome::Complete(SyscallResult::Slot(s)) => s,
|
|
_ => panic!("expected slot"),
|
|
};
|
|
|
|
// Grant a delegatable cap to the caller (endpoint cap with Delegate perm)
|
|
let ep_id = k.create_endpoint_for_test();
|
|
let source_slot = k.grant_cap_for_test(
|
|
pid,
|
|
domain::resource::Resource::Endpoint(ep_id),
|
|
PermissionSet::empty()
|
|
.with(types::permission::Permission::Read)
|
|
.with(types::permission::Permission::Delegate),
|
|
);
|
|
|
|
let outcome = k.handle_syscall(Syscall::Delegate {
|
|
slot: source_slot,
|
|
to_endpoint: target_slot, // using process cap as target identifier
|
|
permissions: PermissionSet::empty().with(types::permission::Permission::Read),
|
|
});
|
|
assert!(matches!(
|
|
outcome,
|
|
SyscallOutcome::Complete(SyscallResult::Slot(_))
|
|
));
|
|
}
|
|
|
|
// --- Generation-based revocation ---
|
|
|
|
#[test]
|
|
fn every_representable_slot_is_rejected_not_panicking() {
|
|
let (mut k, _) = kernel_with_process();
|
|
for raw in 1..=CapSlot::MAX {
|
|
let outcome = k.handle_syscall(Syscall::Send {
|
|
endpoint: CapSlot::new(raw).unwrap(),
|
|
message: domain::message::Message::empty(),
|
|
});
|
|
assert!(
|
|
matches!(outcome, SyscallOutcome::Complete(SyscallResult::Error(_))),
|
|
"slot {raw} should be an error"
|
|
);
|
|
}
|
|
}
|