-
Couldn't load subscription status.
- Fork 71
Description
[BUG] Panic in witness verify when policy file doesn't exist (nil pointer dereference in archivista client)
Description
When running witness verify with a non-existent policy file path, the command panics with a nil pointer dereference in the archivista client code instead of providing a helpful error message about the missing file.
Steps to Reproduce
- Build witness from source (commit ba902d8)
- Create an attestation:
./witness run --step build --signer-file-key-path test/testkey.pem --outfile /tmp/witness-test.att -- echo "test build"
- Attempt to verify with a non-existent policy file:
Note: The file
./witness verify --policy test/policy-signed.json -k test/testpub.pem --attestations /tmp/witness-test.att --artifactfile /Users/nkennedy/proj/witness/witness
test/policy-signed.jsondoes not exist in the repository.
Expected Behavior
The command should fail gracefully with an error message like "policy file not found: test/policy-signed.json" or similar.
Actual Behavior
The command panics with a nil pointer dereference:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x10 pc=0x1051b0438]
goroutine 1 [running]:
github.com/in-toto/go-witness/archivista.(*Client).archivistaRequestOpts(...)
/Users/nkennedy/go/pkg/mod/github.com/in-toto/[email protected]/archivista/client.go:56
github.com/in-toto/go-witness/archivista.(*Client).Download(0x1400071c460?, {0x1076aa518?, 0x108c52980?}, {0x16b09b66a?, 0x14000064f38?})
/Users/nkennedy/go/pkg/mod/github.com/in-toto/[email protected]/archivista/download.go:25 +0x38
github.com/in-toto/witness/internal/policy.LoadPolicy({0x1076aa518, 0x108c52980}, {0x16b09b66a, 0x17}, {0x1076984b8, 0x0})
/Users/nkennedy/proj/witness/internal/policy/policy.go:47 +0x288
github.com/in-toto/witness/cmd.runVerify({_, _}, {{0x0, {0x10685f9b9, 0x20}, {0x108c52980, 0x0, 0x0}}, 0x14000510f60, 0x14000510ed0, ...}, ...)
/Users/nkennedy/proj/witness/cmd/verify.go:167 +0x558
github.com/in-toto/witness/cmd.VerifyCmd.func1(0x140003cd808, {0x10681b560?, 0x4?, 0x10681b4f0?})
/Users/nkennedy/proj/witness/cmd/verify.go:58 +0x19c
github.com/spf13/cobra.(*Command).execute(0x140003cd808, {0x1400070d100, 0x8, 0x8})
/Users/nkennedy/go/pkg/mod/github.com/spf13/[email protected]/command.go:1015 +0x828
github.com/spf13/cobra.(*Command).ExecuteC(0x140003cd208)
/Users/nkennedy/go/pkg/mod/github.com/spf13/[email protected]/command.go:1148 +0x350
github.com/spf13/cobra.(*Command).Execute(...)
/Users/nkennedy/go/pkg/mod/github.com/spf13/[email protected]/command.go:1071
github.com/in-toto/witness/cmd.Execute()
/Users/nkennedy/proj/witness/cmd/root.go:59 +0x20
main.main()
/Users/nkennedy/proj/witness/main.go:22 +0x1c
Analysis
The stack trace shows the issue originates in internal/policy/policy.go:47 when calling LoadPolicy. It appears the code is trying to use an archivista client even when the policy is being loaded from a local file path.
Looking at the trace:
LoadPolicyis called with the policy path "test/policy-signed.json"- This then calls into
archivista.(*Client).Download - The archivista client appears to be nil or uninitialized, causing the panic at
client.go:56
Root Cause Hypothesis
The issue likely occurs because:
- The LoadPolicy function doesn't check if the local file exists before attempting to load it
- When the file doesn't exist, it may fall back to trying archivista
- The archivista client is not properly initialized (nil) in this fallback path
- There are missing nil checks before calling methods on the archivista client
Suggested Fix
The LoadPolicy function should:
- Check if a local file exists before attempting to load it
- Return a clear error message if the file doesn't exist
- Only fall back to archivista if the path looks like an archivista URL/reference
- Add proper nil checks before calling methods on the archivista client
- Handle the case where archivista client is nil gracefully
Environment
- OS: macOS Darwin 24.6.0
- Architecture: arm64 (Apple Silicon)
- Witness Version: dev (built from source)
- Commit: ba902d8
- Go Version: (from go.mod) go 1.23
- go-witness version: v0.9.1
Additional Context
This issue occurs specifically when the policy file doesn't exist. When using an existing signed policy file (e.g., test/policy-hello-signed.json), the command works correctly and either succeeds or fails with appropriate verification errors.
The panic only happens when the file path points to a non-existent file, which suggests missing error handling in the file loading path.
Workaround
Ensure the policy file exists before running witness verify. Double-check the file path and verify the file is present with ls -la <policy-file-path> before attempting verification.