byteflow/scheduler/
delegate.rs1use crate::bytecode::{Cap, CapRights, NativeMask, RevocationCell};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum DelegateError {
13 SourceRevoked,
14 SourceLacksNative,
16}
17
18impl std::fmt::Display for DelegateError {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 DelegateError::SourceRevoked => f.write_str("delegate: source capability revoked"),
22 DelegateError::SourceLacksNative => {
23 f.write_str("delegate: source lacks NATIVE right")
24 }
25 }
26 }
27}
28
29impl std::error::Error for DelegateError {}
30
31pub fn exec_delegate(
32 src: &Cap,
33 src_cell: &RevocationCell,
34 want_rights: CapRights,
35 want_native: Option<&NativeMask>,
36) -> Result<Cap, DelegateError> {
37 if !src.is_valid(src_cell) {
38 return Err(DelegateError::SourceRevoked);
39 }
40 if want_native.is_some() && !src.rights.contains(CapRights::NATIVE) {
41 return Err(DelegateError::SourceLacksNative);
42 }
43 Ok(src.attenuate(want_rights, want_native))
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use crate::bytecode::{CapTarget, RevocationCell};
50
51 #[test]
52 fn cannot_escalate_via_delegate_regardless_of_requested_mask() {
53 let cell = RevocationCell::new();
54 let src = Cap::root(CapTarget::Flow(1), CapRights::SEND, None, &cell);
55 let out = match exec_delegate(
56 &src,
57 &cell,
58 CapRights::SEND.union(CapRights::ADMIN).union(CapRights::NATIVE),
59 None,
60 ) {
61 Ok(c) => c,
62 Err(_) => {
63 assert!(false, "delegate of live SEND cap must succeed");
64 return;
65 }
66 };
67 assert!(out.rights.contains(CapRights::SEND));
68 assert!(!out.rights.contains(CapRights::ADMIN));
69 assert!(!out.rights.contains(CapRights::NATIVE));
70 }
71
72 #[test]
73 fn revoked_source_cannot_delegate() {
74 let cell = RevocationCell::new();
75 let src = Cap::root(CapTarget::Flow(1), CapRights::SEND, None, &cell);
76 cell.revoke();
77 assert!(matches!(
78 exec_delegate(&src, &cell, CapRights::SEND, None),
79 Err(DelegateError::SourceRevoked)
80 ));
81 }
82}