Monorepo for Tangled tangled.org

knot2 misclassifies upload-pack v2 requests that put object-format before command= #774

Open mads.havmand.eu
Open opened by mads.havmand.eu
assigned to oyster.cafe

Summary #

knot2's upload-pack request classifier treats a request as protocol v2 only when the first pkt-line starts with command=. Clients that send object-format=sha256 before the command line (Google's Go module proxy fetch worker does this, running git/2.30.2) get a v0-style response to their negotiated v2 fetch.

Symptom #

fatal: fetch-pack: protocol error: bad band #78
fatal: remote-curl: bad line length character: PACK

The server sends 0008NAK followed by a raw pack. A v2 client with sideband-all reads the N of NAK as a sideband byte (0x4e = 78), and the raw pack bytes land where a pkt-line header belongs.

Reproduction #

Send a fetch request whose first pkt-line is object-format=sha256, followed by command=fetch, with sideband-all and done. The response starts with 0008NAK and raw pack bytes instead of 000e\x01packfile band framing. The same request with command=fetch first gets a fully valid v2 response.

Observed live: go get go.daevix.com/daevix/cmd/dvx@<version> through the default GOPROXY chain failed with the error above because the Go module proxy's fetch worker performs the fetch. Fetches with GOPRIVATE set (which bypass the proxy) and direct git clones all passed, because those clients send command= first.

Impact #

Every fetch by the Go module proxy's worker against a sha256 knot fails, which poisons the module's sum.golang.org record and breaks go get for all users of the vanity import path.

Fix #

Scan the request for the command= line wherever it appears, and dispatch on the found line. Proposed in the branch upload-pack-v2-detect with a regression test reproducing the worker's exact request shape.

Note #

Together with the shallow-boundary fix (#2262, root cause of #769), this fixes the go vanity URL go get failures end to end: the shallow bug broke GOPROXY=direct fetches of tagged versions, and this bug broke every proxied fetch. Both surfaced as the same bad band #78 error, which made diagnosis slow.

Sign up or Sign in to add to the discussion.