openvmm: source RAM unlink invalidates an already-opened snapshot

Open Beginner friendly
#1,144 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
65/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
linux, rust
Domain
backend

Research direction

Start in openvmm/openvmm_helpers/src/snapshot/fs.rs with opened_file_generation, which records ctime, and follow where OpenedSnapshot stores that generation and where validate_memory_generation and duplicate_memory_file_for_mapping compare it. Reproduce by opening a snapshot whose memory.bin is hard-linked, then unlinking the source's temporary file before validation. Done means the opened generation stays valid after that unlink while length and mtime checks still reject real changes; the issue's fix.patch approach is one option to evaluate.

Written by the indexing model from the issue text.

Description

A valid microVM snapshot can fail restore when source teardown occurs after the restore has opened its RAM file. Automatic publication hard-links the source's RAM backing as memory.bin; dropping the source's temporary file removes the sibling link and changes the inode's ctime without changing the snapshot bytes.

In openvmm/openvmm_helpers/src/snapshot/fs.rs, the Linux opened_file_generation records that metadata change time:

        length: metadata.len(),
        modified_seconds: metadata.mtime(),
        modified_nanoseconds: metadata.mtime_nsec(),
        changed_seconds: metadata.ctime(),
        changed_nanoseconds: metadata.ctime_nsec(),
    })
}

OpenedSnapshot saves this generation when it opens the memory handle. Later validate_memory_generation and duplicate_memory_file_for_mapping compare against it, so a source unlink makes mapping preparation reject a snapshot whose identity, length, modification time and content are unchanged.

Trigger

  1. Capture using automatic RAM backing and publish memory.bin as a hard link.
  2. Open the snapshot for restore while the source still owns its temporary backing file.
  3. Tear down the source, removing that other link.
  4. Validate or duplicate the opened RAM handle for mapping.

The final step incorrectly reports that the memory generation changed.

Fix

fix.patch removes ctime from the Linux generation comparison and retains file identity, length and modification time. Link-count changes, chmod and chown no longer invalidate the opened generation.

The alternative is a publication redesign that prevents source teardown from changing the published inode's metadata. Removing ctime fixes the normal unlink race without changing the publication mechanism.

Dominant language
Rust
Stars
758
Forks
48
Avg merge
17h 50m
Merged PRs (30d)
450

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/nvx

All issues in microsoft/nvx

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.