carlos / platform Public

host: Plan 11 pinned-executable test follows #267's root-owned rule

verifiedClaimExecutable hashes only a root-owned executable since #267
(75618480). Unprivileged, the test now proves that a non-root-owned
build is refused and skips the acceptance case, which needs a root-owned
fixture. Production's kernel Owner is root, so the code is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 2ad977565ac080681daa046e7710fbf7c08080f4 parent 068aea4
1 file changed, +9 −0
  • internal/host/claimlaunch_kernel_linux_test.go +9 −0

CI cancelled — superseded by a newer push — run details

diff --git a/internal/host/claimlaunch_kernel_linux_test.go b/internal/host/claimlaunch_kernel_linux_test.go
index 870a9b430..a1c3f151f 100644
--- a/internal/host/claimlaunch_kernel_linux_test.go
+++ b/internal/host/claimlaunch_kernel_linux_test.go
@@ -5,6 +5,7 @@ package host
import (
"crypto/sha256"
"encoding/hex"
+ "errors"
"os"
"os/exec"
"path/filepath"
@@ -134,6 +135,14 @@ func TestPlan11Rev2RootHashesThePinnedExecutable(t *testing.T) {
sum := sha256.Sum256([]byte("app"))
digest := hex.EncodeToString(sum[:])
id := plan11LaunchFileID(t, path)
+ if os.Getuid() != 0 {
+ // The hash is taken only from a root-owned executable (#267), so an
+ // unprivileged run can prove the refusal but not the acceptance.
+ if err := k.VerifyDigest(t.Context(), path, id, digest); !errors.Is(err, hostbox.ErrChanged) {
+ t.Fatalf("non-root-owned executable: err=%v, want ErrChanged", err)
+ }
+ t.Skip("accepting a pinned executable needs a root-owned fixture")
+ }
if err := k.VerifyDigest(t.Context(), path, id, digest); err != nil {
t.Fatal(err)
}