Fix shutdown data loss, bound untrusted metadata_size, harden Docker build#5
Merged
Conversation
…build Three fixes from the 2026-06-13 code review: - cmd/tracker: graceful shutdown only called FlushToDB(), dropping the FlushUsers() + DrainBacklog() steps the periodic flusher runs every tick, so final usage deltas and queued backlog were lost on SIGTERM (the normal Cloud Run stop signal). Now mirrors the tick, and flushes *after* srv.Shutdown() so announces served during the drain window are captured. - internal/client: FetchMetadata allocated make([]byte, MetadataSize) from a peer-supplied (untrusted) value with only a == 0 check — a memory-exhaustion DoS. Cap at 16 MiB and reject <= 0. Adds a regression test. - Dockerfile: ARG TARGETARCH had no default, so a non-BuildKit `docker build` expanded an empty arch into the litestream URL and 404'd. Default to amd64. (Includes the in-progress multi-arch curl + run.sh wait-loop changes the review validated.)
iksnerd
added a commit
that referenced
this pull request
Jun 21, 2026
Fix shutdown data loss, bound untrusted metadata_size, harden Docker build
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three confirmed findings from the 2026-06-13 code review, verified by reading the code (not just agent output).
Changes
Shutdown data loss —
cmd/tracker/main.goThe periodic flusher runs
FlushToDB()+FlushUsers()+DrainBacklog()every tick, but the SIGTERM handler called onlyFlushToDB(). On Cloud Run (SIGTERM is the normal stop signal) the final usage deltas and any queued backlog were silently dropped whenHUB_URLis configured. The flush also ran beforesrv.Shutdown(), so announces served during the 15s drain window mutated state after the final flush. Now: drain HTTP first, then mirror the full tick.Unbounded allocation from untrusted
metadata_size—internal/client/metadata.goFetchMetadatadidmake([]byte, p.MetadataSize)whereMetadataSizecomes straight from a peer's BEP-10 extended handshake, guarded only by== 0. A malicious peer advertising a huge size triggers a memory-exhaustion DoS. Now capped at 16 MiB (far larger than any real info dict) and rejects<= 0. Regression test added.ARG TARGETARCHempty under non-BuildKit —DockerfileWithout BuildKit,
TARGETARCHexpands empty →litestream-v0.3.13-linux-.tar.gz→curl -f404 → broken build on the documenteddocker buildpath. Defaults toamd64. Also folds in the in-progress multi-archcurlswitch and therun.shwait-loop change, both validated in review.Verification
go build ./...clean,go vet ./...clean,gofmtcleango test ./...— all packages pass, including the newTestFetchMetadataRejectsBadSizeNot included (tracked separately)
IPv6 peer parsing,
wire.gocap comment, constant-time admin-key compare,wl gethex-decode error, and the v2 Merkle padding question (inconclusive — needs a Transmission 4.x golden vector before touching the padding logic).🤖 Generated with Claude Code