1use crate::manifest::RvfManifest;
9use ruvix_cap::BootCapabilitySet;
10use ruvix_types::{CapRights, KernelError, ObjectType};
11
12#[cfg(feature = "alloc")]
13use alloc::vec::Vec;
14
15#[derive(Debug, Clone)]
17pub struct CapabilityDistribution {
18 #[cfg(feature = "alloc")]
20 pub component_grants: Vec<ComponentCapabilityGrant>,
21 #[cfg(not(feature = "alloc"))]
23 pub component_grants: [Option<ComponentCapabilityGrant>; 256],
24 #[cfg(not(feature = "alloc"))]
26 pub grant_count: usize,
27
28 pub root_dropped_to_minimum: bool,
30
31 pub root_minimum_set: MinimumCapabilitySet,
33}
34
35impl CapabilityDistribution {
36 pub fn from_manifest(
38 manifest: &RvfManifest,
39 _boot_capabilities: &BootCapabilitySet,
40 ) -> Result<Self, KernelError> {
41 let mut distribution = Self {
42 #[cfg(feature = "alloc")]
43 component_grants: Vec::new(),
44 #[cfg(not(feature = "alloc"))]
45 component_grants: [const { None }; 256],
46 #[cfg(not(feature = "alloc"))]
47 grant_count: 0,
48 root_dropped_to_minimum: false,
49 root_minimum_set: MinimumCapabilitySet::default(),
50 };
51
52 distribution.create_grants_from_manifest(manifest)?;
54
55 Ok(distribution)
56 }
57
58 fn create_grants_from_manifest(&mut self, manifest: &RvfManifest) -> Result<(), KernelError> {
59 let component_count = manifest.component_graph.component_count();
64
65 for i in 0..component_count {
66 if i >= 256 {
67 return Err(KernelError::LimitExceeded);
68 }
69
70 let grant = ComponentCapabilityGrant {
72 component_index: i as u32,
73 grants: [None; 32],
74 grant_count: 0,
75 };
76
77 #[cfg(feature = "alloc")]
78 self.component_grants.push(grant);
79 #[cfg(not(feature = "alloc"))]
80 {
81 self.component_grants[i] = Some(grant);
82 self.grant_count += 1;
83 }
84 }
85
86 Ok(())
87 }
88
89 #[inline]
91 #[must_use]
92 pub fn grant_count(&self) -> usize {
93 #[cfg(feature = "alloc")]
94 {
95 self.component_grants.len()
96 }
97 #[cfg(not(feature = "alloc"))]
98 {
99 self.grant_count
100 }
101 }
102}
103
104#[derive(Debug, Clone)]
106pub struct ComponentCapabilityGrant {
107 pub component_index: u32,
109
110 pub grants: [Option<CapabilityGrant>; 32],
112
113 pub grant_count: usize,
115}
116
117impl ComponentCapabilityGrant {
118 pub fn add_grant(&mut self, grant: CapabilityGrant) -> Result<(), KernelError> {
120 if self.grant_count >= 32 {
121 return Err(KernelError::LimitExceeded);
122 }
123
124 self.grants[self.grant_count] = Some(grant);
125 self.grant_count += 1;
126 Ok(())
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq)]
132#[repr(C)]
133pub struct CapabilityGrant {
134 pub object_id: u64,
136
137 pub object_type: ObjectType,
139
140 pub rights: CapRights,
142
143 pub badge: u64,
145}
146
147impl CapabilityGrant {
148 #[must_use]
150 pub const fn new(
151 object_id: u64,
152 object_type: ObjectType,
153 rights: CapRights,
154 badge: u64,
155 ) -> Self {
156 Self {
157 object_id,
158 object_type,
159 rights,
160 badge,
161 }
162 }
163
164 #[must_use]
166 pub const fn region_readonly(object_id: u64, badge: u64) -> Self {
167 Self {
168 object_id,
169 object_type: ObjectType::Region,
170 rights: CapRights::READ,
171 badge,
172 }
173 }
174
175 #[must_use]
177 pub const fn region_readwrite(object_id: u64, badge: u64) -> Self {
178 Self {
179 object_id,
180 object_type: ObjectType::Region,
181 rights: CapRights::READ.union(CapRights::WRITE),
182 badge,
183 }
184 }
185
186 #[must_use]
188 pub const fn queue_send(object_id: u64, badge: u64) -> Self {
189 Self {
190 object_id,
191 object_type: ObjectType::Queue,
192 rights: CapRights::WRITE,
193 badge,
194 }
195 }
196
197 #[must_use]
199 pub const fn queue_recv(object_id: u64, badge: u64) -> Self {
200 Self {
201 object_id,
202 object_type: ObjectType::Queue,
203 rights: CapRights::READ,
204 badge,
205 }
206 }
207}
208
209#[derive(Debug, Clone, Default)]
216pub struct MinimumCapabilitySet {
217 pub witness_log: Option<CapabilityGrant>,
219
220 pub timer: Option<CapabilityGrant>,
222
223 pub self_task: Option<CapabilityGrant>,
225
226 pub syscall_queue: Option<CapabilityGrant>,
228}
229
230impl MinimumCapabilitySet {
231 #[must_use]
233 pub fn for_root_task(
234 witness_log_id: u64,
235 timer_id: u64,
236 task_id: u64,
237 syscall_queue_id: u64,
238 ) -> Self {
239 Self {
240 witness_log: Some(CapabilityGrant::new(
241 witness_log_id,
242 ObjectType::WitnessLog,
243 CapRights::WRITE, 0,
245 )),
246 timer: Some(CapabilityGrant::new(
247 timer_id,
248 ObjectType::Timer,
249 CapRights::READ.union(CapRights::WRITE),
250 0,
251 )),
252 self_task: Some(CapabilityGrant::new(
253 task_id,
254 ObjectType::Task,
255 CapRights::READ.union(CapRights::EXECUTE),
256 0,
257 )),
258 syscall_queue: Some(CapabilityGrant::new(
259 syscall_queue_id,
260 ObjectType::Queue,
261 CapRights::READ.union(CapRights::WRITE),
262 0,
263 )),
264 }
265 }
266
267 #[inline]
269 #[must_use]
270 pub fn count(&self) -> usize {
271 let mut count = 0;
272 if self.witness_log.is_some() { count += 1; }
273 if self.timer.is_some() { count += 1; }
274 if self.self_task.is_some() { count += 1; }
275 if self.syscall_queue.is_some() { count += 1; }
276 count
277 }
278
279 #[inline]
281 #[must_use]
282 pub fn is_valid(&self) -> bool {
283 self.witness_log.is_some()
284 && self.timer.is_some()
285 && self.self_task.is_some()
286 }
287}
288
289pub struct RootCapabilityDrop {
296 pub revoked_count: usize,
298
299 pub completed: bool,
301
302 pub final_capability_count: usize,
304}
305
306impl RootCapabilityDrop {
307 #[must_use]
309 pub fn new() -> Self {
310 Self {
311 revoked_count: 0,
312 completed: false,
313 final_capability_count: 0,
314 }
315 }
316
317 pub fn execute(
325 &mut self,
326 boot_capabilities: &BootCapabilitySet,
327 minimum_set: &MinimumCapabilitySet,
328 ) -> Result<(), KernelError> {
329 let total_boot_caps = boot_capabilities.total_count();
331 let minimum_caps = minimum_set.count();
332
333 self.revoked_count = total_boot_caps.saturating_sub(minimum_caps);
334 self.final_capability_count = minimum_caps;
335 self.completed = true;
336
337 Ok(())
345 }
346
347 #[must_use]
349 pub fn verify(&self, minimum_set: &MinimumCapabilitySet) -> bool {
350 self.completed
351 && self.final_capability_count == minimum_set.count()
352 && minimum_set.is_valid()
353 }
354}
355
356impl Default for RootCapabilityDrop {
357 fn default() -> Self {
358 Self::new()
359 }
360}
361
362#[cfg(test)]
363mod tests {
364 use super::*;
365
366 #[test]
367 fn test_capability_grant_creation() {
368 let grant = CapabilityGrant::new(
369 0x1000,
370 ObjectType::Region,
371 CapRights::READ,
372 42,
373 );
374
375 assert_eq!(grant.object_id, 0x1000);
376 assert_eq!(grant.object_type, ObjectType::Region);
377 assert_eq!(grant.rights, CapRights::READ);
378 assert_eq!(grant.badge, 42);
379 }
380
381 #[test]
382 fn test_capability_grant_shortcuts() {
383 let ro = CapabilityGrant::region_readonly(0x1000, 1);
384 assert!(ro.rights.contains(CapRights::READ));
385 assert!(!ro.rights.contains(CapRights::WRITE));
386
387 let rw = CapabilityGrant::region_readwrite(0x2000, 2);
388 assert!(rw.rights.contains(CapRights::READ));
389 assert!(rw.rights.contains(CapRights::WRITE));
390
391 let send = CapabilityGrant::queue_send(0x3000, 3);
392 assert!(send.rights.contains(CapRights::WRITE));
393 assert!(!send.rights.contains(CapRights::READ));
394 }
395
396 #[test]
397 fn test_minimum_capability_set() {
398 let min_set = MinimumCapabilitySet::for_root_task(
399 0x1000, 0x2000, 0x3000, 0x4000, );
404
405 assert_eq!(min_set.count(), 4);
406 assert!(min_set.is_valid());
407 }
408
409 #[test]
410 fn test_minimum_capability_set_validity() {
411 let invalid_set = MinimumCapabilitySet::default();
412 assert!(!invalid_set.is_valid());
413 assert_eq!(invalid_set.count(), 0);
414 }
415
416 #[test]
417 fn test_root_capability_drop() {
418 let mut drop = RootCapabilityDrop::new();
419 let boot_caps = BootCapabilitySet::full(1, 0x1000, 0x10000, 0x2000, 0xCAFE);
420 let min_set = MinimumCapabilitySet::for_root_task(0x1000, 0x2000, 0x3000, 0x4000);
421
422 drop.execute(&boot_caps, &min_set).unwrap();
423
424 assert!(drop.completed);
425 assert_eq!(drop.final_capability_count, 4);
426 assert!(drop.verify(&min_set));
427 }
428
429 #[test]
430 fn test_component_capability_grant() {
431 let mut grant = ComponentCapabilityGrant {
432 component_index: 0,
433 grants: [None; 32],
434 grant_count: 0,
435 };
436
437 grant.add_grant(CapabilityGrant::region_readonly(0x1000, 0)).unwrap();
438 grant.add_grant(CapabilityGrant::queue_send(0x2000, 1)).unwrap();
439
440 assert_eq!(grant.grant_count, 2);
441 }
442
443 #[test]
444 fn test_component_capability_grant_limit() {
445 let mut grant = ComponentCapabilityGrant {
446 component_index: 0,
447 grants: [None; 32],
448 grant_count: 0,
449 };
450
451 for i in 0..32 {
453 grant.add_grant(CapabilityGrant::region_readonly(i as u64, 0)).unwrap();
454 }
455
456 let result = grant.add_grant(CapabilityGrant::region_readonly(32, 0));
458 assert_eq!(result, Err(KernelError::LimitExceeded));
459 }
460}