Repository navigation
runtime: prove isolation per backend; firecracker needs no krun - #56
Merged
chxmxii merged 1 commit intoOct 23, 2026
Merged
Conversation
The isolation check that gates every run was cached once per box home, keyed on a fingerprint of krun, crun and podman, whatever the backend: - box up failed on a host with only the firecracker backend, with "no 'krun' on PATH", although firecracker never runs krun. - a proof made on one backend cleared every other. A firecracker sandbox passing the check let a podman sandbox run without its own krun path ever being proven, and the podman backend leaves that to this check: on a host whose crun lacks libkrun, it could run as a plain container on the host kernel. - the Firecracker build and its kernel were not part of the fingerprint. RuntimeIdentity now takes the backend and fingerprints only what that backend runs: krun and the crun it resolves to for podman and krun; the pinned Firecracker and kernel hashes and crun for firecracker. verify.json keeps one proof per backend. A cache in the old single-token format reads as empty, so each backend re-verifies once. box doctor reports each backend's proof.
chxmxii
pushed a commit
that referenced
this pull request
Oct 23, 2026
…change (#57) GitHub's hosted Ubuntu runners expose /dev/kvm, and the firecracker backend needs nothing more than KVM, vsock, podman and crun. escape.yml runs the escape suite there under strict and standard isolation, on every pull request and push to main as well as nightly; each job takes about a minute. Until now the suite ran only on the self-hosted kvm runner, nightly, and that runner has not picked up a job in days. The podman and krun backends need crun built with libkrun, which those runners lack, so security.yml keeps running them on the self-hosted runner. Until #56 lands, box up needs krun on PATH whatever the backend, so the job symlinks krun to crun; the step says to remove that once it does.
chxmxii
pushed a commit
that referenced
this pull request
Oct 29, 2026
govulncheck has failed on main since 2026-10-23: GO-2026-6809 in crypto/x509, reachable from box serve, is fixed in Go 1.26.10, and go.mod pinned 1.26.9, which CI and releases build with. escape.yml symlinked krun to crun until #56 made box stop needing krun for firecracker. #56 has landed, so the step now fails if krun is on PATH instead, and the job stands for a firecracker-only host.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #4, which introduced the cached isolation proof this fixes. Found while running the escape suite for #55.
The bugs
The isolation check that gates every
run,execandup(EnsureIsolated) is cached once per box home. The cache key isRuntimeIdentity(), which on Linux fingerprints krun, crun and podman whatever the backend.box upfails on a firecracker-only host.RuntimeIdentityrequireskrunon PATH and returnsno 'krun' on PATH, although firecracker never runs krun. The self-hostedkvmrunner has krun installed, which hid this.podmanBackend.Preflightchecks only thatkrunexists and leaves libkrun to this check. On a host whose crun lacks libkrun, the podman sandbox could therefore run as a plain container on the host kernel, cleared by the firecracker proof. This takes a broken toolchain plus a mix of backends (whichbackend: automakes ordinary), and it defeats the one guard against that fallback.The fix
RuntimeIdentity(backend)fingerprints only what that backend runs:--versionwith its+LIBKRUNtag);fcAssetschecks both before every use), the tools image tag, and crun, which runs the VMM;verify.jsonholds one proof per backend ({"backends": {...}}), written via a temp file and rename. A cache in the old single-token format reads as empty, so each backend re-verifies once after upgrade. That costs one double boot and never clears a run.MarkVerifiedtakes the spec, sobox buildandbox verifyrecord the proof under the sandbox's backend.box doctorreports a row per proven backend.box inspect --security-reportreports the proof for the sandbox's own backend.Checked
crunandpodmanon PATH, the firecracker identity works while podman and krun refuse;go test -race ./...,go vet,gofmt.upwithno 'krun' on PATH: https://github.com/KoLDXr00T/bluebox/actions/runs/39482241469Not run: the podman and krun backends' escape suite. That needs crun built with libkrun, i.e. the self-hosted
kvmrunner, and none is registered yet (#31).Left as is
box doctorstill marks a missingkrunas FAIL on a firecracker-only host. That's now only cosmetic, sinceupworks, but it misleads. It could become a warning that names the backends needing krun, as a follow-up.