hyperlight_host/sandbox_state/sandbox.rs
1/*
2Copyright 2024 The Hyperlight Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17use std::fmt::Debug;
18
19use tracing::{instrument, Span};
20
21use super::transition::TransitionMetadata;
22use crate::{new_error, Result};
23
24/// The minimal functionality of a Hyperlight sandbox. Most of the types
25/// and operations within this crate require `Sandbox` implementations.
26///
27/// `Sandbox`es include the notion of an ordering in a state machine.
28/// For example, a given `Sandbox` implementation may be the root node
29/// in the state machine to which it belongs, and it may know how to "evolve"
30/// into a next state. That "next state" may in turn know how to roll back
31/// to the root node.
32///
33/// These transitions are expressed as `EvolvableSandbox` and
34/// `DevolvableSandbox` implementations any `Sandbox` implementation can
35/// opt into.
36pub trait Sandbox: Sized + Debug {
37 /// Check to ensure the current stack cookie matches the one that
38 /// was selected when the stack was constructed.
39 ///
40 /// Return an `Err` if there was an error inspecting the stack, `Ok(false)`
41 /// if there was no such error but the stack guard doesn't match, and
42 /// `Ok(true)` in the same situation where the stack guard does match.
43 ///
44
45 // NOTE: this is only needed for UninitializedSandbox and MultiUseSandbox
46 // Those are the only types that need implement this trait
47 // The default implementation is provided so that types that implement Sandbox (e.g. JSSandbox) but do not need to implement this trait do not need to provide an implementation
48 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
49 fn check_stack_guard(&self) -> Result<bool> {
50 Err(new_error!(
51 "check_stack_guard not implemented for this type"
52 ))
53 }
54}
55
56/// A utility trait to recognize a Sandbox that has not yet been initialized.
57/// It allows retrieval of a strongly typed UninitializedSandbox.
58pub trait UninitializedSandbox: Sandbox {
59 /// Retrieves reference to strongly typed `UninitializedSandbox`
60 fn get_uninitialized_sandbox(&self) -> &crate::sandbox::UninitializedSandbox;
61
62 /// Retrieves mutable reference to strongly typed `UninitializedSandbox`
63 fn get_uninitialized_sandbox_mut(&mut self) -> &mut crate::sandbox::UninitializedSandbox;
64}
65
66/// A `Sandbox` that knows how to "evolve" into a next state.
67pub trait EvolvableSandbox<Cur: Sandbox, Next: Sandbox, T: TransitionMetadata<Cur, Next>>:
68 Sandbox
69{
70 /// Evolve `Self` to `Next` providing Metadata.
71 fn evolve(self, tsn: T) -> Result<Next>;
72}
73
74/// A `Sandbox` that knows how to roll back to a "previous" `Sandbox`
75pub trait DevolvableSandbox<Cur: Sandbox, Prev: Sandbox, T: TransitionMetadata<Cur, Prev>>:
76 Sandbox
77{
78 /// Devolve `Self` to `Prev` providing Metadata.
79 fn devolve(self, tsn: T) -> Result<Prev>;
80}