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
// 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 {}

/// The `ExternalProcessCapability` capability allows the holder to use the core
/// kernel resources needed to successfully implement the `Process` trait
/// from outside of the core kernel crate. 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 `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 {}

/// The `NetworkCapabilityCreationCapability` allows the holder to instantiate
/// `NetworkCapability`S and visibility capabilities for the IP and UDP layers
/// of the networking stack. A capsule would never hold this capability although
/// it may hold capabilities created via this capability.
pub unsafe trait NetworkCapabilityCreationCapability {}