Skip to content

[BUG] Panic in witness verify when policy file doesn't exist #675

@colek42

Description

@colek42

[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

  1. Build witness from source (commit ba902d8)
  2. Create an attestation:
    ./witness run --step build --signer-file-key-path test/testkey.pem --outfile /tmp/witness-test.att -- echo "test build"
  3. Attempt to verify with a non-existent policy file:
    ./witness verify --policy test/policy-signed.json -k test/testpub.pem --attestations /tmp/witness-test.att --artifactfile /Users/nkennedy/proj/witness/witness
    Note: The file test/policy-signed.json does 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:

  1. LoadPolicy is called with the policy path "test/policy-signed.json"
  2. This then calls into archivista.(*Client).Download
  3. The archivista client appears to be nil or uninitialized, causing the panic at client.go:56

Root Cause Hypothesis

The issue likely occurs because:

  1. The LoadPolicy function doesn't check if the local file exists before attempting to load it
  2. When the file doesn't exist, it may fall back to trying archivista
  3. The archivista client is not properly initialized (nil) in this fallback path
  4. There are missing nil checks before calling methods on the archivista client

Suggested Fix

The LoadPolicy function should:

  1. Check if a local file exists before attempting to load it
  2. Return a clear error message if the file doesn't exist
  3. Only fall back to archivista if the path looks like an archivista URL/reference
  4. Add proper nil checks before calling methods on the archivista client
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions