GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Gem agent `apply` patches only the ruby-platform `x-1.0/` dir when a `x-1.0-x86_64-linux-gnu/` sibling is also installed, so Bundler loads the unpatched platform gem while `vex` attests `not_affected` · Issue #1092 · SocketDev/socket-patch

Gem agent apply patches only the ruby-platform x-1.0/ dir when a x-1.0-x86_64-linux-gnu/ sibling is also installed, so Bundler loads the unpatched platform gem while vex attests not_affected #1092

New issue
Copy link
New issue
Copy link
Closed
#1395
Closed
Gem agent apply patches only the ruby-platform x-1.0/ dir when a x-1.0-x86_64-linux-gnu/ sibling is also installed, so Bundler loads the unpatched platform gem while vex attests not_affected#1092
#1395
Copy link
Labels
agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:bundlerBundler (RubyGems)Bundler (RubyGems)priority:p2

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Oct 7, 2026
Issue body actions

[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).

Summary

A gem home can hold both the ruby-platform build and a native-platform build of the same gem version, for example ffi-1.17.2/ and ffi-1.17.2-x86_64-linux-gnu/. This happens after any gem install <x> --platform ruby, or after a project toggles force_ruby_platform. Bundler 2.6+ locks list every platform variant (ffi (1.17.2), ffi (1.17.2-x86_64-linux-gnu), …), and on x86_64 Linux Bundler loads the -x86_64-linux-gnu copy.

In agent mode the gem crawler resolves pkg:gem/[email protected] to exactly one directory, and the plain ffi-1.17.2/ dir always wins (locate_gem_dir). So apply patches only the ruby-platform copy and leaves the loaded platform copy unpatched. vex checks the same single directory and writes not_affected / inline_mitigations_already_exist. A manifest key qualified as pkg:gem/[email protected]?platform=x86_64-linux-gnu goes to the same wrong dir, because parse_gem_purl drops the qualifier.

Impact

The vulnerable code keeps running and a false VEX attestation is produced. Nothing warns. apply reports 1 of 1 targeted patch applied, and a re-run says already patched.

Repro (shared gem home, Bundler 4.0.18 / Ruby 3.3.6 and Bundler 2.6.9 / Ruby 3.1.6)

export GEM_HOME=$PWD/gh GEM_PATH=$PWD/gh
mkdir empty && (cd empty && gem install ffi -v 1.17.2 --platform ruby --no-document && gem install ffi -v 1.17.2 --no-document)
ls gh/gems            # ffi-1.17.2  ffi-1.17.2-x86_64-linux-gnu
mkdir app && cd app
printf 'source "https://rubygems.org"\ngem "ffi", "1.17.2"\n' > Gemfile
bundle install        # lock lists ffi (1.17.2) + ffi (1.17.2-<platform>) …
# hand-written agent manifest: pkg:gem/[email protected], file package/lib/ffi/version.rb
# (identical bytes in both builds), afterHash = original + "# SOCKET-PATCH-BUNDLER-MARKER", blob in .socket/blobs
socket-patch apply --offline --ecosystems gem
#   Summary: 1 of 1 targeted patch applied
grep -c MARKER $GEM_HOME/gems/ffi-1.17.2*/lib/ffi/version.rb
#   ffi-1.17.2-x86_64-linux-gnu/lib/ffi/version.rb:0
#   ffi-1.17.2/lib/ffi/version.rb:1
socket-patch vex --offline --product pkg:gem/[email protected] -O vex.json
#   VEX: not_affected
bundle exec ruby -e 'require "ffi"; s=Gem.loaded_specs["ffi"]; puts s.full_name, File.read(s.full_gem_path+"/lib/ffi/version.rb").include?("MARKER")'
#   ffi-1.17.2-x86_64-linux-gnu
#   false

A project-local shape behaves the same way: path vendor/bundle, first installed with force_ruby_platform true, then bundle lock --add-platform x86_64-linux-gnu and a platform install, so vendor/bundle/ruby/3.3.0/gems/ holds both dirs.

Expected vs actual

  • Expected (CLI_CONTRACT.md, agent rows, around lines 393 and 564): "apply/rollback patch/restore every copy", and for vex, "Every installed copy the crawler finds for the purl … must hash to the patched bytes … One unpatched copy omits the purl (not_applied / hash_mismatch)". Both platform dirs are installed copies of [email protected], so apply should patch both (or at least the one Bundler loads), and vex should refuse while either is unpatched.
  • Actual: only ffi-1.17.2/ is patched, and vex attests not_affected while ffi-1.17.2-x86_64-linux-gnu/ loads unpatched.

Matrix

OS Ruby Bundler Shape Result
Linux 3.3.6 4.0.18 vendor/bundle, force_ruby_platform toggled fails (unqualified and ?platform=x86_64-linux-gnu keys)
Linux 3.3.6 4.0.18 shared GEM_HOME, both builds from gem install fails
Linux 3.1.6 2.6.9 shared GEM_HOME, both builds from gem install fails
macOS / Windows — — — untested. The logic is OS-independent, and Windows x64-mingw-ucrt builds use the same suffix scheme

