Skip to content

Reject incomplete time-adjusted snapshot restores - #83

Merged
ppenna merged 1 commit into
mainfrom
fix/require-partition-for-time-adjusted-restore
Sep 20, 2026
Merged

ppenna merged 1 commit into
mainfrom
fix/require-partition-for-time-adjusted-restore

Conversation

@tangruize

Copy link
Copy Markdown

Summary

Reject x86 snapshot restores that request restore-time adjustment without carrying the partition saved-state payload.

Problem

SavedState contains both an inventory of registered state units and a list of serialized unit payloads. A unit can appear in the inventory while its payload is absent.

The restore path permits absent unit payloads: StateUnits::restore skips a unit when no matching serialized state is present. However, when restore_time is set, OpenVMM subsequently advances restored VM time and calls PartitionUnit::advance_tsc for the instantiated virtual processors regardless of whether the snapshot restored the partition and VP state.

As a result, an x86 snapshot with restore-time adjustment but no "partition" payload could report a successful restore while applying the time adjustment to the destination VM's pre-existing VP state. The same snapshot and restore policy could therefore produce different guest TSC values depending on the destination state.

How Verus exposed the bug

The Verus work modeled successful snapshot restoration as a relation between the saved snapshot, the restore-time policy, and the resulting VM state.

For a VP present in the partition payload, the expected restored TSC can be represented as the saved TSC plus the checked downtime adjustment. For a missing saved VP entry, the existing projection preserves the destination VP value because there is no snapshot value from which to derive a restored value.

This revealed an unrepresentable production path: if the entire partition payload is omitted, production restore skips partition restoration but still adjusts every instantiated VP's TSC. The restore request contains no destination pre-restore TSC values, so no faithful request-derived representation can predict the resulting TSC. A concrete reproduction confirmed that identical snapshot inputs can produce different final counters when starting from different destination values.

This was not a Verus verifier failure. The proof attempt exposed a missing runtime validity check in the production restore path.

Fix

Before performing frequency checks, restoring state units, advancing time, or acquiring the restore stop guard, validate that an x86 restore with restore_time includes a serialized state unit named exactly "partition".

If it does not, return:

time-adjusted snapshot restore requires partition state

The check intentionally uses SavedState.units, not SavedState.inventory: inventory membership records that a unit exists in the VM configuration, but does not prove that the snapshot carries its serialized state.

Restores without time adjustment retain the existing sparse-state behavior. Non-x86 builds are unchanged.

Tests

  • Missing partition payload is accepted when no restore-time adjustment is requested.
  • A time-adjusted restore is accepted when the partition payload is present.
  • A time-adjusted restore is rejected when the partition payload is absent.
  • Partition inventory membership alone does not satisfy the payload requirement.

Run with:

cargo +1.95.0 test -p openvmm_core snapshot_restore_tests
cargo +1.95.0 clippy -p openvmm_core --tests -- -D warnings

Copilot AI balanced review requested due to automatic review settings September 20, 2026 06:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The validation correctly addresses the inconsistent restore path and is adequately tested.

Review effort: Balanced
Findings: None

What changed in this PR

Rejects incomplete x86 snapshot restores before applying restore-time TSC adjustments.

Changes:

  • Requires a serialized "partition" payload for time-adjusted restores.
  • Adds coverage for payload presence, absence, and inventory-only cases.
File Description
openvmm/​openvmm_core/​src/​worker/​dispatch.rs Adds validation and focused snapshot-restore tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ppenna ppenna self-assigned this Sep 20, 2026
Time-adjusted x86_64 restores advance partition-owned clock state,
including the restored vCPU TSC. A snapshot without a serialized
partition unit cannot safely participate in that adjustment.

Validate the saved-state payload before applying frequency checks or
restoring VM state. Reject time-adjusted restores when the partition
unit payload is missing, while preserving support for snapshots without
partition state when no time adjustment is requested.

Check the serialized units rather than inventory metadata, and add tests
covering valid restores, missing partition state, unadjusted restores,
and inventory-only partition entries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 92b84e0a-86e8-404d-8265-7a76d8d4ac16
@ppenna
ppenna force-pushed the fix/require-partition-for-time-adjusted-restore branch from ee40bf3 to 89caf8c Compare September 20, 2026 17:07
@ppenna
ppenna merged commit 89caf8c into main Sep 20, 2026
73 checks passed
@ppenna
ppenna deleted the fix/require-partition-for-time-adjusted-restore branch September 20, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants