kernel/
capabilities.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! Special restricted capabilities.
//!
//! Rust provides a mechanism for restricting certain operations to only be used
//! by trusted code through the `unsafe` keyword. This is very useful, but
//! doesn't provide very granular access: code can either access _all_ `unsafe`
//! things, or none.
//!
//! Capabilities are the mechanism in Tock that provides more granular access.
//! For sensitive operations (e.g. operations that could violate isolation)
//! callers must have a particular capability. The type system ensures that the
//! caller does in fact have the capability, and `unsafe` is used to ensure that
//! callers cannot create the capability type themselves.
//!
//! Capabilities are passed to modules from trusted code (i.e. code that can
//! call `unsafe`).
//!
//! Capabilities are expressed as `unsafe` traits. Only code that can use
//! `unsafe` mechanisms can instantiate an object that provides an `unsafe`
//! trait. Functions that require certain capabilities require that they are
//! passed an object that provides the correct capability trait. The object
//! itself does not have to be marked `unsafe`.
//!
//! Creating an object that expresses a capability is straightforward:
//!
//! ```
//! use kernel::capabilities::ProcessManagementCapability;
//!
//! struct ProcessMgmtCap;
//! unsafe impl ProcessManagementCapability for ProcessMgmtCap {}
//! ```
//!
//! Now anything that has a ProcessMgmtCap can call any function that requires
//! the `ProcessManagementCapability` capability.
//!
//! Requiring a certain capability is also straightforward:
//!
//! ```ignore
//! pub fn manage_process<C: ProcessManagementCapability>(_c: &C) {
//!    unsafe {
//!        ...
//!    }
//! }
//! ```
//!
//! Anything that calls `manage_process` must have a reference to some object
//! that provides the `ProcessManagementCapability` trait, which proves that it
//! has the correct capability.

/// The `ProcessManagementCapability` allows the holder to control
/// process execution, such as related to creating, restarting, and
/// otherwise managing processes.
pub unsafe trait ProcessManagementCapability {}

/// The `ProcessStartCapability` allows the holder to start a process.
///
/// This is controlled and separate from `ProcessManagementCapability`
/// because the process must have a unique application identifier and
/// so only modules which check this may do so.
pub unsafe trait ProcessStartCapability {}

/// The `MainLoopCapability` capability allows the holder to start executing as
/// well as manage the main scheduler loop in Tock.
///
/// This is needed in a board's main.rs file to start the kernel. It
/// also allows an external implementation of `Process` to update
/// state in the kernel struct used by the main loop.
pub unsafe trait MainLoopCapability {}

/// The `MemoryAllocationCapability` capability allows the holder to allocate
/// memory, for example by creating grants.
pub unsafe trait MemoryAllocationCapability {}

/// A capability that allows the holder to use the core kernel
/// resources needed to implement the `Process` trait.
///
/// Many of these operations are very sensitive, that is they cannot
/// just be made public. In particular, certain objects can be used
/// outside of the core kernel, but the constructors must be
/// restricted.
pub unsafe trait ExternalProcessCapability {}

/// The KernelruserStorageCapability` capability allows the holder to create
/// permissions to access kernel-only stored values on the system.
pub unsafe trait KerneluserStorageCapability {}

/// The `ApplicationStorageCapability` capability allows the holder to create
/// permissions to allow applications to have access to stored state on the
/// system.
pub unsafe trait ApplicationStorageCapability {}

/// The `UdpDriverCapability` capability allows the holder to use two functions
/// only allowed by the UDP driver.
///
/// The first is the `driver_send_to()` function
/// in udp_send.rs, which does not require being bound to a single port, since
/// the driver manages port bindings for apps on its own. The second is the
/// `set_user_ports()` function in `udp_port_table.rs`, which gives the UDP port
/// table a reference to the UDP driver so that it can check which ports have
/// been bound by apps.
pub unsafe trait UdpDriverCapability {}

/// The `CreatePortTableCapability` capability allows the holder to instantiate
/// a new copy of the UdpPortTable struct.
///
/// There should only ever be one instance of this struct, so this
/// capability should not be distributed to capsules at all, as the
/// port table should only be instantiated once by the kernel
pub unsafe trait CreatePortTableCapability {}

/// A capability that allows the holder to instantiate
/// `NetworkCapability`s and visibility capabilities.
///
/// A capsule would never hold this capability although it may hold
/// capabilities created via this capability.
pub unsafe trait NetworkCapabilityCreationCapability {}