Main 05ecc6e. Published v4.0.0 also patches only ffi-1.17.2/ (its vex stops earlier with ecosystem_not_setup), so this predates v5 and isn't a recent regression.

Suspect code

  • crates/socket-patch-core/src/crawlers/ruby_crawler.rs:978-983 (locate_gem_dir): "Only one platform is installed per environment, so we return the exact dir when present". That assumption is false for shared gem homes and for toggled force_ruby_platform installs.
  • crates/socket-patch-core/src/crawlers/ruby_crawler.rs:1050-1057 (locate_gem_dir_sync, used by find_each_by_purl): same exact-dir-first rule.
  • crates/socket-patch-core/src/utils/purl.rs:279 (parse_gem_purl): the ?platform= qualifier is discarded, so a platform-qualified manifest key can't pick its dir either.
  • The unit test locate_gem_dir_prefers_exact_over_platform (ruby_crawler.rs:4173) pins the current behaviour.

No probe runs: found and confirmed on Linux only.

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agent
    pm:bundlerBundler (RubyGems)Bundler (RubyGems)
    on Oct 7, 2026
  2. mikolalysenko commented on Oct 7, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 7, 2026
    CollaboratorAuthor
    More actions

    [agent] Global mode has the same problem, without Bundler involved. On the same shared GEM_HOME (both ffi-1.17.2/ and ffi-1.17.2-x86_64-linux-gnu/ installed), socket-patch apply -g --global-prefix $GEM_HOME/gems --offline reports 1 of 1 targeted patch applied but only patches ffi-1.17.2/lib/ffi/version.rb. Plain RubyGems (ruby -e 'require "ffi"') activates ffi-1.17.2-x86_64-linux-gnu, which stays unpatched. Main 05ecc6e, Ruby 3.3.6, Linux.


    Generated by Claude Code

  3. mikolalysenko commented on Oct 7, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 7, 2026
    CollaboratorAuthor
    More actions

    [agent] Triage: priority:p1 (RubyGems/Bundler). Confirmed in code on main: locate_gem_dir (crates/socket-patch-core/src/crawlers/ruby_crawler.rs:978-981) and locate_gem_dir_sync (line 1050) still assume one platform per gem home and return the plain <name>-<version>/ dir first, and the locate_gem_dir_prefers_exact_over_platform test pins that. No open or merged PR covers it, and it isn't a duplicate. #952 is also a gem agent-crawl wrong-copy bug, but its cause is different (BUNDLE_GEMFILE moving Bundler.root), so the two aren't clustered.


    Generated by Claude Code

  4. Mikola Lysenko (mikolalysenko)
    added
    agent:triaged
    priority:p1
    on Oct 7, 2026
  5. mikolalysenko commented on Oct 8, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 8, 2026
    CollaboratorAuthor
    More actions

    [agent] Re-triage on main b96a785 (Bundler 4.0.18 / Ruby 3.3.6, shared GEM_HOME with ffi-1.17.2/ + ffi-1.17.2-x86_64-linux-gnu/): this still reproduces. The new apply --check gate from #1029 inherits it:

    socket-patch apply --offline --ecosystems gem   # 1 of 1 applied; only ffi-1.17.2/ gets the marker
    socket-patch apply --check --ecosystems gem     # "Patches are in sync (1 patch checked)."  exit 0
    bundle exec ruby -e '…'                         # ffi-1.17.2-x86_64-linux-gnu, patched=false
    

    The same happens with the key pkg:gem/[email protected]?platform=x86_64-linux-gnu. CLI_CONTRACT says that a release variant "is judged only on the copies holding its distribution", but --check judges the ruby-platform dir and reports in sync, while the loaded -x86_64-linux-gnu copy is unpatched. So a CI gate built on apply --check passes on this shape too. rollback restores the ruby dir correctly (the platform dir was never touched).


    Generated by Claude Code

  6. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 8, 2026

    bundler: run 32 ledger (#1125, #1092/#952 comments)

    efe883c
  7. Mikola Lysenko (mikolalysenko)
    added
    priority:p2
    and removed
    priority:p1
    on Oct 9, 2026
  8. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 9, 2026
    CollaboratorAuthor
    More actions

    v5 triage: P2, not a release blocker. Retain Ruby agent selection among coinstalled platform variants at P2. Default hosted/vendored lockfile behavior is the release focus.

    This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.

  9. mikolalysenko commented on Oct 11, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 11, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue (shared root cause: the gem crawler resolves a gem@version to one directory per gem home, so coinstalled platform variants like ffi-1.17.2/ + ffi-1.17.2-x86_64-linux-gnu/ are never all patched or checked). Branch: agent/fix-gem-every-platform-copy. Claim-ID: 2026-10-11T18:21:19Z-758ce1


    Generated by Claude Code

  10. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 11, 2026
  11. mikolalysenko commented on Oct 11, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 11, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft PR: #1395


    Generated by Claude Code

  12. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 11, 2026

    Patch and check every installed build of a gem

    This issue will close once commit 91668a3 is merged into the 'main' branch.
    91668a3
  13. Mikola Lysenko (mikolalysenko)
    closed this as completedin #1395on Oct 11, 2026
  14. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:bundlerBundler (RubyGems)Bundler (RubyGems)priority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.