Go apply, apply --check and vex treat a module that is only another module's replace target as built, so the patch is reported applied and attested while go builds the unpatched code
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 48/100
Rechercherichtung
Start with crates/socket-patch-core/src/vendor/go_build_list.rs, especially the selection logic around lines 90–99, then trace the callers in patch/redirect/golang_local.rs and vex/discover/golang.rs. Reproduce the reported case with a module named only as a replace target and compare apply, apply --check, and VEX results with workspace mode. Done means those paths refuse or otherwise avoid claiming the patch is active when Go builds the unpatched target.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
[agent] Found by the scheduled Go modules bug-hunt routine (ledger #317).
Summary
A common Go fork idiom is replace other.com/fork v1.0.0 => example.com/upstream v1.0.0 (or the versionless replace other.com/fork => example.com/upstream v1.0.0). go downloads example.com/[email protected] into the module cache and records its zip and /go.mod lines in go.sum under the target's path, but example.com/upstream is not a module of the build: go list -m all shows only other.com/fork v1.0.0 => example.com/upstream v1.0.0. go doesn't chain replaces, so a replace of example.com/upstream is ignored.
In module mode (no go.work), with a patch for pkg:golang/example.com/[email protected], socket-patch:
applywritesreplace example.com/upstream v1.0.0 => ./.socket/go-patches/example.com/[email protected]and exits 0 ("1 of 1 targeted patch applied"),apply --checksays "Patches are in sync" (exit 0),vexemitsnot_affected/inline_mitigations_already_exist(exit 0),
while go run / go build -mod=readonly link the unpatched code.
Impact
A false VEX attestation for a vulnerable dependency, and a green apply --check in CI. Replacing a module with a fork is common (abandoned upstreams, security forks), and the fork's code is exactly what Socket would patch.
Repro (Linux, go 1.24.7, hermetic file GOPROXY serving example.com/upstream v1.0.0 whose lib.go returns "PRISTINE"; hand-staged .socket/manifest.json + blob that makes it return "PATCHED", as in e2e_golang_build.rs)
mkdir app && cd app
cat > go.mod <<'EOF'
module example.com/app
go 1.21
require other.com/fork v1.0.0
replace other.com/fork v1.0.0 => example.com/upstream v1.0.0
EOF
cat > main.go <<'EOF'
package main
import (
"fmt"
u "other.com/fork"
)
func main() { fmt.Println("app:", u.Greeting()) }
EOF
go mod tidy # go.sum: example.com/upstream v1.0.0 h1:… and /go.mod h1:…
# stage .socket/manifest.json + blob for pkg:golang/example.com/[email protected]
socket-patch apply --offline --ecosystems golang # exit 0, 1 of 1 applied; go.mod gains the replace
go list -m all # example.com/app / other.com/fork v1.0.0 => example.com/upstream v1.0.0
GOFLAGS=-mod=readonly go run . # app: PRISTINE
socket-patch apply --check --ecosystems golang # exit 0, "Patches are in sync"
socket-patch vex --product pkg:golang/example.com/app # status not_affected, exit 0
Expected vs actual
docs/ecosystems.md, "Go: directory replaces and go.sum": "A replace names an exact module version, so it only works while the build selects that version. socket-patch reads which version that is from go.mod and go.sum … the require line in a go 1.17+ module … apply and scan --mode hosted refuse to write a replace for any other version." Here no require names example.com/upstream at all. Expected: apply refuses (as it does with "is not in this project's build graph … nothing written" when there's no zip line), apply --check fails, and vex leaves the patch out. Alternatively, patch it through the replace that actually selects the code (other.com/fork v1.0.0 => ./.socket/go-patches/…). Actual: all three report success while the build is unpatched. CLI_CONTRACT: vex must not attest a patch that isn't in effect.
Workspace mode is correct: the same module as a go.work member (apply from the member or the root) refuses with "not in this project's build graph", because GoWorkspace::selection walks the module graph.
OS × version
| OS | go | go directive | replace form | main ecd4924 |
v5.0.1 |
|---|---|---|---|---|---|
| Linux | 1.21.13 | 1.21 | versioned | fail | — |
| Linux | 1.24.7 | 1.16 | versioned / versionless | fail / fail | — |
| Linux | 1.24.7 | 1.21 | versioned / versionless | fail / fail | fail |
| Linux | 1.26.8 | 1.21 | versioned | fail | — |
| Linux | 1.24.7 | go.work member | versioned | refuses (correct) | — |
| macOS / Windows | — | — | — | untested (no probe branch this run) | — |
Untested: vendored (vendor uses the same selection_refusal) and hosted (patch/redirect/mod.rs:9633 calls the same go_build_list::select), which probably behave the same.
First bad release
Not a recent regression: v5.0.1 shows it too.
Suspect code
crates/socket-patch-core/src/vendor/go_build_list.rs:90: in a pruned (go 1.17+) graph,None if zips.contains(&version) => Selection::Selected. And:94-99for go < 1.17: a go.sum zip line counts as evidence that the module is built. A zip line also appears for a version that is only a replace target, under the target's path. The selection should ignore go.sum lines for a module/version that go.mod names only on the right-hand side of areplace(or, as workspace mode does, walk the graph).- Callers:
patch/redirect/golang_local.rs:669(selection_refusal, used by apply and vendor),vex/discover/golang.rs:300,patch/redirect/mod.rs:9633(hosted). - Open PR #1698 mentions "unused replacements" in its audits; I couldn't tell whether it covers this shape.
- Vorherrschende Sprache
- Rust
- Sterne
- 8
- Forks
- 2
- Ø Merge
- 19 Std. 31 Min.
- Gemergte PRs (30 T.)
- 686
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus SocketDev/socket-patch
-
bug bughunt pm:npm
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 53/100
SocketDev/socket-patch#1827 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Vendored gem mode writes the rewired `gem` line of a CRLF Gemfile with an LF ending, leaving the Gemfile with mixed line endingsEvtl. vergeben @mikolalysenko hat das heute übernommen. Offenagent:claimed agent:triaged bug bughunt pm:bundler priority:p1
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 25/100
SocketDev/socket-patch#1821 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
CI perf: workflow_dispatch of CI — Windows-only janitor fixes re-run the full Linux + macOS nightly matrix (~100 min/day, ~30 macOS)Evtl. vergeben @mikolalysenko hat das heute übernommen. Offenagent:claimed agent:triaged ci-perf priority:p3
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 1/100
SocketDev/socket-patch#1818 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Nightly Windows: 3 Go workspace unit tests fail (Unix-only GOWORK paths)Evtl. vergeben @mikolalysenko hat das heute übernommen. Offenagent:claimed agent:triaged ci-janitor priority:p3
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 35/100
SocketDev/socket-patch#1815 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Go apply writes the shared replace into ./go.work when GOWORK names another file in the same directory, reports success, and the workspace builds unpatchedEvtl. vergeben @mikolalysenko hat das heute übernommen. Offenagent:claimed agent:triaged bug bughunt pm:go priority:p2
Schwierigkeit 4/5 1-2 Tage Anfängerfreundlichkeit 35/100
SocketDev/socket-patch#1810 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in SocketDev/socket-patch
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag
-
memory_patch_page drops the `#` of headings like `## Notes on C#`Evtl. vergeben @viniciusdsandrade hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
akitaonrails/ai-memory#1859 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
wealthfolio/wealthfolio#2376 ·
Maintainer antworten meist innerhalb von 1 Tag
-
kind/bug kind/security
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
spiceai/spiceai#15826 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
area:cli bug dotnet good first issue priority:medium
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
rtk-ai/rtk#4844 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag