Skip to content

tests: enforce the runtime adapter's networks in VMs - #883

Merged
Pedro Henrique Penna (ppenna) merged 2 commits into
devfrom
esaurez/822-pr11-network-enforcement-vms-20261023
Oct 27, 2026
Merged

Pedro Henrique Penna (ppenna) merged 2 commits into
devfrom
esaurez/822-pr11-network-enforcement-vms-20261023

Conversation

@esaurez

@esaurez Enrique Saurez (esaurez) commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #882; this PR retargets when its parent merges.

Stack: #866 → #882 → #883 (this PR) → #876 → #871 → #873 → #874, on dev. #863, #864, #865, #867, #868, #869, #870, #872, #875, and #878 are merged.

Part of #822: PR 11 of 11, enforcement in VMs (C4).

What changed

Tests only, in tests/vm_layered.rs, with the adapter's README. The layered scenarios check what each kind of network lets the guest's executions reach, on NVX's Ubuntu EROFS image over a scratch, as NVX's proxy-only scenario (scripts/nvx_tools/sandbox_proxy_tests.py) probes its network:

  • a_denied_network_lets_no_probe_through: a network that lets nothing through, which attaches no network device, and in which an execution reaches neither the test proxy nor any destination;
  • an_allow_rule_lets_only_its_destination_through: egress denied but for one rule, TCP to a port of host loopback at the gateway, which alone arrives;
  • a_proxy_only_network_lets_only_its_proxy_through: an execution reaches the test proxy through the URL in its environment, while the other destinations never arrive;
  • outbound_host_loopback_publishes_no_listener: outbound host-loopback access, through which an execution reaches host loopback, while the host does not reach the guest's listener, which OpenVMM does not publish;
  • allowed_host_loopback_publishes_the_listeners: host-loopback access allowed, with egress denied, through which the host reaches the guest's listener at the guest's port of host loopback, while an execution reaches nothing;
  • a_forward_reaches_its_guest_port: the host reaches the guest's listener through a forward of a port of host loopback.

How:

  • Before the launch, the test binds the host's side of the network, Host, whose ports the network names, each drawn at random from the dynamic range and free on every host address and on loopback: a test proxy on host IPv4 loopback, which the guest reaches at the same port of its gateway, and the sockets of the probes' destinations: another port of host loopback over TCP, the proxy's port over UDP, and the proxy's port over TCP at the host's own address and on host IPv6 loopback, where the host has them. Scenarios run at the same time, so each Host holds the ports that it drew until its scenario ends, or for good if the scenario fails, and draws none that another holds: OpenVMM binds the ports of a listener and of a forward only once it runs, and again for the scenario's VM after the positive control's.
  • A scenario whose network stops traffic first boots the positive control, Expect::Controlled: a VM of an open network over the same host's side, in which every probe arrives and the host reaches a listener of the guest. The host then discards what is left at its sockets, and the scenario's own VM runs the same checks, so that what does not arrive there shows the network's policy, not a broken probe. The control's VM is staged, launched, and checked as every scenario's: the table applied, its mappings counted, and the sandbox started.
  • Each VM with a network first has its network devices checked, and that OpenVMM asks /init on the kernel command line to publish the guest's listeners exactly where the root configuration says that they are published.
  • The scenarios' guest is at 192.0.2.2/24, in a range reserved for documentation, so that no host's own address is on its network; the proxy-only network's proxy is the test proxy, at a port of its own.

Validation

At this head, on #882 at a7f43d2f, with OpenVMM built at the pinned a12d9167, and each of this PR's commits with Clippy in the three configurations. The previous head, fa5ee256, moved onto #882's new head unchanged: its git range-diff is all =.

  • vm_layered (43 scenarios: runtime adapter: run cold sandboxes end to end on KVM, MSHV and WHP #822's and runtime adapter: settle executions through cgroups and run them in a VM #805's 35, tests: give the runtime adapter's executions their network's settings #882's 2, and these 6), vm_restart (3), and vm_steps (3) on WHP (local) and MSHV (Linux x86_64, as root).
  • Windows (local), in tests/runtime-adapter: cargo fmt --all --check; the protocol-only and host-only configurations' cargo clippy --locked --all-targets [--features host] -- -D warnings, cargo build --locked, cargo test --locked, and cargo +1.89 check --locked --all-targets.
  • Linux (x86_64), in tests/runtime-adapter: the same, plus the guest-only configuration (--features guest --target x86_64-unknown-linux-musl): clippy, build, tests, and the MSRV check; the guest-only library and guest_session tests as root; and a stress run of guest_session, 10 times as root and 10 times as a user, and of the library's tests, 3 times as root.
  • python scripts/check_markdown_links.py.
  • Left to CI: everything, once this PR targets dev, KVM's VM tests included; a stacked PR runs no NVX CI.

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

The test-only changes have no identified blocking issues and check network behavior using positive controls and host-side observations.

No open issues 🎉

What changed in this PR

Adds VM-level network enforcement tests for the runtime adapter, completing the network validation portion of #822 on top of #882’s execution settings.

Changes:

  • Adds six scenarios covering denied traffic, allow rules, proxy-only access, host-loopback access, and port forwarding.
  • Uses open-network positive controls and host-side traffic checks to distinguish policy enforcement from broken probes.
  • Documents the scenarios, dynamic port selection, and listener-publication checks.
File Description
tests/​runtime-adapter/​tests/​vm_layered.rs Adds network scenarios, host socket fixtures, traffic probes, and listener checks.
tests/​runtime-adapter/​README.md Documents network enforcement coverage and the test setup.

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.

🟡 Changes recommended

Parallel network scenarios can select the same unreserved ports, causing intermittent launch or listener-publication failures.

1 open issue

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.

🟢 Approval recommended

No unresolved blocking issues remain in the test and documentation changes; VM validation was not independently rerun.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/822-pr10-guest-network-settings-20261023 branch from a7f7862 to 23eb4ef Compare October 27, 2026 00:00
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/822-pr11-network-enforcement-vms-20261023 branch from b3c6c74 to fa5ee25 Compare October 27, 2026 00:02
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 27, 2026 00:02

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

The concurrent, cross-platform socket and VM checks warrant final human review, with KVM validation still pending.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/822-pr10-guest-network-settings-20261023 branch from 23eb4ef to a7f43d2 Compare October 27, 2026 00:55
@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/822-pr11-network-enforcement-vms-20261023 branch from fa5ee25 to c453a9f Compare October 27, 2026 00:56
@esaurez
Enrique Saurez (esaurez) requested a balanced review from Copilot October 27, 2026 00:56

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 blocking issues remain in the test-only changes, and the previously reported port-coordination issue is resolved.

No open issues 🎉

Review effort: Balanced

Base automatically changed from esaurez/822-pr10-guest-network-settings-20261023 to dev October 27, 2026 03:18
Enrique Saurez and others added 2 commits October 26, 2026 20:22
The layered scenarios check what each kind of network lets the guest's
executions reach, as NVX's proxy-only scenario probes its network: a
network that denies everything, which attaches no network device; an
allow rule; a proxy-only network, whose other destinations never
arrive; outbound host-loopback access, which publishes no listener of
the guest; and host-loopback access in both directions, through which
the host reaches a listener of the guest, at its port or through a
forward.

Before the launch, the test binds the host's side of the network, whose
ports the network names, each drawn at random from the dynamic range: a
test proxy on host loopback, and the sockets of the probes'
destinations. A scenario whose network stops traffic first boots a VM
of an open network over the same sockets, the positive control, in
which every probe arrives and the host reaches the guest's listener.
Each VM with a network has its network devices checked, and that
OpenVMM asks /init to publish the guest's listeners exactly where the
root configuration says that they are published.

The scenarios' guest moves to 192.0.2.2/24, in a range reserved for
documentation, so that no host's own address is on its network, and the
proxy-only network's proxy is the test proxy, at a port of its own.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a7c15634-094a-4a66-af59-25a58e732f4b
The VM scenarios run at the same time. The host's side of a network
draws the ports of a listener of the guest and of a forward, then
releases them, since OpenVMM binds them only once it runs, and again for
the scenario's VM after the positive control's. Another scenario could
draw the same ports in between, and one of the two VMs would then fail
to bind them.

Each host's side now holds the ports that it drew, in a set that the
scenarios share, until its scenario ends, and draws none that another
holds. A scenario that ends confirmed that its VMs ended; one that fails
keeps its ports for good, since one of its VMs might still run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a7c15634-094a-4a66-af59-25a58e732f4b
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