Hosted cargo scan in a `cargo vendor` project reports success but breaks every fresh `cargo build --frozen --offline`, and VEX then omits the patch
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 55/100
Hướng nghiên cứu
Start with crates/socket-patch-core/src/patch/redirect/mod.rs:1062 (rewrite_cargo) and crates/socket-patch-core/src/crawlers/cargo_crawler.rs:144 (get_crate_source_paths). Run the wiremock scenario in crates/socket-patch-cli/tests/e2e_redirect_cargo_shapes.rs, then verify that hosted scans handle directory source replacement without breaking fresh offline builds and that VEX hashes the copy Cargo uses.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
[agent] Found by the scheduled Cargo bug-hunt routine (ledger #315).
Summary
Take a project that builds from a committed cargo vendor tree: vendor/ plus .cargo/config.toml with [source.crates-io] replace-with = "vendored-sources" / [source.vendored-sources] directory = "vendor". Run socket-patch scan --mode hosted on it. The redirect goes through as if the project fetched from crates.io:
Cargo.tomlgetscfg-if = { version = "1.0.4", registry = "socket-patch-<uuid>" },.cargo/config.tomlgets[registries.socket-patch-<uuid>] index = "sparse+…"appended after the existing source replacement,Cargo.lockgets the per-patch sparsesourceand checksum,- the scan exits 0 with
redirected: 1andwarnings: [].
Nothing puts the patched crate into the directory source, and nothing replaces the new registry with it. vendor/cfg-if stays the stale, unpatched crates.io copy that nothing references any more. So the build this project is set up for, cargo build --frozen --offline from a fresh checkout, fails:
error: no matching package named `cfg-if` found
location searched: `socket-patch-c1f90104-5a0c-4e7a-9c0d-1a2b3c4d5e01` index
required by package `consumer v0.1.0 (…)`
note: offline mode (via `--frozen`) can sometimes cause surprising resolution failures
The only way to get it building again is to re-run cargo vendor with network access and hand-merge the [source."sparse+…"] replace-with = "vendored-sources" snippet it prints into .cargo/config.toml. socket-patch says nothing about this.
There's a second symptom. A fresh checkout that does build online (cargo fetch --locked, then build --locked --offline) links the patched crate from the per-patch registry. But vex on it prints omitting pkg:cargo/[email protected] from VEX: the patched files still hold the original content (not_applied) and exits 1 with "No applied patches with vulnerability metadata to attest". The crawler hashes vendor/cfg-if, a copy the build no longer uses. That's the same hard-coded vendor/ lookup as #338, here as a false negative in hosted mode.
Impact
cargo vendoris how offline, air-gapped and reproducible builds are usually done, and every CI build of such a repo uses--frozen/--offline. After a "successful" hosted scan, every fresh checkout of the project fails to build, and the failure points at a socket-patch registry rather than at what needs doing.- When the project does build online, VEX won't attest a patch that's actually linked.
- Fails closed (nothing unpatched is attested), so this isn't a silent false fix. It's a broken build after a scan that reported success.
Repro
This uses the wiremock sparse-registry harness in crates/socket-patch-cli/tests/e2e_redirect_cargo_shapes.rs (local change, not committed). The baseline is the standard consumer_manifest("cfg-if = \"1.0.4\"\n") shape. After the baseline lock and build, and before the scan, the shape runs:
cargo vendor -q --locked vendor
mkdir -p .cargo && printf '[source.crates-io]\nreplace-with = "vendored-sources"\n\n[source.vendored-sources]\ndirectory = "vendor"\n' > .cargo/config.toml
cargo build -q --frozen --offline # baseline: OK
Then the harness's usual chain runs, with one extra step after the scan: copy the committed files into a fresh dir with an empty CARGO_HOME, then build.
socket-patch scan --mode hosted --json --yes … -> exit 0, redirected 1, warnings []
fresh: cargo build --frozen --offline -> error: no matching package named `cfg-if` found (socket-patch-… index)
fresh: cargo fetch --locked && cargo build --locked --offline
-> OK, links cfg_if::socket_patched()
fresh: socket-patch vex --product pkg:cargo/[email protected] …
-> "omitting pkg:cargo/[email protected] … (not_applied)", exit 1
# manual recovery:
fresh: cargo vendor --locked vendor (prints [source."sparse+http://…/index/"] replace-with = "vendored-sources")
+ merge that snippet into .cargo/config.toml
fresh: cargo build --frozen --offline -> OK; vendor/cfg-if now patched; vex attests
It reproduced 3 of 3 times on Linux.
Expected vs actual
- Expected: docs/ecosystems.md (Cargo row) describes hosted mode as redirecting direct crates.io dependencies, with refusals for shapes where the redirect can't work (transitive dependents, lockless projects with other dependencies). It doesn't mention source replacement. A project whose crates.io source is replaced by a directory source can't build a per-patch registry crate offline. So hosted mode should either refuse loudly with nothing written (vendored mode already refuses a
cargo vendortree, withalready_vendored_in_tree), or finish the job: vendor the patched.crateinto the directory source and add the[source."sparse+…"] replace-withentry. At a minimum it should warn thatcargo vendormust be re-run. Separately,vexshould hash the copy cargo builds (see #338). - Actual:
success,redirected: 1, no warning. Every--frozen/--offlinebuild of a fresh checkout breaks, and VEX reportsnot_appliedfor a patch that is linked.
Matrix
| OS | cargo | Lock | fresh --frozen --offline build |
online fresh build | vex |
|---|---|---|---|---|---|
| Linux | 1.93.1 (repo toolchain) | v4 | fail (2/2) | pass | not_applied |
| Linux | 1.97.0 (stable) | v4 | fail | pass | not_applied |
| macOS / Windows | — | — | not probed. Cargo's source-replacement semantics and the rewriter are platform-independent |
Control: the same shape without vendor/ and the source replacement passes the whole chain (repo test cargo_hosted_legacy_config_is_restored_byte_for_byte and siblings, all green on 2463257).
Not bisected. Present on main 2463257 (#277).
Suspect code
crates/socket-patch-core/src/patch/redirect/mod.rs:1062(rewrite_cargo): plans the manifest, lock and[registries]edits without looking at[source.crates-io] replace-with/[source.*] directoryin the project's.cargo/config*.crates/socket-patch-core/src/crawlers/cargo_crawler.rs:144(get_crate_source_paths): returns<cwd>/vendorwhenever it exists, sovexhashes the stale vendored copy instead of the per-patch registry copy cargo builds (same root cause as #338, shape 3).
- Ngôn ngữ chính
- Rust
- Star
- 8
- Fork
- 0
- Merge trung bình
- 22 giờ 30 phút
- Pull request đã merge (30 ngày)
- 329
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của SocketDev/socket-patch
-
agent:triaged bug bughunt pm:pipenv priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
SocketDev/socket-patch#1219 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:npm priority:p2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
SocketDev/socket-patch#1127 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:bundler priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
SocketDev/socket-patch#1125 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:npm priority:p3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
SocketDev/socket-patch#1072 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged arch-audit bug priority:p3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
SocketDev/socket-patch#1062 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của SocketDev/socket-patch
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 75/100
element-hq/lk-jwt-service#248 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
pact-foundation/pact-cli#154 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
antithesishq/bombadil#361 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
test(executor_l0): assert execute() TaskOutcome, not only bus events / 断言 execute() 返回的 TaskOutcomeĐang mởtype:debt
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
skaiy/wild_agentos#425 ·
Maintainer thường phản hồi trong vòng 1 ngày