diff --git a/backport-Cleanup-ephemeral-IP-routes-on-exception.patch b/backport-Cleanup-ephemeral-IP-routes-on-exception.patch new file mode 100644 index 0000000000000000000000000000000000000000..909976265797f1d026d226ec355e4a791b1a5a33 --- /dev/null +++ b/backport-Cleanup-ephemeral-IP-routes-on-exception.patch @@ -0,0 +1,161 @@ +From 0273712c90d6facfc0fbf8d6def352f9810902a3 Mon Sep 17 00:00:00 2001 +From: sxt1001 +Date: Mon, 3 Apr 2023 23:52:15 +0800 +Subject: [PATCH] Cleanup ephemeral IP routes on exception (#2100) + +If an exception occurs during EphemeralIPv4Network setup, any routes +that were setup need to be torn down. This wasn't happening, and this +commit adds the teardown. +--- + cloudinit/net/__init__.py | 43 +++++++++++-------- + tests/unittests/net/test_init.py | 73 ++++++++++++++++++++++++++++++++ + 2 files changed, 99 insertions(+), 17 deletions(-) + +diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py +index 3297a31..fc9668e 100644 +--- a/cloudinit/net/__init__.py ++++ b/cloudinit/net/__init__.py +@@ -1370,23 +1370,32 @@ class EphemeralIPv4Network(object): + ) + return + +- self._bringup_device() +- +- # rfc3442 requires us to ignore the router config *if* classless static +- # routes are provided. +- # +- # https://tools.ietf.org/html/rfc3442 +- # +- # If the DHCP server returns both a Classless Static Routes option and +- # a Router option, the DHCP client MUST ignore the Router option. +- # +- # Similarly, if the DHCP server returns both a Classless Static Routes +- # option and a Static Routes option, the DHCP client MUST ignore the +- # Static Routes option. +- if self.static_routes: +- self._bringup_static_routes() +- elif self.router: +- self._bringup_router() ++ try: ++ self._bringup_device() ++ ++ # rfc3442 requires us to ignore the router config *if* ++ # classless static routes are provided. ++ # ++ # https://tools.ietf.org/html/rfc3442 ++ # ++ # If the DHCP server returns both a Classless Static Routes ++ # option and a Router option, the DHCP client MUST ignore ++ # the Router option. ++ # ++ # Similarly, if the DHCP server returns both a Classless ++ # Static Routes option and a Static Routes option, the DHCP ++ # client MUST ignore the Static Routes option. ++ if self.static_routes: ++ self._bringup_static_routes() ++ elif self.router: ++ self._bringup_router() ++ except subp.ProcessExecutionError: ++ LOG.error( ++ "Error bringing up EphemeralIPv4Network. " ++ "Datasource setup cannot continue" ++ ) ++ self.__exit__(None, None, None) ++ raise + + def __exit__(self, excp_type, excp_value, excp_traceback): + """Teardown anything we set up.""" +diff --git a/tests/unittests/net/test_init.py b/tests/unittests/net/test_init.py +index 768cc11..5da1232 100644 +--- a/tests/unittests/net/test_init.py ++++ b/tests/unittests/net/test_init.py +@@ -13,6 +13,7 @@ import pytest + import requests + + import cloudinit.net as net ++from cloudinit import subp + from cloudinit.subp import ProcessExecutionError + from cloudinit.util import ensure_file, write_file + from tests.unittests.helpers import CiTestCase, HttprettyTestCase +@@ -853,6 +854,78 @@ class TestEphemeralIPV4Network(CiTestCase): + self.assertEqual(expected_setup_calls, m_subp.call_args_list) + m_subp.assert_has_calls(expected_teardown_calls) + ++ def test_teardown_on_enter_exception(self, m_subp): ++ """Ensure ephemeral teardown happens. ++ ++ Even though we're using a context manager, we need to handle any ++ exceptions raised in __enter__ manually and do the appropriate ++ teardown. ++ """ ++ ++ def side_effect(args, **kwargs): ++ if args[3] == "append" and args[4] == "3.3.3.3/32": ++ raise subp.ProcessExecutionError("oh no!") ++ ++ m_subp.side_effect = side_effect ++ ++ with pytest.raises(subp.ProcessExecutionError): ++ with net.EphemeralIPv4Network( ++ interface="eth0", ++ ip="1.1.1.1", ++ prefix_or_mask="255.255.255.0", ++ broadcast="1.1.1.255", ++ static_routes=[ ++ ("2.2.2.2/32", "9.9.9.9"), ++ ("3.3.3.3/32", "8.8.8.8"), ++ ], ++ ): ++ pass ++ ++ expected_teardown_calls = [ ++ mock.call( ++ [ ++ "ip", ++ "-4", ++ "route", ++ "del", ++ "2.2.2.2/32", ++ "via", ++ "9.9.9.9", ++ "dev", ++ "eth0", ++ ], ++ capture=True, ++ ), ++ mock.call( ++ [ ++ "ip", ++ "-family", ++ "inet", ++ "link", ++ "set", ++ "dev", ++ "eth0", ++ "down", ++ ], ++ capture=True, ++ ), ++ mock.call( ++ [ ++ "ip", ++ "-family", ++ "inet", ++ "addr", ++ "del", ++ "1.1.1.1/24", ++ "dev", ++ "eth0", ++ ], ++ capture=True, ++ ), ++ ] ++ for teardown in expected_teardown_calls: ++ assert teardown in m_subp.call_args_list ++ + @mock.patch("cloudinit.net.readurl") + def test_ephemeral_ipv4_no_network_if_url_connectivity( + self, m_readurl, m_subp +-- +2.33.0 + diff --git a/cloud-init.spec b/cloud-init.spec index 6e95702b08b6a2861da0ab7f364a7e2f1e55d315..52adeaccb8c206043ae94689cd34ed00e2b0f4b5 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init Version: 22.2 -Release: 8 +Release: 9 Summary: the defacto multi-distribution package that handles early initialization of a cloud instance. License: ASL 2.0 or GPLv3 URL: http://launchpad.net/cloud-init @@ -16,6 +16,7 @@ Patch4: Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patc Patch5: backport-Fix-permission-of-SSH-host-keys-1971.patch Patch6: backport-Do-not-change-permissions-of-netrules-target.patch Patch7: backport-CVE-2022-2084.patch +Patch8: backport-Cleanup-ephemeral-IP-routes-on-exception.patch Patch9000: fix-permission-of-the-private-key.patch @@ -132,6 +133,12 @@ fi %exclude /usr/share/doc/* %changelog +* Thu May 18 2023 shixuantong - 22.2-9 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Cleanup ephemeral IP routes on exception + * Thu May 4 2023 wangyongcong - 22.2-8 - Type:CVE - ID: CVE-2022-2084