transparency-dev / transparency-dev/tesseract
cmd/fsck: `--ui=false` Exits 0 on Corrupted Logs
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 37
- Forks
- 18
- Avg merge
- 19h 22m
- Merged PRs (30d)
- 15
Description
[discovered w/ the help of Claude]
Problem
fsck --ui=false always exits 0 even on corruption, discarding errors before they reach $?. In 2 of 3 failure modes, no diagnostic is printed, making --ui=false unusable as an automated CI/pipeline gate.
Impact Matrix (Fault Injection on Static-CT Log)
| Corruption Type | Detected Internally | Output Diagnostic | Exit Code |
|---|---|---|---|
Bit flip (tile/0/042) |
Yes (hash mismatch) | None | 0 |
Truncation (tile/data/042) |
Yes (bundle parse error) | None | 0 |
Missing issuer (issuer/<hex>) |
Yes (fetch failure) | WARN only |
0 |
Underlying detection logic in tessera/fsck is sound; only cmd/fsck error reporting fails.
Root Causes
- Early Return Bypasses
eg.Wait()(main.go:92–101):
f.Checkcompletion invokes deferredcancel(), closingctx.Done(). The non-TUI loop executescase <-ctx.Done(): return, exitingmaindirectly and skippingeg.Wait(),os.Exit(1), andslog.Info("OK"). - Disconnected Issuer Status:
Successfully fsck'd log(tessera/fsck/fsck.go:167) reflects tree verification only, omitting concurrentcheckIssuersTaskstatus. - LIFO Defer Prematurely Cancels Context (
main.go:76–81):
defer cancel()runs beforedefer lsc.Close(), cancelingctxwhile issuer workers may still be drainingissuersToCheck, potentially truncating checks on large logs or causing spurious HTTPcontext cancelederrors. - Regression test: No test currently invokes the cmd/fsck binary — all existing fsck coverage calls Check() directly and inspects the returned error, which is why this went unnoticed. Add a test that execs the built binary against a corrupted fixture with --ui=false and asserts a non-zero exit.
Minimal Reproduction
go build -o /tmp/fsck-ct ./cmd/fsck
# Corrupt single byte in a mirrored log tile:
cp -r /path/to/log /tmp/broken
printf '\x01' | dd of=/tmp/broken/tile/0/042 bs=1 seek=100 conv=notrunc
# Run without TUI:
/tmp/fsck-ct --monitoring_url=file:///tmp/broken \
--origin=<origin> --public_key=<key> --ui=false
echo $? # Returns 0 with no error diagnostics (BUG)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with cmd/fsck/main.go:76–101 and tessera/fsck/fsck.go:167, then build ./cmd/fsck and reproduce the corrupted-log case with --ui=false. Add a test that executes the fsck binary against a corrupted fixture and verifies diagnostics plus a non-zero exit; done also requires issuer checks to be included without premature cancellation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100