Skip to content

Commit 727f73b

Browse files
committed
[host/mem] added 'user memory' region to store additional guest blob
+ added some extra configuration to set the maximum memory size (needed for extra blob) + if guest blob is provided, we now write it to shared mem when creating a sandbox Signed-off-by: danbugs <[email protected]>
1 parent f9836b1 commit 727f73b

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

src/hyperlight_host/src/mem/layout.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ use crate::sandbox::SandboxConfiguration;
3131
use crate::{Result, new_error};
3232

3333
// +-------------------------------------------+
34+
// | User Memory | (get_total_memory - size_a)
35+
// +-------------------------------------------+ (size_a)
3436
// | Guest (User) Stack |
3537
// +-------------------------------------------+
3638
// | Guard Page (4KiB) |
@@ -103,6 +105,7 @@ pub(crate) struct SandboxMemoryLayout {
103105
guest_heap_buffer_offset: usize,
104106
guard_page_offset: usize,
105107
guest_user_stack_buffer_offset: usize, // the lowest address of the user stack
108+
user_memory_offset: usize,
106109

107110
// other
108111
pub(crate) peb_address: usize,
@@ -181,6 +184,10 @@ impl Debug for SandboxMemoryLayout {
181184
"Guest User Stack Buffer Offset",
182185
&format_args!("{:#x}", self.guest_user_stack_buffer_offset),
183186
)
187+
.field(
188+
"User Memory Offset",
189+
&format_args!("{:#x}", self.user_memory_offset),
190+
)
184191
.field(
185192
"Page Table Size",
186193
&format_args!("{:#x}", self.total_page_table_size),
@@ -275,6 +282,7 @@ impl SandboxMemoryLayout {
275282
let guest_user_stack_buffer_offset = guard_page_offset + PAGE_SIZE_USIZE;
276283
// round up stack size to page size. This is needed for MemoryRegion
277284
let stack_size_rounded = round_up_to(stack_size, PAGE_SIZE_USIZE);
285+
let user_memory_offset = guest_user_stack_buffer_offset + stack_size_rounded;
278286

279287
Ok(Self {
280288
peb_offset,
@@ -299,6 +307,7 @@ impl SandboxMemoryLayout {
299307
guard_page_offset,
300308
total_page_table_size,
301309
guest_code_offset,
310+
user_memory_offset,
302311
})
303312
}
304313

@@ -444,7 +453,11 @@ impl SandboxMemoryLayout {
444453
/// layout.
445454
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
446455
fn get_unaligned_memory_size(&self) -> usize {
447-
self.get_top_of_user_stack_offset() + self.stack_size
456+
if self.sandbox_memory_config.get_guest_memory_size() == 0 {
457+
self.user_memory_offset
458+
} else {
459+
self.sandbox_memory_config.get_guest_memory_size()
460+
}
448461
}
449462

450463
/// get the code offset
@@ -682,12 +695,34 @@ impl SandboxMemoryLayout {
682695
}
683696

684697
// stack
685-
let final_offset = builder.push_page_aligned(
698+
let user_memory_offset = builder.push_page_aligned(
686699
self.get_guest_stack_size(),
687700
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE,
688701
Stack,
689702
);
690703

704+
let expected_user_memory_offset = TryInto::<usize>::try_into(self.user_memory_offset)?;
705+
706+
if user_memory_offset != expected_user_memory_offset {
707+
return Err(new_error!(
708+
"User Memory offset does not match expected User Memory offset expected: {}, actual: {}",
709+
expected_user_memory_offset,
710+
user_memory_offset
711+
));
712+
}
713+
714+
let user_region_size = self.get_memory_size()? - user_memory_offset;
715+
716+
let final_offset = if user_region_size > 0 {
717+
builder.push_page_aligned(
718+
user_region_size,
719+
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE,
720+
Code,
721+
)
722+
} else {
723+
user_memory_offset
724+
};
725+
691726
let expected_final_offset = TryInto::<usize>::try_into(self.get_memory_size()?)?;
692727

693728
if final_offset != expected_final_offset {
@@ -701,6 +736,21 @@ impl SandboxMemoryLayout {
701736
Ok(builder.build())
702737
}
703738

739+
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
740+
pub(crate) fn write_user_memory(
741+
&self,
742+
shared_mem: &mut ExclusiveSharedMemory,
743+
bytes: &[u8],
744+
) -> Result<(u64, usize)> {
745+
if self.user_memory_offset + bytes.len() > self.get_memory_size()? {
746+
return Err(new_error!(
747+
"Not enough memory in shared memory to write user memory, increase guest memory size with set_guest_memory_size"
748+
));
749+
}
750+
shared_mem.copy_from_slice(bytes, self.user_memory_offset)?;
751+
Ok((self.user_memory_offset as u64, bytes.len()))
752+
}
753+
704754
/// Write the finished memory layout to `shared_mem` and return
705755
/// `Ok` if successful.
706756
///

src/hyperlight_host/src/sandbox/config.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ pub struct SandboxConfiguration {
5555
/// The size of the memory buffer that is made available for input to the
5656
/// Guest Binary
5757
output_data_size: usize,
58+
/// Total guest memory size
59+
guest_memory_size: usize,
5860
/// The stack size to use in the guest sandbox. If set to 0, the stack
5961
/// size will be determined from the PE file header.
6062
///
@@ -133,6 +135,7 @@ impl SandboxConfiguration {
133135
interrupt_vcpu_sigrtmin_offset,
134136
#[cfg(gdb)]
135137
guest_debug_info,
138+
guest_memory_size: 0,
136139
#[cfg(crashdump)]
137140
guest_core_dump,
138141
}
@@ -262,6 +265,16 @@ impl SandboxConfiguration {
262265
(self.heap_size_override > 0).then_some(self.heap_size_override)
263266
}
264267

268+
/// Set the total memory size.
269+
pub fn set_guest_memory_size(&mut self, guest_memory_size: usize) {
270+
self.guest_memory_size = guest_memory_size;
271+
}
272+
273+
/// Get the total memory size.
274+
pub(crate) fn get_guest_memory_size(&self) -> usize {
275+
self.guest_memory_size
276+
}
277+
265278
/// If self.stack_size is non-zero, return it. Otherwise,
266279
/// return exe_info.stack_reserve()
267280
#[instrument(skip_all, parent = Span::current(), level= "Trace")]

src/hyperlight_host/src/sandbox/mem_mgr.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ impl MemMgrWrapper<ExclusiveSharedMemory> {
9898
let mem_size = shared_mem.mem_size();
9999
layout.write(shared_mem, SandboxMemoryLayout::BASE_ADDRESS, mem_size)
100100
}
101+
102+
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
103+
pub(super) fn write_user_memory(&mut self, user_memory: &[u8]) -> Result<()> {
104+
let mgr = self.unwrap_mgr_mut();
105+
let layout = mgr.layout;
106+
let shared_mem = mgr.get_shared_mem_mut();
107+
layout.write_user_memory(shared_mem, user_memory)?;
108+
Ok(())
109+
}
101110
}
102111

103112
impl MemMgrWrapper<HostSharedMemory> {

src/hyperlight_host/src/sandbox/uninitialized.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,19 @@ impl UninitializedSandbox {
240240

241241
let mut mem_mgr_wrapper = {
242242
let mut mgr = UninitializedSandbox::load_guest_binary(sandbox_cfg, &guest_binary)?;
243+
243244
let stack_guard = Self::create_stack_guard();
244245
mgr.set_stack_guard(&stack_guard)?;
245246
MemMgrWrapper::new(mgr, stack_guard)
246247
};
247248

248249
mem_mgr_wrapper.write_memory_layout()?;
249250

251+
// if env has a guest blob, load it into shared mem
252+
if let Some(bytes) = env.guest_blob {
253+
mem_mgr_wrapper.write_user_memory(bytes)?;
254+
}
255+
250256
let host_funcs = Arc::new(Mutex::new(FunctionRegistry::default()));
251257

252258
let mut sandbox = Self {

0 commit comments

Comments
 (0)