Skip to main content

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.
56///
57/// # Safety
58///
59/// Capabilities can only be created in trusted crates that can use `unsafe`.
60pub unsafe trait ProcessManagementCapability {}
61
62/// The `ProcessStartCapability` allows the holder to start a process.
63///
64/// This is controlled and separate from `ProcessManagementCapability`
65/// because the process must have a unique application identifier and
66/// so only modules which check this may do so.
67///
68/// # Safety
69///
70/// Capabilities can only be created in trusted crates that can use `unsafe`.
71pub unsafe trait ProcessStartCapability {}
72
73/// The `MainLoopCapability` capability allows the holder to start executing as
74/// well as manage the main scheduler loop in Tock.
75///
76/// This is needed in a board's main.rs file to start the kernel. It
77/// also allows an external implementation of `Process` to update
78/// state in the kernel struct used by the main loop.
79///
80/// # Safety
81///
82/// Capabilities can only be created in trusted crates that can use `unsafe`.
83pub unsafe trait MainLoopCapability {}
84
85/// The `MemoryAllocationCapability` capability allows the holder to allocate
86/// memory, for example by creating grants.
87///
88/// # Safety
89///
90/// Capabilities can only be created in trusted crates that can use `unsafe`.
91pub unsafe trait MemoryAllocationCapability {}
92
93/// A capability that allows the holder to use the core kernel
94/// resources needed to implement the `Process` trait.
95///
96/// Many of these operations are very sensitive, that is they cannot
97/// just be made public. In particular, certain objects can be used
98/// outside of the core kernel, but the constructors must be
99/// restricted.
100///
101/// # Safety
102///
103/// Capabilities can only be created in trusted crates that can use `unsafe`.
104pub unsafe trait ExternalProcessCapability {}
105
106/// The KernelruserStorageCapability` capability allows the holder to create
107/// permissions to access kernel-only stored values on the system.
108///
109/// # Safety
110///
111/// Capabilities can only be created in trusted crates that can use `unsafe`.
112pub unsafe trait KerneluserStorageCapability {}
113
114/// The `ApplicationStorageCapability` capability allows the holder to create
115/// permissions to allow applications to have access to stored state on the
116/// system.
117///
118/// # Safety
119///
120/// Capabilities can only be created in trusted crates that can use `unsafe`.
121pub unsafe trait ApplicationStorageCapability {}
122
123/// The `UdpDriverCapability` capability allows the holder to use two functions
124/// only allowed by the UDP driver.
125///
126/// The first is the `driver_send_to()` function
127/// in udp_send.rs, which does not require being bound to a single port, since
128/// the driver manages port bindings for apps on its own. The second is the
129/// `set_user_ports()` function in `udp_port_table.rs`, which gives the UDP port
130/// table a reference to the UDP driver so that it can check which ports have
131/// been bound by apps.
132///
133/// # Safety
134///
135/// Capabilities can only be created in trusted crates that can use `unsafe`.
136pub unsafe trait UdpDriverCapability {}
137
138/// The `CreatePortTableCapability` capability allows the holder to instantiate
139/// a new copy of the UdpPortTable struct.
140///
141/// There should only ever be one instance of this struct, so this
142/// capability should not be distributed to capsules at all, as the
143/// port table should only be instantiated once by the kernel.
144///
145/// # Safety
146///
147/// Capabilities can only be created in trusted crates that can use `unsafe`.
148pub unsafe trait CreatePortTableCapability {}
149
150/// A capability that allows the holder to instantiate
151/// `NetworkCapability`s and visibility capabilities.
152///
153/// A capsule would never hold this capability although it may hold
154/// capabilities created via this capability.
155///
156/// # Safety
157///
158/// Capabilities can only be created in trusted crates that can use `unsafe`.
159pub unsafe trait NetworkCapabilityCreationCapability {}
160
161/// The `SetDebugWriterCapability` allows the holder to set the debug writer
162/// mechanism in the kernel.
163///
164/// The debug writer is held by the kernel to enable the `debug!()` macro. The
165/// debug writer mechanism has access to debugging print messages which may
166/// contain information about the operation of the kernel.
167///
168/// # Safety
169///
170/// Capabilities can only be created in trusted crates that can use `unsafe`.
171pub unsafe trait SetDebugWriterCapability {}
172
173/// The `CpuStateControlCapability` allows the holder to perform low-level
174/// microcontroller operations.
175///
176/// These including resetting the MCU and putting it in sleep mode.
177///
178/// # Safety
179///
180/// Capabilities can only be created in trusted crates that can use `unsafe`.
181pub unsafe trait CpuStateControlCapability {}