!34 fix CVE-2021-31799 CVE-2021-31810 CVE-2021-32066
From: @tong_1001 Reviewed-by: @small_leek Signed-off-by: @small_leek
This commit is contained in:
commit
c8f9599e54
51
backport-CVE-2021-31799.patch
Normal file
51
backport-CVE-2021-31799.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From a7f5d6ab88632b3b482fe10611382ff73d14eed7 Mon Sep 17 00:00:00 2001
|
||||
From: aycabta <aycabta@gmail.com>
|
||||
Date: Sun, 2 May 2021 20:52:23 +0900
|
||||
Subject: [PATCH] Use File.open to fix the OS Command Injection vulnerability
|
||||
in CVE-2021-31799
|
||||
|
||||
Reference:https://github.com/ruby/rdoc/commit/a7f5d6ab88632b3b482fe10611382ff73d14eed7
|
||||
---
|
||||
lib/rdoc/rdoc.rb | 2 +-
|
||||
test/rdoc/test_rdoc_rdoc.rb | 12 ++++++++++++
|
||||
2 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
|
||||
index 68775c8..0095eb7 100644
|
||||
--- a/lib/rdoc/rdoc.rb
|
||||
+++ b/lib/rdoc/rdoc.rb
|
||||
@@ -433,7 +433,7 @@ The internal error was:
|
||||
files.reject do |file|
|
||||
file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or
|
||||
(file =~ /tags$/i and
|
||||
- open(file, 'rb') { |io|
|
||||
+ File.open(file, 'rb') { |io|
|
||||
io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/
|
||||
})
|
||||
end
|
||||
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
|
||||
index bd47943..07541df 100644
|
||||
--- a/test/rdoc/test_rdoc_rdoc.rb
|
||||
+++ b/test/rdoc/test_rdoc_rdoc.rb
|
||||
@@ -366,6 +366,18 @@ class TestRDocRDoc < RDoc::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
+ def test_remove_unparseable_CVE_2021_31799
|
||||
+ temp_dir do
|
||||
+ file_list = ['| touch evil.txt && echo tags']
|
||||
+ file_list.each do |f|
|
||||
+ FileUtils.touch f
|
||||
+ end
|
||||
+
|
||||
+ assert_equal file_list, @rdoc.remove_unparseable(file_list)
|
||||
+ assert_equal file_list, Dir.children('.')
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
def test_setup_output_dir
|
||||
Dir.mktmpdir {|d|
|
||||
path = File.join d, 'testdir'
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
248
backport-CVE-2021-31810.patch
Normal file
248
backport-CVE-2021-31810.patch
Normal file
@ -0,0 +1,248 @@
|
||||
From 5709ece67cf57a94655e34532f8a7899b28d496a Mon Sep 17 00:00:00 2001l/pkcs5.
|
||||
From: Shugo Maeda <shugo@ruby-lang.org>
|
||||
Date: Wed, 7 Jul 2021 16:00:45 +0900/pkey.rb
|
||||
Subject: [PATCH] This fixes CVE-2021-31810. Reported by Alexandr Savca inssl.rb
|
||||
<https://hackerone.com/reports/1145454>./x509.rb
|
||||
|
||||
Reference:https://github.com/ruby/net-ftp/commit/5709ece67cf57a94655e34532f8a7899b28d496a
|
||||
---
|
||||
lib/net/ftp.rb | 15 ++++-
|
||||
test/net/ftp/test_ftp.rb | 159 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 170 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
|
||||
index 9902f9d..cd446b4 100644
|
||||
--- a/lib/net/ftp.rb
|
||||
+++ b/lib/net/ftp.rb
|
||||
@@ -97,6 +97,10 @@ module Net
|
||||
# When +true+, the connection is in passive mode. Default: +true+.
|
||||
attr_accessor :passive
|
||||
|
||||
+ # When +true+, use the IP address in PASV responses. Otherwise, it uses
|
||||
+ # the same IP address for the control connection. Default: +false+.
|
||||
+ attr_accessor :use_pasv_ip
|
||||
+
|
||||
# When +true+, all traffic to and from the server is written
|
||||
# to +$stdout+. Default: +false+.
|
||||
attr_accessor :debug_mode
|
||||
@@ -205,6 +209,9 @@ module Net
|
||||
# handshake.
|
||||
# See Net::FTP#ssl_handshake_timeout for
|
||||
# details. Default: +nil+.
|
||||
+ # use_pasv_ip:: When +true+, use the IP address in PASV responses.
|
||||
+ # Otherwise, it uses the same IP address for the control
|
||||
+ # connection. Default: +false+.
|
||||
# debug_mode:: When +true+, all traffic to and from the server is
|
||||
# written to +$stdout+. Default: +false+.
|
||||
#
|
||||
@@ -265,6 +272,7 @@ module Net
|
||||
@open_timeout = options[:open_timeout]
|
||||
@ssl_handshake_timeout = options[:ssl_handshake_timeout]
|
||||
@read_timeout = options[:read_timeout] || 60
|
||||
+ @use_pasv_ip = options[:use_pasv_ip] || false
|
||||
if host
|
||||
connect(host, options[:port] || FTP_PORT)
|
||||
if options[:username]
|
||||
@@ -1330,7 +1338,12 @@ module Net
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
if m = /\((?<host>\d+(,\d+){3}),(?<port>\d+,\d+)\)/.match(resp)
|
||||
- return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
|
||||
+ if @use_pasv_ip
|
||||
+ host = parse_pasv_ipv4_host(m["host"])
|
||||
+ else
|
||||
+ host = @bare_sock.remote_address.ip_address
|
||||
+ end
|
||||
+ return host, parse_pasv_port(m["port"])
|
||||
else
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb
|
||||
index 8e0a688..52fb3a9 100644
|
||||
--- a/test/net/ftp/test_ftp.rb
|
||||
+++ b/test/net/ftp/test_ftp.rb
|
||||
@@ -61,7 +61,7 @@ class FTPTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_parse227
|
||||
- ftp = Net::FTP.new
|
||||
+ ftp = Net::FTP.new(nil, use_pasv_ip: true)
|
||||
host, port = ftp.send(:parse227, "227 Entering Passive Mode (192,168,0,1,12,34)")
|
||||
assert_equal("192.168.0.1", host)
|
||||
assert_equal(3106, port)
|
||||
@@ -80,6 +80,14 @@ class FTPTest < Test::Unit::TestCase
|
||||
assert_raise(Net::FTPProtoError) do
|
||||
ftp.send(:parse227, "227 ) foo bar (")
|
||||
end
|
||||
+
|
||||
+ ftp = Net::FTP.new
|
||||
+ sock = OpenStruct.new
|
||||
+ sock.remote_address = OpenStruct.new
|
||||
+ sock.remote_address.ip_address = "10.0.0.1"
|
||||
+ ftp.instance_variable_set(:@bare_sock, sock)
|
||||
+ host, port = ftp.send(:parse227, "227 Entering Passive Mode (192,168,0,1,12,34)")
|
||||
+ assert_equal("10.0.0.1", host)
|
||||
end
|
||||
|
||||
def test_parse228
|
||||
@@ -2360,10 +2368,155 @@ EOF
|
||||
end
|
||||
end
|
||||
|
||||
+ def test_ignore_pasv_ip
|
||||
+ commands = []
|
||||
+ binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
|
||||
+ server = create_ftp_server(nil, "127.0.0.1") { |sock|
|
||||
+ sock.print("220 (test_ftp).\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("331 Please specify the password.\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("230 Login successful.\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("200 Switching to Binary mode.\r\n")
|
||||
+ line = sock.gets
|
||||
+ commands.push(line)
|
||||
+ data_server = TCPServer.new("127.0.0.1", 0)
|
||||
+ port = data_server.local_address.ip_port
|
||||
+ sock.printf("227 Entering Passive Mode (999,0,0,1,%s).\r\n",
|
||||
+ port.divmod(256).join(","))
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("150 Opening BINARY mode data connection for foo (#{binary_data.size} bytes)\r\n")
|
||||
+ conn = data_server.accept
|
||||
+ binary_data.scan(/.{1,1024}/nm) do |s|
|
||||
+ conn.print(s)
|
||||
+ end
|
||||
+ conn.shutdown(Socket::SHUT_WR)
|
||||
+ conn.read
|
||||
+ conn.close
|
||||
+ data_server.close
|
||||
+ sock.print("226 Transfer complete.\r\n")
|
||||
+ }
|
||||
+ begin
|
||||
+ begin
|
||||
+ ftp = Net::FTP.new
|
||||
+ ftp.passive = true
|
||||
+ ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
|
||||
+ ftp.connect("127.0.0.1", server.port)
|
||||
+ ftp.login
|
||||
+ assert_match(/\AUSER /, commands.shift)
|
||||
+ assert_match(/\APASS /, commands.shift)
|
||||
+ assert_equal("TYPE I\r\n", commands.shift)
|
||||
+ buf = ftp.getbinaryfile("foo", nil)
|
||||
+ assert_equal(binary_data, buf)
|
||||
+ assert_equal(Encoding::ASCII_8BIT, buf.encoding)
|
||||
+ assert_equal("PASV\r\n", commands.shift)
|
||||
+ assert_equal("RETR foo\r\n", commands.shift)
|
||||
+ assert_equal(nil, commands.shift)
|
||||
+ ensure
|
||||
+ ftp.close if ftp
|
||||
+ end
|
||||
+ ensure
|
||||
+ server.close
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+ def test_use_pasv_ip
|
||||
+ commands = []
|
||||
+ binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
|
||||
+ server = create_ftp_server(nil, "127.0.0.1") { |sock|
|
||||
+ sock.print("220 (test_ftp).\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("331 Please specify the password.\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("230 Login successful.\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("200 Switching to Binary mode.\r\n")
|
||||
+ line = sock.gets
|
||||
+ commands.push(line)
|
||||
+ data_server = TCPServer.new("127.0.0.1", 0)
|
||||
+ port = data_server.local_address.ip_port
|
||||
+ sock.printf("227 Entering Passive Mode (127,0,0,1,%s).\r\n",
|
||||
+ port.divmod(256).join(","))
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("150 Opening BINARY mode data connection for foo (#{binary_data.size} bytes)\r\n")
|
||||
+ conn = data_server.accept
|
||||
+ binary_data.scan(/.{1,1024}/nm) do |s|
|
||||
+ conn.print(s)
|
||||
+ end
|
||||
+ conn.shutdown(Socket::SHUT_WR)
|
||||
+ conn.read
|
||||
+ conn.close
|
||||
+ data_server.close
|
||||
+ sock.print("226 Transfer complete.\r\n")
|
||||
+ }
|
||||
+ begin
|
||||
+ begin
|
||||
+ ftp = Net::FTP.new
|
||||
+ ftp.passive = true
|
||||
+ ftp.use_pasv_ip = true
|
||||
+ ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
|
||||
+ ftp.connect("127.0.0.1", server.port)
|
||||
+ ftp.login
|
||||
+ assert_match(/\AUSER /, commands.shift)
|
||||
+ assert_match(/\APASS /, commands.shift)
|
||||
+ assert_equal("TYPE I\r\n", commands.shift)
|
||||
+ buf = ftp.getbinaryfile("foo", nil)
|
||||
+ assert_equal(binary_data, buf)
|
||||
+ assert_equal(Encoding::ASCII_8BIT, buf.encoding)
|
||||
+ assert_equal("PASV\r\n", commands.shift)
|
||||
+ assert_equal("RETR foo\r\n", commands.shift)
|
||||
+ assert_equal(nil, commands.shift)
|
||||
+ ensure
|
||||
+ ftp.close if ftp
|
||||
+ end
|
||||
+ ensure
|
||||
+ server.close
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+ def test_use_pasv_invalid_ip
|
||||
+ commands = []
|
||||
+ binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
|
||||
+ server = create_ftp_server(nil, "127.0.0.1") { |sock|
|
||||
+ sock.print("220 (test_ftp).\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("331 Please specify the password.\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("230 Login successful.\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ sock.print("200 Switching to Binary mode.\r\n")
|
||||
+ line = sock.gets
|
||||
+ commands.push(line)
|
||||
+ sock.print("227 Entering Passive Mode (999,0,0,1,48,57).\r\n")
|
||||
+ commands.push(sock.gets)
|
||||
+ }
|
||||
+ begin
|
||||
+ begin
|
||||
+ ftp = Net::FTP.new
|
||||
+ ftp.passive = true
|
||||
+ ftp.use_pasv_ip = true
|
||||
+ ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
|
||||
+ ftp.connect("127.0.0.1", server.port)
|
||||
+ ftp.login
|
||||
+ assert_match(/\AUSER /, commands.shift)
|
||||
+ assert_match(/\APASS /, commands.shift)
|
||||
+ assert_equal("TYPE I\r\n", commands.shift)
|
||||
+ assert_raise(SocketError) do
|
||||
+ ftp.getbinaryfile("foo", nil)
|
||||
+ end
|
||||
+ ensure
|
||||
+ ftp.close if ftp
|
||||
+ end
|
||||
+ ensure
|
||||
+ server.close
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
private
|
||||
|
||||
- def create_ftp_server(sleep_time = nil)
|
||||
- server = TCPServer.new(SERVER_ADDR, 0)
|
||||
+ def create_ftp_server(sleep_time = nil, addr = SERVER_ADDR)
|
||||
+ server = TCPServer.new(addr, 0)
|
||||
@thread = Thread.start do
|
||||
if sleep_time
|
||||
sleep(sleep_time)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
95
backport-CVE-2021-32066.patch
Normal file
95
backport-CVE-2021-32066.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From adba6f0c3e5c5607c4822b9120322eb7e9a77891 Mon Sep 17 00:00:00 2001
|
||||
From: Shugo Maeda <shugo@ruby-lang.org>
|
||||
Date: Wed, 7 Jul 2021 16:09:03 +0900
|
||||
Subject: [PATCH] This fixes CVE-2021-32066. Reported by Alexandr Savca in
|
||||
<https://hackerone.com/reports/1178562>.
|
||||
|
||||
Reference:https://github.com/ruby/net-imap/commit/adba6f0c3e5c5607c4822b9120322eb7e9a77891
|
||||
---
|
||||
lib/net/imap.rb | 8 +++++++-
|
||||
test/net/imap/test_imap.rb | 31 +++++++++++++++++++++++++++++++
|
||||
2 files changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
|
||||
index da7d0d5..eedcb4f 100644
|
||||
--- a/lib/net/imap.rb
|
||||
+++ b/lib/net/imap.rb
|
||||
@@ -1213,12 +1213,14 @@ module Net
|
||||
end
|
||||
resp = @tagged_responses.delete(tag)
|
||||
case resp.name
|
||||
+ when /\A(?:OK)\z/ni
|
||||
+ return resp
|
||||
when /\A(?:NO)\z/ni
|
||||
raise NoResponseError, resp
|
||||
when /\A(?:BAD)\z/ni
|
||||
raise BadResponseError, resp
|
||||
else
|
||||
- return resp
|
||||
+ raise UnknownResponseError, resp
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3714,6 +3716,10 @@ module Net
|
||||
class ByeResponseError < ResponseError
|
||||
end
|
||||
|
||||
+ # Error raised upon an unknown response from the server.
|
||||
+ class UnknownResponseError < ResponseError
|
||||
+ end
|
||||
+
|
||||
RESPONSE_ERRORS = Hash.new(ResponseError)
|
||||
RESPONSE_ERRORS["NO"] = NoResponseError
|
||||
RESPONSE_ERRORS["BAD"] = BadResponseError
|
||||
diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb
|
||||
index 41f25fe..9247062 100644
|
||||
--- a/test/net/imap/test_imap.rb
|
||||
+++ b/test/net/imap/test_imap.rb
|
||||
@@ -110,6 +110,16 @@ class IMAPTest < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
end
|
||||
+
|
||||
+ def test_starttls_stripping
|
||||
+ starttls_stripping_test do |port|
|
||||
+ imap = Net::IMAP.new("localhost", :port => port)
|
||||
+ assert_raise(Net::IMAP::UnknownResponseError) do
|
||||
+ imap.starttls(:ca_file => CA_FILE)
|
||||
+ end
|
||||
+ imap
|
||||
+ end
|
||||
+ end
|
||||
end
|
||||
|
||||
if defined?(OpenSSL::SSL)
|
||||
@@ -760,6 +770,27 @@ EOF
|
||||
end
|
||||
end
|
||||
|
||||
+ def starttls_stripping_test
|
||||
+ server = create_tcp_server
|
||||
+ port = server.addr[1]
|
||||
+ start_server do
|
||||
+ sock = server.accept
|
||||
+ begin
|
||||
+ sock.print("* OK test server\r\n")
|
||||
+ sock.gets
|
||||
+ sock.print("RUBY0001 BUG unhandled command\r\n")
|
||||
+ ensure
|
||||
+ sock.close
|
||||
+ server.close
|
||||
+ end
|
||||
+ end
|
||||
+ begin
|
||||
+ imap = yield(port)
|
||||
+ ensure
|
||||
+ imap.disconnect if imap && !imap.disconnected?
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
def create_tcp_server
|
||||
return TCPServer.new(server_addr, 0)
|
||||
end
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: ruby
|
||||
Version: 2.5.8
|
||||
Release: 113
|
||||
Release: 114
|
||||
Summary: Object-oriented scripting language interpreter
|
||||
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
|
||||
URL: https://www.ruby-lang.org/en/
|
||||
@ -40,6 +40,9 @@ Patch6002: CVE-2019-16163.patch
|
||||
Patch6003: CVE-2020-25613.patch
|
||||
Patch6004: upgrade_lib_rexml.patch
|
||||
Patch6005: upgrade_lib_rexml_test.patch
|
||||
Patch6006: backport-CVE-2021-31799.patch
|
||||
Patch6007: backport-CVE-2021-31810.patch
|
||||
Patch6008: backport-CVE-2021-32066.patch
|
||||
|
||||
Provides: %{name}-libs = %{version}-%{release}
|
||||
Obsoletes: %{name}-libs < %{version}-%{release}
|
||||
@ -579,6 +582,9 @@ make runruby TESTRUN_SCRIPT=%{SOURCE13}
|
||||
%exclude %{gem_dir}/gems/xmlrpc-0.3.0/.*
|
||||
|
||||
%changelog
|
||||
* Sat Jul 31 2021 shixuantong <shixuantong@huawei.com> - 2.5.8-114
|
||||
- fix CVE-2021-31799 CVE-2021-31810 CVE-2021-32066
|
||||
|
||||
* Fri Apr 30 2021 Shinwell_Hu <huxinwei@huawei.com> - 2.5.8-113
|
||||
- Upgrade bundled REXML gem to fix CVE-2021-28965, which is an XML
|
||||
round-trip vulnerability in REXML.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user