diff --git a/docs/how-to-use-flatbuffers.md b/docs/how-to-use-flatbuffers.md index 99ab70491..dc26b58c7 100644 --- a/docs/how-to-use-flatbuffers.md +++ b/docs/how-to-use-flatbuffers.md @@ -1,5 +1,7 @@ # How to use FlatBuffers +> Note: the last generation of the flatbuffer code was with done with flatc version 25.2.10 (i.e., the last version as of May 1st, 2025). + Flatbuffers is used to serialize and deserialize some data structures. Schema files are used to define the data structures and are used to generate the code to serialize and deserialize the data structures. diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs b/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs index 42a26c81c..d6016db19 100644 --- a/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs +++ b/src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs @@ -710,7 +710,7 @@ impl TryFrom<&ReturnValue> for Vec { &mut builder, &hlsizeprefixedbufferArgs { value: Some(val), - size_: v.len() as i32, + size: v.len() as i32, }, ) }; diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/host_function_definition.rs b/src/hyperlight_common/src/flatbuffer_wrappers/host_function_definition.rs deleted file mode 100644 index 23c6976da..000000000 --- a/src/hyperlight_common/src/flatbuffer_wrappers/host_function_definition.rs +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright 2024 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use alloc::string::{String, ToString}; -use alloc::vec::Vec; - -use anyhow::{anyhow, Error, Result}; -use flatbuffers::{FlatBufferBuilder, WIPOffset}; -#[cfg(feature = "tracing")] -use tracing::{instrument, Span}; - -use super::function_types::{ParameterType, ReturnType}; -use crate::flatbuffers::hyperlight::generated::{ - HostFunctionDefinition as FbHostFunctionDefinition, - HostFunctionDefinitionArgs as FbHostFunctionDefinitionArgs, ParameterType as FbParameterType, -}; - -/// The definition of a function exposed from the host to the guest -#[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct HostFunctionDefinition { - /// The function name - pub function_name: String, - /// The type of the parameter values for the host function call. - pub parameter_types: Option>, - /// The type of the return value from the host function call - pub return_type: ReturnType, -} - -impl HostFunctionDefinition { - /// Create a new `HostFunctionDefinition`. - #[cfg_attr(feature = "tracing", instrument(skip_all, parent = Span::current(), level= "Trace"))] - pub fn new( - function_name: String, - parameter_types: Option>, - return_type: ReturnType, - ) -> Self { - Self { - function_name, - parameter_types, - return_type, - } - } - - /// Convert this `HostFunctionDefinition` into a `WIPOffset`. - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - pub(crate) fn convert_to_flatbuffer_def<'a>( - &self, - builder: &mut FlatBufferBuilder<'a>, - ) -> Result>> { - let host_function_name = builder.create_string(&self.function_name); - let return_value_type = self.return_type.into(); - let vec_parameters = match &self.parameter_types { - Some(vec_pvt) => { - let num_items = vec_pvt.len(); - let mut parameters: Vec = Vec::with_capacity(num_items); - for pvt in vec_pvt { - let fb_pvt = pvt.clone().into(); - parameters.push(fb_pvt); - } - Some(builder.create_vector(¶meters)) - } - None => None, - }; - - let fb_host_function_definition: WIPOffset = - FbHostFunctionDefinition::create( - builder, - &FbHostFunctionDefinitionArgs { - function_name: Some(host_function_name), - return_type: return_value_type, - parameters: vec_parameters, - }, - ); - - Ok(fb_host_function_definition) - } - - /// Verify that the function call has the correct parameter types. - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - pub fn verify_equal_parameter_types( - &self, - function_call_parameter_types: &[ParameterType], - ) -> Result<()> { - if let Some(parameter_types) = &self.parameter_types { - for (i, parameter_type) in parameter_types.iter().enumerate() { - if parameter_type != &function_call_parameter_types[i] { - return Err(anyhow!("Incorrect parameter type for parameter {}", i + 1)); - } - } - } - Ok(()) - } -} - -impl TryFrom<&FbHostFunctionDefinition<'_>> for HostFunctionDefinition { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(value: &FbHostFunctionDefinition) -> Result { - let function_name = value.function_name().to_string(); - let return_type = value.return_type().try_into().map_err(|_| { - anyhow!( - "Failed to convert return type for function {}", - function_name - ) - })?; - let parameter_types = match value.parameters() { - Some(pvt) => { - let len = pvt.len(); - let mut pv: Vec = Vec::with_capacity(len); - for fb_pvt in pvt { - let pvt: ParameterType = fb_pvt.try_into().map_err(|_| { - anyhow!( - "Failed to convert parameter type for function {}", - function_name - ) - })?; - pv.push(pvt); - } - Some(pv) - } - None => None, - }; - - Ok(Self::new(function_name, parameter_types, return_type)) - } -} - -impl TryFrom<&[u8]> for HostFunctionDefinition { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(value: &[u8]) -> Result { - let fb_host_function_definition = flatbuffers::root::>(value) - .map_err(|e| anyhow!("Error while reading HostFunctionDefinition: {:?}", e))?; - Self::try_from(&fb_host_function_definition) - } -} - -impl TryFrom<&HostFunctionDefinition> for Vec { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(hfd: &HostFunctionDefinition) -> Result> { - let mut builder = flatbuffers::FlatBufferBuilder::new(); - let host_function_definition = hfd.convert_to_flatbuffer_def(&mut builder)?; - builder.finish_size_prefixed(host_function_definition, None); - Ok(builder.finished_data().to_vec()) - } -} diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/host_function_details.rs b/src/hyperlight_common/src/flatbuffer_wrappers/host_function_details.rs deleted file mode 100644 index 33bd7d7c7..000000000 --- a/src/hyperlight_common/src/flatbuffer_wrappers/host_function_details.rs +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2024 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use alloc::vec::Vec; - -use anyhow::{Error, Result}; -use flatbuffers::{size_prefixed_root, WIPOffset}; -#[cfg(feature = "tracing")] -use tracing::{instrument, Span}; - -use super::host_function_definition::HostFunctionDefinition; -use crate::flatbuffers::hyperlight::generated::{ - HostFunctionDefinition as FbHostFunctionDefinition, - HostFunctionDetails as FbHostFunctionDetails, - HostFunctionDetailsArgs as FbHostFunctionDetailsArgs, -}; - -/// `HostFunctionDetails` represents the set of functions that the host exposes to the guest. -#[derive(Debug, Default, Clone)] -pub struct HostFunctionDetails { - /// The host functions. - pub host_functions: Option>, -} - -impl HostFunctionDetails { - /// Create a new `HostFunctionDetails`. - #[cfg_attr(feature = "tracing", instrument(skip_all, parent = Span::current(), level= "Trace"))] - pub fn new(host_functions: Option>) -> Self { - Self { host_functions } - } - - /// Insert a host function into the host function details. - #[cfg_attr(feature = "tracing", instrument(skip_all, parent = Span::current(), level= "Trace"))] - pub fn insert_host_function(&mut self, host_function: HostFunctionDefinition) { - match &mut self.host_functions { - Some(host_functions) => host_functions.push(host_function), - None => { - let host_functions = Vec::from(&[host_function]); - self.host_functions = Some(host_functions); - } - } - } - - /// Sort the host functions by name. - #[cfg_attr(feature = "tracing", instrument(skip_all, parent = Span::current(), level= "Trace"))] - pub fn sort_host_functions_by_name(&mut self) { - match &mut self.host_functions { - Some(host_functions) => { - host_functions.sort_by(|a, b| a.function_name.cmp(&b.function_name)) - } - None => {} - } - } - - /// Find a host function by name. - #[cfg_attr(feature = "tracing", instrument(skip_all, parent = Span::current(), level= "Trace"))] - pub fn find_by_function_name(&self, function_name: &str) -> Option { - match &self.host_functions { - Some(host_functions) => { - for host_function in host_functions { - if host_function.function_name == function_name { - return Some(host_function.clone()); - } - } - - None - } - None => None, - } - } -} - -impl TryFrom<&[u8]> for HostFunctionDetails { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(value: &[u8]) -> Result { - let host_function_details_fb = size_prefixed_root::(value) - .map_err(|e| anyhow::anyhow!("Error while reading HostFunctionDetails: {:?}", e))?; - - let host_function_definitions = match host_function_details_fb.functions() { - Some(hfd) => { - let len = hfd.len(); - let mut vec_hfd: Vec = Vec::with_capacity(len); - for i in 0..len { - let fb_host_function_definition = hfd.get(i); - let hfdef = HostFunctionDefinition::try_from(&fb_host_function_definition)?; - vec_hfd.push(hfdef); - } - - Some(vec_hfd) - } - - None => None, - }; - - Ok(Self { - host_functions: host_function_definitions, - }) - } -} - -impl TryFrom<&HostFunctionDetails> for Vec { - type Error = Error; - #[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))] - fn try_from(value: &HostFunctionDetails) -> Result> { - let mut builder = flatbuffers::FlatBufferBuilder::new(); - let vec_host_function_definitions = match &value.host_functions { - Some(vec_hfd) => { - let num_items = vec_hfd.len(); - let mut host_function_definitions: Vec> = - Vec::with_capacity(num_items); - - for hfd in vec_hfd { - let host_function_definition = hfd.convert_to_flatbuffer_def(&mut builder)?; - host_function_definitions.push(host_function_definition); - } - - Some(host_function_definitions) - } - None => None, - }; - - let fb_host_function_definitions = - vec_host_function_definitions.map(|v| builder.create_vector(&v)); - - let host_function_details = FbHostFunctionDetails::create( - &mut builder, - &FbHostFunctionDetailsArgs { - functions: fb_host_function_definitions, - }, - ); - builder.finish_size_prefixed(host_function_details, None); - let res = builder.finished_data().to_vec(); - - Ok(res) - } -} diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/mod.rs b/src/hyperlight_common/src/flatbuffer_wrappers/mod.rs index cfab9c792..39dc9b9cd 100644 --- a/src/hyperlight_common/src/flatbuffer_wrappers/mod.rs +++ b/src/hyperlight_common/src/flatbuffer_wrappers/mod.rs @@ -21,8 +21,4 @@ pub mod guest_error; pub mod guest_log_data; /// cbindgen:ignore pub mod guest_log_level; -/// cbindgen:ignore -pub mod host_function_definition; -/// cbindgen:ignore -pub mod host_function_details; pub mod util; diff --git a/src/hyperlight_common/src/flatbuffer_wrappers/util.rs b/src/hyperlight_common/src/flatbuffer_wrappers/util.rs index 184da6afe..ff453edc4 100644 --- a/src/hyperlight_common/src/flatbuffer_wrappers/util.rs +++ b/src/hyperlight_common/src/flatbuffer_wrappers/util.rs @@ -82,7 +82,7 @@ impl FlatbufferSerializable for &[u8] { Fbhlsizeprefixedbuffer::create( builder, &FbhlsizeprefixedbufferArgs { - size_: self.len() as i32, + size: self.len() as i32, value: Some(vec_offset), }, ) diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/hlsizeprefixedbuffer_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/hlsizeprefixedbuffer_generated.rs index e4aa6455c..ed1e74b37 100644 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/hlsizeprefixedbuffer_generated.rs +++ b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/hlsizeprefixedbuffer_generated.rs @@ -28,7 +28,7 @@ impl<'a> flatbuffers::Follow<'a> for hlsizeprefixedbuffer<'a> { } impl<'a> hlsizeprefixedbuffer<'a> { - pub const VT_SIZE_: flatbuffers::VOffsetT = 4; + pub const VT_SIZE: flatbuffers::VOffsetT = 4; pub const VT_VALUE: flatbuffers::VOffsetT = 6; #[inline] @@ -44,18 +44,18 @@ impl<'a> hlsizeprefixedbuffer<'a> { if let Some(x) = args.value { builder.add_value(x); } - builder.add_size_(args.size_); + builder.add_size(args.size); builder.finish() } #[inline] - pub fn size_(&self) -> i32 { + pub fn size(&self) -> i32 { // Safety: // Created from valid Table for this object // which contains a valid value in this slot unsafe { self._tab - .get::(hlsizeprefixedbuffer::VT_SIZE_, Some(0)) + .get::(hlsizeprefixedbuffer::VT_SIZE, Some(0)) .unwrap() } } @@ -82,7 +82,7 @@ impl flatbuffers::Verifiable for hlsizeprefixedbuffer<'_> { ) -> Result<(), flatbuffers::InvalidFlatbuffer> { use self::flatbuffers::Verifiable; v.visit_table(pos)? - .visit_field::("size_", Self::VT_SIZE_, false)? + .visit_field::("size", Self::VT_SIZE, false)? .visit_field::>>( "value", Self::VT_VALUE, @@ -93,14 +93,14 @@ impl flatbuffers::Verifiable for hlsizeprefixedbuffer<'_> { } } pub struct hlsizeprefixedbufferArgs<'a> { - pub size_: i32, + pub size: i32, pub value: Option>>, } impl<'a> Default for hlsizeprefixedbufferArgs<'a> { #[inline] fn default() -> Self { hlsizeprefixedbufferArgs { - size_: 0, + size: 0, value: None, } } @@ -112,9 +112,9 @@ pub struct hlsizeprefixedbufferBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + ' } impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> hlsizeprefixedbufferBuilder<'a, 'b, A> { #[inline] - pub fn add_size_(&mut self, size_: i32) { + pub fn add_size(&mut self, size: i32) { self.fbb_ - .push_slot::(hlsizeprefixedbuffer::VT_SIZE_, size_, 0); + .push_slot::(hlsizeprefixedbuffer::VT_SIZE, size, 0); } #[inline] pub fn add_value(&mut self, value: flatbuffers::WIPOffset>) { @@ -141,7 +141,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> hlsizeprefixedbufferBuilder<'a, impl core::fmt::Debug for hlsizeprefixedbuffer<'_> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let mut ds = f.debug_struct("hlsizeprefixedbuffer"); - ds.field("size_", &self.size_()); + ds.field("size", &self.size()); ds.field("value", &self.value()); ds.finish() } diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs deleted file mode 100644 index 099ca44f2..000000000 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_definition_generated.rs +++ /dev/null @@ -1,289 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::cmp::Ordering; -use core::mem; - -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum HostFunctionDefinitionOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct HostFunctionDefinition<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for HostFunctionDefinition<'a> { - type Inner = HostFunctionDefinition<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { - _tab: flatbuffers::Table::new(buf, loc), - } - } -} - -impl<'a> HostFunctionDefinition<'a> { - pub const VT_FUNCTION_NAME: flatbuffers::VOffsetT = 4; - pub const VT_PARAMETERS: flatbuffers::VOffsetT = 6; - pub const VT_RETURN_TYPE: flatbuffers::VOffsetT = 8; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - HostFunctionDefinition { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args HostFunctionDefinitionArgs<'args>, - ) -> flatbuffers::WIPOffset> { - let mut builder = HostFunctionDefinitionBuilder::new(_fbb); - if let Some(x) = args.parameters { - builder.add_parameters(x); - } - if let Some(x) = args.function_name { - builder.add_function_name(x); - } - builder.add_return_type(args.return_type); - builder.finish() - } - - #[inline] - pub fn function_name(&self) -> &'a str { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { - self._tab - .get::>( - HostFunctionDefinition::VT_FUNCTION_NAME, - None, - ) - .unwrap() - } - } - #[inline] - pub fn key_compare_less_than(&self, o: &HostFunctionDefinition) -> bool { - self.function_name() < o.function_name() - } - - #[inline] - pub fn key_compare_with_value(&self, val: &str) -> ::core::cmp::Ordering { - let key = self.function_name(); - key.cmp(val) - } - #[inline] - pub fn parameters(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { - self._tab - .get::>>( - HostFunctionDefinition::VT_PARAMETERS, - None, - ) - } - } - #[inline] - pub fn return_type(&self) -> ReturnType { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { - self._tab - .get::( - HostFunctionDefinition::VT_RETURN_TYPE, - Some(ReturnType::hlint), - ) - .unwrap() - } - } -} - -impl flatbuffers::Verifiable for HostFunctionDefinition<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, - pos: usize, - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>( - "function_name", - Self::VT_FUNCTION_NAME, - true, - )? - .visit_field::>>( - "parameters", - Self::VT_PARAMETERS, - false, - )? - .visit_field::("return_type", Self::VT_RETURN_TYPE, false)? - .finish(); - Ok(()) - } -} -pub struct HostFunctionDefinitionArgs<'a> { - pub function_name: Option>, - pub parameters: Option>>, - pub return_type: ReturnType, -} -impl<'a> Default for HostFunctionDefinitionArgs<'a> { - #[inline] - fn default() -> Self { - HostFunctionDefinitionArgs { - function_name: None, // required field - parameters: None, - return_type: ReturnType::hlint, - } - } -} - -pub struct HostFunctionDefinitionBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> HostFunctionDefinitionBuilder<'a, 'b, A> { - #[inline] - pub fn add_function_name(&mut self, function_name: flatbuffers::WIPOffset<&'b str>) { - self.fbb_.push_slot_always::>( - HostFunctionDefinition::VT_FUNCTION_NAME, - function_name, - ); - } - #[inline] - pub fn add_parameters( - &mut self, - parameters: flatbuffers::WIPOffset>, - ) { - self.fbb_.push_slot_always::>( - HostFunctionDefinition::VT_PARAMETERS, - parameters, - ); - } - #[inline] - pub fn add_return_type(&mut self, return_type: ReturnType) { - self.fbb_.push_slot::( - HostFunctionDefinition::VT_RETURN_TYPE, - return_type, - ReturnType::hlint, - ); - } - #[inline] - pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - ) -> HostFunctionDefinitionBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - HostFunctionDefinitionBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - self.fbb_ - .required(o, HostFunctionDefinition::VT_FUNCTION_NAME, "function_name"); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for HostFunctionDefinition<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("HostFunctionDefinition"); - ds.field("function_name", &self.function_name()); - ds.field("parameters", &self.parameters()); - ds.field("return_type", &self.return_type()); - ds.finish() - } -} -#[inline] -/// Verifies that a buffer of bytes contains a `HostFunctionDefinition` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_definition_unchecked`. -pub fn root_as_host_function_definition( - buf: &[u8], -) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `HostFunctionDefinition` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_host_function_definition_unchecked`. -pub fn size_prefixed_root_as_host_function_definition( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `HostFunctionDefinition` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_definition_unchecked`. -pub fn root_as_host_function_definition_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `HostFunctionDefinition` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_definition_unchecked`. -pub fn size_prefixed_root_as_host_function_definition_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a HostFunctionDefinition and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `HostFunctionDefinition`. -pub unsafe fn root_as_host_function_definition_unchecked(buf: &[u8]) -> HostFunctionDefinition { - flatbuffers::root_unchecked::(buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed HostFunctionDefinition and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `HostFunctionDefinition`. -pub unsafe fn size_prefixed_root_as_host_function_definition_unchecked( - buf: &[u8], -) -> HostFunctionDefinition { - flatbuffers::size_prefixed_root_unchecked::(buf) -} -#[inline] -pub fn finish_host_function_definition_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_host_function_definition_buffer< - 'a, - 'b, - A: flatbuffers::Allocator + 'a, ->( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs b/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs deleted file mode 100644 index 71edd22b3..000000000 --- a/src/hyperlight_common/src/flatbuffers/hyperlight/generated/host_function_details_generated.rs +++ /dev/null @@ -1,215 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify -// @generated -extern crate alloc; -extern crate flatbuffers; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::cmp::Ordering; -use core::mem; - -use self::flatbuffers::{EndianScalar, Follow}; -use super::*; -pub enum HostFunctionDetailsOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct HostFunctionDetails<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for HostFunctionDetails<'a> { - type Inner = HostFunctionDetails<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { - _tab: flatbuffers::Table::new(buf, loc), - } - } -} - -impl<'a> HostFunctionDetails<'a> { - pub const VT_FUNCTIONS: flatbuffers::VOffsetT = 4; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - HostFunctionDetails { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args HostFunctionDetailsArgs<'args>, - ) -> flatbuffers::WIPOffset> { - let mut builder = HostFunctionDetailsBuilder::new(_fbb); - if let Some(x) = args.functions { - builder.add_functions(x); - } - builder.finish() - } - - #[inline] - pub fn functions( - &self, - ) -> Option>>> - { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { - self._tab.get::>, - >>(HostFunctionDetails::VT_FUNCTIONS, None) - } - } -} - -impl flatbuffers::Verifiable for HostFunctionDetails<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, - pos: usize, - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>, - >>("functions", Self::VT_FUNCTIONS, false)? - .finish(); - Ok(()) - } -} -pub struct HostFunctionDetailsArgs<'a> { - pub functions: Option< - flatbuffers::WIPOffset< - flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset>>, - >, - >, -} -impl<'a> Default for HostFunctionDetailsArgs<'a> { - #[inline] - fn default() -> Self { - HostFunctionDetailsArgs { functions: None } - } -} - -pub struct HostFunctionDetailsBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> HostFunctionDetailsBuilder<'a, 'b, A> { - #[inline] - pub fn add_functions( - &mut self, - functions: flatbuffers::WIPOffset< - flatbuffers::Vector<'b, flatbuffers::ForwardsUOffset>>, - >, - ) { - self.fbb_.push_slot_always::>( - HostFunctionDetails::VT_FUNCTIONS, - functions, - ); - } - #[inline] - pub fn new( - _fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - ) -> HostFunctionDetailsBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - HostFunctionDetailsBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for HostFunctionDetails<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("HostFunctionDetails"); - ds.field("functions", &self.functions()); - ds.finish() - } -} -#[inline] -/// Verifies that a buffer of bytes contains a `HostFunctionDetails` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_details_unchecked`. -pub fn root_as_host_function_details( - buf: &[u8], -) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `HostFunctionDetails` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_host_function_details_unchecked`. -pub fn size_prefixed_root_as_host_function_details( - buf: &[u8], -) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `HostFunctionDetails` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_details_unchecked`. -pub fn root_as_host_function_details_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `HostFunctionDetails` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_host_function_details_unchecked`. -pub fn size_prefixed_root_as_host_function_details_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a HostFunctionDetails and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `HostFunctionDetails`. -pub unsafe fn root_as_host_function_details_unchecked(buf: &[u8]) -> HostFunctionDetails { - flatbuffers::root_unchecked::(buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed HostFunctionDetails and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `HostFunctionDetails`. -pub unsafe fn size_prefixed_root_as_host_function_details_unchecked( - buf: &[u8], -) -> HostFunctionDetails { - flatbuffers::size_prefixed_root_unchecked::(buf) -} -#[inline] -pub fn finish_host_function_details_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_host_function_details_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>, -) { - fbb.finish_size_prefixed(root, None); -} diff --git a/src/hyperlight_common/src/flatbuffers/mod.rs b/src/hyperlight_common/src/flatbuffers/mod.rs index f8ac0929d..6674216df 100644 --- a/src/hyperlight_common/src/flatbuffers/mod.rs +++ b/src/hyperlight_common/src/flatbuffers/mod.rs @@ -44,10 +44,6 @@ pub mod hyperlight { pub use self::error_code_generated::*; mod guest_error_generated; pub use self::guest_error_generated::*; - mod host_function_definition_generated; - pub use self::host_function_definition_generated::*; - mod host_function_details_generated; - pub use self::host_function_details_generated::*; mod hlsizeprefixedbuffer_generated; pub use self::hlsizeprefixedbuffer_generated::*; mod log_level_generated; diff --git a/src/hyperlight_common/src/mem/mod.rs b/src/hyperlight_common/src/mem/mod.rs index 8995f1d64..0d523d43d 100644 --- a/src/hyperlight_common/src/mem/mod.rs +++ b/src/hyperlight_common/src/mem/mod.rs @@ -89,7 +89,6 @@ pub struct GuestPanicContextData { pub struct HyperlightPEB { pub security_cookie_seed: u64, pub guest_function_dispatch_ptr: u64, - pub hostFunctionDefinitions: HostFunctionDefinitions, pub hostException: HostException, pub guestErrorData: GuestErrorData, pub pCode: *mut c_char, diff --git a/src/hyperlight_guest/src/host_function_call.rs b/src/hyperlight_guest/src/host_function_call.rs index c5a496c8c..e66bff4fd 100644 --- a/src/hyperlight_guest/src/host_function_call.rs +++ b/src/hyperlight_guest/src/host_function_call.rs @@ -29,7 +29,6 @@ use hyperlight_common::mem::RunMode; use crate::error::{HyperlightGuestError, Result}; use crate::host_error::check_for_host_error; -use crate::host_functions::validate_host_function_call; use crate::shared_input_data::try_pop_shared_input_data_into; use crate::shared_output_data::push_shared_output_data; use crate::{OUTB_PTR, OUTB_PTR_WITH_CONTEXT, P_PEB, RUNNING_MODE}; @@ -71,8 +70,6 @@ pub fn call_host_function( return_type, ); - validate_host_function_call(&host_function_call)?; - let host_function_call_buffer: Vec = host_function_call .try_into() .expect("Unable to serialize host function call"); diff --git a/src/hyperlight_guest/src/host_functions.rs b/src/hyperlight_guest/src/host_functions.rs deleted file mode 100644 index e35fa6d2e..000000000 --- a/src/hyperlight_guest/src/host_functions.rs +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright 2024 The Hyperlight Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use alloc::format; -use alloc::string::ToString; -use alloc::vec::Vec; -use core::slice::from_raw_parts; - -use hyperlight_common::flatbuffer_wrappers::function_call::FunctionCall; -use hyperlight_common::flatbuffer_wrappers::function_types::ParameterType; -use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; -use hyperlight_common::flatbuffer_wrappers::host_function_details::HostFunctionDetails; - -use crate::error::{HyperlightGuestError, Result}; -use crate::P_PEB; - -pub(crate) fn validate_host_function_call(function_call: &FunctionCall) -> Result<()> { - // get host function details - let host_function_details = get_host_function_details(); - - // check if there are any host functions - if host_function_details.host_functions.is_none() { - return Err(HyperlightGuestError::new( - ErrorCode::GuestError, - "No host functions found".to_string(), - )); - } - - // check if function w/ given name exists - let host_function = if let Some(host_function) = - host_function_details.find_by_function_name(&function_call.function_name) - { - host_function - } else { - return Err(HyperlightGuestError::new( - ErrorCode::GuestError, - format!( - "Host Function Not Found: {}", - function_call.function_name.clone() - ), - )); - }; - - let function_call_fparameters = if let Some(parameters) = function_call.parameters.clone() { - parameters - } else { - if host_function.parameter_types.is_some() { - return Err(HyperlightGuestError::new( - ErrorCode::GuestError, - format!( - "Incorrect parameter count for function: {}", - function_call.function_name.clone() - ), - )); - } - - Vec::new() // if no parameters (and no mismatches), return empty vector - }; - - let function_call_parameter_types = function_call_fparameters - .iter() - .map(|p| p.into()) - .collect::>(); - - // Verify that the function call has the correct parameter types. - host_function - .verify_equal_parameter_types(&function_call_parameter_types) - .map_err(|_| { - HyperlightGuestError::new( - ErrorCode::GuestError, - format!( - "Incorrect parameter type for function: {}", - function_call.function_name.clone() - ), - ) - })?; - - Ok(()) -} - -pub fn get_host_function_details() -> HostFunctionDetails { - let peb_ptr = unsafe { P_PEB.unwrap() }; - - let host_function_details_buffer = - unsafe { (*peb_ptr).hostFunctionDefinitions.fbHostFunctionDetails } as *const u8; - let host_function_details_size = - unsafe { (*peb_ptr).hostFunctionDefinitions.fbHostFunctionDetailsSize }; - - let host_function_details_slice: &[u8] = unsafe { - from_raw_parts( - host_function_details_buffer, - host_function_details_size as usize, - ) - }; - - host_function_details_slice - .try_into() - .expect("Failed to convert buffer to HostFunctionDetails") -} diff --git a/src/hyperlight_guest/src/lib.rs b/src/hyperlight_guest/src/lib.rs index 181274c1e..dc1d1fa3b 100644 --- a/src/hyperlight_guest/src/lib.rs +++ b/src/hyperlight_guest/src/lib.rs @@ -40,7 +40,6 @@ pub mod guest_function_register; pub mod host_error; pub mod host_function_call; -pub mod host_functions; pub(crate) mod guest_logger; pub mod memory; diff --git a/src/hyperlight_host/src/func/host_functions.rs b/src/hyperlight_host/src/func/host_functions.rs index ce30d9c45..0f26aea4d 100644 --- a/src/hyperlight_host/src/func/host_functions.rs +++ b/src/hyperlight_host/src/func/host_functions.rs @@ -17,8 +17,9 @@ limitations under the License. #![allow(non_snake_case)] use std::sync::{Arc, Mutex}; -use hyperlight_common::flatbuffer_wrappers::function_types::ParameterValue; -use hyperlight_common::flatbuffer_wrappers::host_function_definition::HostFunctionDefinition; +use hyperlight_common::flatbuffer_wrappers::function_types::{ + ParameterType, ParameterValue, ReturnType, +}; use paste::paste; use tracing::{instrument, Span}; @@ -27,6 +28,32 @@ use crate::sandbox::{ExtraAllowedSyscall, UninitializedSandbox}; use crate::HyperlightError::UnexpectedNoOfArguments; use crate::{log_then_return, new_error, Result}; +/// The definition of a function exposed from the host to the guest +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct HostFunctionDefinition { + /// The function name + pub function_name: String, + /// The type of the parameter values for the host function call. + pub parameter_types: Option>, + /// The type of the return value from the host function call + pub return_type: ReturnType, +} + +impl HostFunctionDefinition { + /// Create a new `HostFunctionDefinition`. + pub fn new( + function_name: String, + parameter_types: Option>, + return_type: ReturnType, + ) -> Self { + Self { + function_name, + parameter_types, + return_type, + } + } +} + macro_rules! host_function { // Special case for zero parameters (0) => { @@ -109,7 +136,6 @@ macro_rules! host_function { .try_lock() .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))? .register_host_function_with_syscalls( - sandbox.mgr.as_mut(), &HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()), HyperlightFunction::new(func), _eas, @@ -126,7 +152,6 @@ macro_rules! host_function { .try_lock() .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))? .register_host_function( - sandbox.mgr.as_mut(), &HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()), HyperlightFunction::new(func), )?; @@ -236,7 +261,6 @@ macro_rules! host_function { .try_lock() .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))? .register_host_function_with_syscalls( - sandbox.mgr.as_mut(), &HostFunctionDefinition::new( name.to_string(), parameter_types, @@ -257,7 +281,6 @@ macro_rules! host_function { .try_lock() .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))? .register_host_function( - sandbox.mgr.as_mut(), &HostFunctionDefinition::new( name.to_string(), parameter_types, diff --git a/src/hyperlight_host/src/mem/layout.rs b/src/hyperlight_host/src/mem/layout.rs index 62ba47c33..69e1be38e 100644 --- a/src/hyperlight_host/src/mem/layout.rs +++ b/src/hyperlight_host/src/mem/layout.rs @@ -22,8 +22,8 @@ use rand::{rng, RngCore}; use tracing::{instrument, Span}; use super::memory_region::MemoryRegionType::{ - Code, GuardPage, GuestErrorData, Heap, HostExceptionData, HostFunctionDefinitions, InputData, - OutputData, PageTables, PanicContext, Peb, Stack, + Code, GuardPage, GuestErrorData, Heap, HostExceptionData, InputData, OutputData, PageTables, + PanicContext, Peb, Stack, }; use super::memory_region::{MemoryRegion, MemoryRegionFlags, MemoryRegionVecBuilder}; use super::mgr::AMOUNT_OF_MEMORY_PER_PT; @@ -49,9 +49,7 @@ use crate::{log_then_return, new_error, Result}; // +-------------------------------------------+ // | Host Exception Handlers | // +-------------------------------------------+ -// | Host Function Definitions | -// +-------------------------------------------+ -// | PEB Struct (0x98) | +// | PEB Struct | (HyperlightPEB size) // +-------------------------------------------+ // | Guest Code | // +-------------------------------------------+ @@ -64,9 +62,6 @@ use crate::{log_then_return, new_error, Result}; // | PML4 | // +-------------------------------------------+ 0x0_000 -/// -/// - `HostDefinitions` - the length of this is the `HostFunctionDefinitionSize` -/// field from `SandboxConfiguration` /// /// - `HostExceptionData` - memory that contains details of any Host Exception that /// occurred in outb function. it contains a 32 bit length following by a json @@ -108,7 +103,6 @@ pub(crate) struct SandboxMemoryLayout { peb_offset: usize, peb_security_cookie_seed_offset: usize, peb_guest_dispatch_function_ptr_offset: usize, // set by guest in guest entrypoint - pub(super) peb_host_function_definitions_offset: usize, pub(crate) peb_host_exception_offset: usize, peb_guest_error_offset: usize, peb_code_and_outb_pointer_offset: usize, @@ -121,7 +115,6 @@ pub(crate) struct SandboxMemoryLayout { // The following are the actual values // that are written to the PEB struct - pub(crate) host_function_definitions_buffer_offset: usize, pub(crate) host_exception_buffer_offset: usize, pub(super) guest_error_buffer_offset: usize, pub(super) input_data_buffer_offset: usize, @@ -160,10 +153,6 @@ impl Debug for SandboxMemoryLayout { "Guest Dispatch Function Pointer Offset", &format_args!("{:#x}", self.peb_guest_dispatch_function_ptr_offset), ) - .field( - "Host Function Definitions Offset", - &format_args!("{:#x}", self.peb_host_function_definitions_offset), - ) .field( "Host Exception Offset", &format_args!("{:#x}", self.peb_host_exception_offset), @@ -196,10 +185,6 @@ impl Debug for SandboxMemoryLayout { "Guest Stack Offset", &format_args!("{:#x}", self.peb_guest_stack_data_offset), ) - .field( - "Host Function Definitions Buffer Offset", - &format_args!("{:#x}", self.host_function_definitions_buffer_offset), - ) .field( "Host Exception Buffer Offset", &format_args!("{:#x}", self.host_exception_buffer_offset), @@ -292,8 +277,6 @@ impl SandboxMemoryLayout { peb_offset + offset_of!(HyperlightPEB, security_cookie_seed); let peb_guest_dispatch_function_ptr_offset = peb_offset + offset_of!(HyperlightPEB, guest_function_dispatch_ptr); - let peb_host_function_definitions_offset = - peb_offset + offset_of!(HyperlightPEB, hostFunctionDefinitions); let peb_host_exception_offset = peb_offset + offset_of!(HyperlightPEB, hostException); let peb_guest_error_offset = peb_offset + offset_of!(HyperlightPEB, guestErrorData); let peb_code_and_outb_pointer_offset = peb_offset + offset_of!(HyperlightPEB, pCode); @@ -308,14 +291,9 @@ impl SandboxMemoryLayout { // The following offsets are the actual values that relate to memory layout, // which are written to PEB struct let peb_address = Self::BASE_ADDRESS + peb_offset; - // make sure host function definitions buffer starts at 4K boundary - let host_function_definitions_buffer_offset = round_up_to( - peb_guest_stack_data_offset + size_of::(), - PAGE_SIZE_USIZE, - ); // make sure host exception buffer starts at 4K boundary let host_exception_buffer_offset = round_up_to( - host_function_definitions_buffer_offset + cfg.get_host_function_definition_size(), + peb_guest_stack_data_offset + size_of::(), PAGE_SIZE_USIZE, ); let guest_error_buffer_offset = round_up_to( @@ -351,7 +329,6 @@ impl SandboxMemoryLayout { heap_size, peb_security_cookie_seed_offset, peb_guest_dispatch_function_ptr_offset, - peb_host_function_definitions_offset, peb_host_exception_offset, peb_guest_error_offset, peb_code_and_outb_pointer_offset, @@ -364,7 +341,6 @@ impl SandboxMemoryLayout { guest_error_buffer_offset, sandbox_memory_config: cfg, code_size, - host_function_definitions_buffer_offset, host_exception_buffer_offset, input_data_buffer_offset, output_data_buffer_offset, @@ -410,22 +386,6 @@ impl SandboxMemoryLayout { self.peb_output_data_offset } - /// Get the offset in guest memory to the host function definitions - /// size - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - pub(super) fn get_host_function_definitions_size_offset(&self) -> usize { - // The size field is the first field in the `HostFunctions` struct - self.peb_host_function_definitions_offset - } - - /// Get the offset in guest memory to the host function definitions - /// pointer. - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn get_host_function_definitions_pointer_offset(&self) -> usize { - // The size field is the field after the size field in the `HostFunctions` struct which is a u64 - self.peb_host_function_definitions_offset + size_of::() - } - /// Get the offset in guest memory to the minimum guest stack address. #[instrument(skip_all, parent = Span::current(), level= "Trace")] fn get_min_guest_stack_address_offset(&self) -> usize { @@ -623,8 +583,6 @@ impl SandboxMemoryLayout { total_mapped_memory_size += round_up_to(stack_size, PAGE_SIZE_USIZE); total_mapped_memory_size += round_up_to(heap_size, PAGE_SIZE_USIZE); total_mapped_memory_size += round_up_to(cfg.get_host_exception_size(), PAGE_SIZE_USIZE); - total_mapped_memory_size += - round_up_to(cfg.get_host_function_definition_size(), PAGE_SIZE_USIZE); total_mapped_memory_size += round_up_to(cfg.get_guest_error_buffer_size(), PAGE_SIZE_USIZE); total_mapped_memory_size += round_up_to(cfg.get_input_data_size(), PAGE_SIZE_USIZE); total_mapped_memory_size += round_up_to(cfg.get_output_data_size(), PAGE_SIZE_USIZE); @@ -709,31 +667,12 @@ impl SandboxMemoryLayout { } // PEB - let host_functions_definitions_offset = builder.push_page_aligned( + let host_exception_offset = builder.push_page_aligned( size_of::(), MemoryRegionFlags::READ | MemoryRegionFlags::WRITE, Peb, ); - let expected_host_functions_definitions_offset = - TryInto::::try_into(self.host_function_definitions_buffer_offset)?; - - if host_functions_definitions_offset != expected_host_functions_definitions_offset { - return Err(new_error!( - "Host Function Definitions offset does not match expected Host Function Definitions offset expected: {}, actual: {}", - expected_host_functions_definitions_offset, - host_functions_definitions_offset - )); - } - - // host function definitions - let host_exception_offset = builder.push_page_aligned( - self.sandbox_memory_config - .get_host_function_definition_size(), - MemoryRegionFlags::READ, - HostFunctionDefinitions, - ); - let expected_host_exception_offset = TryInto::::try_into(self.host_exception_buffer_offset)?; @@ -938,16 +877,6 @@ impl SandboxMemoryLayout { // Skip guest_dispatch_function_ptr_offset because it is set by the guest - // Set up Host Function Definition - shared_mem.write_u64( - self.get_host_function_definitions_size_offset(), - self.sandbox_memory_config - .get_host_function_definition_size() - .try_into()?, - )?; - let addr = get_address!(host_function_definitions_buffer); - shared_mem.write_u64(self.get_host_function_definitions_pointer_offset(), addr)?; - // Set up Host Exception Header // The peb only needs to include the size, not the actual buffer // since the the guest wouldn't want to read the buffer anyway @@ -1098,8 +1027,6 @@ mod tests { expected_size += round_up_to(size_of::(), PAGE_SIZE_USIZE); - expected_size += round_up_to(cfg.get_host_function_definition_size(), PAGE_SIZE_USIZE); - expected_size += round_up_to(cfg.get_host_exception_size(), PAGE_SIZE_USIZE); expected_size += round_up_to(cfg.get_guest_error_buffer_size(), PAGE_SIZE_USIZE); diff --git a/src/hyperlight_host/src/mem/memory_region.rs b/src/hyperlight_host/src/mem/memory_region.rs index 889ee2f0c..6ad40ca20 100644 --- a/src/hyperlight_host/src/mem/memory_region.rs +++ b/src/hyperlight_host/src/mem/memory_region.rs @@ -131,8 +131,6 @@ pub enum MemoryRegionType { Code, /// The region contains the PEB Peb, - /// The region contains the Host Function Definitions - HostFunctionDefinitions, /// The region contains the Host Exception Data HostExceptionData, /// The region contains the Guest Error Data diff --git a/src/hyperlight_host/src/mem/mgr.rs b/src/hyperlight_host/src/mem/mgr.rs index f94119c28..e1d9a9275 100644 --- a/src/hyperlight_host/src/mem/mgr.rs +++ b/src/hyperlight_host/src/mem/mgr.rs @@ -25,7 +25,6 @@ use hyperlight_common::flatbuffer_wrappers::function_call::{ use hyperlight_common::flatbuffer_wrappers::function_types::ReturnValue; use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError}; use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData; -use hyperlight_common::flatbuffer_wrappers::host_function_details::HostFunctionDetails; use serde_json::from_str; use tracing::{instrument, Span}; @@ -206,8 +205,6 @@ where MemoryRegionType::InputData => PAGE_PRESENT | PAGE_RW | PAGE_NX, MemoryRegionType::OutputData => PAGE_PRESENT | PAGE_RW | PAGE_NX, MemoryRegionType::Peb => PAGE_PRESENT | PAGE_RW | PAGE_NX, - // Host Function Definitions are readonly in the guest - MemoryRegionType::HostFunctionDefinitions => PAGE_PRESENT | PAGE_NX, MemoryRegionType::PanicContext => PAGE_PRESENT | PAGE_RW | PAGE_NX, MemoryRegionType::GuestErrorData => PAGE_PRESENT | PAGE_RW | PAGE_NX, // Host Exception Data are readonly in the guest @@ -460,42 +457,6 @@ impl SandboxMemoryManager { } } - /// Writes host function details to memory - #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - pub(crate) fn write_buffer_host_function_details(&mut self, buffer: &[u8]) -> Result<()> { - let host_function_details = HostFunctionDetails::try_from(buffer).map_err(|e| { - new_error!( - "write_buffer_host_function_details: failed to convert buffer to HostFunctionDetails: {}", - e - ) - })?; - - let host_function_call_buffer: Vec = (&host_function_details).try_into().map_err(|_| { - new_error!( - "write_buffer_host_function_details: failed to convert HostFunctionDetails to Vec" - ) - })?; - - let buffer_size = { - let size_u64 = self - .shared_mem - .read_u64(self.layout.get_host_function_definitions_size_offset())?; - usize::try_from(size_u64) - }?; - - if host_function_call_buffer.len() > buffer_size { - log_then_return!( - "Host Function Details buffer is too big for the host_function_definitions buffer" - ); - } - - self.shared_mem.copy_from_slice( - host_function_call_buffer.as_slice(), - self.layout.host_function_definitions_buffer_offset, - )?; - Ok(()) - } - /// Set the stack guard to `cookie` using `layout` to calculate /// its location and `shared_mem` to write it. #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] diff --git a/src/hyperlight_host/src/sandbox/host_funcs.rs b/src/hyperlight_host/src/sandbox/host_funcs.rs index b0d3fa05c..fe4226d84 100644 --- a/src/hyperlight_host/src/sandbox/host_funcs.rs +++ b/src/hyperlight_host/src/sandbox/host_funcs.rs @@ -17,18 +17,17 @@ limitations under the License. use std::io::{IsTerminal, Write}; use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnValue}; -use hyperlight_common::flatbuffer_wrappers::host_function_definition::HostFunctionDefinition; -use hyperlight_common::flatbuffer_wrappers::host_function_details::HostFunctionDetails; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use tracing::{instrument, Span}; use super::{ExtraAllowedSyscall, FunctionsMap}; +use crate::func::host_functions::HostFunctionDefinition; use crate::func::HyperlightFunction; -use crate::mem::mgr::SandboxMemoryManager; -use crate::mem::shared_mem::ExclusiveSharedMemory; use crate::HyperlightError::HostFunctionNotFound; use crate::{new_error, Result}; +type HostFunctionDetails = Option>; + #[derive(Default, Clone)] /// A Wrapper around details of functions exposed by the Host pub struct HostFuncsWrapper { @@ -58,11 +57,10 @@ impl HostFuncsWrapper { #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] pub(crate) fn register_host_function( &mut self, - mgr: &mut SandboxMemoryManager, hfd: &HostFunctionDefinition, func: HyperlightFunction, ) -> Result<()> { - register_host_function_helper(self, mgr, hfd, func, None) + register_host_function_helper(self, hfd, func, None) } /// Register a host function with the sandbox, with a list of extra syscalls @@ -71,12 +69,11 @@ impl HostFuncsWrapper { #[cfg(all(feature = "seccomp", target_os = "linux"))] pub(crate) fn register_host_function_with_syscalls( &mut self, - mgr: &mut SandboxMemoryManager, hfd: &HostFunctionDefinition, func: HyperlightFunction, extra_allowed_syscalls: Vec, ) -> Result<()> { - register_host_function_helper(self, mgr, hfd, func, Some(extra_allowed_syscalls)) + register_host_function_helper(self, hfd, func, Some(extra_allowed_syscalls)) } /// Assuming a host function called `"HostPrint"` exists, and takes a @@ -109,11 +106,21 @@ impl HostFuncsWrapper { ) -> Result { call_host_func_impl(self.get_host_funcs(), name, args) } + + /// Insert a host function into the list of registered host functions. + pub(super) fn insert_host_function(&mut self, host_function: HostFunctionDefinition) { + match &mut self.function_details { + Some(host_functions) => host_functions.push(host_function), + None => { + let host_functions = Vec::from(&[host_function]); + self.function_details = Some(host_functions); + } + } + } } fn register_host_function_helper( self_: &mut HostFuncsWrapper, - mgr: &mut SandboxMemoryManager, hfd: &HostFunctionDefinition, func: HyperlightFunction, extra_allowed_syscalls: Option>, @@ -133,22 +140,7 @@ fn register_host_function_helper( .get_host_funcs_mut() .insert(hfd.function_name.to_string(), func, None); } - self_ - .get_host_func_details_mut() - .insert_host_function(hfd.clone()); - // Functions need to be sorted so that they are serialised in sorted order - // this is required in order for flatbuffers C implementation used in the Gues Library - // to be able to search the functions by name. - self_ - .get_host_func_details_mut() - .sort_host_functions_by_name(); - let buffer: Vec = self_.get_host_func_details().try_into().map_err(|e| { - new_error!( - "Error serializing host function details to flatbuffer: {}", - e - ) - })?; - mgr.write_buffer_host_function_details(&buffer)?; + self_.insert_host_function(hfd.clone()); Ok(()) } diff --git a/src/schema/host_function_definition.fbs b/src/schema/host_function_definition.fbs deleted file mode 100644 index 2367007b7..000000000 --- a/src/schema/host_function_definition.fbs +++ /dev/null @@ -1,11 +0,0 @@ -include "function_types.fbs"; - -namespace Hyperlight.Generated; - -table HostFunctionDefinition { - function_name:string(required, key); - parameters:[ParameterType]; - return_type:ReturnType; -} - -root_type HostFunctionDefinition; \ No newline at end of file diff --git a/src/schema/host_function_details.fbs b/src/schema/host_function_details.fbs deleted file mode 100644 index 5ebd68576..000000000 --- a/src/schema/host_function_details.fbs +++ /dev/null @@ -1,9 +0,0 @@ -include "host_function_definition.fbs"; - -namespace Hyperlight.Generated; - -table HostFunctionDetails { - functions:[HostFunctionDefinition]; -} - -root_type HostFunctionDetails; \ No newline at end of file