kernel/capabilities.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Special restricted capabilities.
6//!
7//! Rust provides a mechanism for restricting certain operations to only be used
8//! by trusted code through the `unsafe` keyword. This is very useful, but
9//! doesn't provide very granular access: code can either access _all_ `unsafe`
10//! things, or none.
11//!
12//! Capabilities are the mechanism in Tock that provides more granular access.
13//! For sensitive operations (e.g. operations that could violate isolation)
14//! callers must have a particular capability. The type system ensures that the
15//! caller does in fact have the capability, and `unsafe` is used to ensure that
16//! callers cannot create the capability type themselves.
17//!
18//! Capabilities are passed to modules from trusted code (i.e. code that can
19//! call `unsafe`).
20//!
21//! Capabilities are expressed as `unsafe` traits. Only code that can use
22//! `unsafe` mechanisms can instantiate an object that provides an `unsafe`
23//! trait. Functions that require certain capabilities require that they are
24//! passed an object that provides the correct capability trait. The object
25//! itself does not have to be marked `unsafe`.
26//!
27//! Creating an object that expresses a capability is straightforward:
28//!
29//! ```
30//! use kernel::capabilities::ProcessManagementCapability;
31//!
32//! struct ProcessMgmtCap;
33//! unsafe impl ProcessManagementCapability for ProcessMgmtCap {}
34//! ```
35//!
36//! Now anything that has a ProcessMgmtCap can call any function that requires
37//! the `ProcessManagementCapability` capability.
38//!
39//! Requiring a certain capability is also straightforward:
40//!
41//! ```ignore
42//! pub fn manage_process<C: ProcessManagementCapability>(_c: &C) {
43//! unsafe {
44//! ...
45//! }
46//! }
47//! ```
48//!
49//! Anything that calls `manage_process` must have a reference to some object
50//! that provides the `ProcessManagementCapability` trait, which proves that it
51//! has the correct capability.
52
53/// The `ProcessManagementCapability` allows the holder to control
54/// process execution, such as related to creating, restarting, and
55/// otherwise managing processes.
56pub unsafe trait ProcessManagementCapability {}
57
58/// The `ProcessStartCapability` allows the holder to start a process.
59///
60/// This is controlled and separate from `ProcessManagementCapability`
61/// because the process must have a unique application identifier and
62/// so only modules which check this may do so.
63pub unsafe trait ProcessStartCapability {}
64
65/// The `MainLoopCapability` capability allows the holder to start executing as
66/// well as manage the main scheduler loop in Tock.
67///
68/// This is needed in a board's main.rs file to start the kernel. It
69/// also allows an external implementation of `Process` to update
70/// state in the kernel struct used by the main loop.
71pub unsafe trait MainLoopCapability {}
72
73/// The `MemoryAllocationCapability` capability allows the holder to allocate
74/// memory, for example by creating grants.
75pub unsafe trait MemoryAllocationCapability {}
76
77/// A capability that allows the holder to use the core kernel
78/// resources needed to implement the `Process` trait.
79///
80/// Many of these operations are very sensitive, that is they cannot
81/// just be made public. In particular, certain objects can be used
82/// outside of the core kernel, but the constructors must be
83/// restricted.
84pub unsafe trait ExternalProcessCapability {}
85
86/// The KernelruserStorageCapability` capability allows the holder to create
87/// permissions to access kernel-only stored values on the system.
88pub unsafe trait KerneluserStorageCapability {}
89
90/// The `ApplicationStorageCapability` capability allows the holder to create
91/// permissions to allow applications to have access to stored state on the
92/// system.
93pub unsafe trait ApplicationStorageCapability {}
94
95/// The `UdpDriverCapability` capability allows the holder to use two functions
96/// only allowed by the UDP driver.
97///
98/// The first is the `driver_send_to()` function
99/// in udp_send.rs, which does not require being bound to a single port, since
100/// the driver manages port bindings for apps on its own. The second is the
101/// `set_user_ports()` function in `udp_port_table.rs`, which gives the UDP port
102/// table a reference to the UDP driver so that it can check which ports have
103/// been bound by apps.
104pub unsafe trait UdpDriverCapability {}
105
106/// The `CreatePortTableCapability` capability allows the holder to instantiate
107/// a new copy of the UdpPortTable struct.
108///
109/// There should only ever be one instance of this struct, so this
110/// capability should not be distributed to capsules at all, as the
111/// port table should only be instantiated once by the kernel
112pub unsafe trait CreatePortTableCapability {}
113
114/// A capability that allows the holder to instantiate
115/// `NetworkCapability`s and visibility capabilities.
116///
117/// A capsule would never hold this capability although it may hold
118/// capabilities created via this capability.
119pub unsafe trait NetworkCapabilityCreationCapability {}