[rubygems/rubygems] Fix another race condition

We also need to protect prior removal of the binstub, otherwise it can
happen that:

* Process A removes prior binstub FOO.
* Process B removes prior binstub FOO (does nothing actually because Process A already removed it).
* Process A writes binstub FOO for gem BAR from the beginning of file.
* Process B writes binstub FOO for gem BAZ from the beginning of file.

Similarly as before, if binstub FOO for gem BAR is bigger that binstub
FOO for gem BAZ, garbage bytes will be left around at the end of the
file, corrupting the binstub.

The solution is to also protect removal of the previous binstub. To do
this, we use a file lock on an explicit `.lock` file.

https://github.com/rubygems/rubygems/commit/d99a80e62d
This commit is contained in:
David Rodríguez 2024-07-03 13:26:21 +02:00 коммит произвёл Hiroshi SHIBATA
Родитель d90a930ede
Коммит e4825a5194
1 изменённых файлов: 7 добавлений и 5 удалений

Просмотреть файл

@ -538,12 +538,14 @@ class Gem::Installer
def generate_bin_script(filename, bindir) def generate_bin_script(filename, bindir)
bin_script_path = File.join bindir, formatted_program_filename(filename) bin_script_path = File.join bindir, formatted_program_filename(filename)
require "fileutils" Gem.open_file_with_flock("#{bin_script_path}.lock") do
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers require "fileutils"
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
Gem.open_file_with_flock(bin_script_path) do |file| File.open(bin_script_path, "wb", 0o755) do |file|
file.write app_script_text(filename) file.write app_script_text(filename)
file.chmod(options[:prog_mode] || 0o755) file.chmod(options[:prog_mode] || 0o755)
end
end end
verbose bin_script_path verbose bin_script_path