fix(firecracker): keep the snapshot partial private even if one was left behind
test / unit (pull_request) Successful in 1m9s
test / integration (pull_request) Successful in 21s
test / coverage (pull_request) Successful in 1m14s
lint / lint (push) Successful in 2m21s
test / unit (push) Successful in 1m18s
test / integration (push) Successful in 30s
test / coverage (push) Successful in 1m27s
Update Quality Badges / update-badges (push) Successful in 1m17s

Follow-up to the codex review on #398. os.open's mode arg only applies on
creation, so a committed-rootfs.tar.partial left 0644 by an interrupted run
would be opened/truncated (not re-moded) and stay world-readable for the
whole SSH stream. Unlink any leftover and exclusively recreate it
(O_EXCL|O_NOFOLLOW), then fchmod 0600 immediately so umask can't loosen it.

Test pre-creates a 0644 partial and asserts the fd is 0600 mid-stream.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UoEZHDjv84ChoZbozQERhJ
This commit was merged in pull request #398.
This commit is contained in:
2026-07-17 01:02:19 -04:00
parent 39d47b8108
commit dfc693e0b6
2 changed files with 47 additions and 14 deletions
+11 -3
View File
@@ -64,9 +64,17 @@ def _commit_rootfs_via_ssh(private_key: Path, guest_ip: str, tar_path: Path) ->
partial = tar_path.with_name(tar_path.name + ".partial")
ssh = util.ssh_base_argv(private_key, guest_ip)
# The snapshot can contain the bottle's private workspace, so keep it
# owner-only (0600) — create it that way and re-assert after the rename
# (os.replace carries the source mode, but be explicit).
fd = os.open(partial, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
# owner-only (0600) for the whole stream. The `os.open` mode only applies
# on *creation*, so unlink any leftover partial (a prior interrupted run
# could have left it world-readable, or something could swap in a symlink
# at this predictable name) and exclusively recreate it — O_EXCL|O_NOFOLLOW
# — then fchmod immediately so umask can't loosen it. Re-assert after the
# rename too (os.replace carries the source mode, but be explicit).
partial.unlink(missing_ok=True)
fd = os.open(
partial, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600
)
os.fchmod(fd, 0o600)
with os.fdopen(fd, "wb") as tar_out:
result = subprocess.run(
[*ssh, "--", "tar", "--create", "--one-file-system",