1use crate::state::{PluginState, State};
9use crate::{CapId, Capability, Error, PluginId, SecurityLevel, Size, Step};
10
11#[derive(Debug, Clone)]
27pub struct Kernel {
28 state: State,
29}
30
31impl Kernel {
32 pub fn new() -> Self {
34 Kernel {
35 state: State::empty(),
36 }
37 }
38
39 #[inline]
41 pub fn state(&self) -> &State {
42 &self.state
43 }
44
45 #[inline]
47 pub fn time(&self) -> u64 {
48 self.state.time()
49 }
50
51 pub fn tick(&mut self) -> Result<(), Error> {
57 self.state.tick()?;
58 Ok(())
59 }
60
61 pub fn execute(&mut self, step: &Step) -> Result<(), Error> {
70 let new_state = step.execute(&self.state)?;
71 self.state = new_state;
72 Ok(())
73 }
74
75 pub fn execute_mut(&mut self, step: &Step) -> Result<(), Error> {
86 step.execute_mut(&mut self.state).map_err(Error::Step)
87 }
88
89 pub fn register_plugin(
95 &mut self,
96 id: PluginId,
97 level: SecurityLevel,
98 mem_size: Size,
99 ) -> Result<(), Error> {
100 let ps = PluginState::empty(level, mem_size);
101 self.state.insert_plugin(id, ps)?;
102 Ok(())
103 }
104
105 pub fn plugin_level(&self, id: PluginId) -> Option<SecurityLevel> {
107 self.state.plugin_level(id)
108 }
109
110 pub fn get_cap(&self, cap_id: CapId) -> Option<&Capability> {
112 self.state.get_cap(cap_id)
113 }
114
115 pub fn cap_is_valid(&self, cap_id: CapId) -> bool {
117 self.state.cap_is_valid(cap_id)
118 }
119
120 pub fn plugin_holds(&self, pid: PluginId, cap_id: CapId) -> bool {
122 self.state.plugin_holds(pid, cap_id)
123 }
124
125 pub fn delegate_cap(
147 &mut self,
148 parent_id: CapId,
149 target: PluginId,
150 requested_rights: crate::Rights,
151 ) -> Result<CapId, Error> {
152 let parent = self
153 .state
154 .get_cap(parent_id)
155 .cloned()
156 .ok_or(crate::state::KernelError::CapNotFound(parent_id))?;
157
158 if !parent.is_valid() {
159 return Err(crate::CapabilityError::Revoked.into());
160 }
161
162 let child_rights = requested_rights.intersection(parent.rights());
163 if child_rights.is_empty() {
164 return Err(crate::CapabilityError::EmptyRights.into());
165 }
166
167 let id = self.state.kernel_mut().alloc_cap_id()?;
168 let epoch = self.state.kernel().key_epoch();
169 let payload = crate::CapPayload::new(
170 target,
171 parent.target(),
172 child_rights.clone(),
173 Some(parent_id),
174 epoch,
175 );
176 let sig = crate::crypto::seal_payload(self.state.kernel().hmac_key(), &payload);
177
178 let child = Capability::new(
179 id,
180 target,
181 parent.target(),
182 child_rights,
183 Some(parent_id),
184 epoch,
185 sig,
186 )?;
187
188 self.state.apply_cap_delegate_mut(child, target)?;
189 Ok(id)
190 }
191
192 pub fn insert_cap_raw(&mut self, cap: Capability, target: PluginId) -> Result<(), Error> {
200 self.state.apply_cap_delegate_mut(cap, target)?;
201 Ok(())
202 }
203
204 pub fn revoke_cap(&mut self, cap_id: CapId) -> Result<(), Error> {
213 self.state.apply_cap_revoke_mut(cap_id)?;
214 Ok(())
215 }
216
217 pub fn alloc(&mut self, owner: PluginId, size: Size) -> u64 {
219 self.state.apply_alloc_mut(owner, size)
220 }
221
222 pub fn free(&mut self, addr: u64) -> Result<(), Error> {
229 self.state.apply_free_mut(addr)?;
230 Ok(())
231 }
232
233 #[inline]
235 pub fn plugin_count(&self) -> usize {
236 self.state.plugin_count()
237 }
238
239 #[inline]
241 pub fn actor_count(&self) -> usize {
242 self.state.actor_count()
243 }
244
245 #[inline]
247 pub fn resource_count(&self) -> usize {
248 self.state.resource_count()
249 }
250
251 #[inline]
253 pub fn workflow_count(&self) -> usize {
254 self.state.workflow_count()
255 }
256}
257
258impl Default for Kernel {
259 fn default() -> Self {
260 Self::new()
261 }
262}
263
264#[cfg(test)]
265mod tests {
266 use super::*;
267 use crate::{KernelOp, Right, Rights};
268
269 #[test]
270 fn test_new_kernel() {
271 let k = Kernel::new();
272 assert_eq!(k.time(), 0);
273 assert_eq!(k.plugin_count(), 0);
274 }
275
276 #[test]
277 fn test_tick() {
278 let mut k = Kernel::new();
279 k.tick().unwrap();
280 assert_eq!(k.time(), 1);
281 k.tick().unwrap();
282 assert_eq!(k.time(), 2);
283 }
284
285 #[test]
286 fn test_register_plugin() {
287 let mut k = Kernel::new();
288 k.register_plugin(1, SecurityLevel::Public, 4096).unwrap();
289 assert_eq!(k.plugin_count(), 1);
290 assert_eq!(k.plugin_level(1), Some(SecurityLevel::Public));
291 }
292
293 #[test]
294 fn test_register_duplicate_plugin() {
295 let mut k = Kernel::new();
296 k.register_plugin(1, SecurityLevel::Public, 0).unwrap();
297 let result = k.register_plugin(1, SecurityLevel::Internal, 0);
298 assert!(result.is_err());
299 }
300
301 #[test]
302 fn test_delegate_and_revoke() {
303 let mut k = Kernel::new();
304 k.register_plugin(1, SecurityLevel::Public, 0).unwrap();
305
306 let cap = Capability::new(
308 100,
309 1,
310 1,
311 Rights::singleton(Right::Read),
312 None,
313 0,
314 crate::SealedTag::empty(),
315 )
316 .unwrap();
317
318 k.insert_cap_raw(cap, 1).unwrap();
319 assert!(k.cap_is_valid(100));
320 assert!(k.plugin_holds(1, 100));
321
322 k.revoke_cap(100).unwrap();
323 assert!(!k.cap_is_valid(100));
324 }
325
326 #[test]
327 fn test_delegate_cap_kernel_minted() {
328 let mut k = Kernel::new();
329 k.register_plugin(1, SecurityLevel::Public, 0).unwrap();
330 k.register_plugin(2, SecurityLevel::Public, 0).unwrap();
331
332 let root = Capability::new(
334 100,
335 1,
336 42,
337 Rights::singleton(Right::Read),
338 None,
339 0,
340 crate::SealedTag::empty(),
341 )
342 .unwrap();
343 k.insert_cap_raw(root, 1).unwrap();
344
345 let child_id = k
347 .delegate_cap(100, 2, Rights::singleton(Right::Read))
348 .unwrap();
349
350 assert!(k.cap_is_valid(child_id));
351 assert!(k.plugin_holds(2, child_id));
352
353 let child = k.get_cap(child_id).unwrap();
355 assert!(child.rights().is_subset_of(&Rights::singleton(Right::Read)));
356 assert_eq!(child.parent(), Some(100));
357 }
358
359 #[test]
360 fn test_delegate_cap_revoked_parent_fails() {
361 let mut k = Kernel::new();
362 k.register_plugin(1, SecurityLevel::Public, 0).unwrap();
363 k.register_plugin(2, SecurityLevel::Public, 0).unwrap();
364
365 let root = Capability::new(
366 100,
367 1,
368 42,
369 Rights::singleton(Right::Read),
370 None,
371 0,
372 crate::SealedTag::empty(),
373 )
374 .unwrap();
375 k.insert_cap_raw(root, 1).unwrap();
376 k.revoke_cap(100).unwrap();
377
378 let result = k.delegate_cap(100, 2, Rights::singleton(Right::Read));
380 assert!(result.is_err());
381 }
382
383 #[test]
384 fn test_delegate_cap_empty_rights_intersection_fails() {
385 let mut k = Kernel::new();
386 k.register_plugin(1, SecurityLevel::Public, 0).unwrap();
387 k.register_plugin(2, SecurityLevel::Public, 0).unwrap();
388
389 let root = Capability::new(
390 100,
391 1,
392 42,
393 Rights::singleton(Right::Read),
394 None,
395 0,
396 crate::SealedTag::empty(),
397 )
398 .unwrap();
399 k.insert_cap_raw(root, 1).unwrap();
400
401 let result = k.delegate_cap(100, 2, Rights::singleton(Right::Write));
403 assert!(result.is_err());
404 }
405
406 #[test]
407 fn test_alloc_and_free() {
408 let mut k = Kernel::new();
409 let addr = k.alloc(1, 1024);
410 k.free(addr).unwrap();
411 }
412
413 #[test]
414 fn test_execute_time_tick() {
415 let mut k = Kernel::new();
416 let step = Step::KernelInternal {
417 op: KernelOp::TimeTick,
418 };
419 k.execute(&step).unwrap();
420 assert_eq!(k.time(), 1);
421 }
422
423 fn assert_kernels_eq(a: &Kernel, b: &Kernel) {
427 assert_eq!(a.time(), b.time(), "time mismatch");
428 assert_eq!(a.plugin_count(), b.plugin_count(), "plugin_count mismatch");
429 assert_eq!(a.actor_count(), b.actor_count(), "actor_count mismatch");
430 assert_eq!(
431 a.resource_count(),
432 b.resource_count(),
433 "resource_count mismatch"
434 );
435 assert_eq!(
436 a.workflow_count(),
437 b.workflow_count(),
438 "workflow_count mismatch"
439 );
440 }
441
442 #[test]
443 fn test_equiv_time_tick() {
444 let base = Kernel::new();
445
446 let mut k_pure = base.clone();
447 let mut k_mut = base;
448
449 let step = Step::KernelInternal {
450 op: KernelOp::TimeTick,
451 };
452
453 k_pure.execute(&step).unwrap();
454 k_mut.execute_mut(&step).unwrap();
455
456 assert_kernels_eq(&k_pure, &k_mut);
457 }
458
459 #[test]
460 fn test_equiv_plugin_internal() {
461 use crate::state::ActorRuntime;
462 use crate::step::PluginInternal;
463
464 let mut base = Kernel::new();
465 base.register_plugin(1, SecurityLevel::Public, 1024)
466 .unwrap();
467 base.state.insert_actor(1, ActorRuntime::empty(10)).unwrap();
469
470 let mut k_pure = base.clone();
471 let mut k_mut = base;
472
473 let step = Step::PluginInternal {
474 pid: 1,
475 pi: PluginInternal::with_writes(vec![(0, 64)]),
476 };
477
478 k_pure.execute(&step).unwrap();
479 k_mut.execute_mut(&step).unwrap();
480
481 assert_kernels_eq(&k_pure, &k_mut);
482 assert_eq!(
483 k_pure.plugin_level(1),
484 k_mut.plugin_level(1),
485 "plugin level diverged"
486 );
487 }
488
489 #[test]
490 fn test_equiv_route_one() {
491 use crate::state::{ActorRuntime, Message};
492
493 let mut base = Kernel::new();
494 let mut actor = ActorRuntime::empty(10);
495 actor.enqueue_pending_mut(Message::new(1, 2, 1, SecurityLevel::Public, vec![1, 2]));
496 base.state.insert_actor(1, actor).unwrap();
497
498 let mut k_pure = base.clone();
499 let mut k_mut = base;
500
501 let step = Step::KernelInternal {
502 op: KernelOp::RouteOne { dst: 1 },
503 };
504
505 k_pure.execute(&step).unwrap();
506 k_mut.execute_mut(&step).unwrap();
507
508 assert_kernels_eq(&k_pure, &k_mut);
509
510 let a_pure = k_pure.state().get_actor(1).unwrap();
511 let a_mut = k_mut.state().get_actor(1).unwrap();
512 assert_eq!(a_pure.pending_len(), a_mut.pending_len());
513 assert_eq!(a_pure.mailbox_len(), a_mut.mailbox_len());
514 }
515
516 #[test]
517 fn test_equiv_unblock_send() {
518 use crate::state::ActorRuntime;
519
520 let mut base = Kernel::new();
521 let mut actor = ActorRuntime::empty(10);
522 actor.set_blocked_mut(42);
523 base.state.insert_actor(1, actor).unwrap();
524
525 let mut k_pure = base.clone();
526 let mut k_mut = base;
527
528 let step = Step::KernelInternal {
529 op: KernelOp::UnblockSend { dst: 1 },
530 };
531
532 k_pure.execute(&step).unwrap();
533 k_mut.execute_mut(&step).unwrap();
534
535 assert_kernels_eq(&k_pure, &k_mut);
536
537 let a_pure = k_pure.state().get_actor(1).unwrap();
538 let a_mut = k_mut.state().get_actor(1).unwrap();
539 assert_eq!(a_pure.is_blocked(), a_mut.is_blocked());
540 assert!(!a_pure.is_blocked());
541 }
542
543 #[test]
544 fn test_equiv_mem_free() {
545 let mut base = Kernel::new();
546 let addr = base.alloc(1, 256);
547
548 let mut k_pure = base.clone();
549 let mut k_mut = base;
550
551 let step = Step::MemFree { caller: 1, addr };
552
553 k_pure.execute(&step).unwrap();
554 k_mut.execute_mut(&step).unwrap();
555
556 assert_kernels_eq(&k_pure, &k_mut);
557 assert!(k_pure.state().ghost().is_freed(addr));
558 assert!(k_mut.state().ghost().is_freed(addr));
559 }
560
561 #[test]
562 fn test_equiv_cap_revoke() {
563 let mut base = Kernel::new();
564 base.register_plugin(1, SecurityLevel::Public, 0).unwrap();
565
566 let cap = Capability::new(
567 100,
568 1,
569 42,
570 Rights::singleton(Right::Read),
571 None,
572 0,
573 crate::SealedTag::empty(),
574 )
575 .unwrap();
576 base.insert_cap_raw(cap, 1).unwrap();
577
578 let mut k_pure = base.clone();
579 let mut k_mut = base;
580
581 let step = Step::CapRevoke {
582 caller: 1,
583 cap_id: 100,
584 };
585
586 k_pure.execute(&step).unwrap();
587 k_mut.execute_mut(&step).unwrap();
588
589 assert_kernels_eq(&k_pure, &k_mut);
590 assert!(!k_pure.cap_is_valid(100));
591 assert!(!k_mut.cap_is_valid(100));
592 }
593
594 #[test]
595 fn test_equiv_cap_revoke_delegation_tree() {
596 let mut base = Kernel::new();
597 base.register_plugin(1, SecurityLevel::Public, 0).unwrap();
598
599 let cap_root = Capability::new(
601 100,
602 1,
603 42,
604 Rights::singleton(Right::Read),
605 None,
606 0,
607 crate::SealedTag::empty(),
608 )
609 .unwrap();
610 base.insert_cap_raw(cap_root, 1).unwrap();
611
612 let cap_child = Capability::new(
613 101,
614 1,
615 42,
616 Rights::singleton(Right::Read),
617 Some(100),
618 0,
619 crate::SealedTag::empty(),
620 )
621 .unwrap();
622 base.insert_cap_raw(cap_child, 1).unwrap();
623
624 let cap_grandchild = Capability::new(
625 102,
626 1,
627 42,
628 Rights::singleton(Right::Read),
629 Some(101),
630 0,
631 crate::SealedTag::empty(),
632 )
633 .unwrap();
634 base.insert_cap_raw(cap_grandchild, 1).unwrap();
635
636 let cap_unrelated = Capability::new(
637 103,
638 1,
639 42,
640 Rights::singleton(Right::Read),
641 None,
642 0,
643 crate::SealedTag::empty(),
644 )
645 .unwrap();
646 base.insert_cap_raw(cap_unrelated, 1).unwrap();
647
648 let mut k_pure = base.clone();
649 let mut k_mut = base;
650
651 let step = Step::CapRevoke {
652 caller: 1,
653 cap_id: 100,
654 };
655
656 k_pure.execute(&step).unwrap();
657 k_mut.execute_mut(&step).unwrap();
658
659 assert_kernels_eq(&k_pure, &k_mut);
660
661 assert!(!k_pure.cap_is_valid(100));
663 assert!(!k_pure.cap_is_valid(101));
664 assert!(!k_pure.cap_is_valid(102));
665 assert!(k_pure.cap_is_valid(103));
667
668 assert!(!k_mut.cap_is_valid(100));
670 assert!(!k_mut.cap_is_valid(101));
671 assert!(!k_mut.cap_is_valid(102));
672 assert!(k_mut.cap_is_valid(103));
673 }
674
675 #[test]
676 fn test_equiv_error_paths_match() {
677 let mut k_pure = Kernel::new();
679 let addr = k_pure.alloc(1, 256);
680 k_pure.free(addr).unwrap();
681 let mut k_mut = k_pure.clone();
682
683 let step = Step::MemFree { caller: 1, addr };
684
685 let r_pure = k_pure.execute(&step);
686 let r_mut = k_mut.execute_mut(&step);
687
688 assert!(r_pure.is_err(), "pure should fail on double-free");
689 assert!(r_mut.is_err(), "mut should fail on double-free");
690 }
691}