[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1109058: unblock: cloud-init/25.1.4-1



Package: release.debian.org
Severity: normal
X-Debbugs-Cc: cloud-init@packages.debian.org
Control: affects -1 + src:cloud-init
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package cloud-init

(Please provide enough (but not too much) information to help
the release team to judge the request efficiently. E.g. by
filling in the sections below.)

[ Reason ]

This update pulls in the latest upstream patch release to 25.1.  The primary
rationale for pulling this into trixie is fixes for two CVEs:

 - CVE-2024-6174 - When a non-x86 platform is detected, cloud-init grants
   root access to a hardcoded url with a local IP address. To prevent this,
   cloud-init default configurations disable platform enumeration.

 - CVE-2024-11584 - cloud-init through 25.1.2 includes the systemd socket
   unit cloud-init-hotplugd.socket with default SocketMode that grants 0666
   permissions, making it world-writable. This is used for the
   "/run/cloud-init/hook-hotplug-cmd" FIFO. An unprivileged user could
   trigger hotplug-hook commands. 

The complete upstream changelog from 25.1.1 (currently in trixie) is:

25.1.4
- fix: disable cloud-init when non-x86 environments have no DMI-data and
  no strict datasources detected (LP: #2069607) (CVE-2024-6174)

25.1.3
 - docs: provide example3 for PAM and ssh_pwauth behavior (#27)
 - fix: Make hotplug socket writable only by root (#25) (CVE-2024-11584)
 - fix: Don't attempt to identify non-x86 OpenStack instances (LP: #2069607)
   (CVE-2024-6174)

25.1.2
 - fix: ensure MAAS datasource retries on failure (#6167)

[ Impact ]

Exposure to two security risks.  Although NVD rates CVE-2024-6174 as high
severity, with an 8.8 CVSSv3 score, I don't agree with this assessment and
would rate both CVEs as moderate in severity.  Nevertheless, we should get
the fixes into trixe and I expect that we'll want to update bookworm to
address CVE-2024-6174 as well.

[ Tests ]

Upstream's automated test suite.  The changes have also been validated using
repro steps for CVE-2024-6174 in upstream's bug tracker
(https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/2069607)

[ Risks ]

The fix to CVE-2024-6174 does introduce a behavior change, which is the
highest source of risk.  However, because the behavior change is limited to
uncommon scenarios (non-x86 architectures relying on network based instance
metadata service in openstack or non-cloud standalone VMs), it's been deemed
acceptable by upstrea.  The cloud team concurs with this conclusion.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

unblock cloud-init/25.1.4-1
diff -Nru cloud-init-25.1.1/ChangeLog cloud-init-25.1.4/ChangeLog
--- cloud-init-25.1.1/ChangeLog	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/ChangeLog	2025-06-24 16:50:00.000000000 -0400
@@ -1,3 +1,16 @@
+25.1.4
+- fix: disable cloud-init when non-x86 environments have no DMI-data and
+  no strict datasources detected (LP: #2069607) (CVE-2024-6174)
+
+25.1.3
+ - docs: provide example3 for PAM and ssh_pwauth behavior (#27)
+ - fix: Make hotplug socket writable only by root (#25) (CVE-2024-11584)
+ - fix: Don't attempt to identify non-x86 OpenStack instances (LP: #2069607)
+   (CVE-2024-6174)
+
+25.1.2
+ - fix: ensure MAAS datasource retries on failure (#6167)
+
 25.1.1
  - test: pytestify cc_chef tests, add migration test
  - chef: migrate files in old config directories for backups and cache
diff -Nru cloud-init-25.1.1/cloudinit/cmd/devel/logs.py cloud-init-25.1.4/cloudinit/cmd/devel/logs.py
--- cloud-init-25.1.1/cloudinit/cmd/devel/logs.py	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/cloudinit/cmd/devel/logs.py	2025-06-24 16:50:00.000000000 -0400
@@ -295,7 +295,7 @@
     Note that this only globs the top-level directory as there are currently
     no relevant files within subdirectories.
     """
-    return (p for p in run_dir.glob("*") if p.name != "hook-hotplug-cmd")
+    return run_dir.glob("*")
 
 
 def _collect_logs_into_tmp_dir(
diff -Nru cloud-init-25.1.1/cloudinit/url_helper.py cloud-init-25.1.4/cloudinit/url_helper.py
--- cloud-init-25.1.1/cloudinit/url_helper.py	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/cloudinit/url_helper.py	2025-06-24 16:50:00.000000000 -0400
@@ -1097,7 +1097,7 @@
         return self._wrapped(readurl, args, kwargs)
 
     def _exception_cb(self, extra_exception_cb, exception):
-        ret = None
+        ret = True
         try:
             if extra_exception_cb:
                 ret = extra_exception_cb(exception)
diff -Nru cloud-init-25.1.1/cloudinit/version.py cloud-init-25.1.4/cloudinit/version.py
--- cloud-init-25.1.1/cloudinit/version.py	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/cloudinit/version.py	2025-06-24 16:50:00.000000000 -0400
@@ -4,7 +4,7 @@
 #
 # This file is part of cloud-init. See LICENSE file for license information.
 
-__VERSION__ = "25.1.1"
+__VERSION__ = "25.1.4"
 _PACKAGED_VERSION = "@@PACKAGED_VERSION@@"
 
 FEATURES = [
diff -Nru cloud-init-25.1.1/debian/changelog cloud-init-25.1.4/debian/changelog
--- cloud-init-25.1.1/debian/changelog	2025-03-24 15:35:46.000000000 -0400
+++ cloud-init-25.1.4/debian/changelog	2025-07-07 15:13:38.000000000 -0400
@@ -1,3 +1,11 @@
+cloud-init (25.1.4-1) unstable; urgency=medium
+
+  * New upstream version 25.1.4 (Closes: #1108402, #1108403)
+    - Fixes CVE-2024-6174
+    - Fixes CVE-2024-11584
+
+ -- Noah Meyerhans <noahm@debian.org>  Mon, 07 Jul 2025 15:13:38 -0400
+
 cloud-init (25.1.1-1) unstable; urgency=medium
 
   * New upstream version 25.1.1
diff -Nru cloud-init-25.1.1/doc/module-docs/cc_set_passwords/data.yaml cloud-init-25.1.4/doc/module-docs/cc_set_passwords/data.yaml
--- cloud-init-25.1.1/doc/module-docs/cc_set_passwords/data.yaml	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/doc/module-docs/cc_set_passwords/data.yaml	2025-06-24 16:50:00.000000000 -0400
@@ -4,7 +4,15 @@
     ``chpasswd`` and ``password``.
     
     The ``ssh_pwauth`` config key determines whether or not sshd will be
-    configured to accept password authentication.
+    configured to accept password authentication. Disabling SSH password
+    authentication is limited to setting the specific sshd_config value
+    ``PasswordAuthentication no`` in sshd_config.
+
+    .. note::
+       If your image uses PAM for authentication, providing
+       ``PasswordAuthentication no`` may not be sufficient if your
+       distribution default is to provide ``KbdInteractiveAuthentication yes``
+       in sshd_config. See Example 3 for suggested user-data in this case.
     
     The ``chpasswd`` config key accepts a dictionary containing either (or
     both) of ``users`` and ``expire``.
@@ -36,5 +44,10 @@
       - Set the password for user3 to be a randomly generated password, which
         will be written to the system console.
     file: cc_set_passwords/example2.yaml
+  - comment: |
+      Example 3: Disable SSH password authentication and PAM interactive
+      password authentication by manually supplementing cloud-init's default
+      sshd_config.
+    file: cc_set_passwords/example3.yaml
   name: Set Passwords
   title: Set user passwords and enable/disable SSH password auth
diff -Nru cloud-init-25.1.1/doc/module-docs/cc_set_passwords/example3.yaml cloud-init-25.1.4/doc/module-docs/cc_set_passwords/example3.yaml
--- cloud-init-25.1.1/doc/module-docs/cc_set_passwords/example3.yaml	1969-12-31 19:00:00.000000000 -0500
+++ cloud-init-25.1.4/doc/module-docs/cc_set_passwords/example3.yaml	2025-06-24 16:50:00.000000000 -0400
@@ -0,0 +1,9 @@
+#cloud-config
+ssh_pwauth: false
+# Supplement sshd_config part with overrides for images using PAM
+# for authentication on distributions which default to
+# KbdInteractiveAuthentication yes in sshd_config.
+write_files:
+- path: /etc/ssh/sshd_config.d/70-no-pam-password-auth.conf
+  content: 'KbdInteractiveAuthentication no'
+  permissions: '0500'
diff -Nru cloud-init-25.1.1/doc/rtd/reference/breaking_changes.rst cloud-init-25.1.4/doc/rtd/reference/breaking_changes.rst
--- cloud-init-25.1.1/doc/rtd/reference/breaking_changes.rst	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/doc/rtd/reference/breaking_changes.rst	2025-06-24 16:50:00.000000000 -0400
@@ -11,6 +11,54 @@
     many operating system vendors patch out breaking changes in
     cloud-init to ensure consistent behavior on their platform.
 
+25.1.3
+======
+
+Strict datasource identity before network
+-----------------------------------------
+Affects detection of Ec2, OpenStack or AltCloud datasources for non-x86
+architectures where DMI may not be accessible.
+
+Datasource detection provided by ds-identify in cloud-init now requires strict
+identification based on DMI platform information, kernel command line or
+`datasource_list:` system configuration in /etc/cloud/cloud.cfg.d.
+
+Prior to this change, ds-identify would allow non-x86 architectures without
+strict identifying platform information to run in a discovery mode which would
+attempt to reach out to well known static link-local IPs to attempt to
+retrieve configuration once system networking is up.
+
+To mitigate the potential of a bad-actor in a local network responding
+to such provisioning requests from cloud-init clients, ds-identify will no
+longer allow this late discovery mode for platforms unable to expose clear
+identifying characteristics of a known cloud-init datasource.
+
+The most likely affected cloud platforms are AltCloud, Ec2 and OpenStack for
+non-x86 architectures where DMI data is not exposed by the kernel.
+
+If your non-x86 architecture or images no longer detect the proper datasource,
+any of the following steps can ensure proper detection of cloud-init config:
+
+- Provide kernel commandline containing ``ds=<lowercase_datasource_name>``
+  which forces ds-identify to discover a specific datasource.
+- Image creators: provide a config file part such as
+  :file:`/etc/cloud/cloud.cfg.d/*.cfg` containing the
+  case-sensitive ``datasource_list: [ <datasource_name> ]`` to force cloud-init
+  to use a specific datasource without performing discovery.
+
+For example, to force OpenStack discovery in cloud-init any of the following
+approaches work:
+
+- OpenStack: `attach a ConfigDrive`_ as an alternative config source
+- Kernel command line containing ``ds=openstack``
+- Custom images provide :file:`/etc/cloud/cloud.cfg.d/91-set-datasource.cfg`
+  containing:
+
+.. code-block:: yaml
+
+   datasource_list: [ OpenStack ]
+
+
 25.1
 ====
 
@@ -162,5 +210,6 @@
 a ``datasource_list`` in ``/etc/cloud/cloud.cfg.d/*.cfg``.
 
 
+.. _attach a ConfigDrive: https://docs.openstack.org/nova/2024.1/admin/config-drive.html
 .. _this patch: https://github.com/canonical/cloud-init/blob/ubuntu/noble/debian/patches/no-single-process.patch
 .. _Python3 equivalent:  https://github.com/canonical/cloud-init/pull/5489#issuecomment-2408210561
diff -Nru cloud-init-25.1.1/systemd/cloud-init-hotplugd.service cloud-init-25.1.4/systemd/cloud-init-hotplugd.service
--- cloud-init-25.1.1/systemd/cloud-init-hotplugd.service	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/systemd/cloud-init-hotplugd.service	2025-06-24 16:50:00.000000000 -0400
@@ -1,5 +1,5 @@
 # Paired with cloud-init-hotplugd.socket to read from the FIFO
-# /run/cloud-init/hook-hotplug-cmd which is created during a udev network
+# hook-hotplug-cmd which is created during a udev network
 # add or remove event as processed by 90-cloud-init-hook-hotplug.rules.
 
 # On start, read args from the FIFO, process and provide structured arguments
diff -Nru cloud-init-25.1.1/systemd/cloud-init-hotplugd.socket cloud-init-25.1.4/systemd/cloud-init-hotplugd.socket
--- cloud-init-25.1.1/systemd/cloud-init-hotplugd.socket	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/systemd/cloud-init-hotplugd.socket	2025-06-24 16:50:00.000000000 -0400
@@ -1,5 +1,5 @@
 # cloud-init-hotplugd.socket listens on the FIFO file
-# /run/cloud-init/hook-hotplug-cmd which is created during a udev network
+# hook-hotplug-cmd which is created during a udev network
 # add or remove event as processed by 90-cloud-init-hook-hotplug.rules.
 
 # Known bug with an enforcing SELinux policy: LP: #1936229
@@ -14,7 +14,8 @@
 ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
 
 [Socket]
-ListenFIFO=/run/cloud-init/hook-hotplug-cmd
+ListenFIFO=/run/cloud-init/share/hook-hotplug-cmd
+SocketMode=0600
 
 [Install]
 WantedBy=cloud-config.target
diff -Nru cloud-init-25.1.1/tests/unittests/sources/test_maas.py cloud-init-25.1.4/tests/unittests/sources/test_maas.py
--- cloud-init-25.1.1/tests/unittests/sources/test_maas.py	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/tests/unittests/sources/test_maas.py	2025-06-24 16:50:00.000000000 -0400
@@ -4,11 +4,13 @@
 from unittest import mock
 
 import pytest
+import responses
 import yaml
 
 from cloudinit import helpers, settings, url_helper
 from cloudinit.sources import DataSourceMAAS
-from tests.unittests.helpers import populate_dir
+from tests.unittests.helpers import get_mock_paths, populate_dir
+from tests.unittests.util import MockDistro
 
 
 class TestMAASDataSource:
@@ -221,6 +223,56 @@
             klibc_net_cfg.write(initramfs_file)
         assert expected == ds.get_data()
 
+    @responses.activate
+    def test_get_data_with_retry(self, mocker, tmp_path, caplog):
+        """Ensure we can get data from IMDS even if some attempts fail."""
+        mocker.patch("time.sleep")
+        metadata_url = "http://169.254.169.254/MAAS/metadata";
+        response_data = {
+            "instance-id": "i-123",
+            "local-hostname": "myhostname",
+            "public-keys": "ssh-rsa AAAAB...yc2E= keyname",
+            "vendor-data": "my-vendordata",
+        }
+
+        responses.add(
+            responses.GET,
+            url=f"{metadata_url}/2012-03-01/meta-data/instance-id",
+            status=404,
+        )
+
+        for key, value in response_data.items():
+            responses.add(
+                responses.GET,
+                f"{metadata_url}/2012-03-01/meta-data/{key}",
+                value.encode(),
+            )
+
+        responses.add(
+            responses.GET,
+            url=f"{metadata_url}/2012-03-01/user-data",
+            status=404,
+        )
+        responses.add(
+            responses.GET,
+            f"{metadata_url}/2012-03-01/user-data",
+            b"my-userdata",
+        )
+
+        cfg = {"datasource": {"MAAS": {"metadata_url": metadata_url}}}
+        ds = DataSourceMAAS.DataSourceMAAS(
+            cfg, MockDistro(), get_mock_paths(tmp_path)({})
+        )
+        assert ds.get_data()
+        assert ds.metadata["instance-id"] == "i-123"
+        assert ds.metadata["local-hostname"] == "myhostname"
+        assert ds.metadata["public-keys"] == "ssh-rsa AAAAB...yc2E= keyname"
+        assert ds.vendordata_raw == "my-vendordata"
+        assert ds.userdata_raw == b"my-userdata"
+        assert (
+            "Please wait 1 seconds while we wait to try again" in caplog.text
+        )
+
 
 @mock.patch("cloudinit.sources.DataSourceMAAS.url_helper.OauthUrlHelper")
 class TestGetOauthHelper:
diff -Nru cloud-init-25.1.1/tests/unittests/test_ds_identify.py cloud-init-25.1.4/tests/unittests/test_ds_identify.py
--- cloud-init-25.1.1/tests/unittests/test_ds_identify.py	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/tests/unittests/test_ds_identify.py	2025-06-24 16:50:00.000000000 -0400
@@ -208,9 +208,9 @@
 """
 
 POLICY_FOUND_ONLY = "search,found=all,maybe=none,notfound=disabled"
-POLICY_FOUND_OR_MAYBE = "search,found=all,maybe=all,notfound=disabled"
-DI_DEFAULT_POLICY = "search,found=all,maybe=all,notfound=disabled"
-DI_DEFAULT_POLICY_NO_DMI = "search,found=all,maybe=all,notfound=enabled"
+POLICY_FOUND_OR_MAYBE = "search,found=all,maybe=none,notfound=disabled"
+DI_DEFAULT_POLICY = "search,found=all,maybe=none,notfound=disabled"
+DI_DEFAULT_POLICY_NO_DMI = "search,found=all,maybe=none,notfound=disabled"
 DI_EC2_STRICT_ID_DEFAULT = "true"
 OVF_MATCH_STRING = "http://schemas.dmtf.org/ovf/environment/1";
 
@@ -947,7 +947,7 @@
         self._test_ds_found("OpenStack-AssetTag-Compute")
 
     def test_openstack_on_non_intel_is_maybe(self):
-        """On non-Intel, openstack without dmi info is maybe.
+        """On non-Intel, openstack without dmi info is none.
 
         nova does not identify itself on platforms other than intel.
         https://bugs.launchpad.net/cloud-init/+bugs?field.tag=dsid-nova""";
@@ -957,7 +957,7 @@
         data.update(
             {
                 "policy_dmi": POLICY_FOUND_OR_MAYBE,
-                "policy_no_dmi": POLICY_FOUND_OR_MAYBE,
+                "policy_no_dmi": DI_DEFAULT_POLICY_NO_DMI,
             }
         )
 
@@ -967,10 +967,11 @@
 
         # updating the uname to ppc64 though should get a maybe.
         data.update({"mocks": [MOCK_VIRT_IS_KVM, MOCK_UNAME_IS_PPC64]})
-        (_, _, err, _, _) = self._check_via_dict(
-            data, RC_FOUND, dslist=["OpenStack", "None"]
-        )
+        (_, _, err, _, _) = self._check_via_dict(data, RC_NOT_FOUND)
         self.assertIn("check for 'OpenStack' returned maybe", err)
+        self.assertIn("No ds found", err)
+        self.assertIn("Disabled cloud-init", err)
+        self.assertIn("returning 1", err)
 
     def test_default_ovf_is_found(self):
         """OVF is identified found when ovf/ovf-env.xml seed file exists."""
diff -Nru cloud-init-25.1.1/tools/cloud-init-hotplugd cloud-init-25.1.4/tools/cloud-init-hotplugd
--- cloud-init-25.1.1/tools/cloud-init-hotplugd	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/tools/cloud-init-hotplugd	2025-06-24 16:50:00.000000000 -0400
@@ -9,7 +9,7 @@
 # upon a network device event). Anything received via the pipe is then
 # passed on via the "cloud-init devel hotplug-hook handle" command.
 
-PIPE="/run/cloud-init/hook-hotplug-cmd"
+PIPE="/run/cloud-init/share/hook-hotplug-cmd"
 
 mkfifo -m700 $PIPE
 
diff -Nru cloud-init-25.1.1/tools/ds-identify cloud-init-25.1.4/tools/ds-identify
--- cloud-init-25.1.1/tools/ds-identify	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/tools/ds-identify	2025-06-24 16:50:00.000000000 -0400
@@ -14,7 +14,7 @@
 #   The format is:
 #        <mode>,found=value,maybe=value,notfound=value
 #   default setting is:
-#     search,found=all,maybe=all,notfound=disabled
+#     search,found=all,maybe=none,notfound=disabled
 #
 #   kernel command line option: ci.di.policy=<policy>
 #   example line in /etc/cloud/ds-identify.cfg:
@@ -40,7 +40,7 @@
 #         first: use the first found do no further checking
 #         all: enable all DS_FOUND
 #
-#      maybe: (default=all)
+#      maybe: (default=none)
 #       if nothing returned 'found', then how to handle maybe.
 #       no network sources are allowed to return 'maybe'.
 #         all: enable all DS_MAYBE
@@ -100,8 +100,8 @@
 
 DI_BLKID_EXPORT_OUT=""
 DI_GEOM_LABEL_STATUS_OUT=""
-DI_DEFAULT_POLICY="search,found=all,maybe=all,notfound=${DI_DISABLED}"
-DI_DEFAULT_POLICY_NO_DMI="search,found=all,maybe=all,notfound=${DI_ENABLED}"
+DI_DEFAULT_POLICY="search,found=all,maybe=none,notfound=${DI_DISABLED}"
+DI_DEFAULT_POLICY_NO_DMI="search,found=all,maybe=none,notfound=${DI_DISABLED}"
 DI_DMI_BOARD_NAME=""
 DI_DMI_CHASSIS_ASSET_TAG=""
 DI_DMI_PRODUCT_NAME=""
diff -Nru cloud-init-25.1.1/tools/hook-hotplug cloud-init-25.1.4/tools/hook-hotplug
--- cloud-init-25.1.1/tools/hook-hotplug	2025-03-24 13:18:23.000000000 -0400
+++ cloud-init-25.1.4/tools/hook-hotplug	2025-06-24 16:50:00.000000000 -0400
@@ -4,7 +4,7 @@
 # This script checks if cloud-init has hotplug hooked and if
 # cloud-init is ready; if so invoke cloud-init hotplug-hook
 
-fifo=/run/cloud-init/hook-hotplug-cmd
+fifo=/run/cloud-init/share/hook-hotplug-cmd
 log_file=/run/cloud-init/hook-hotplug.log
 
 should_run() {

Reply to: