From 3315ce69044b511c7fe5d462985756a7948e95d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 25 Mar 2020 21:22:00 +0100 Subject: [rubygems/rubygems] Fix race condition on bundler's parallel installer When installing in parallel, bundler creates several `Gem::Installer` instances that run in parallel. These installers access the `@@all` class variable of `Gem::Specification` concurrently. If a concurrent thread calls `Gem::Specification.reset` (resetting `@all` to `nil`) while another thread is running `Gem::Specification._all` or another method that expects `@@all` to be loaded and not `nil`, that can result in `Enumerable` methods being called on `nil`, resulting in crashes. I fix it by protecting the other concurrent access to the `@all` variable. https://github.com/rubygems/rubygems/commit/58b343c530 --- lib/rubygems/installer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 241f541bb4..cb212e9ae3 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -509,7 +509,7 @@ class Gem::Installer end def generate_plugins # :nodoc: - latest = Gem::Specification.latest_spec_for(spec.name) + latest = Gem::Installer.install_lock.synchronize { Gem::Specification.latest_spec_for(spec.name) } return if latest && latest.version > spec.version ensure_writable_dir @plugins_dir -- cgit v1.2.3