GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||
GeezerVison is showing github.com — Fix hosted cargo contested lock in vex and restore (#679, #863) by mikolalysenko · Pull Request #1313 · SocketDev/socket-patch Conversation
|
| Issue | Test | Red before fix |
|---|---|---|
| #679 | socket-patch-core vex::discover::cargo::tests::crates_io_twin_of_the_hosted_crate_withholds_the_ref (crates.io and git twins; another version doesn't count) |
FAILED with the new call disabled |
| #863 | patch::redirect::upstream::cargo::tests::restore_merges_into_an_existing_crates_io_twin, restore_merge_keeps_versioned_refs_while_the_name_is_ambiguous, restore_merge_in_a_v1_lock |
all 3 FAILED (restore refused / duplicate) |
| both, real cargo | e2e_redirect_cargo_shapes::cargo_hosted_contested_by_a_later_crates_io_copy: hosted scan → fresh checkout adds crc32fast = "=1.5.0" → contested lock (2 blocks); vex doesn't attest cfg-if; remove exits 0 leaving one crates.io block; cargo build --locked --offline succeeds |
new |
CLI_CONTRACT.md: the cargo discovery row and the cargo bullet in "Hosted unwind coverage" are updated.
cargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-core --lib: 6113 passedcargo test -p socket-patch-cli --test e2e_redirect_cargo_shapes: 28 passed (cargo 1.93.1)cargo test -p socket-patch-cli --test mode_migration_cargo: 28 passede2e_vendor_cargo_build: the 2 old-toolchain legs (*_old_toolchains, *_below_1_45) fail locally. They exercise vendored wiring under old rustup toolchains, which this diff doesn't touch, so I'm leaving them to CI.🤖 Generated with Claude Code
Note
Medium Risk
Changes hosted Cargo lockfile restore and VEX attestation for duplicate name@version blocks; incorrect merge or reference respelling could break cargo build --locked or mis-attest patches.
Overview
Fixes hosted Cargo when Cargo.lock holds both a Socket sparse-index block and a separate crates.io (or git) block for the same name@version—typically after a dependency is added post-scan (#679, #863).
VEX / discovery adds unpatched_twins: any non-Socket twin of a hosted crate is recorded via unpatched_copy, so attestation is withheld (patched_ref_unattributable, “UNPATCHED”) while the pin stays shadowed so rollback / remove / list still unwind it. Upstream restore no longer rewrites the Socket block to crates.io (which duplicated blocks and broke cargo parsing); it drops the Socket [[package]] (and v1 [metadata] checksum lines), skips index lookup when the twin already has the checksum, and respells dependent references with merged_references to match what Cargo would write.
CLI_CONTRACT.md documents the contested-lock behavior for discovery and hosted unwind. Tests cover unit restore/merge paths, discovery withholding, and a new e2e shape cargo_hosted_contested_by_a_later_crates_io_copy.
Reviewed by Cursor Bugbot for commit 659fcbc. Configure here.
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
After a hosted cargo scan pins cfg-if 1.0.4, a dependency added later can lock its own crates.io cfg-if 1.0.4 beside the Socket one. Cargo cannot unify the two sources, so the build compiles the unpatched copy too. - vex: the hosted ref is withheld (patched_ref_unattributable, naming the crates.io entry) instead of attested not_affected. It stays a shadowed ref, so rollback, remove and list still unwind it (#679). - remove / rollback: the upstream restore merges the Socket block into the existing crates.io block. It drops the block (and a v1 lock's [metadata] line) and respells dependents' references the way cargo writes them. Before, it left two identical blocks that cargo refused to parse while the command reported success (#863). No index lookup is needed, so this also works offline. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
|
BugBot review |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
bugbot run Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 659fcbc. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // crates.io's source into the Socket block would leave two | ||
| // identical blocks, which cargo refuses to parse (#863). The twin | ||
| // already carries the checksum, so no registry lookup is needed. | ||
| let twin_of = |h: &LockHit| { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
🔒 Agentic Security Review
Severity: MEDIUM
Description: Hosted Cargo restore treats a contested crates.io twin as already bound and skips the sparse-index checksum rebind. twin_of matches only name, version, and source registry+https://github.com/rust-lang/crates.io-index, then those hits are filtered out of UpstreamClient::cargo_cksum (the lookup that refuses offline and returns the public index cksum). Restore deletes the Socket [[package]] block and its v1 [metadata] checksum line, respells dependents onto the surviving twin, and marks the uuid handled, so the Cargo.toml registry pin and unused [registries.socket-patch-<uuid>] block are removed. The twin checksum bytes are never read or compared. A later cargo fetch from the canonical index still fails closed when that checksum differs from the index cksum, before crate code runs. A [source.crates-io] replace-with registry or vendor directory does not consult that index: cargo accepts the .crate when its sha256 equals the lock checksum. This merge moves former Socket-sourced dependents, which were outside crates.io replacement, onto that checksum.
Impact: Rollback, remove, and vendored takeover all run this restore. A lockfile author can leave a non-index sha256 on the crates.io twin; restore now succeeds offline and publishes that sha256 as the only pin. Builds that use the real crates.io index error on the mismatch. Builds whose crates.io source is replaced or vendored, including a replacement committed next to the lockfile, run the bytes that hash to the preserved checksum (crate code and build scripts). Re-resolving cargo_cksum would have written the public-index checksum and made those divergent bytes fail closed. An honest twin produced by cargo against the real index is unchanged, because that checksum is already the index cksum.
Remediation: Still call cargo_cksum for a contested twin and refuse that pin when the lookup fails or the twin's inline or v1 metadata checksum is not exactly the sparse-index cksum, including under --offline. Only after that match, delete the Socket block, keep the twin, and mark the uuid handled.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Hosted cargo remove writes a duplicate cfg-if block into Cargo.lock when crates.io also locks the same crate@version, so cargo can no longer parse the lock while remove reports success Hosted cargo vex attests not_affected while Cargo.lock also builds an unpatched crates.io copy of the same crate@version
There was an error while loading. Please reload this page.