Skip to content

host: give each VM a private directory with fixed names - #1280

Merged
Pedro Henrique Penna (ppenna) merged 1 commit into
feature/nvx-refactorfrom
esaurez/slim-2.2.1-sl2.7-20261104
Nov 6, 2026
Merged

Pedro Henrique Penna (ppenna) merged 1 commit into
feature/nvx-refactorfrom
esaurez/slim-2.2.1-sl2.7-20261104

Conversation

@esaurez

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

Copy link
Copy Markdown
Contributor

Part of #1099.

Implements SL2.7 only: a caller-owned private VM directory, fixed output
names, and a redacted control capability. Launch preparation, output creation,
spawning, restore listeners and credential persistence remain outside this PR.

Changes

  • Add host::vm::{VmDir, VmOutputs, Capability, create_private_dir} in the
    existing nvx crate. The fallible directory functions return the crate's Result;
    a non-private directory is ErrorKind::Io, and native I/O failures retain
    their cause.
  • Linux requires the effective user's ownership and exact mode 0700. Creation
    preserves the caller's umask and never repairs an unsafe existing directory.
  • Windows requires the current user's owner SID and a present, non-NULL,
    protected DACL containing only allow entries for that user. At least one
    entry must grant full access through bitwise FILE_ALL_ACCESS containment
    or GENERIC_ALL, with OI and CI and without IO or NP.
  • Normalize trailing separators and dot components before both entry points'
    no-follow checks, without resolving symlinks or parent components. This
    refuses a final symbolic link even when its path ends in / or /..
  • Document the reserved log, outcome, control, console, restore-ready, snapshot
    and capture names. The snapshot directory is openvmm/; the separate
    temporary-file prefix is .openvmm.
  • Windows control and console outputs independently receive fresh
    //./pipe/openvmm-microvm-<32 lowercase hex> names; restore-ready uses
    //./pipe/nvx-restore-ready-<32 lowercase hex>.
  • Capability::as_bytes() borrows the protocol-sized bytes. Both Debug forms
    redact them, and these APIs write no credential file or launch output.

The existing broader store, template, snapshot, log-job and pipe policies are
unchanged. The PR's own diff changes no package, workspace, manifest, lockfile,
version, protocol or OpenVMM pin. The seven temporary dead-code expectations
name their later callers; no later lifecycle step is implemented to suppress a lint.

Both public API inventories add exactly 12 VM entries and remove none.
The rebase onto feature/nvx-refactor at ef703702 retains both the existing
runtime documentation and the VM documentation.

Windows CI repair

The Windows all-features job in run
42160212636
failed two VM-directory assertions. The test helper returned expanded SID
strings, while the security-descriptor serializer uses canonical SDDL aliases
such as LA. Equivalent ownership was therefore compared using different
spellings, including in the inherited-directory error classification.

Correct only user_sid() in the owning test module to serialize the owner
through the same SDDL API and revision as the ACL snapshot. Add
security_identifier_spelling_matches_the_descriptor_snapshot with the
deterministic SYSTEM and LocalService aliases (SY and LS). The regression
failed before the fix and passes afterward. Production SID comparisons, all
privacy checks, and both original assertions remain unchanged.

Existing tests and size

check_test_changes against the recorded base ef703702 reports two changes
to existing tests, zero relocations and 30 added entries, which include helpers:

Existing test or policy Disposition
private_directories_support_long_paths Strengthened with VM-directory creation and checking in the existing long-path cases; its store and file assertions remain.
scripts/test-layout-allowlist.json Add only the seven bounded expectations in host/vm.rs; existing entries are unchanged.
renames_support_long_paths_without_replacing_existing_files, invalid_paths_do_not_create_or_rename_their_prefix Kept unchanged.
the_store_is_private_to_the_current_user, stores_belong_to_the_current_user_with_mode_700, stores_open_only_existing_directories, directories_that_others_may_access_are_refused Kept unchanged.
private_directories_belong_to_the_current_user_and_grant_others_nothing, snapshots_that_openvmm_published_are_private_without_entries_for_their_files Kept unchanged.
links_and_unsafe_ownership_are_refused_before_the_vm_starts, stores_too_deep_for_the_control_socket_of_a_capture_are_refused Kept unchanged.
vmms_start_with_the_callers_umask_without_the_owners_bits, one_shot_vmms_start_with_the_callers_umask_without_the_owners_bits, spawns_fail_with_the_error_of_a_refused_umask Kept unchanged.
a_vm_directory_is_created_owner_only_and_protected_under_a_permissive_parent, existing_vm_directories_that_grant_others_or_inherit_are_refused_and_left_unchanged Kept unchanged; their SID-spelling helper is corrected as described above.

