Skip to content

Commit 032b1f2

Browse files
committed
[common,guest,host] modified HyperlightPEB API + added rsp mod in hosts
- cleaned up the HyperlightPEB API in the common library. -- added MemoryRegion struct to better group related offsets and sizes. -- removed pub fields from HyperlightPEB struct making fields accessible only via getters/setters. -- cleaned up, commented, and re-organized existing fxns for HyperlightPEB struct. - now we modify the rsp in the host if the guest sets up a new stack region (i.e., essentially dropping the tmp stack). Signed-off-by: danbugs <[email protected]>
1 parent bcb9246 commit 032b1f2

File tree

14 files changed

+485
-293
lines changed

14 files changed

+485
-293
lines changed

Diff for: src/hyperlight_common/src/outb.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ pub fn outb(port: u16, value: u8) {
4545
}
4646
RunMode::InProcessLinux | RunMode::InProcessWindows => {
4747
if let Some(outb_func) = OUTB_HANDLER_CTX {
48-
outb_func((*PEB).outb_ptr_ctx as *mut core::ffi::c_void, port, value);
48+
outb_func(
49+
(*PEB).get_outb_ptr_ctx() as *mut core::ffi::c_void,
50+
port,
51+
value,
52+
);
4953
} else if let Some(outb_func) = OUTB_HANDLER {
5054
outb_func(port, value);
5155
} else {

Diff for: src/hyperlight_common/src/peb.rs

+333-187
Large diffs are not rendered by default.

Diff for: src/hyperlight_guest/src/entrypoint.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static INIT: Once = Once::new();
7676
pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, max_log_level: u64) {
7777
INIT.call_once(|| unsafe {
7878
PEB = peb_address as *mut HyperlightPEB;
79-
RUNNING_MODE = (*PEB).clone().run_mode;
79+
RUNNING_MODE = (*PEB).clone().get_run_mode();
8080

8181
// The guest receives an undifferentiated block of memory that it can address as it sees fit.
8282
// This 'addressing' is done by writing to the PEB the guest's memory layout via this function,
@@ -87,15 +87,15 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, max_log_level: u64
8787

8888
// The guest sets the address to a "guest function dispatch" function, which is a function
8989
// that is called by the host to dispatch calls to guest functions.
90-
(*PEB).guest_function_dispatch_ptr = dispatch_function as usize as u64;
90+
(*PEB).set_guest_function_dispatch_ptr(dispatch_function as u64);
9191

9292
// Set up the guest heap
9393
HEAP_ALLOCATOR
9494
.try_lock()
9595
.expect("Failed to access HEAP_ALLOCATOR")
9696
.init(
9797
(*PEB).get_heap_data_address() as usize,
98-
(*PEB).guest_heap_data_size as usize,
98+
(*PEB).get_guest_heap_data_size() as usize,
9999
);
100100

101101
__security_cookie = peb_address ^ seed;
@@ -125,17 +125,17 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, max_log_level: u64
125125
RunMode::InProcessLinux | RunMode::InProcessWindows => {
126126
OUTB_HANDLER = {
127127
let outb_handler: extern "C" fn(u16, u8) =
128-
core::mem::transmute((*PEB).outb_ptr);
128+
core::mem::transmute((*PEB).get_outb_ptr());
129129
Some(outb_handler)
130130
};
131131

132-
if (*PEB).outb_ptr_ctx == 0 {
132+
if (*PEB).get_outb_ptr_ctx() == 0 {
133133
panic!("outb_ptr_ctx is null");
134134
}
135135

136136
OUTB_HANDLER_CTX = {
137137
let outb_handler_ctx: extern "C" fn(*mut core::ffi::c_void, u16, u8) =
138-
core::mem::transmute((*PEB).outb_ptr);
138+
core::mem::transmute((*PEB).get_outb_ptr());
139139
Some(outb_handler_ctx)
140140
};
141141
}

Diff for: src/hyperlight_guest/src/guest_error.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
3838
unsafe {
3939
assert_ne!(!peb.get_guest_error_data_address(), 0);
4040
let len = guest_error_buffer.len();
41-
if guest_error_buffer.len() > peb.guest_error_data_size as usize {
41+
if guest_error_buffer.len() > peb.get_guest_error_data_size() as usize {
4242
error!(
4343
"Guest error buffer is too small to hold the error message: size {} buffer size {} message may be truncated",
4444
guest_error_buffer.len(),
45-
peb.guest_error_data_size as usize
45+
peb.get_guest_error_data_size() as usize
4646
);
4747
// get the length of the message
4848
let message_len = message.map_or("".to_string(), |m| m.to_string()).len();
4949
// message is too long, truncate it
5050
let truncate_len =
51-
message_len - (guest_error_buffer.len() - peb.guest_error_data_size as usize);
51+
message_len - (guest_error_buffer.len() - peb.get_guest_error_data_size() as usize);
5252
let truncated_message = message
5353
.map_or("".to_string(), |m| m.to_string())
5454
.chars()
@@ -77,7 +77,7 @@ pub(crate) fn reset_error() {
7777
core::ptr::write_bytes(
7878
(*PEB).get_guest_error_data_address() as *mut u8,
7979
0,
80-
(*PEB).guest_error_data_size as usize,
80+
(*PEB).get_guest_error_data_size() as usize,
8181
);
8282
}
8383
}

Diff for: src/hyperlight_guest/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
7272
copy_nonoverlapping(
7373
info.to_string().as_ptr(),
7474
(*PEB).get_guest_panic_context_address() as *mut u8,
75-
(*PEB).guest_panic_context_size as usize,
75+
(*PEB).get_guest_panic_context_size() as usize,
7676
);
7777
}
7878
outb(OutBAction::Abort as u16, ErrorCode::UnknownError as u8);

Diff for: src/hyperlight_host/src/func/guest_dispatch.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ pub(crate) fn call_function_on_guest(
5454
.try_into()
5555
.map_err(|_| HyperlightError::Error("Failed to serialize FunctionCall".to_string()))?;
5656

57-
let input_data_region = mem_mgr.read_hyperlight_peb()?.get_input_data_guest_region();
57+
let input_data_region = mem_mgr
58+
.memory_sections
59+
.read_hyperlight_peb()?
60+
.get_input_data_guest_region();
5861

5962
mem_mgr.write_guest_function_call(input_data_region, &buffer)?;
6063

@@ -81,6 +84,7 @@ pub(crate) fn call_function_on_guest(
8184
check_for_guest_error(mem_mgr)?;
8285

8386
let output_data_region = mem_mgr
87+
.memory_sections
8488
.read_hyperlight_peb()?
8589
.get_output_data_guest_region();
8690

Diff for: src/hyperlight_host/src/hypervisor/hyperv_linux.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,16 @@ impl Hypervisor for HypervLinuxDriver {
488488
dbg_mem_access_fn,
489489
)?;
490490

491-
// TODO(danbugs:297): here, we should update the rsp to what the guest configured.
491+
// The guest may have chosen a different stack region. If so, we drop usage of our tmp stack.
492+
let hyperlight_peb = self.mem_sections.read_hyperlight_peb()?;
493+
494+
if let Some(guest_stack_data) = &hyperlight_peb.get_guest_stack_data_region() {
495+
if guest_stack_data.offset.is_some() {
496+
// If we got here, it means the guest has set up a new stack
497+
let rsp = hyperlight_peb.get_top_of_guest_stack_data();
498+
self.orig_rsp = GuestPtr::try_from(RawPtr::from(rsp))?;
499+
}
500+
}
492501

493502
Ok(())
494503
}

Diff for: src/hyperlight_host/src/hypervisor/hyperv_windows.rs

+11
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,17 @@ impl Hypervisor for HypervWindowsDriver {
338338
dbg_mem_access_hdl,
339339
)?;
340340

341+
// The guest may have chosen a different stack region. If so, we drop usage of our tmp stack.
342+
let hyperlight_peb = self.mem_sections.read_hyperlight_peb()?;
343+
344+
if let Some(guest_stack_data) = &hyperlight_peb.get_guest_stack_data_region() {
345+
if guest_stack_data.offset.is_some() {
346+
// If we got here, it means the guest has set up a new stack
347+
let rsp = hyperlight_peb.get_top_of_guest_stack_data();
348+
self.orig_rsp = GuestPtr::try_from(RawPtr::from(rsp))?;
349+
}
350+
}
351+
341352
Ok(())
342353
}
343354

Diff for: src/hyperlight_host/src/hypervisor/hypervisor_handler.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ impl HypervisorHandler {
399399
.as_mut()
400400
.ok_or_else(|| {
401401
new_error!("guest shm lock: {}:{}", file!(), line!())
402-
})?.read_hyperlight_peb()?.guest_function_dispatch_ptr);
402+
})?.memory_sections.read_hyperlight_peb()?.get_guest_function_dispatch_ptr());
403403

404404
if dispatch_function_addr == RawPtr(0) {
405405
log_then_return!(

Diff for: src/hyperlight_host/src/hypervisor/kvm.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,16 @@ impl Hypervisor for KVMDriver {
438438
dbg_mem_access_fn,
439439
)?;
440440

441-
// TODO(danbugs:297): here, we should update the rsp to what the guest configured.
441+
// The guest may have chosen a different stack region. If so, we drop usage of our tmp stack.
442+
let hyperlight_peb = self.mem_sections.read_hyperlight_peb()?;
443+
444+
if let Some(guest_stack_data) = &hyperlight_peb.get_guest_stack_data_region() {
445+
if guest_stack_data.offset.is_some() {
446+
// If we got here, it means the guest has set up a new stack
447+
let rsp = hyperlight_peb.get_top_of_guest_stack_data();
448+
self.orig_rsp = GuestPtr::try_from(RawPtr::from(rsp))?;
449+
}
450+
}
442451

443452
Ok(())
444453
}

Diff for: src/hyperlight_host/src/hypervisor/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use log::LevelFilter;
1818
use tracing::{instrument, Span};
1919

2020
use crate::error::HyperlightError::ExecutionCanceledByHost;
21-
use crate::sandbox::sandbox_builder::{MemoryRegionFlags, SandboxMemorySections};
2221
use crate::metrics::METRIC_GUEST_CANCELLATION;
22+
use crate::sandbox::sandbox_builder::{MemoryRegionFlags, SandboxMemorySections};
2323
use crate::{log_then_return, new_error, HyperlightError, Result};
2424

2525
/// Util for handling x87 fpu state

Diff for: src/hyperlight_host/src/mem/mgr.rs

+56-39
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use hyperlight_common::flatbuffer_wrappers::function_call::{
2525
use hyperlight_common::flatbuffer_wrappers::function_types::ReturnValue;
2626
use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError};
2727
use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData;
28-
use hyperlight_common::peb::HyperlightPEB;
2928
use serde_json::from_str;
3029
use tracing::{instrument, Span};
3130

@@ -236,28 +235,6 @@ impl<S> SandboxMemoryManager<S>
236235
where
237236
S: SharedMemory,
238237
{
239-
pub(crate) fn write_hyperlight_peb(&mut self, hyperlight_peb: HyperlightPEB) -> Result<()> {
240-
let peb_offset = self
241-
.memory_sections
242-
.get_hyperlight_peb_section_host_address()
243-
.unwrap() as *mut HyperlightPEB;
244-
245-
unsafe {
246-
peb_offset.copy_from(&hyperlight_peb, 1);
247-
}
248-
249-
Ok(())
250-
}
251-
252-
pub(crate) fn read_hyperlight_peb(&self) -> Result<HyperlightPEB> {
253-
let peb_offset = self
254-
.memory_sections
255-
.get_hyperlight_peb_section_host_address()
256-
.unwrap() as *mut HyperlightPEB;
257-
258-
Ok(unsafe { peb_offset.read() })
259-
}
260-
261238
/// Create a memory snapshot and push it onto the stack of snapshots.
262239
///
263240
/// It should be used when you want to save the state of the memory—for example, when evolving a
@@ -376,7 +353,10 @@ impl SandboxMemoryManager<HostSharedMemory> {
376353
/// Reads a host function call from memory
377354
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
378355
pub(crate) fn get_host_function_call(&mut self) -> Result<FunctionCall> {
379-
let (ptr, size) = self.read_hyperlight_peb()?.get_output_data_guest_region();
356+
let (ptr, size) = self
357+
.memory_sections
358+
.read_hyperlight_peb()?
359+
.get_output_data_guest_region();
380360
self.shared_mem
381361
.try_pop_buffer_into::<FunctionCall>(ptr as usize, size as usize)
382362
}
@@ -390,7 +370,10 @@ impl SandboxMemoryManager<HostSharedMemory> {
390370
)
391371
})?;
392372

393-
let (ptr, size) = self.read_hyperlight_peb()?.get_input_data_guest_region();
373+
let (ptr, size) = self
374+
.memory_sections
375+
.read_hyperlight_peb()?
376+
.get_input_data_guest_region();
394377

395378
self.shared_mem.push_buffer(
396379
ptr as usize,
@@ -434,23 +417,32 @@ impl SandboxMemoryManager<HostSharedMemory> {
434417
/// Read guest log data from the `SharedMemory` contained within `self`
435418
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
436419
pub(crate) fn read_guest_log_data(&mut self) -> Result<GuestLogData> {
437-
let (ptr, size) = self.read_hyperlight_peb()?.get_output_data_guest_region();
420+
let (ptr, size) = self
421+
.memory_sections
422+
.read_hyperlight_peb()?
423+
.get_output_data_guest_region();
438424
self.shared_mem
439425
.try_pop_buffer_into::<GuestLogData>(ptr as usize, size as usize)
440426
}
441427

442428
/// Get the length of the host exception
443429
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
444430
fn get_host_error_length(&self) -> Result<i32> {
445-
let offset = self.read_hyperlight_peb()?.get_host_error_guest_offset() as usize;
431+
let offset = self
432+
.memory_sections
433+
.read_hyperlight_peb()?
434+
.get_host_error_guest_address() as usize;
446435
// The host exception field is expected to contain a 32-bit length followed by the exception data.
447436
self.shared_mem.read::<i32>(offset)
448437
}
449438

450439
/// Get a bool indicating if there is a host error
451440
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
452441
fn has_host_error(&self) -> Result<bool> {
453-
let offset = self.read_hyperlight_peb()?.get_host_error_guest_offset() as usize;
442+
let offset = self
443+
.memory_sections
444+
.read_hyperlight_peb()?
445+
.get_host_error_guest_address() as usize;
454446
// The host exception field is expected to contain a 32-bit length followed by the exception data.
455447
let len = self.shared_mem.read::<i32>(offset)?;
456448
Ok(len != 0)
@@ -465,7 +457,10 @@ impl SandboxMemoryManager<HostSharedMemory> {
465457
/// self.get_host_error_length()
466458
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
467459
fn get_host_error_data(&self, exception_data_slc: &mut [u8]) -> Result<()> {
468-
let offset = self.read_hyperlight_peb()?.get_host_error_guest_offset() as usize;
460+
let offset = self
461+
.memory_sections
462+
.read_hyperlight_peb()?
463+
.get_host_error_guest_address() as usize;
469464
let len = self.get_host_error_length()?;
470465

471466
let exception_data_slc_len = exception_data_slc.len();
@@ -510,9 +505,14 @@ impl SandboxMemoryManager<HostSharedMemory> {
510505
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
511506
pub(crate) fn get_guest_error(&self) -> Result<GuestError> {
512507
// get memory buffer max size
513-
let guest_error_data_ptr =
514-
self.read_hyperlight_peb()?.get_guest_error_guest_offset() as usize;
515-
let guest_error_data_size = self.read_hyperlight_peb()?.guest_error_data_size as usize;
508+
let guest_error_data_ptr = self
509+
.memory_sections
510+
.read_hyperlight_peb()?
511+
.get_guest_error_guest_address() as usize;
512+
let guest_error_data_size = self
513+
.memory_sections
514+
.read_hyperlight_peb()?
515+
.get_guest_error_data_size() as usize;
516516

517517
// get guest error from layout and shared mem
518518
let mut guest_error_buffer = vec![b'0'; guest_error_data_size];
@@ -541,18 +541,29 @@ impl SandboxMemoryManager<HostSharedMemory> {
541541
.try_into()
542542
.map_err(|_| new_error!("write_outb_error: failed to convert GuestError to Vec<u8>"))?;
543543

544-
let guest_error_data_ptr = self.read_hyperlight_peb()?.get_guest_error_guest_offset();
545-
let guest_error_data_size = self.read_hyperlight_peb()?.guest_error_data_size;
544+
let guest_error_data_ptr = self
545+
.memory_sections
546+
.read_hyperlight_peb()?
547+
.get_guest_error_guest_address();
548+
let guest_error_data_size = self
549+
.memory_sections
550+
.read_hyperlight_peb()?
551+
.get_guest_error_data_size();
546552

547553
if guest_error_buffer.len() as u64 > guest_error_data_size {
548554
log_then_return!("The guest error message is too large to fit in the shared memory");
549555
}
550556
self.shared_mem
551557
.copy_from_slice(guest_error_buffer.as_slice(), guest_error_data_ptr as usize)?;
552558

553-
let host_error_data_ptr =
554-
self.read_hyperlight_peb()?.get_host_error_guest_offset() as usize;
555-
let host_error_data_size = self.read_hyperlight_peb()?.host_error_data_size as usize;
559+
let host_error_data_ptr = self
560+
.memory_sections
561+
.read_hyperlight_peb()?
562+
.get_host_error_guest_address() as usize;
563+
let host_error_data_size = self
564+
.memory_sections
565+
.read_hyperlight_peb()?
566+
.get_host_error_data_size() as usize;
556567

557568
// First four bytes of host exception are length
558569

@@ -574,8 +585,14 @@ impl SandboxMemoryManager<HostSharedMemory> {
574585
/// Read guest panic data from the `SharedMemory` contained within `self`
575586
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
576587
pub fn read_guest_panic_context_data(&self) -> Result<Vec<u8>> {
577-
let offset = self.read_hyperlight_peb()?.get_guest_panic_context_offset() as usize;
578-
let size = self.read_hyperlight_peb()?.guest_panic_context_size as usize;
588+
let offset = self
589+
.memory_sections
590+
.read_hyperlight_peb()?
591+
.get_guest_panic_context_guest_address() as usize;
592+
let size = self
593+
.memory_sections
594+
.read_hyperlight_peb()?
595+
.get_guest_panic_context_size() as usize;
579596
let mut vec_out = vec![0; size];
580597
self.shared_mem
581598
.copy_to_slice(vec_out.as_mut_slice(), offset)?;

Diff for: src/hyperlight_host/src/sandbox/leaked_outb.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ impl<'a> LeakedOutBWrapper<'a> {
9999
};
100100

101101
let addr: u64 = res.hdl_wrapper_addr()?;
102-
let mut peb = mgr.read_hyperlight_peb()?;
102+
let mut peb = mgr.memory_sections.read_hyperlight_peb()?;
103103
peb.set_outb_ptr(Self::outb_addr());
104104
peb.set_outb_ptr_ctx(addr);
105-
mgr.write_hyperlight_peb(peb)?;
105+
mgr.memory_sections.write_hyperlight_peb(peb)?;
106106

107107
Ok(res)
108108
}

0 commit comments

Comments
 (0)