feat(kernel): derivation-tree revocation, region caps
- caps record parent (mint/delegate/ipc), CapRef w/ pid+slot gens - Revoke = delete subtree, keep self; drop/death re-parents children - CreateRegion/MapRegion; mapping lives only as long as its cap - drop Permission::Revoke + object-wide revoke - mint any cap (badge only ep/ntfn), process caps delegable - kani: descendants == subtree; model-based fuzz vs spec
This commit is contained in:
@@ -109,7 +109,6 @@ fn restrict_to_cannot_add_permissions() {
|
||||
Permission::Write,
|
||||
Permission::Execute,
|
||||
Permission::Delegate,
|
||||
Permission::Revoke,
|
||||
]);
|
||||
|
||||
let result = read_only.restrict_to(&wants_everything);
|
||||
@@ -118,7 +117,6 @@ fn restrict_to_cannot_add_permissions() {
|
||||
assert!(!result.allows(Permission::Write));
|
||||
assert!(!result.allows(Permission::Execute));
|
||||
assert!(!result.allows(Permission::Delegate));
|
||||
assert!(!result.allows(Permission::Revoke));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -138,7 +136,6 @@ fn empty_permission_set_allows_nothing() {
|
||||
assert!(!empty.allows(Permission::Write));
|
||||
assert!(!empty.allows(Permission::Execute));
|
||||
assert!(!empty.allows(Permission::Delegate));
|
||||
assert!(!empty.allows(Permission::Revoke));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -150,3 +147,45 @@ fn capability_preserves_resource_and_permissions() {
|
||||
assert_eq!(cap.permissions(), &expected_permissions);
|
||||
assert_eq!(cap.generation(), &Generation::initial());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn removing_a_cap_changes_its_slot_generation() {
|
||||
let mut table = CapabilityTable::new();
|
||||
let slot = table.insert(endpoint_cap(1, &[Permission::Read])).unwrap();
|
||||
let before = table.slot_generation(slot).unwrap();
|
||||
table.remove(slot).unwrap();
|
||||
assert_eq!(
|
||||
table.slot_generation(slot),
|
||||
None,
|
||||
"empty slots have no generation"
|
||||
);
|
||||
let again = table.insert(endpoint_cap(2, &[Permission::Read])).unwrap();
|
||||
assert_eq!(again, slot);
|
||||
assert!(!before.is_valid_against(&table.slot_generation(again).unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iter_lists_occupied_slots() {
|
||||
let mut table = CapabilityTable::new();
|
||||
let a = table.insert(endpoint_cap(1, &[])).unwrap();
|
||||
let b = table.insert(endpoint_cap(2, &[])).unwrap();
|
||||
table.remove(a).unwrap();
|
||||
let slots: [Option<types::bounded::CapSlot>; 2] = {
|
||||
let mut it = table.iter().map(|(s, _)| s);
|
||||
[it.next(), it.next()]
|
||||
};
|
||||
assert_eq!(slots, [Some(b), None]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn caps_record_their_parent() {
|
||||
let parent = CapRef {
|
||||
process: types::id::ProcessId::from_raw(3),
|
||||
process_generation: Generation::initial(),
|
||||
slot: types::bounded::CapSlot::new(4).unwrap(),
|
||||
slot_generation: Generation::initial(),
|
||||
};
|
||||
let cap = endpoint_cap(1, &[]).with_parent(Some(parent));
|
||||
assert_eq!(cap.parent(), Some(parent));
|
||||
assert_eq!(endpoint_cap(1, &[]).parent(), None);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user