Hi, ports@:
Here is a security patch for python27, which fix two security issues,
CVE-2021-4189 and CVE-2022-0391, copied from NetBSD and they
sourced via Fedora.
I am not sure which REVISION should be bumped so I did not update
REVISION.
wen
Index: patches/patch-Lib_ftplib_py
===================================================================
RCS file: patches/patch-Lib_ftplib_py
diff -N patches/patch-Lib_ftplib_py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-Lib_ftplib_py 26 Feb 2022 13:30:12 -0000
@@ -0,0 +1,33 @@
+$OpenBSD$
+
+Fix CVE-2021-4189: ftplib should not use the host from the PASV response
+Via Fedora:
+https://src.fedoraproject.org/rpms/python2.7/raw/40dd05e5d77dbfa81777c9f84b704bc2239bf710/f/00372-CVE-2021-4189.patch
+
+Index: Lib/ftplib.py
+--- Lib/ftplib.py.orig
++++ Lib/ftplib.py
+@@ -108,6 +108,8 @@ class FTP:
+ file = None
+ welcome = None
+ passiveserver = 1
++ # Disables security if set to True. https://bugs.python.org/issue43285
++ trust_server_pasv_ipv4_address = False
+
+ # Initialization method (called by class instantiation).
+ # Initialize host to localhost, port to standard ftp port
+@@ -310,8 +312,13 @@ class FTP:
+ return sock
+
+ def makepasv(self):
++ """Internal: Does the PASV or EPSV handshake -> (address, port)"""
+ if self.af == socket.AF_INET:
+- host, port = parse227(self.sendcmd('PASV'))
++ untrusted_host, port = parse227(self.sendcmd('PASV'))
++ if self.trust_server_pasv_ipv4_address:
++ host = untrusted_host
++ else:
++ host = self.sock.getpeername()[0]
+ else:
+ host, port = parse229(self.sendcmd('EPSV'),
self.sock.getpeername())
+ return host, port
Index: patches/patch-Lib_test_test_ftplib_py
===================================================================
RCS file: patches/patch-Lib_test_test_ftplib_py
diff -N patches/patch-Lib_test_test_ftplib_py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-Lib_test_test_ftplib_py 26 Feb 2022 13:30:12 -0000
@@ -0,0 +1,57 @@
+$OpenBSD$
+
+Fix CVE-2021-4189: ftplib should not use the host from the PASV response
+Via Fedora:
+https://src.fedoraproject.org/rpms/python2.7/raw/40dd05e5d77dbfa81777c9f84b704bc2239bf710/f/00372-CVE-2021-4189.patch
+
+Index: Lib/test/test_ftplib.py
+--- Lib/test/test_ftplib.py.orig
++++ Lib/test/test_ftplib.py
+@@ -67,6 +67,10 @@ class DummyFTPHandler(asynchat.async_chat):
+ self.rest = None
+ self.next_retr_data = RETR_DATA
+ self.push('220 welcome')
++ # We use this as the string IPv4 address to direct the client
++ # to in response to a PASV command. To test security behavior.
++ # https://bugs.python.org/issue43285/.
++ self.fake_pasv_server_ip = '252.253.254.255'
+
+ def collect_incoming_data(self, data):
+ self.in_buffer.append(data)
+@@ -109,7 +113,8 @@ class DummyFTPHandler(asynchat.async_chat):
+ sock.bind((self.socket.getsockname()[0], 0))
+ sock.listen(5)
+ sock.settimeout(10)
+- ip, port = sock.getsockname()[:2]
++ port = sock.getsockname()[1]
++ ip = self.fake_pasv_server_ip
+ ip = ip.replace('.', ',')
+ p1, p2 = divmod(port, 256)
+ self.push('227 entering passive mode (%s,%d,%d)' %(ip, p1, p2))
+@@ -576,6 +581,26 @@ class TestFTPClass(TestCase):
+ conn.close()
+ # IPv4 is in use, just make sure send_epsv has not been used
+ self.assertEqual(self.server.handler_instance.last_received_cmd,
'pasv')
++
++ def test_makepasv_issue43285_security_disabled(self):
++ """Test the opt-in to the old vulnerable behavior."""
++ self.client.trust_server_pasv_ipv4_address = True
++ bad_host, port = self.client.makepasv()
++ self.assertEqual(
++ bad_host, self.server.handler_instance.fake_pasv_server_ip)
++ # Opening and closing a connection keeps the dummy server happy
++ # instead of timing out on accept.
++ socket.create_connection((self.client.sock.getpeername()[0], port),
++ timeout=TIMEOUT).close()
++
++ def test_makepasv_issue43285_security_enabled_default(self):
++ self.assertFalse(self.client.trust_server_pasv_ipv4_address)
++ trusted_host, port = self.client.makepasv()
++ self.assertNotEqual(
++ trusted_host,
self.server.handler_instance.fake_pasv_server_ip)
++ # Opening and closing a connection keeps the dummy server happy
++ # instead of timing out on accept.
++ socket.create_connection((trusted_host, port),
timeout=TIMEOUT).close()
+
+ def test_line_too_long(self):
+ self.assertRaises(ftplib.Error, self.client.sendcmd,