Skip to content

Commit 04e8e96

Browse files
committed
[guest,host/leaked_outb] Fixed inprocess execution for Windows
- Changed the ABI for the inprocess outb handler from `extern "C"` to `extern sysv64`. This was needed because `extern "C"` caused issues on Windows. Previously, we used `extern "win64"`, which was problematic for guests intending to use `hyperlight_common` and not supporting the Windows ABI. - Added a test for running inprocess on Windows w/ load library. Signed-off-by: danbugs <[email protected]>
1 parent 642fcdc commit 04e8e96

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

src/hyperlight_common/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ pub static mut RUNNING_MODE: peb::RunMode = peb::RunMode::None;
5656
/// instruction. Instead, we use a function pointer to call an `outb_handler` function.
5757
/// For in-process mode, we can't call the `outb` instruction directly because it is a privileged
5858
/// instruction. Instead, we use a function pointer to call an `outb_handler` function.
59-
pub static mut OUTB_HANDLER: Option<extern "C" fn(u16, u8)> = None;
59+
pub static mut OUTB_HANDLER: Option<extern "sysv64" fn(u16, u8)> = None;
6060

61-
pub static mut OUTB_HANDLER_CTX: Option<extern "C" fn(*mut core::ffi::c_void, u16, u8)> = None;
61+
pub static mut OUTB_HANDLER_CTX: Option<extern "sysv64" fn(*mut core::ffi::c_void, u16, u8)> = None;
6262

6363
/// Hyperlight operates with a host-guest execution model.
6464
///

src/hyperlight_guest/src/entrypoint.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, max_log_level: u64
123123
}
124124
RunMode::InProcessLinux | RunMode::InProcessWindows => {
125125
OUTB_HANDLER = {
126-
let outb_handler: extern "C" fn(u16, u8) =
126+
let outb_handler: extern "sysv64" fn(u16, u8) =
127127
core::mem::transmute((*PEB).get_outb_ptr());
128128
Some(outb_handler)
129129
};
@@ -133,7 +133,7 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, max_log_level: u64
133133
}
134134

135135
OUTB_HANDLER_CTX = {
136-
let outb_handler_ctx: extern "C" fn(*mut core::ffi::c_void, u16, u8) =
136+
let outb_handler_ctx: extern "sysv64" fn(*mut core::ffi::c_void, u16, u8) =
137137
core::mem::transmute((*PEB).get_outb_ptr());
138138
Some(outb_handler_ctx)
139139
};

src/hyperlight_host/src/sandbox/leaked_outb.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ use crate::mem::shared_mem::GuestSharedMemory;
2929
///
3030
/// NOTE: This is not part of the C Hyperlight API , it is intended only to be
3131
/// called in proc through a pointer passed to the guest.
32-
extern "C" fn call_outb(ptr: *mut Arc<Mutex<dyn OutBHandlerCaller>>, port: u16, data: u64) {
33-
let outb_handlercaller = unsafe { Box::from_raw(ptr) };
32+
extern "sysv64" fn call_outb(ptr: *mut core::ffi::c_void, port: u16, data: u64) {
33+
// Convert from *mut core::ffi::c_void to *mut Arc<Mutex<dyn OutBHandlerCaller>>
34+
let outb_handlercaller =
35+
unsafe { Box::from_raw(ptr as *mut Arc<Mutex<dyn OutBHandlerCaller>>) };
36+
3437
let res = outb_handlercaller
3538
.try_lock()
3639
.map_err(|_| crate::new_error!("Error locking"))

src/hyperlight_host/src/sandbox/sandbox_builder.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ mod tests {
888888
use hyperlight_testing::simple_guest_as_string;
889889

890890
use super::*;
891-
use crate::func::{HostFunction0, HostFunction2};
891+
use crate::func::HostFunction2;
892892
use crate::sandbox_state::sandbox::EvolvableSandbox;
893893
use crate::sandbox_state::transition::Noop;
894894
use crate::HyperlightError;
@@ -954,6 +954,39 @@ mod tests {
954954
Ok(())
955955
}
956956

957+
#[test]
958+
#[cfg(target_os = "windows")]
959+
fn test_sandbox_builder_in_process_load_library() -> Result<()> {
960+
use hyperlight_testing::simple_guest_exe_as_string;
961+
962+
// Tests building an uninitialized sandbox w/ the sandbox builder
963+
let sandbox_builder =
964+
SandboxBuilder::new(GuestBinary::FilePath(simple_guest_exe_as_string()?))?
965+
.set_sandbox_run_options(SandboxRunOptions::RunInProcess(true))?;
966+
967+
let mut uninitialized_sandbox = sandbox_builder.build()?;
968+
969+
// Tests registering a host function
970+
fn add(a: i32, b: i32) -> Result<i32> {
971+
Ok(a + b)
972+
}
973+
let host_function = Arc::new(Mutex::new(add));
974+
host_function.register(&mut uninitialized_sandbox, "HostAdd")?;
975+
976+
// Tests evolving to a multi-use sandbox
977+
let mut multi_use_sandbox = uninitialized_sandbox.evolve(Noop::default())?;
978+
979+
let result = multi_use_sandbox.call_guest_function_by_name(
980+
"Add",
981+
ReturnType::Int,
982+
Some(vec![ParameterValue::Int(1), ParameterValue::Int(41)]),
983+
)?;
984+
985+
assert_eq!(result, ReturnValue::Int(42));
986+
987+
Ok(())
988+
}
989+
957990
#[test]
958991
#[cfg(crashdump)]
959992
fn test_sandbox_builder_crashdump() -> Result<()> {
@@ -1084,6 +1117,8 @@ mod tests {
10841117
#[ignore]
10851118
#[cfg(target_os = "linux")]
10861119
fn test_sandbox_builder_violate_seccomp_filters() -> Result<()> {
1120+
use crate::func::HostFunction0;
1121+
10871122
fn make_get_pid_syscall() -> Result<u64> {
10881123
let pid = unsafe { libc::syscall(libc::SYS_getpid) };
10891124
Ok(pid as u64)

0 commit comments

Comments
 (0)