File CVE-2021-31810.patch of Package ruby2.5.openSUSE_Leap_15.2_Update

From 4d2754b6275a3592b34f692e7607b1da9b748dd1 Mon Sep 17 00:00:00 2001
From: Ali Abdallah <ali.abdallah@suse.com>
Date: Wed, 6 Oct 2021 17:36:07 +0200
Subject: [PATCH 2/3] Backport upstream fix for CVE-2021-31810

Backport upstream commit 3ca1399150ed4eacfd2fe1ee251b966f8d1ee469

[PATCH] Ignore IP addresses in PASV responses by default, and add new
 option use_pasv_ip

 This fixes CVE-2021-81810.
Reported by Alexandr Savca.

 Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
---
 lib/net/ftp.rb           | 15 ++++++++++++++-
 test/net/ftp/test_ftp.rb |  7 +++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
index 9902f9dc65..338dbbc5a8 100644
--- a/lib/net/ftp.rb
+++ b/lib/net/ftp.rb
@@ -97,6 +97,10 @@ class FTP < Protocol
     # 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 @@ def FTP.open(host, *args)
     #                          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 @@ def initialize(host = nil, user_or_options = {}, passwd = nil, acct = nil)
       @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 @@ def parse227(resp) # :nodoc:
         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 = @sock.peeraddr[3]
+        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 8e0a688135..7a85488ddb 100644
--- a/test/net/ftp/test_ftp.rb
+++ b/test/net/ftp/test_ftp.rb
@@ -62,6 +62,7 @@ def test_connect_fail
 
   def test_parse227
     ftp = Net::FTP.new
+    ftp.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 +81,12 @@ def test_parse227
     assert_raise(Net::FTPProtoError) do
       ftp.send(:parse227, "227 ) foo bar (")
     end
+    ftp = Net::FTP.new
+    sock = OpenStruct.new
+    sock.peeraddr = [nil, nil, nil, "10.0.0.1"]
+    ftp.instance_variable_set(:@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
-- 
2.32.0

openSUSE Build Service is sponsored by