Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/hyperlight_host/src/hypervisor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub(crate) mod surrogate_process;
pub(crate) mod surrogate_process_manager;
/// Safe wrappers around windows types like `PSTR`
#[cfg(target_os = "windows")]
pub(crate) mod wrappers;
pub mod wrappers;

#[cfg(crashdump)]
pub(crate) mod crashdump;
Expand Down
8 changes: 4 additions & 4 deletions src/hyperlight_host/src/mem/memory_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl TryFrom<hv_arm64_memory_intercept_message> for MemoryRegionFlags {
// and crash dumps. Not part of the public API.
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
/// The type of memory region
pub(crate) enum MemoryRegionType {
pub enum MemoryRegionType {
/// The region contains the guest's code
Code,
/// The region contains the guest's init data
Expand All @@ -156,7 +156,7 @@ impl MemoryRegionType {
/// `MappedFile` regions use read-only file-backed mappings with no
/// guard pages; all other region types use the standard sandbox
/// shared memory mapping with guard pages.
pub(crate) fn surrogate_mapping(&self) -> SurrogateMapping {
pub fn surrogate_mapping(&self) -> SurrogateMapping {
match self {
MemoryRegionType::MappedFile => SurrogateMapping::ReadOnlyFile,
_ => SurrogateMapping::SandboxMemory,
Expand Down Expand Up @@ -203,7 +203,7 @@ impl MemoryRegionKind for HostGuestMemoryRegion {
/// behaviour when projected into the surrogate process via `MapViewOfFileNuma2`.
#[cfg(target_os = "windows")]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub(crate) enum SurrogateMapping {
pub enum SurrogateMapping {
/// Standard sandbox shared memory: mapped with `PAGE_READWRITE` protection
/// and guard pages (`PAGE_NOACCESS`) set on the first and last pages.
SandboxMemory,
Expand Down Expand Up @@ -293,7 +293,7 @@ pub struct MemoryRegion_<K: MemoryRegionKind> {
/// memory access flags for the given region
pub flags: MemoryRegionFlags,
/// the type of memory region
pub(crate) region_type: MemoryRegionType,
pub region_type: MemoryRegionType,
}

/// A memory region that tracks both host and guest addresses.
Expand Down
80 changes: 80 additions & 0 deletions src/hyperlight_host/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1768,3 +1768,83 @@ fn interrupt_cancel_delete_race() {
handle.join().unwrap();
}
}

/// Compile-time regression guard for public visibility of memory
/// region types.
///
/// This test MUST live in an integration test (not a unit test)
/// because integration tests are compiled as separate crates and can
/// only access items marked `pub`. A unit test inside the crate
/// would also see `pub(crate)` items, defeating the purpose.
///
/// If any of these types or fields revert to `pub(crate)`, this test
/// will fail to **compile** — catching the regression before CI even
/// runs the test binary.
#[test]
fn memory_region_types_are_publicly_accessible() {
use hyperlight_host::mem::memory_region::{
HostGuestMemoryRegion, MemoryRegion_, MemoryRegionFlags, MemoryRegionKind, MemoryRegionType,
};

// This test is a compile-time guard. If it compiles, it passes.
// Every line below would cause a compile error if the referenced
// type, variant, or field reverted to pub(crate).

// MemoryRegionType enum and all its variants are pub
let _rt = MemoryRegionType::Code;
let _rt = MemoryRegionType::InitData;
let _rt = MemoryRegionType::Peb;
let _rt = MemoryRegionType::Heap;
let _rt = MemoryRegionType::Scratch;
let _rt = MemoryRegionType::Snapshot;
let _rt = MemoryRegionType::MappedFile;

// MemoryRegionFlags is pub and combinable
let _flags = MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE;

// SurrogateMapping enum and MemoryRegionType::surrogate_mapping()
// are pub (Windows only).
#[cfg(target_os = "windows")]
{
use hyperlight_host::mem::memory_region::SurrogateMapping;

let mapping = MemoryRegionType::MappedFile.surrogate_mapping();
let _: SurrogateMapping = mapping;
let _ = SurrogateMapping::SandboxMemory;
let _ = SurrogateMapping::ReadOnlyFile;
}

// MemoryRegion_ struct and all its fields are pub (struct literal
// construction requires every field to be pub).
#[cfg(not(target_os = "windows"))]
{
let base: <HostGuestMemoryRegion as MemoryRegionKind>::HostBaseType = 0x1000;
let _region = MemoryRegion_::<HostGuestMemoryRegion> {
guest_region: 0x1000..0x2000,
host_region: base..<HostGuestMemoryRegion as MemoryRegionKind>::add(base, 0x1000),
flags: MemoryRegionFlags::READ,
region_type: MemoryRegionType::Code,
};
}

#[cfg(target_os = "windows")]
{
use hyperlight_host::hypervisor::wrappers::HandleWrapper;
use hyperlight_host::mem::memory_region::HostRegionBase;
use windows::Win32::Foundation::HANDLE;

let host_base = HostRegionBase {
from_handle: HandleWrapper::from(HANDLE(std::ptr::null_mut())),
handle_base: 0x1000,
handle_size: 0x1000,
offset: 0,
};
let _region = MemoryRegion_::<HostGuestMemoryRegion> {
guest_region: 0x1000..0x2000,
host_region: host_base
..<HostGuestMemoryRegion as MemoryRegionKind>::add(host_base, 0x1000),
flags: MemoryRegionFlags::READ,
region_type: MemoryRegionType::Code,
};
}
}
Loading