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