Skip to content

Allow host mappings to have destructors #700

Open

Description

@syntactically

We should provide some support for ensuring that when host mapping objects are no longer needed, they have a chance to run a destructor. This is particularly important as, currently, map_file_cow has no way to ensure that its mappings are cleaned up, so it leaks a bit of virtual memory whenever it is run.

Activity

  1. added theissue type on Jul 8, 2025
  2. added this to the v0.8.0 milestone on Jul 16, 2025
  3. modified the milestones: v0.8.0, v0.9.0 on Jul 30, 2025
  4. modified the milestones: v0.9.0, v0.10.0 on Aug 13, 2025
  5. ludfjig commented on Aug 27, 2025

    @ludfjig
    Contributor

    Since map_file_cow currently only calls map_region, could we remove map_file_cow, and have the caller just use map_region and keep track of the handle themselves?

  6. modified the milestones: v0.10.0, v0.11.0 on Oct 1, 2025
  7. modified the milestones: v0.11.0, v0.12.0 on Oct 22, 2025
  8. modified the milestones: v0.12.0, v0.13.0 on Nov 5, 2025
  9. modified the milestones: v0.13.0, Backlog on Feb 18, 2026
  10. modified the milestones: Backlog, v0.14.0 on Mar 11, 2026
  11. jsturtevant commented on Mar 11, 2026

    @jsturtevant
    Contributor

    from #1290:

    Root Cause
    The raw *mut c_void pointer returned by libc::mmap is cast to usize and stored in MemoryRegion.host_region — a plain integer with no ownership or Drop semantics. Nothing in the cleanup chain calls munmap:
    
    HyperlightVm::unmap_region — removes the KVM/MSHV slot only, does not munmap
    HyperlightVm::Drop — only calls interrupt_handle.set_dropped()
    MultiUseSandbox — has no Drop impl
    Snapshot restore() — calls unmap_region for stale regions (same problem)
    The error path in map_file_cow correctly calls munmap, confirming the success path omission is an oversight.
    
    Proposed Fix
    Introduce a Linux OwnedFileMapping struct that stores the mmap pointer and size with a Drop impl calling libc::munmap. Track these in a Vec on MultiUseSandbox and clean up in restore() (when regions are unmapped during snapshot restore) and on MultiUseSandbox::Drop (catch-all for remaining mappings).
    
  12. syntactically commented on Aug 5, 2026

    @syntactically
    MemberAuthor

    The correct solution here is probably that map_region instead of taking a MemoryRegion directly takes some where for<'a> &'a T: Into<MemoryRegion> + Clone object that it holds onto and drops at the appropriate times. When map_file_cow calls map_region, it uses some (arch-specific) FileMapping structure that implements that properly. That would also let you write code that shared one mapping between multiple sandboxes and use it on both Linux and Windows without disaster striking from the strange lifecycle management of the region on Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions