Skip to content

host: add a peer-verified restore-ready listener - #1297

Merged
Pedro Henrique Penna (ppenna) merged 5 commits into
feature/nvx-refactorfrom
esaurez/slim-2.2.1-sl2.17-20261105
Nov 7, 2026
Merged

Pedro Henrique Penna (ppenna) merged 5 commits into
feature/nvx-refactorfrom
esaurez/slim-2.2.1-sl2.17-20261105

Conversation

@esaurez

@esaurez Enrique Saurez (esaurez) commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1099

Stacked on #1280.

Adds an exact byte decoder for OPENVMM_RESTORE_READY_V1\n and a reusable
restore-ready listener. Linux and Windows endpoints are owner-only; receives
verify the peer against the held VM process and check its liveness before and
after I/O. into_std transfers the existing native listener without reopening
it. Construction and blocking receive remain crate-private; no restore
sequencing or async framework is added.

The new Linux receiver authenticates the original socket peer with
SO_PEERPIDFD, not a pidfd reopened from cached numeric credentials. An exited
client's queued event cannot impersonate a later VM with a recycled PID.
Missing or denied kernel support fails closed as Unavailable; this requirement
is specific to the new receiver, not a general Linux minimum. The existing clone
receive path is unchanged.

The four logical implementation and follow-up commits are retained on the
updated parent. The original-peer authentication, older-kernel error mapping,
held-process exit precedence, and strict PID-reuse regression are preserved.

The full counted scope is 236 core lines in seven files: six production Rust
files and the required existing test-layout policy JSON. The original
six-production-file allowance has been extended only for that required metadata
path, with the 600-line ceiling unchanged. Its two changed lines are counted,
not exempted; no seventh production Rust file is authorized.

Existing tests and wiring

  • nvx-rs/src/host/vm.rs: remove the fulfilled dead-code test hook from
    restore_ready_endpoint now that the listener uses it, and tighten its
    allowlist count.
  • nvx-rs/src/host/sys/process/tests.rs: extract the existing test-only seccomp
    installer so the unchanged umask refusal test and the new selective peer-pidfd
    denial test can share it. The umask filter and its assertions are preserved;
    no production unsafe code or dependency is added.
  • scripts/test-layout-allowlist.json: allow the new restore module's three
    necessary future-call hooks for its crate-private bind, endpoint, and receive
    methods. Tests stay in their own module files; no assertions are relaxed.
  • scripts/test_adversarial.py: carry SL2.4a1: the root's kernel tokens carry what VmConfig sets, and the guest caps a RAM upper #1278's published test-fixture correction.
    Wait at most five seconds for real fixture readiness and an atomically
    published live child PID before starting the unchanged 0.5-second workload
    deadline. Accept the API's existing raw TimeoutError or wrapped
    RuntimeError with the exact timeout message, preserve descendant-exit
    assertions, and wait for the Windows fixture child to exit after teardown.
    Production code, workload deadlines, and skip guards are unchanged.

New tests cover exact/malformed bytes, real correct/rogue/exited child processes,
immutable expected identity, owner-only permissions, and native transfer after
an empty receive. Linux also exercises actual PID recycling after the original
queued peer exits and is reaped, plus missing/denied/stale peer-pidfd errors.
That regression verifies private PID and mount namespaces with a Bash reaper;
if unprivileged user namespaces are refused, only its isolated helper uses
passwordless sudo. Failure of both setup routes is a real test failure, never
a skip or a passing early return.

Local validation

The updated #1280 parent and inherited OpenVMM revision have actual passing
Rust, CLI, API, and quality results, including 1,814 Python tests on each OS,
the adversarial and host-resolver suites, and newly assembled native guests
from the candidate's validated Rust binaries. WHP and MSHV each passed all five
public sandbox/snapshot scenarios and all 156 canonical adapter scenarios
across 11 targets, including setup and teardown, with the consumed artifact
hashes unchanged. Independent read-only review of the exact rebased source is
clear. These results remain evidence for their recorded inputs.

The canonical-CLI correction is now complete on the unchanged candidate.
Windows used the workflow's cli feature and static CRT; Linux used cli and
the static-musl target. Each platform passed the complete twelve-command action
under its whole-command compiler budget, including 1,814 Python tests
(67 Windows and 30 Linux recorded skips), all required real-CLI,
canceled-capture and native PowerShell cases, 84 adversarial tests, four resolver
tests and eight help probes. Linux PowerShell used normal globalization with
verified ICU, not invariant mode.

Both WHP and MSHV then passed all five public scenarios, setup and teardown,
and all 156 canonical adapter scenarios across 11 targets against the new CLI
artifacts. There were no failed or ignored adapter scenarios; all 34 consumed
input hashes remained unchanged, including the 14 retained non-CLI inputs.
Original CLI paths and earlier results remain attributed to their original
inputs; explicit canonical outputs were used for this qualification, not a
claim that default-path packaging changed.

The first Linux evidence-auditor attempt failed after misreading a passing
test's two-line description; its raw failure is retained, and the complete
action passed after correcting only that auditor. The Windows compiler gateway
also recorded cleanup of its owned MSVC telemetry process after successful
commands; this is not represented as a zero-warning run. Optional unprepared
kernel-source and unelevated Windows ownership prerequisites remain recorded
skips, not passes. Native listener/PID-reuse controls and the exact-source
independent review remain valid at their recorded inputs. These are local
results, not a CI, KVM, macOS-runtime, performance or enclosing-group pass.

@esaurez Enrique Saurez (esaurez) added the tests-modified Changes existing tests, test data, or test wiring label Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

This pull request changes existing tests

It modifies or removes 5 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests.

Test code

Change What Before After
modified helper fn refuse_umask_on_spawn in host::sys::process::tests nvx-rs/src/host/sys/process/tests.rs:7 nvx-rs/src/host/sys/process/tests.rs:14
modified test def AdversarialOracleTests.test_contained_guest_runner_timeout_kills_descendants in scripts/test_adversarial.py scripts/test_adversarial.py:853 scripts/test_adversarial.py:857
modified test def ExecutorCloseTests.test_close_is_bounded_when_a_surviving_child_holds_executor_stdout in scripts/test_adversarial.py scripts/test_adversarial.py:3162 scripts/test_adversarial.py:3215
removed hook the test hooks of fn restore_ready_endpoint in host::vm (impl VmDir) nvx-rs/src/host/vm.rs:121

Test policy

Change What Before After
loosened allowlist entry nvx-rs/src/host/restore.rs (the seams allow 3 test hooks) scripts/test-layout-allowlist.json

Relocated unchanged: 0; added: 31. Compared the merge base 1790d3f4caca with f7c97633f6b7.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

A critical Linux authentication flaw allows an exited client's queued event to be accepted if its PID is recycled for the VM, requiring stable peer identification and a stale-peer regression test.

1 open issue
What changed in this PR

Adds a reusable restore-ready listener and exact event parser as part of the caller-owned VM lifecycle work in #1099. Construction and blocking receive remain internal; native listener transfer supports caller-managed I/O.

Changes:

  • Add exact decoding of OPENVMM_RESTORE_READY_V1\n.
  • Add owner-only endpoints, process checks, and native listener ownership transfer.
  • Add protocol and listener tests, documentation, and public API entries.
File Description
scripts/​test-layout-allowlist.json Update temporary test-hook allowances.
nvx-rs/​src/​protocol/​restore_ready/​tests.rs Test exact event bytes and malformed inputs.
nvx-rs/​src/​protocol/​restore_ready.rs Add the restore-ready event parser.
nvx-rs/​src/​protocol/​mod.rs Export the parser module.
nvx-rs/​src/​host/​vm.rs Remove the fulfilled endpoint dead-code allowance.
nvx-rs/​src/​host/​restore/​tests.rs Test process checks, endpoint privacy, and native transfer.
nvx-rs/​src/​host/​restore.rs Add the process-checked listener wrapper.
nvx-rs/​src/​host/​platform/​windows/​endpoint.rs Extract reusable pipe binding and add handle transfer.
nvx-rs/​src/​host/​platform/​linux/​endpoint.rs Add native Unix listener transfer.
nvx-rs/​src/​host/​mod.rs Export and document the restore module.
nvx-rs/​README.md Document parser and listener contracts.
nvx-rs/​public-api/​windows.txt Record the new Windows public API entries.
nvx-rs/​public-api/​linux.txt Record the new Linux public API entries.

Review effort: Balanced

Comment thread nvx-rs/src/host/restore.rs Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are recorded for the restore-ready parsing and peer-verified listener changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-critical peer authentication depends on Linux and Windows semantics, and native PID-reuse, exited-peer, and ownership-transfer regression results still need confirmation beyond this source-only review.

No open issues 🎉

Review effort: Balanced

@esaurez

Copy link
Copy Markdown
Contributor Author

The native results requested by the current review were rerun on
0c5de2d57798f56b8b432e8fedfd5eb8515ef4a9, based on
b93206ab3804792116ac4aae0451aa0f70892e8d:

Native listener tests Passed Failed Ignored
Windows 6 0 0
Linux 8 0 0

Both platforms actually passed the real correct-process and rogue-process
controls, rejection of an exited held process despite an already queued event,
immutable expected identity, owner-only endpoint checks, and
a_native_listener_transfer_keeps_the_endpoint_usable_after_an_empty_receive.
These same tests also passed in the complete source-test commands.

On Linux, a_queued_peer_cannot_be_the_vm_that_reuses_its_pid actually queued
the old client's event, exited and reaped that client, recycled its PID to the
live held process, and rejected the stale peer. The isolated child and outer
test each passed, and the child emitted NVX-READY-PID-REUSE-VERIFIED only after
the critical assertions. Both the unprivileged namespace route and the scoped
private-helper fallback were exercised. Deliberately denying both setup routes
instead produced exit 101 with a failed test and no verification marker, not a
skip or a false pass. The original-peer capability/error-mapping test passed
too; that is not a claim to have tested every Linux kernel version.

Separately, fresh WHP and MSHV runs each passed the five public scenarios and
all 156 canonical adapter scenarios across 11 targets, with setup/teardown
passing and all 16 consumed input hashes unchanged. These are current-input
local results, not transferred old-head results or a claim that CI ran.

@esaurez
Enrique Saurez (esaurez) marked this pull request as ready for review November 6, 2026 14:49
Base automatically changed from esaurez/slim-2.2.1-sl2.7-20261104 to feature/nvx-refactor November 6, 2026 20:37
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/slim-2.2.1-sl2.17-20261105 branch from 0c5de2d to 691a7e7 Compare November 6, 2026 22:58
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot November 6, 2026 22:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

This security-sensitive authentication boundary spans Linux pidfd/kernel behavior and Windows pipe lifetimes, requiring maintainer confirmation of platform guarantees and exact-revision native regression results.

No open issues 🎉

Review effort: Balanced

@esaurez

Copy link
Copy Markdown
Contributor Author

Current native regression evidence for exact head
691a7e7fc33619a5d3464e58ecd39b314cbd521a:

Native listener tests Passed Failed Ignored
Windows 6 0 0
Linux 8 0 0

These executed in the complete current local Rust commands, with explicit serial
test dispatch. Both platforms exercised real held/rogue/exited processes,
immutable expected identity, owner-only endpoints, and usable native ownership
transfer after an empty receive. Linux also passed actual queued-peer PID
recycling and the missing/denied/stale original-peer-pidfd cases. The PID-reuse
test requires both private namespace identities and its post-assertion
verification marker; failure to establish isolation is not a passing skip.

The rebase retained all four commits with equal patches, without conflicts or an
implementation rewrite. All eight authentication/parser/native-regression source
files are byte-identical to the previous head. Current Windows/Linux local
Rust, API and quality checks passed, as did each complete CLI action with 1,817
Python tests, the adversarial and resolver suites, and the required real-CLI,
canceled-capture and native PowerShell cases.

This is exact-head native process/socket/pipe regression evidence, not a claim
that every kernel or Windows version was exercised. The earlier WHP/MSHV
matrices remain evidence only for their recorded inputs; they were not relabeled
as new-head runtime passes. CI was not queried, and maintainer confirmation of
the platform guarantees remains maintainer review, not a formal approval from
this COMMENTED review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive peer authentication and listener transfer require native Linux PID-reuse and Windows overlapped-I/O validation tied to the exact reviewed source, which this source-only review cannot provide.

No open issues 🎉

Review effort: Balanced

@esaurez

Copy link
Copy Markdown
Contributor Author

Current native regression evidence for exact reviewed head
4a2685826ca6183ee955ec29b4c2b68b9207fecc:

Native listener tests Passed Failed Ignored
Windows 6 0 0
Linux 8 0 0

These ran in the complete current local Rust commands, with explicit serial
test dispatch, not a claim of default-parallel execution.

Linux's a_queued_peer_cannot_be_the_vm_that_reuses_its_pid queues the event,
exits and reaps the original client, recycles its PID in verified private PID
and mount namespaces, and rejects that old socket peer against the new held
process. Its post-assertion verification marker is required; failed isolation
is not a passing skip. Missing, denied, and stale original-peer-pidfd controls
also passed.

Windows's native-transfer regression first performs an empty timed receive,
then transfers the same overlapped pipe handle. Its native reader completes
ConnectNamedPipe with GetOverlappedResult, checks the client's PID and the
held process's liveness, and reads the exact event using
ReadFile/GetOverlappedResult. The fresh first-instance protected owner-only
pipe, real correct/rogue/exited processes, and immutable expected identity were
also exercised.

The rebase retained all four commits and resolved only README adjacency,
keeping both module descriptions. Two patches are equal; two differ only in
README hunk context. All eight authentication/parser/native-regression source
files are byte-identical to the previous head. Current Windows and Linux local
Rust checks passed, along with Linux's dual-platform API snapshots,
guest-binary, and quality checks. Both complete CLI actions passed with 1,817
Python cases, their recorded platform skips, and the adversarial, resolver,
real-CLI, capture, and native PowerShell cases.

This is exact-head native process/socket/pipe evidence, not coverage of every
kernel, Windows release, or external driver's cancellation strategy. Earlier
hypervisor matrices remain attributed to their original inputs, not new-head
runtime passes. CI was not queried. Maintainer confirmation of the platform
guarantees remains maintainer review; the COMMENTED advisory is not formal
approval.

Enrique Saurez and others added 2 commits November 6, 2026 19:42
Parse only the complete OpenVMM readiness event. Reuse the clone endpoint mechanics for private restore listeners, verify the held process during receives, and transfer native listeners without reopening them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e19737a6-412b-4652-b67e-b37837521925
Require a held-process liveness check after native peer PID matching. Keep temporary unused-code expectations active in unsupported-platform test builds, where the listener tests do not compile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e19737a6-412b-4652-b67e-b37837521925
Enrique Saurez and others added 3 commits November 6, 2026 19:42
Authenticate Linux restore-ready connections through SO_PEERPIDFD rather than a recycled peer credential PID. Fail closed when that capability is unavailable, and preserve the existing clone receiver. Document native callers' original-peer checks.

Cover a queued client that exits before the VM starts and whose PID the VM reuses in a private PID namespace. Check unavailable and denied peer-pidfd capabilities through child-scoped seccomp filters without relaxing existing tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e19737a6-412b-4652-b67e-b37837521925
Classify the older kernel's EINVAL for a reaped socket peer as a protocol refusal, and preserve the held VM's Exited outcome before mapping a receive error.

Keep the PID-reuse regression strict when user namespaces are refused: use passwordless sudo only for its private PID/mount helper, keep Bash as the reaper, validate both namespace identities and matching process users, and require proof that the critical body ran. Fail explicitly if neither isolation route works; never change host namespace policy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e19737a6-412b-4652-b67e-b37837521925
Carry only scripts/test_adversarial.py from #1278 at 5b7f85d.
Wait for the fixture's actual live child before timing the workload, accept
the existing raw or wrapped timeout, and await Windows fixture teardown.
Keep the 0.5-second workload deadline and descendant-exit assertions.
Production code and skip guards are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e19737a6-412b-4652-b67e-b37837521925

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Human review is needed to confirm kernel-specific authentication and ownership-transfer guarantees because native Linux PID-reuse and Windows named-pipe validation could not be independently verified in this source-only review.

No open issues 🎉

Review effort: Balanced

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

Labels

feat-nvx-refactor tests-modified Changes existing tests, test data, or test wiring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants