diff --git a/Cargo.lock b/Cargo.lock index 7b95df4d7..9245b9594 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -196,26 +196,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.9.4", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -372,15 +352,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-expr" version = "0.20.2" @@ -443,17 +414,6 @@ dependencies = [ "half", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.46" @@ -1463,7 +1423,6 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "page_size", - "proc-maps", "proptest", "rand", "rust-embed", @@ -1828,27 +1787,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.3", -] - -[[package]] -name = "libproc" -version = "0.14.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78a09b56be5adbcad5aa1197371688dc6bb249a26da3bca2011ee2fb987ebfb" -dependencies = [ - "bindgen", - "errno", - "libc", -] - [[package]] name = "libredox" version = "0.1.9" @@ -1912,15 +1850,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "mach2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" -dependencies = [ - "libc", -] - [[package]] name = "macho-unwind-info" version = "0.5.0" @@ -2012,12 +1941,6 @@ dependencies = [ "sketches-ddsketch", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2107,16 +2030,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "nu-ansi-term" version = "0.50.1" @@ -2629,20 +2542,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "proc-maps" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db44c5aa60e193a25fcd93bb9ed27423827e8f118897866f946e2cf936c44fb" -dependencies = [ - "anyhow", - "bindgen", - "libc", - "libproc", - "mach2", - "winapi", -] - [[package]] name = "proptest" version = "1.7.0" @@ -2933,12 +2832,6 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc_version" version = "0.4.1" diff --git a/Justfile b/Justfile index 6e8218958..d91acad36 100644 --- a/Justfile +++ b/Justfile @@ -151,7 +151,6 @@ test-isolated target=default-target features="": cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_log_trace --exact --ignored cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::initialized_multi_use::tests::create_1000_sandboxes --exact --ignored cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::outb::tests::test_log_outb_log --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- mem::shared_mem::tests::test_drop --exact --ignored cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --test integration_test -- log_message --exact --ignored @# metrics tests cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F function_call_metrics,init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- metrics::tests::test_metrics_are_emitted --exact diff --git a/src/hyperlight_host/Cargo.toml b/src/hyperlight_host/Cargo.toml index ea934c696..28770ec88 100644 --- a/src/hyperlight_host/Cargo.toml +++ b/src/hyperlight_host/Cargo.toml @@ -114,9 +114,6 @@ windows = { version = "0.62", features = [ "Win32_System_Diagnostics_ToolHelp", ] } -[target.'cfg(unix)'.dev-dependencies] -proc-maps = "0.4.0" - [build-dependencies] anyhow = { version = "1.0.99" } cfg_aliases = "0.2.1" diff --git a/src/hyperlight_host/src/mem/shared_mem.rs b/src/hyperlight_host/src/mem/shared_mem.rs index 84cbb4c8e..c3b654ec3 100644 --- a/src/hyperlight_host/src/mem/shared_mem.rs +++ b/src/hyperlight_host/src/mem/shared_mem.rs @@ -1127,51 +1127,112 @@ mod tests { assert_eq!(data, ret_vec); } - /// A test to ensure that, if a `SharedMem` instance is cloned - /// and _all_ clones are dropped, the memory region will no longer - /// be valid. - /// - /// This test is ignored because it is incompatible with other tests as - /// they may be allocating memory at the same time. - /// - /// Marking this test as ignored means that running `cargo test` will not - /// run it. This feature will allow a developer who runs that command - /// from their workstation to be successful without needing to know about - /// test interdependencies. This test will, however, be run explicitly as a - /// part of the CI pipeline. + /// Makes sure drop actually frees the underlying memory #[test] - #[ignore] - #[cfg(target_os = "linux")] fn test_drop() { - use proc_maps::maps_contain_addr; - - let pid = std::process::id(); - - let eshm = ExclusiveSharedMemory::new(PAGE_SIZE_USIZE).unwrap(); + let eshm = ExclusiveSharedMemory::new(128 * 1024 * 1024).unwrap(); // large number to prevent race condition from other tests let (hshm1, gshm) = eshm.build(); let hshm2 = hshm1.clone(); - let addr = hshm1.raw_ptr() as usize; - - // ensure the address is in the process's virtual memory - let maps_before_drop = proc_maps::get_process_maps(pid.try_into().unwrap()).unwrap(); - assert!( - maps_contain_addr(addr, &maps_before_drop), - "shared memory address {:#x} was not found in process map, but should be", - addr, - ); - // drop both shared memory instances, which should result + let addr = hshm1.raw_ptr(); + let _size = hshm1.raw_mem_size(); + + // Verify memory is initially accessible + #[cfg(target_os = "linux")] + { + let result = + unsafe { libc::madvise(addr as *mut libc::c_void, _size, libc::MADV_NORMAL) }; + assert_eq!( + result, + 0, + "Memory should be accessible before drop - madvise failed with errno: {}", + std::io::Error::last_os_error().raw_os_error().unwrap() + ); + } + + #[cfg(target_os = "windows")] + { + use core::ffi::c_void; + + use windows::Win32::System::Memory::{ + MEM_FREE, MEMORY_BASIC_INFORMATION, VirtualQuery, + }; + + let mut mbi = MEMORY_BASIC_INFORMATION::default(); + let result = unsafe { + VirtualQuery( + Some(addr as *const c_void), + &mut mbi, + std::mem::size_of::(), + ) + }; + assert_ne!( + result, 0, + "VirtualQuery should succeed on mapped memory at address {:#x}", + addr as usize + ); + assert_ne!( + mbi.State, MEM_FREE, + "Memory should not be in MEM_FREE state before drop at address {:#x}", + addr as usize + ); + } + + // Drop both shared memory instances, which should result // in freeing the memory region drop(hshm1); drop(hshm2); drop(gshm); - let maps_after_drop = proc_maps::get_process_maps(pid.try_into().unwrap()).unwrap(); - // now, ensure the address is not in the process's virtual memory - assert!( - !maps_contain_addr(addr, &maps_after_drop), - "shared memory address {:#x} was found in the process map, but shouldn't be", - addr - ); + // Verify memory is no longer accessible + #[cfg(target_os = "linux")] + { + // Try madvise on the unmapped memory - should fail with ENOMEM + let result = + unsafe { libc::madvise(addr as *mut libc::c_void, _size, libc::MADV_NORMAL) }; + assert_eq!( + result, -1, + "madvise should return -1 on unmapped memory at address {:#x}", + addr as usize + ); + + let errno = std::io::Error::last_os_error().raw_os_error().unwrap_or(-1); + assert_eq!( + errno, + libc::ENOMEM, + "Expected ENOMEM for unmapped memory, but got errno: {} at address {:#x}", + errno, + addr as usize + ); + } + + #[cfg(target_os = "windows")] + { + use core::ffi::c_void; + + use windows::Win32::System::Memory::{ + MEM_FREE, MEMORY_BASIC_INFORMATION, VirtualQuery, + }; + + // Try VirtualQuery on the unmapped memory - should show MEM_FREE state + let mut mbi_after = MEMORY_BASIC_INFORMATION::default(); + let result = unsafe { + VirtualQuery( + Some(addr as *const c_void), + &mut mbi_after, + std::mem::size_of::(), + ) + }; + assert_ne!( + result, 0, + "VirtualQuery should succeed even on unmapped memory at address {:#x}", + addr as usize + ); + assert_eq!( + mbi_after.State, MEM_FREE, + "Memory should be in MEM_FREE state after drop at address {:#x}", + addr as usize + ); + } } #[cfg(target_os = "linux")]