No existing executable test was removed, moved or weakened. The new tests cover
privacy and unchanged unsafe directories, native errors, every fixed and reserved
name, fresh Windows pipe names, capability redaction and no file writes. The
Linux symlink regression covers /, /., /./ and //.// on both functions,
including unchanged links and targets. There are 14 new test definitions:
10 run on Linux and 10 on Windows. The tests and their helpers remain out of
line. The tests-modified label is retained.

Measured against ef703702: 244 tool-counted core lines in five counted
files
: 242 production lines in four files, plus two JSON policy lines.
This remains below the issue's 520-line stop; the CI repair adds test code only.

Validation

All current results below cover clean source head b93206ab and tree
6b8ce93719f5f781923db77f1d752a5d6c9c426b, including the SID-helper repair.
Historical results for 935ec708 and the intermediate uncommitted repair
are not counted as current-head passes.

Check Result
Complete check-nvx-rs action Passed on Windows and Linux: formatting, five warning-denied feature configurations, all-features/default/no-default tests and builds, real artifact bundling, warning-denied documentation, MSRV 1.89, and runtime-adapter protocol/host configurations.
Original failed Windows all-features command Passed; the two original VM-directory tests and the new SID-spelling regression pass.
Bundling Passed with NVX_BUNDLE genuinely unset: 18 tests on Windows and 19 on Linux.
Linux-only Rust gates Public API inventories, macOS cross-check, guest lint/tests, guest-binary build and 39 behavior checks, and 146 adapter guest-only tests passed.
Native Windows CLI/Python gates Complete 1,813-test direct module command passed with 67 platform skips, plus the separately admitted Rust-helper test (1,814 total); the shell query/RCU case executed. All 84 adversarial tests (11 platform skips), four inventory tests and every help check passed.
Native Linux CLI/Python gates Complete module command passed: 1,814 tests, 35 platform skips; all 84 adversarial tests and four host-inventory tests passed.
Complete native Linux check-quality action Ruff, both Pyright platforms, links, test layout, kernel configuration, 25 Specula tests, pinned ShellCheck/shfmt and native PowerShell syntax passed.
OpenVMM vectors and CPU profiles Passed on both hosts against the inherited submodule revision.
Windows/WHP runtime The four public sandbox scenarios and all 156 canonical adapter scenarios across 11 targets passed, with no task-source VMM remaining.
Linux/MSHV runtime The same four public scenarios and all 156 canonical adapter scenarios across 11 targets passed; a private data-backed short temporary path and PID/mount namespace preserve Unix socket bounds and leave host namespaces unchanged.
Independent read-only implementation review Clean at the exact source head and tree above.

The four public scenarios are managed-exec-config, sandbox-lifecycle,
sandbox-proxy-only and sandbox-ram-upper. The adapter runs the exact prebuilt
tests named by its committed scenario inventory, with the original naming and
per-test outcome checks. Source cleanliness, executable hashes and runtime
provenance are verified before and after each VM set.

Both host CLIs and the adapter programs are built from the current sources.
Native OpenVMM 14dc4116 and kernel 6.18.38 are authenticated, hash-verified
inputs from v0.1.0-dev.cbfe738d4ca8; they are not relabeled as new builds.
The Alpine and Ubuntu initramfses and Ubuntu EROFS fixture are assembled from
this checkout with its validated static guest binaries, then rehashed and
validated on both platforms. No release's nvx-rs or guest image is substituted.

This is the selected host-API regression set, not the later group-final full
distribution matrix. KVM remains for CI. The existing Draft state and
feature/nvx-refactor destination are preserved; no manual CI run, readiness
transition or merge is requested.

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

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

This pull request changes existing tests

It modifies or removes 2 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 test fn private_directories_support_long_paths in host::platform::windows::private::tests nvx-rs/src/host/platform/windows/private/tests.rs:17 nvx-rs/src/host/platform/windows/private/tests.rs:17

Test policy

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

Relocated unchanged: 0; added: 30. Compared the merge base ef703702cb40 with b93206ab3804.

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 symlink-refusal bypass in VM directory opening and creation accepts paths ending in / or /., allowing retained paths to be redirected later.

1 open issue
What changed in this PR

Implements SL2.7 of the host API slimming workstream: caller-owned private VM directories, fixed output names, and a redacted capability type. Launching processes and persisting credentials remain outside this slice.

Changes:

  • Adds host::vm directory, output, and capability types.
  • Reuses Linux privacy checks and adds a stricter, VM-specific Windows access policy.
  • Adds platform tests, documents reserved names, and updates both public API inventories.
File Description
scripts/​test-layout-allowlist.json Allows seven temporary dead-code expectations for later callers.
nvx-rs/​src/​host/​vm/​tests.rs Tests directory privacy, output names, and capability redaction.
nvx-rs/​src/​host/​vm.rs Defines VM directories, fixed outputs, and capabilities.
nvx-rs/​src/​host/​platform/​windows/​tests.rs Re-exports security inspection helpers for tests.
nvx-rs/​src/​host/​platform/​windows/​private/​tests.rs Adds security inspection helpers and VM access-policy cases.
nvx-rs/​src/​host/​platform/​windows/​private.rs Adds owner-only, protected VM directory validation.
nvx-rs/​src/​host/​platform/​windows/​mod.rs Exposes VM directory helpers internally.
nvx-rs/​src/​host/​platform/​tests.rs Makes Windows inspection helpers available to host tests.
nvx-rs/​src/​host/​mod.rs Exports and documents host::vm.
nvx-rs/​README.md Documents directory privacy, reserved names, and credentials.
nvx-rs/​public-api/​windows.txt Records the 12 new VM API entries on Windows.
nvx-rs/​public-api/​linux.txt Records the 12 new VM API entries on Linux.

Review effort: Balanced

Comment thread nvx-rs/src/host/vm.rs Resolved
@esaurez
Enrique Saurez (esaurez) changed the base branch from esaurez/slim-2.1.1-sl2.1-20261103 to dev November 4, 2026 19:00
@esaurez

Copy link
Copy Markdown
Contributor Author

Scope update following the revised #1076/#1099 contract: SL2.7 needs the public-API foundation, not retired error-type PR #1267.

The base is being updated to dev; remove #1267's commit from the branch. New VM-directory APIs use the crate's Result, and refusal of a non-private directory is ErrorKind::Io, consistent with the existing store checks. Do not retain a LaunchError/ConfigError facade.

Preserve fixed names, capability redaction, owner-only permissions and the required trailing-slash/dot symlink correction. The existing symlink finding is not waived by this API change. Earlier validation remains evidence for its recorded head; revised code/inputs need affected checks and reviews before readiness. No Ready transition or manual CI dispatch is included.

@esaurez
Enrique Saurez (esaurez) force-pushed the esaurez/slim-2.2.1-sl2.7-20261104 branch from f91df78 to 935ec70 Compare November 5, 2026 19:18
Copilot AI balanced review requested due to automatic review settings November 5, 2026 19:18

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 reported for the caller-owned VM directory contract changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Add caller-owned VM directories, fixed output names and redacted control
capabilities without creating launch outputs or persisting credentials.
Require current-user ownership and mode 0700 on Linux, or a protected
owner-only DACL on Windows, without changing existing directories.

Use the crate's Result and report a non-private directory as ErrorKind::Io.
Normalize trailing separators and dot components before no-follow checks
so a final symbolic link is refused, while preserving parent components.
Keep the existing store privacy policies unchanged.

Compare Windows ACL snapshots using the same canonical SDDL SID
spellings as the descriptor serializer, including well-known aliases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d334d041-d2f2-47db-be92-5564ff14f2d7

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 block the caller-owned private VM directory API changes.

No open issues 🎉

Review effort: Balanced

@esaurez
Enrique Saurez (esaurez) marked this pull request as ready for review November 6, 2026 07:36
@ppenna
Pedro Henrique Penna (ppenna) merged commit aaa6bfd into feature/nvx-refactor Nov 6, 2026
107 of 108 checks passed
@ppenna
Pedro Henrique Penna (ppenna) deleted the esaurez/slim-2.2.1-sl2.7-20261104 branch November 6, 2026 20:37
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