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>
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) |
| } |