Skip to content

fix(guest): cp into a running box's runtime mounts (/tmp) via the container mnt ns#628

Open
G4614 wants to merge 4 commits into
boxlite-ai:mainfrom
G4614:fix/cp-into-runtime-mounts
Open

fix(guest): cp into a running box's runtime mounts (/tmp) via the container mnt ns#628
G4614 wants to merge 4 commits into
boxlite-ai:mainfrom
G4614:fix/cp-into-runtime-mounts

Conversation

@G4614
Copy link
Copy Markdown
Contributor

@G4614 G4614 commented May 29, 2026

Resolve boxlite cp paths through the running container's live mount namespace (/proc/<init_pid>/root) so files land in runtime mounts like the /tmp tmpfs (matching docker cp), falling back to the on-disk rootfs when the box is stopped.

Test plan

CLI integration tests (first end-to-end boxlite cp coverage):

  • cp_runtime_mount.rs::cp_into_tmpfs_tmp_is_visible_in_containercp into /tmp on a running box, assert the container sees it via exec cat. Two-side verified — fails (cat: No such file or directory) with the live-ns resolution disabled, passes with it.
  • cp.rs::test_cp_roundtrip_lands_file_and_preserves_contentcp a file into a running box, confirm it reached the target path with intact content via exec cat inside the box, cp it back out and compare, then an all-256-byte-values blob for binary fidelity. Guards the CLI's BOX:PATH parsing + direction plumbing.
observed pre-fix (on-disk rootfs) post-fix (live mnt ns)
cp host:/tmp/x then cat /tmp/x in box "No such file" / rc=1 — landed beneath the tmpfs content intact
cp host:/root/x (persistent path) works works
binary blob round-trip (n/a) byte-identical
stopped box on-disk rootfs on-disk rootfs (unchanged)

Ubuntu and others added 4 commits May 29, 2026 09:23
…mnt ns

copy_into/copy_out resolved paths against the container's on-disk rootfs dir.
That works for persistent paths (/root, /app…) but lands *beneath* runtime
mounts: a path under the tmpfs at /tmp resolves to the shadowed on-disk /tmp,
invisible to the container (and the copy can fail outright with rc=1). So
`boxlite cp host:/tmp/x` silently didn't reach the container's /tmp.

Resolve a running container's copy paths through its live mount namespace
(`/proc/<init_pid>/root/...`) instead, matching `docker cp`: writes land in the
tmpfs the container actually sees. Fall back to the on-disk rootfs when the
container isn't running (offline copy to a stopped box, where no such mounts
exist). One change in container_rootfs covers both copy directions.

Test (cp_runtime_mount.rs): cp into /tmp on a running box, assert the container
sees it via `exec cat`. Two-side verified — fails ("No such file or directory")
with the live-ns resolution disabled, passes with it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `boxlite cp` CLI command had no integration test (only the lib
LiteBox::copy_into/out path in tests/copy.rs was covered). Add an end-to-end
test that cp's a file into a running box, confirms it landed at the target path
with intact content by `exec cat`-ing it from inside the box, cp's it back out
and compares to the original, and repeats with an all-256-byte-values blob for
binary fidelity. Guards the CLI's BOX:PATH parsing + direction plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lure

Resolve a running container's copy paths through a held `/proc/<pid>/root`
handle (`/proc/self/fd/<n>`) captured at check time, instead of re-deriving
the `/proc/<pid>` path at tar I/O time — so a PID recycled between the
running check and the copy can't redirect the write into another process's
mount namespace.

Surface a libcontainer state-load error as a warning rather than silently
falling back to the on-disk rootfs: a running container always has loadable
state, so a read error means the copy could land beneath a runtime mount
(an invisible drop) without any signal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…urce)

Add error-path coverage for the two deterministic guards the cp happy-path
tests don't exercise: a destination containing `..` is rejected
(invalid_argument — no escaping the container rootfs / mount namespace), and
copying out a path that doesn't exist in the box fails loudly (not_found)
without leaving a partial host file. Each runs against an otherwise-valid
running box and host file, so the failure is attributable to the path alone;
the stderr assertions pin it to each guard's own message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@G4614 G4614 marked this pull request as ready for review May 29, 2026 13:23
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.

1 participant