From 20f2fa55d96933740d0020e132836d2962ee80dd Mon Sep 17 00:00:00 2001 From: Loic Nageleisen Date: Wed, 13 Nov 2024 12:27:39 +0100 Subject: [PATCH] Deny `rubygems-update` injection `rubygems-update` `setup.rb` re-execs itself when `RUBYOPT` is detected, which causes endless looping because injection adds it back immediately. See: https://github.com/rubygems/rubygems/blob/90c90addee4bda3130cf44f1321eebf162367d1b/setup.rb#L13-L20 Coverage is twofold: - Deny on `--disable-gems`: gems are required for ruby injector - Deny on `setup.rb`: This may be wide-catching but we don't want to instrument any of them anyway. --- lib-injection/requirements.json | 34 +++++++++++++++++++++++++++++++++ lib-injection/requirements.rb | 25 ++++++++++++++++++++++++ lib-injection/test_block.json | 8 ++++++++ 3 files changed, 67 insertions(+) diff --git a/lib-injection/requirements.json b/lib-injection/requirements.json index 1fe425d0fd0..c753ec54b45 100644 --- a/lib-injection/requirements.json +++ b/lib-injection/requirements.json @@ -47,6 +47,40 @@ ], "envars": null }, + { + "id": "ruby_disable_gems", + "description": "Rubygems is required for injection to function", + "os": null, + "cmds": [ + "**/ruby" + ], + "args": [ + { + "args": [ + "--disable-gems" + ], + "position": null + } + ], + "envars": null + }, + { + "id": "gem_update_system", + "description": "Ignore the rubygems update setup.rb", + "os": null, + "cmds": [ + "**/ruby" + ], + "args": [ + { + "args": [ + "setup.rb" + ], + "position": null + } + ], + "envars": null + }, { "id": "bundle_install", "description": "Ignore bundle install", diff --git a/lib-injection/requirements.rb b/lib-injection/requirements.rb index d5c3bdc6301..e63e05b736f 100755 --- a/lib-injection/requirements.rb +++ b/lib-injection/requirements.rb @@ -50,6 +50,31 @@ def requirements 'envars' => nil, } + reqs['deny'] << { + 'id' => 'ruby_disable_gems', + 'description' => 'Rubygems is required for injection to function', + 'os' => nil, + 'cmds' => [ + '**/ruby' + ], + 'args' => [{ 'args' => ['--disable-gems'], 'position' => nil }], + 'envars' => nil, + } + + # Prevent endless reexecution when RUBYOPTS is forcefully set + # Command: {"Path":"/usr/local/bin/ruby","Args":["/usr/local/bin/ruby","--disable-gems","setup.rb","--no-document","--previous-version","3.3.26"]} + # See: https://github.com/rubygems/rubygems/blob/90c90addee4bda3130cf44f1321eebf162367d1b/setup.rb#L13-L20 + reqs['deny'] << { + 'id' => 'gem_update_system', + 'description' => 'Ignore the rubygems update setup.rb', + 'os' => nil, + 'cmds' => [ + '**/ruby' + ], + 'args' => [{ 'args' => ['setup.rb'], 'position' => nil }], + 'envars' => nil, + } + # `bundle exec` is the only command we want to inject into. # there is no `allow` overriding `deny` so we're left to exclude all of the # possible others. diff --git a/lib-injection/test_block.json b/lib-injection/test_block.json index f45a728813f..a39fd80efd3 100644 --- a/lib-injection/test_block.json +++ b/lib-injection/test_block.json @@ -13,6 +13,14 @@ {"name": "❌ gem", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "/path/to/gem" ], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, {"name": "❌ gem install", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "/path/to/gem", "install" ], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + {"name": "❌ ruby disable gems", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "--disable-gems"], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + {"name": "❌ ruby disable gems", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "-w", "--disable-gems"], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + {"name": "❌ ruby disable gems", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "-w", "-w", "--disable-gems"], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + {"name": "❌ ruby disable gems", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "-w", "-w", "-w", "--disable-gems"], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + {"name": "❌ ruby disable gems", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "-w", "-w", "-w", "-w", "--disable-gems"], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + + {"name": "❌ ruby rubygems-update setup.rb", "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "--disable-gems", "setup.rb", "--no-document", "--previous-version", "3.3.26"], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, + {"name": "❌ bundle" , "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "/path/to/bundle", "install" ], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, {"name": "❌ bundle" , "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "/path/to/bundle", "_2.4.0_", "install" ], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}}, {"name": "❌ bundle" , "filepath": "/path/to/ruby", "args": ["/path/to/ruby", "/path/to/bundle", "--verbose", "install" ], "envars": [], "host": {"os": "linux", "arch": "x64", "libc": "glibc:2.40"}},