Skip to content

Commit 9701f95

Browse files
committed
Begin to enable virtual memory in wasmtime
There is a big caveat here, which is that wasmtime's mprotect calls are ignored, so this sandbox is very unsound: a wasm module can take over the entire guest easily Signed-off-by: Lucy Menon <[email protected]>
1 parent ceb7c25 commit 9701f95

File tree

4 files changed

+52
-21
lines changed

4 files changed

+52
-21
lines changed

src/hyperlight_wasm_aot/src/main.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,5 @@ fn main() {
150150
fn get_config() -> Config {
151151
let mut config = Config::new();
152152
config.target("x86_64-unknown-none").unwrap();
153-
config.memory_reservation(0);
154-
config.memory_reservation_for_growth(0);
155-
config.memory_guard_size(0);
156-
config.guard_before_linear_memory(false);
157153
config
158154
}

src/wasm_runtime/src/component.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,9 @@ fn load_wasm_module_phys(function_call: &FunctionCall) -> Result<Vec<u8>> {
107107

108108
#[no_mangle]
109109
pub extern "C" fn hyperlight_main() {
110+
crate::platform::register_page_fault_handler();
111+
110112
let mut config = Config::new();
111-
config.memory_reservation(0);
112-
config.memory_guard_size(0);
113-
config.memory_reservation_for_growth(0);
114-
config.guard_before_linear_memory(false);
115113
config.with_custom_code_memory(Some(alloc::sync::Arc::new(
116114
crate::platform::WasmtimeCodeMemory {}
117115
)));

src/wasm_runtime/src/module.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ pub fn guest_dispatch_function(function_call: &FunctionCall) -> Result<Vec<u8>>
9090

9191
fn init_wasm_runtime() -> Result<Vec<u8>> {
9292
let mut config = Config::new();
93-
config.memory_reservation(0);
94-
config.memory_guard_size(0);
95-
config.memory_reservation_for_growth(0);
96-
config.guard_before_linear_memory(false);
9793
config.with_custom_code_memory(Some(alloc::sync::Arc::new(
9894
crate::platform::WasmtimeCodeMemory {},
9995
)));
@@ -171,6 +167,8 @@ fn load_wasm_module_phys(function_call: &FunctionCall) -> Result<Vec<u8>> {
171167
#[no_mangle]
172168
#[allow(clippy::fn_to_numeric_cast)] // GuestFunctionDefinition expects a function pointer as i64
173169
pub extern "C" fn hyperlight_main() {
170+
crate::platform::register_page_fault_handler();
171+
174172
register_function(GuestFunctionDefinition::new(
175173
"PrintOutput".to_string(),
176174
vec![ParameterType::String],

src/wasm_runtime/src/platform.rs

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,48 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
use alloc::alloc::{alloc, dealloc, Layout};
1817
use core::ffi::c_void;
1918
use core::sync::atomic::{AtomicPtr, AtomicU64, Ordering};
2019

2120
use hyperlight_guest_bin::exceptions::handler;
21+
use hyperlight_guest_bin::paging;
22+
23+
// Extremely stupid virtual address allocator
24+
// 0x1_0000_0000 is where the module is
25+
// we start at
26+
// 0x100_0000_0000 and go up from there
27+
static FIRST_VADDR: AtomicU64 = AtomicU64::new(0x100_0000_0000u64);
28+
fn page_fault_handler(
29+
_exception_number: u64,
30+
info: *mut handler::ExceptionInfo,
31+
_ctx: *mut handler::Context,
32+
page_fault_address: u64,
33+
) -> bool {
34+
let error_code = unsafe { (&raw const (*info).error_code).read_volatile() };
35+
// TODO: check if this is a guard-region trap (which can't happen
36+
// right now since we don't actually set the permissions properly
37+
// in mprotect)
38+
39+
// TODO: replace this with some generic virtual memory area data
40+
// structure in hyperlight core
41+
if (error_code & 0x1) == 0x0 && page_fault_address >= 0x100_0000_0000u64 {
42+
unsafe {
43+
let phys_page = paging::alloc_phys_pages(1);
44+
let virt_base = (page_fault_address & !0xFFF) as *mut u8;
45+
paging::map_region(
46+
phys_page,
47+
virt_base,
48+
hyperlight_guest_bin::OS_PAGE_SIZE as u64,
49+
);
50+
virt_base.write_bytes(0u8, hyperlight_guest_bin::OS_PAGE_SIZE as usize);
51+
}
52+
return true; // Try again!
53+
}
54+
false
55+
}
56+
pub(crate) fn register_page_fault_handler() {
57+
handler::handlers[14].store(page_fault_handler as usize as u64, Ordering::Release);
58+
}
2259

2360
// Wasmtime Embedding Interface
2461

@@ -27,24 +64,26 @@ use hyperlight_guest_bin::exceptions::handler;
2764
* appropriate interrupt handler yet. Consequently, we configure
2865
* wasmtime not to use any guard region, and precommit memory. */
2966
#[no_mangle]
30-
pub extern "C" fn wasmtime_mmap_new(size: usize, _prot_flags: u32, ret: &mut *mut u8) -> i32 {
31-
*ret = unsafe { alloc(Layout::from_size_align(size, 0x1000).unwrap()) };
67+
pub extern "C" fn wasmtime_mmap_new(_size: usize, _prot_flags: u32, ret: &mut *mut u8) -> i32 {
68+
*ret = FIRST_VADDR.fetch_add(0x100_0000_0000, Ordering::Relaxed) as *mut u8;
3269
0
3370
}
3471

3572
/* Because of the precommitted memory strategy, we can't generally
3673
* support remap */
3774
#[no_mangle]
3875
pub extern "C" fn wasmtime_mmap_remap(addr: *mut u8, size: usize, prot_flags: u32) -> i32 {
39-
panic!(
40-
"wasmtime_mmap_remap {:x} {:x} {:x}",
41-
addr as usize, size, prot_flags
42-
);
76+
if size > 0x100_0000_0000 {
77+
panic!(
78+
"wasmtime_mmap_remap {:x} {:x} {:x}",
79+
addr as usize, size, prot_flags
80+
);
81+
}
82+
0
4383
}
4484

4585
#[no_mangle]
46-
pub extern "C" fn wasmtime_munmap(ptr: *mut u8, size: usize) -> i32 {
47-
unsafe { dealloc(ptr, Layout::from_size_align(size, 0x1000).unwrap()) };
86+
pub extern "C" fn wasmtime_munmap(_ptr: *mut u8, _size: usize) -> i32 {
4887
0
4988
}
5089

0 commit comments

Comments
 (0)