From: Markus Koschany <apo@debian.org> Date: Sun, 29 Apr 2018 21:39:35 +0200 Subject: CVE-2018-1000076 Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=895778 Origin: https://github.com/rubygems/rubygems/commit/f5042b879259b1f1ce95a0c5082622c646376693 --- lib/ruby/shared/rubygems/package.rb | 4 ++++ lib/ruby/shared/rubygems/package/tar_writer.rb | 2 ++ .../rubygems/test_gem_package_tar_output.rb | 27 ++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/lib/ruby/shared/rubygems/package.rb b/lib/ruby/shared/rubygems/package.rb index 25ac814..42b753c 100644 --- a/lib/ruby/shared/rubygems/package.rb +++ b/lib/ruby/shared/rubygems/package.rb @@ -589,6 +589,10 @@ EOM raise Gem::Package::FormatError.new \ 'package content (data.tar.gz) is missing', @gem end + + if duplicates = @files.group_by {|f| f }.select {|k,v| v.size > 1 }.map(&:first) and duplicates.any? + raise Gem::Security::Exception, "duplicate files in the package: (#{duplicates.map(&:inspect).join(', ')})" + end end ## diff --git a/lib/ruby/shared/rubygems/package/tar_writer.rb b/lib/ruby/shared/rubygems/package/tar_writer.rb index dfd6357..59bb476 100644 --- a/lib/ruby/shared/rubygems/package/tar_writer.rb +++ b/lib/ruby/shared/rubygems/package/tar_writer.rb @@ -195,6 +195,8 @@ class Gem::Package::TarWriter digest_name == signer.digest_name end + raise "no #{signer.digest_name} in #{digests.values.compact}" unless signature_digest + if signer.key then signature = signer.sign signature_digest.digest diff --git a/test/externals/ruby1.9/rubygems/test_gem_package_tar_output.rb b/test/externals/ruby1.9/rubygems/test_gem_package_tar_output.rb index ecf25ef..c8b500f 100644 --- a/test/externals/ruby1.9/rubygems/test_gem_package_tar_output.rb +++ b/test/externals/ruby1.9/rubygems/test_gem_package_tar_output.rb @@ -48,6 +48,33 @@ class TestGemPackageTarOutput < Gem::Package::TarTestCase gz.close if gz end + def test_verify_duplicate_file + FileUtils.mkdir_p 'lib' + FileUtils.touch 'lib/code.rb' + + build = Gem::Package.new @gem + build.spec = @spec + build.setup_signer + open @gem, 'wb' do |gem_io| + Gem::Package::TarWriter.new gem_io do |gem| + build.add_metadata gem + build.add_contents gem + + gem.add_file_simple 'a.sig', 0444, 0 + gem.add_file_simple 'a.sig', 0444, 0 + end + end + + package = Gem::Package.new @gem + + e = assert_raises Gem::Security::Exception do + package.verify + end + + assert_equal 'duplicate files in the package: ("a.sig")', e.message + end + + if defined? OpenSSL then def test_self_open_signed @private_key = File.expand_path('test/rubygems/private_key.pem', @@project_dir)