--- Begin Message ---
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() {
--- End Message ---