Repository navigation
tests: start clones with exports in VMs - #956
Enrique Saurez (esaurez) wants to merge 10 commits into
Conversation
nvx's restore sequence now sends a clone's mapping table itself, through
CloneControl::map, once the clone is ready, and Start only once the guest
applied every mapping. The test adapter's CloneOrder therefore takes only
the guest agent's build: clone_order(), the one place that makes it, for a
clone's start and a reattach to it, builds CloneOrder { build }.
A clone's request names no export yet, CloneRequest.export: None, so a
clone still maps nothing. The harness's Early framing, which ends before
the clone is ready, gains a map() that it never reaches.
Part of #846.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
`runtime-adapter-host start` takes the shares of a launch, `--share HOST:TARGET[:ro]`, `--deny`, `--reserved`, and `--share-root`, with the same rules: `--deny`, `--reserved`, and `--share-root` need a `--share`. `clone::Request` carries them as `layered::Shares`, and `Request::export` plans their export as a launch plans it, with NVX's `filesystem::plan` for the container root, so the start refuses shares that it cannot export, with status 1, before it reads the template store, needs NVX's artifacts, or creates the sandbox's store. `Request::clone_request` takes the planned export into NVX's `CloneRequest`, whose `ClonePlan` takes only an export of one directory, which the clone's restore binds to the template's dormant filesystem slot, and refuses others, as a failure of the request, before any VMM starts. The restore sequence sends the export's mapping table through the adapter's clone order once the clone is ready, and `mapped` now prints the number of mappings that the clone's activation record announces, which the guest applied before its sandbox started. Tests without a hypervisor cover the new usage errors, the refusals before the template store, and the export that NVX's request carries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
The VM tests start clones that share host directories with their roots, through `runtime-adapter-host start` and its shares, which NVX exports as one directory, bound to the template's dormant filesystem slot, and whose mapping table the restore sequence sends once the clone is ready. In vm_clone: - A clone over a scratch image shares one host directory: the directory itself, read-only, a read-write directory inside it, at its target there, a read-only file, and a read-write directory, with a file hidden. It starts with four mappings, and its activation record names the export, a directory, by the identity of its plan, with four mappings. On Linux, its VMM has one `--mount`, of the directory, read-write. The guest mounted the export once, read-write, nosuid and nodev, and the mappings below the root, in the table's order, each with its access, showing what the host holds but for the hidden file. An execution finds the same, and the writable mappings alone take its writes, which the host's directory holds, before and after the stop. - Four clones of one generation at once: one with a read-write export of its own and a generated machine ID, two over the same read-only export, and one without an export. Each record names its export by the identity of its plan, the same for the clones of one export, and the clone without one has none, no mapping, and on Linux no `--mount`, which leaves the slot dormant. Each export is mounted read-write, even where its mapping is read-only; the mount table lists the bind of the generated machine ID beside the mapping; and the helper of the `entries` probe, which writes the root's machine ID, finds that file read-only. - A start refuses two directories, or a file, before any VMM starts, with status 8 and the record of a failure of the request, at the plan, by the evidence of invalid mappings. - A clone whose second mapping puts a directory onto a file of the image ends at its Ready, before its sandbox starts, with status 8, the guest's report that the table failed after its first mapping, and the record of a failure of the start, by the evidence of the protocol: nothing quarantined, the lease released, and the host's directory unchanged. The harness reads a clone's activation record from its sandbox, and on Linux the arguments of its VMM. Part of #846 Part of #845 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
ClonePlan::new refuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a `..` component, which an absolute path keeps. The plan now resolves the store's directory with filesystem::canonicalize, as filesystem::plan resolves the export's paths, before it compares them. It does so only for a clone with an export, so a clone without one reads nothing more. A store whose directory cannot be resolved fails the plan as the host's failure. The test of the overlap names its store in another spelling of its directory: through `..` on Unix, and with the verbatim prefix on Windows. Part of #846 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
There was a problem hiding this comment.
🔵 Needs a closer look
The final restack depends on the external OpenVMM fix in #904 and still requires confirmation of the corrected pin and passing export VM scenarios on KVM, MSHV, and WHP.
No open issues 🎉
What changed in this PR
Adds clone-export support to the runtime adapter and VM coverage for #845 and #846, intended to fold into #955. It also closes a template-store overlap-check gap caused by alternate path spellings.
Changes:
- Lets clone starts accept host shares and pass their planned export to NVX’s restore sequence.
- Adds tests for mapping access, clone isolation, invalid exports, and cleanup after mapping failures.
- Canonicalizes the template-store path before checking export overlap and updates documentation.
The three VM scenarios that send mapping tables depend on the OpenVMM fix tracked by #904.
| File | Description |
|---|---|
tests/runtime-adapter/tests/vm_clone.rs |
Adds four clone-export VM scenarios and inspection helpers. |
tests/runtime-adapter/tests/clone_start.rs |
Tests share validation and export propagation. |
tests/runtime-adapter/src/clone.rs |
Adds shares and export planning to clone requests. |
tests/runtime-adapter/src/bin/runtime-adapter-host.rs |
Accepts clone share options and reports mapping counts. |
tests/runtime-adapter/README.md |
Documents clone shares, mapping behavior, and scenarios. |
nvx-rs/src/host/template/clone/tests.rs |
Tests overlap rejection with alternate store paths. |
nvx-rs/src/host/template/clone/export.rs |
Clarifies the resolved-path requirement for overlap checks. |
nvx-rs/src/host/template/clone.rs |
Resolves the store path before checking export overlap. |
nvx-rs/README.md |
Updates the documented overlap-check behavior. |
Review effort: Balanced
Let anyone create entries in each directory of a scenario's export, its root included, so that only a mapping's access refuses what a clone's execution writes there. A Linux host shows the guest each host object's owner and mode, which the guest's kernel checks. On an unprivileged host, the export belongs to the test's user, not to user ID 0, as which the executions run without the capabilities that override the check, so the guest refused their writes through the writable mappings. A Windows host shows the guest user ID 0 as each object's owner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
There was a problem hiding this comment.
🔵 Needs a closer look
Three new VM scenarios fail against the frozen OpenVMM pin, requiring maintainer confirmation that the final restack includes #904’s restore fix and that export mapping and teardown pass on KVM, MSHV, and WHP.
No open issues 🎉
Review effort: Balanced
…check nvx-rs: resolve the template store's path in a clone's export check ClonePlan::new refuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a `..` component, which an absolute path keeps. The plan now resolves the store's directory with filesystem::canonicalize, as filesystem::plan resolves the export's paths, before it compares them. The host still reaches the store, and OpenVMM the snapshots in it, by the path that the store names, so the plan also resolves the directories through which that path leads, links included, and refuses an export that lets the guest write in one of them: the guest could otherwise replace a link of the path, and turn the host's later operations on the store elsewhere. It does both only for a clone with an export, so a clone without one reads nothing more. A store whose path cannot be resolved fails the plan as the host's failure. The test of the overlap names its store in another spelling of its directory: through `..` on Unix, and with the verbatim prefix on Windows. Another names it through two links, one to the other's directory: it refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link. Part of #846 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
There was a problem hiding this comment.
🔵 Needs a closer look
Security-sensitive symlink and junction traversal needs platform-specific maintainer review of path resolution and rename-attack protections, with runtime validation unavailable in this source-only review.
No open issues 🎉
Review effort: Balanced
This branch exists only to run CI. It is never a pull request's head, and this commit never goes onto a pull request's branch. It is #958's head, 4a614d9, which holds #955, #956, and #958, with the fixes that dev carries for the failures that their review bases, pinned to OpenVMM 79a501b6, show in CI, and that the pull requests do not change: - #885's test-only 3fbaf8a, cherry-picked before this commit. On GitHub's hosted Windows runners an open with backup semantics bypasses the test's access list. - This commit, which moves the openvmm gitlink 79a501b6 -> e68871cc, the virtio-fs fix of #904 that dev pins since #918, so that a clone's export serves requests after a gated restore. The platform tier's allowlist there admits maxcpus=, so the copy of it in nvx-rs/tests/vectors/openvmm, which the CLI jobs compare with the submodule, takes that line too. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
…check nvx-rs: resolve the template store's path in a clone's export check ClonePlan::new refuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a `..` component, which an absolute path keeps. The plan now resolves the store's directory with filesystem::canonicalize, as filesystem::plan resolves the export's paths, before it compares them. The host still reaches the store, and OpenVMM the snapshots in it, by the path that the store names, so the plan also resolves the directories in which the host looks up the names of that path, links followed and `..` included, and refuses an export that lets the guest write in one of them: the guest could otherwise replace a link of the path, and turn the host's later operations on the store elsewhere, or make a directory of the path unsearchable, and keep the host from the store. It does both only for a clone with an export, so a clone without one reads nothing more. A store whose path cannot be resolved fails the plan as the host's failure. The test of the overlap names its store in another spelling of its directory: through `..` on Unix, and with the verbatim prefix on Windows. Another names it through two links, one to the other's directory: it refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link. A third names it through a directory and its `..`, which Unix looks up in that directory: Unix refuses a writable export of the directory, and Windows, which resolves `..` from the path's text, accepts it. Part of #846 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
There was a problem hiding this comment.
🔵 Needs a closer look
The new VM scenarios depend on an external OpenVMM fix, and the final restacked integration head still needs confirmation on KVM, MSHV, and WHP because reported validation used a combined stack.
No open issues 🎉
Review effort: Balanced
…check nvx-rs: resolve the template store's path in a clone's export check ClonePlan::new refuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a `..` component, which an absolute path keeps. The plan now resolves the store's directory with filesystem::canonicalize, as filesystem::plan resolves the export's paths, before it compares them. The host still reaches the store, and OpenVMM the snapshots in it, by the path that the store names, so the plan also resolves the directories in which the host looks up the names of that path, links followed and `..` included, and refuses an export that lets the guest write in one of them: the guest could otherwise replace a link of the path, and turn the host's later operations on the store elsewhere, or make a directory of the path unsearchable, and keep the host from the store. It does both only for a clone with an export, so a clone without one reads nothing more. A store whose path cannot be resolved fails the plan as the host's failure. These checks compare paths, so an alias of the store that an administrator configures, such as a bind mount of it, is outside them, as the directories above the store are: the documentation of the export, in ClonePlan's and in the README, now says that whoever names an export must not name such an alias, nor a directory that holds one. The test of the overlap names its store in another spelling of its directory: through `..` on Unix, and with the verbatim prefix on Windows. Another names it through two links, one to the other's directory: it refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link. A third names it through a directory and its `..`, which Unix looks up in that directory: Unix refuses a writable export of the directory, and Windows, which resolves `..` from the path's text, accepts it. Part of #846 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
There was a problem hiding this comment.
🔵 Needs a closer look
Custom symlink/junction traversal and path-based exclusions create a security-sensitive isolation boundary requiring human review of Unix and Windows path-resolution and permission assumptions.
No open issues 🎉
Review effort: Balanced
This branch exists only to run CI. It is never a pull request's head, and this commit never goes onto a pull request's branch. It is #958's head, 4a614d9, which holds #955, #956, and #958, with the fixes that dev carries for the failures that their review bases, pinned to OpenVMM 79a501b6, show in CI, and that the pull requests do not change: - #885's test-only 3fbaf8a, cherry-picked before this commit. On GitHub's hosted Windows runners an open with backup semantics bypasses the test's access list. - This commit, which moves the openvmm gitlink 79a501b6 -> e68871cc, the virtio-fs fix of #904 that dev pins since #918, so that a clone's export serves requests after a gated restore. The platform tier's allowlist there admits maxcpus=, so the copy of it in nvx-rs/tests/vectors/openvmm, which the CLI jobs compare with the submodule, takes that line too. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
…check nvx-rs: resolve the template store's path in a clone's export check ClonePlan::new refuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a `..` component, which an absolute path keeps. The plan now resolves the store's directory with filesystem::canonicalize, as filesystem::plan resolves the export's paths, before it compares them. The host still reaches the store, and OpenVMM the snapshots in it, by the path that the store names, so the plan also resolves the directories in which the host looks up the names of that path, links followed and `..` included, and refuses an export that lets the guest write in one of them: the guest could otherwise replace a link of the path, and turn the host's later operations on the store elsewhere, or make a directory of the path unsearchable, and keep the host from the store. It does both only for a clone with an export, so a clone without one reads nothing more. A store whose path cannot be resolved fails the plan as the host's failure. These checks compare paths, so an alias of the store that an administrator configures, such as a bind mount of it, is outside them, as the directories above the store are, and they cannot see what changes after them: OpenVMM resolves an export's path again at each launch and restore. The documentation of the export, in ClonePlan's and in the README, now says that whoever names an export must not name such an alias, nor a directory that holds one, nor one inside a directory that a writable export of another sandbox or clone holds: the directories above an export's directory must be ones that no guest may change, as those above the clone's block devices must. The test of the overlap names its store in another spelling of its directory: through `..` on Unix, and with the verbatim prefix on Windows. Another names it through two links, one to the other's directory: it refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link. A third names it through a directory and its `..`, which Unix looks up in that directory: Unix refuses a writable export of the directory, and Windows, which resolves `..` from the path's text, accepts it. Part of #846 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
This branch exists only to run CI. It is never a pull request's head, and this commit never goes onto a pull request's branch. It is #958's head, 4a614d9, which holds #955, #956, and #958, with the fixes that dev carries for the failures that their review bases, pinned to OpenVMM 79a501b6, show in CI, and that the pull requests do not change: - #885's test-only 3fbaf8a, cherry-picked before this commit. On GitHub's hosted Windows runners an open with backup semantics bypasses the test's access list. - This commit, which moves the openvmm gitlink 79a501b6 -> e68871cc, the virtio-fs fix of #904 that dev pins since #918, so that a clone's export serves requests after a gated restore. The platform tier's allowlist there admits maxcpus=, so the copy of it in nvx-rs/tests/vectors/openvmm, which the CLI jobs compare with the submodule, takes that line too. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
…check nvx-rs: resolve the template store's path in a clone's export check ClonePlan::new refuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a `..` component, which an absolute path keeps. The plan now resolves the store's directory with filesystem::canonicalize, as filesystem::plan resolves the export's paths, before it compares them. The host still reaches the store, and OpenVMM the snapshots in it, by the path that the store names, so the plan also resolves the directories in which the host looks up the names of that path, links followed and `..` included, and refuses an export that lets the guest write in one of them: the guest could otherwise replace a link of the path, and turn the host's later operations on the store elsewhere, or make a directory of the path unsearchable, and keep the host from the store. It does both only for a clone with an export, so a clone without one reads nothing more. A store whose path cannot be resolved fails the plan as the host's failure. The plan also refuses an export whose directory is, or holds, the directory of the clone's sandbox, in which the host writes the clone's records by their paths: the guest could otherwise change them, or replace the directory with a link and turn the host's writes elsewhere, into a leased snapshot, say. The lease names the sandbox by its path with its links resolved, so the directories through which that path leads are the ones above it, which only such an export could let the guest change. A directory inside the sandbox's, among the caller's files, may still be exported. These checks compare paths, so an alias of the store that an administrator configures, such as a bind mount of it, is outside them, as the directories above the store are, and they cannot see what changes after them: OpenVMM resolves an export's path again at each launch and restore. The documentation of the export, in ClonePlan's and in the README, now says that whoever names an export must not name such an alias, nor a directory that holds one, nor one inside a directory that a writable export of another sandbox or clone holds: the directories above an export's directory must be ones that no guest may change, as those above the clone's block devices must. The test of the overlap names its store in another spelling of its directory: through `..` on Unix, and with the verbatim prefix on Windows. Another names it through two links, one to the other's directory: it refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link. A third names it through a directory and its `..`, which Unix looks up in that directory: Unix refuses a writable export of the directory, and Windows, which resolves `..` from the path's text, accepts it. A fourth refuses an export of the sandbox's directory, and of the directory that holds it, but not of a directory inside the sandbox's. Part of #846 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
This branch exists only to run CI. It is never a pull request's head, and this commit never goes onto a pull request's branch. It is #958's head, 4a614d9, which holds #955, #956, and #958, with the fixes that dev carries for the failures that their review bases, pinned to OpenVMM 79a501b6, show in CI, and that the pull requests do not change: - #885's test-only 3fbaf8a, cherry-picked before this commit. On GitHub's hosted Windows runners an open with backup semantics bypasses the test's access list. - This commit, which moves the openvmm gitlink 79a501b6 -> e68871cc, the virtio-fs fix of #904 that dev pins since #918, so that a clone's export serves requests after a gated restore. The platform tier's allowlist there admits maxcpus=, so the copy of it in nvx-rs/tests/vectors/openvmm, which the CLI jobs compare with the submodule, takes that line too. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 34e6ffe3-3ebf-42db-bfca-e0ecfade6873
|
Folded into #955 at the final restack:
#955 now holds these commits, on #960, and this pull request closes. |
Review base: this PR temporarily targets
esaurez/846-vm-tests-base-snapshot-20261028, a frozen copy of the work it builds on, so that its diff shows only its own commits while the pull requests below it are in review. That work is #846's PR 1 (#955) merged with #845's VM scenarios (#961). This pull request does not merge on its own: at the final restack, its commits fold into #846's PR 1 (#955), and it then closes.Part of #846 (PR 1's VM scenarios) and of #845 (its export scenarios).
Commits
runtime-adapter: let the restore sequence send a clone's mapping table: what the merge of nvx-rs: exports, MAPS and network templates for clones #846's PR 1 with nvx-rs: activate a clone's root for GPT images and either upper, with its export, network settings and workload view #845's VM scenarios needs. NVX's restore sequence now sends a clone's mapping table itself, soclone_order(), the one place that makes the adapter'sCloneOrderfor a clone's start and a reattach to it, buildsCloneOrder { build }. A clone's request names no export yet,CloneRequest.export: None, and the harness'sEarlyframing, which ends before the clone is ready, gains amap()that it never reaches.runtime-adapter: let a clone's start share host paths with its root:runtime-adapter-host starttakes a launch's shares,--share HOST:TARGET[:ro],--deny,--reserved, and--share-root, with the same rules:--deny,--reserved, and--share-rootneed a--share.clone::Requestcarries them, andRequest::exportplans their export as a launch plans it, withfilesystem::planfor the container root, so a start refuses shares that it cannot export, with status 1, before it reads the template store, needs NVX's artifacts, or creates the sandbox's store.Request::clone_requesttakes the planned export into NVX'sCloneRequest, andmapped=prints the number of mappings that the clone's activation record announces.runtime-adapter: start clones with exports, in VMs: the scenarios below. The harness reads a clone's activation record from its sandbox, and, on Linux, the arguments of its VMM.nvx-rs: resolve the template store's path in a clone's export check: a fix of PR 1's export check.ClonePlan::newrefuses an export that overlaps the template store, whose leased payloads nothing may change. It compared the paths that the export's plan resolved with the store's directory as the store names it, so another spelling of the store's path hid an overlap: a link; on Windows, another letter case, a short name, or the verbatim prefix; and on Unix, a..component, which an absolute path keeps. The plan now resolves the store's directory withfilesystem::canonicalize, asfilesystem::planresolves the export's paths. The host still reaches the store, and OpenVMM the snapshots in it, by the path that the store names, so the plan also resolves the directories in which the host looks up the names of that path, links followed and..included, and refuses an export that lets the guest write in one of them, where the guest could replace a link of the path and turn the host's later operations on the store elsewhere, or make a directory of the path unsearchable and keep the host from the store. It does both only for a clone with an export, so a clone without one reads nothing more. A store whose path cannot be resolved fails the plan as the host's failure:HostFailure, orResourceExhaustionwhen the error proves it. The plan also refuses an export whose directory is, or holds, the directory of the clone's sandbox, in which the host writes the clone's records by their paths, which the guest could otherwise change, or turn elsewhere, into a leased snapshot, say; a directory inside the sandbox's, among the caller's files, may still be exported. These checks compare paths, so an alias of the store that an administrator configures, such as a bind mount of it, is outside them, as the directories above the store are, and they cannot see what changes after them, since OpenVMM resolves an export's path again at each launch and restore: the description of the export, inClonePlan's documentation and in the README, says that whoever names an export must not name such an alias, nor a directory that holds one, nor one inside a directory that a writable export of another sandbox or clone holds, so that no guest may change the directories above an export's directory, as for the clone's block devices.Fix-ups
fixup! runtime-adapter: start clones with exports, in VMs:Export::write, the fixture of the scenarios' exports, now lets anyone create entries in each directory of an export, its root included, so that only a mapping's access refuses what an execution writes there. A Linux host shows the guest the owner and the mode of each host object, which the guest's kernel checks, and an execution as user ID 0 holds no capability that overrides the check. Where the tests run unprivileged, the export belongs to the test's user, so the guest refused the execution's writes even through the writable mappings. A Windows host shows the guest user ID 0 as each object's owner.amend! nvx-rs: resolve the template store's path in a clone's export check: the check of the directories through which the store's path leads, above, which the commit's resolution of the store's path alone had dropped: an export of a directory that holds a link of the store's path, which the store's resolved path does not pass, no longer overlaps the store, though a guest that writes in it could replace the link.path_directoriesfollows each link of the path, and of its targets, through at most 64 links, and the export's check compares them with the paths in which the guest may write: the whole directory of a writable export, or the paths to which the plan limits its writes. A test names its store through two links, one to the other's directory, and refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link.amend! nvx-rs: resolve the template store's path in a clone's export check:path_directoriesskipped.., but Unix looks..up in the directory before it, which the host must be able to search, so with a store named/srv/traverse/../private/templates, a writable export of/srv/traverselet the guest make that directory unsearchable, and keep an unprivileged host from the store. The directory in which the host looks up.or..now joins the others, and the refusal says that the guest could turn the store's path elsewhere, or keep the host from following it. A test names its store through a directory and its..: Unix refuses a writable export of the directory, but not a read-only one, nor one whose writes the plan limits to a directory in it, and Windows, which resolves..from the path's text, accepts all three.amend! nvx-rs: resolve the template store's path in a clone's export check, documentation only: the export's checks compare paths, so an alias of the store that an administrator configures is outside them, as the directories above the store are: a bind mount or a mount point of the store, or of a directory above or inside it, a loopback share, or a hard link of a payload.ClonePlan's description of the export,DirectoryExport::check_outside, and the README'snvx::host::templaterow now say that whoever names an export must not name such an alias, nor a directory that holds one.ClonePlan's description of the export also states the check of the store's path, which it had left out.amend! nvx-rs: resolve the template store's path in a clone's export check, documentation only: OpenVMM resolves an export's path again at each launch and restore, after the plan's checks andExportPlan::verify, so a guest that may write the directory that holds an export's directory, through a writable export of another sandbox or clone, could replace that directory with a link as OpenVMM resolves it, and turn the export elsewhere, to a leased payload, say.ClonePlan's description of the export,DirectoryExport::check_outside, and the README'snvx::host::templaterow now say that the directories above an export's directory must be ones that no guest may change, as those above the clone's block devices must, which the store's "Block devices by path" describes: whoever names an export must not name one inside a directory that a writable export of another sandbox or clone holds.amend! nvx-rs: resolve the template store's path in a clone's export check: the export check also refuses an export whose directory is, or holds, the directory of the clone's sandbox. The host writes the clone's records there by their paths, such as its runtime record when a launch commits and its failure records, so a guest that could reach the directory through a writable export could change them, or replace the directory with a link to a leased snapshot and turn the host's writes into it. The lease names the sandbox by its path with its links resolved, so the directories through which that path leads are the ones above it, which only such an export could let the guest change, and the check reads nothing more. A directory inside the sandbox's, among the caller's files, may still be exported. A test refuses an export of the sandbox's directory, writable, and of the directory that holds it, read-only, and accepts a writable export of a directory inside the sandbox's.VM scenarios (
vm_clone), on MSHV and WHP--mount, of the directory, read-write. The guest mounted the export once, read-write,nosuid, andnodev, and the mappings below the root in the table's order, each with its access, showing what the host holds but for the hidden file. An execution finds the same, and the writable mappings alone take its writes, which the host's directory holds before and after the stop.--mount, so its slot stays dormant. Each sees only its own directory, and the records of one export name it by the same identity. An export is mounted read-write even where its mapping is read-only, the mount table lists the bind of the generated machine ID beside the mapping, and the helper of theentriesprobe, which writes the root's machine ID, finds that file read-only.Ready, before its sandbox starts, with status 8, the guest's report that the table failed after its first mapping, and the record of a failure of the start, by the evidence of the protocol: nothing quarantined, the lease released, and the host's directory unchanged.Depends on an OpenVMM fix
Three of the scenarios send a mapping table, so they need the OpenVMM fix that #904 tracks:
a_clone_maps_its_export_beneath_its_root_before_its_sandbox_starts,clones_at_once_see_only_their_own_exports, anda_clone_whose_mapping_fails_ends_before_its_sandbox_starts. With the pinned OpenVMM, their mapping requests time out; with the fix, they pass. The fourth,a_start_refuses_an_export_that_a_dormant_filesystem_slot_cannot_bind_before_any_vmm_starts, starts no VMM, and passes with either.Tests without a hypervisor
clone_start: the start's new usage errors (--deny,--reserved, and--share-rootwithout a share, and malformed shares); shares that it cannot export, refused with status 1 before the template store; and the export that NVX's request carries: none without shares, and with them one directory, the root of a read-only share that holds a read-write one, mapped from an empty source and from its path.nvx-rs: the test of an export that overlaps the store names the store in another spelling of its directory, through..on Unix and with the verbatim prefix on Windows; another names it through two links, symbolic links on Unix and junctions on Windows, and refuses a writable export of the directory of either link, but not a read-only one, nor one whose writes the plan limits to a directory beside the link; a third names it through a directory and its.., whose writable export Unix refuses and Windows accepts; a fourth refuses an export of the sandbox's directory, and of the directory that holds it, but not of a directory inside it.Validation
At this head, with the guest agent and the initramfs built from it:
nvx-rschecks, the test adapter's checks, theaci_edge_sandboxeschecks, Clippy of thenvx-rsguest code forx86_64-unknown-linux-musl,scripts/nvx.py verify, and the Markdown link check.check-nvx-rsand of the dependent crates' checks, and the root-only tests, 12 of 12.vm_clone16 of 19 (all but the three scenarios above),vm_layered43,vm_restart3,vm_steps3,vm_template9,host_session25,layered_launch20, andclone_start6. With the OpenVMM fix, the four export scenarios pass on both.For the fix-up: the test adapter's checks on Windows, and the 29 steps of the Linux checks. On MSHV with the OpenVMM fix, the export scenarios pass, and with an export owned by another user than root, as on an unprivileged host, an execution as user ID 0 had its writes through the writable mappings refused before the fix-up, and makes them after it.
With OpenVMM e68871cc, which has the fix, at a head that holds this pull request and #846's PR 2 (#958):
vm_clonepassed 24 of 24 on each.vm_clone24 of 24,vm_layered43,vm_restart3,vm_steps3,vm_template9,host_session25,layered_launch20, andclone_start8.