Accepting request 1098540 from Cloud:Tools

Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/1098540
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/cloud-init?expand=0&rev=88
This commit is contained in:
Dominique Leuenberger 2023-07-18 19:53:44 +00:00 committed by Git OBS Bridge
commit c4435ac5c3
7 changed files with 301 additions and 17 deletions

View File

@ -0,0 +1,175 @@
--- cloudinit/sources/DataSourceLXD.py.orig
+++ cloudinit/sources/DataSourceLXD.py
@@ -173,6 +173,8 @@ class DataSourceLXD(sources.DataSource):
"user.meta-data",
"user.vendor-data",
"user.user-data",
+ "cloud-init.user-data",
+ "cloud-init.vendor-data",
)
skip_hotplug_detect = True
--- cloudinit/sources/DataSourceVultr.py.orig
+++ cloudinit/sources/DataSourceVultr.py
@@ -5,6 +5,8 @@
# Vultr Metadata API:
# https://www.vultr.com/metadata/
+from typing import Tuple
+
import cloudinit.sources.helpers.vultr as vultr
from cloudinit import log as log
from cloudinit import sources, util, version
@@ -27,6 +29,9 @@ BUILTIN_DS_CONFIG = {
class DataSourceVultr(sources.DataSource):
dsname = "Vultr"
+ sensitive_metadata_keys: \
+ Tuple[str, ...] = \
+ sources.DataSource.sensitive_metadata_keys + ("startup-script",)
def __init__(self, sys_cfg, distro, paths):
super(DataSourceVultr, self).__init__(sys_cfg, distro, paths)
@@ -54,13 +59,8 @@ class DataSourceVultr(sources.DataSource
self.get_datasource_data(self.metadata)
# Dump some data so diagnosing failures is manageable
- LOG.debug("Vultr Vendor Config:")
- LOG.debug(util.json_dumps(self.metadata["vendor-data"]))
LOG.debug("SUBID: %s", self.metadata["instance-id"])
LOG.debug("Hostname: %s", self.metadata["local-hostname"])
- if self.userdata_raw is not None:
- LOG.debug("User-Data:")
- LOG.debug(self.userdata_raw)
return True
@@ -146,7 +146,4 @@ if __name__ == "__main__":
config = md["vendor-data"]
sysinfo = vultr.get_sysinfo()
- print(util.json_dumps(sysinfo))
- print(util.json_dumps(config))
-
# vi: ts=4 expandtab
--- cloudinit/sources/__init__.py.orig
+++ cloudinit/sources/__init__.py
@@ -132,6 +132,12 @@ def redact_sensitive_keys(metadata, reda
Replace any keys values listed in 'sensitive_keys' with redact_value.
"""
+ # While 'sensitive_keys' should already sanitized to only include what
+ # is in metadata, it is possible keys will overlap. For example, if
+ # "merged_cfg" and "merged_cfg/ds/userdata" both match, it's possible that
+ # "merged_cfg" will get replaced first, meaning "merged_cfg/ds/userdata"
+ # no longer represents a valid key.
+ # Thus, we still need to do membership checks in this function.
if not metadata.get("sensitive_keys", []):
return metadata
md_copy = copy.deepcopy(metadata)
@@ -139,9 +145,14 @@ def redact_sensitive_keys(metadata, reda
path_parts = key_path.split("/")
obj = md_copy
for path in path_parts:
- if isinstance(obj[path], dict) and path != path_parts[-1]:
+ if (
+ path in obj
+ and isinstance(obj[path], dict)
+ and path != path_parts[-1]
+ ):
obj = obj[path]
- obj[path] = redact_value
+ if path in obj:
+ obj[path] = redact_value
return md_copy
@@ -249,6 +260,14 @@ class DataSource(CloudInitPickleMixin, m
sensitive_metadata_keys: Tuple[str, ...] = (
"merged_cfg",
"security-credentials",
+ "userdata",
+ "user-data",
+ "user_data",
+ "vendordata",
+ "vendor-data",
+ # Provide ds/vendor_data to avoid redacting top-level
+ # "vendor_data": {enabled: True}
+ "ds/vendor_data",
)
# True on datasources that may not see hotplugged devices reflected
--- cloudinit/stages.py.orig
+++ cloudinit/stages.py
@@ -203,7 +203,9 @@ class Init:
util.ensure_dirs(self._initial_subdirs())
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
if log_file:
- util.ensure_file(log_file, mode=0o640, preserve_mode=True)
+ # At this point the log file should have already been created
+ # in the setupLogging function of log.py
+ util.ensure_file(log_file, mode=0o640, preserve_mode=False)
perms = self.cfg.get("syslog_fix_perms")
if not perms:
perms = {}
--- tests/unittests/sources/test_init.py.orig
+++ tests/unittests/sources/test_init.py
@@ -464,6 +464,12 @@ class TestDataSource(CiTestCase):
(
"merged_cfg",
"security-credentials",
+ "userdata",
+ "user-data",
+ "user_data",
+ "vendordata",
+ "vendor-data",
+ "ds/vendor_data",
),
datasource.sensitive_metadata_keys,
)
@@ -574,6 +580,12 @@ class TestDataSource(CiTestCase):
(
"merged_cfg",
"security-credentials",
+ "userdata",
+ "user-data",
+ "user_data",
+ "vendordata",
+ "vendor-data",
+ "ds/vendor_data",
),
datasource.sensitive_metadata_keys,
)
--- tests/unittests/test_stages.py.orig
+++ tests/unittests/test_stages.py
@@ -606,19 +606,23 @@ class TestInit_InitializeFilesystem:
# Assert we create it 0o640 by default if it doesn't already exist
assert 0o640 == stat.S_IMODE(log_file.stat().mode)
- def test_existing_file_permissions_are_not_modified(self, init, tmpdir):
- """If the log file already exists, we should not modify its permissions
+ def test_existing_file_permissions(self, init, tmpdir):
+ """Test file permissions are set as expected.
+
+ CIS Hardening requires 640 permissions. These permissions are
+ currently hardcoded on every boot, but if there's ever a reason
+ to change this, we need to then ensure that they
+ are *not* set every boot.
See https://bugs.launchpad.net/cloud-init/+bug/1900837.
"""
- # Use a mode that will never be made the default so this test will
- # always be valid
- mode = 0o606
log_file = tmpdir.join("cloud-init.log")
log_file.ensure()
- log_file.chmod(mode)
+ # Use a mode that will never be made the default so this test will
+ # always be valid
+ log_file.chmod(0o606)
init._cfg = {"def_log_file": str(log_file)}
init._initialize_filesystem()
- assert mode == stat.S_IMODE(log_file.stat().mode)
+ assert 0o640 == stat.S_IMODE(log_file.stat().mode)

View File

@ -0,0 +1,19 @@
--- cloudinit/config/cc_refresh_rmc_and_interface.py.orig
+++ cloudinit/config/cc_refresh_rmc_and_interface.py
@@ -15,7 +15,6 @@ from cloudinit import netinfo, subp, uti
from cloudinit.cloud import Cloud
from cloudinit.config import Config
from cloudinit.config.schema import MetaSchema
-from cloudinit.distros import ALL_DISTROS
from cloudinit.settings import PER_ALWAYS
MODULE_DESCRIPTION = """\
@@ -42,7 +41,7 @@ meta: MetaSchema = {
"name": "Refresh IPv6 Interface and RMC",
"title": "Ensure Network Manager is not managing IPv6 interface",
"description": MODULE_DESCRIPTION,
- "distros": [ALL_DISTROS],
+ "distros": ["fedora", "rhel"],
"frequency": PER_ALWAYS,
"examples": [],
"activate_by_schema_keys": [],

View File

@ -18,7 +18,15 @@
if bring_up:
--- cloudinit/distros/opensuse.py.orig
+++ cloudinit/distros/opensuse.py
@@ -238,6 +238,143 @@ class Distro(distros.Distro):
@@ -15,6 +15,7 @@ from cloudinit import log as logging
from cloudinit import subp, util
from cloudinit.distros import rhel_util as rhutil
from cloudinit.distros.parsers.hostname import HostnameConf
+from cloudinit.net import ipv4_mask_to_net_prefix
from cloudinit.settings import PER_INSTANCE
LOG = logging.getLogger(__name__)
@@ -238,6 +239,144 @@ class Distro(distros.Distro):
conf.set_hostname(hostname)
util.write_file(filename, str(conf), 0o644)
@ -72,10 +80,10 @@
+ )
+ continue
+ if (
+ dest == 'default' and
+ has_default_route and
+ gateway == seen_default_gateway
+ ):
+ dest == 'default'
+ and has_default_route
+ and gateway == seen_default_gateway
+ ):
+ dest_info = dest
+ if gateway:
+ dest_info = ' '.join([dest, gateway, '-', '-'])
@ -138,9 +146,10 @@
+ for route in device_config.get('routes', []):
+ config_routes += self._render_route_string(route)
+ if config_routes:
+ route_file = '/etc/sysconfig/network/ifroute-{}'.format(
+ device_name
+ )
+ route_file = \
+ '/etc/sysconfig/network/ifroute-{}'.format(
+ device_name
+ )
+ util.write_file(route_file, config_routes)
+ except Exception:
+ # the parser above epxects another level of nesting

View File

@ -1,3 +1,29 @@
-------------------------------------------------------------------
Thu Jul 6 12:06:22 UTC 2023 - Robert Schweikert <rjschwei@suse.com>
- Update cloud-init-write-routes.patch (bsc#1212879)
+ Add necessary import statement
- Enable flake8 linting, fix up patches
+ cloud-init-cve-2023-1786-redact-instance-data-json-main.patch
+ cloud-init-power-rhel-only.patch
+ cloud-init-write-routes.patch
+ datasourceLocalDisk.patch
-------------------------------------------------------------------
Thu Apr 27 12:22:11 UTC 2023 - Robert Schweikert <rjschwei@suse.com>
- Add cloud-init-power-rhel-only.patch (bsc#1210273)
+ Config module cc_refresh_rmc_and_interface is implemented such that
it will only work on RH distros. Set the module availability accordingly.
-------------------------------------------------------------------
Tue Apr 11 18:48:30 UTC 2023 - Robert Schweikert <rjschwei@suse.com>
- Sensitive data exposure (bsc#1210277, CVE-2023-1786)
+ Add hidesensitivedata
+ Add cloud-init-cve-2023-1786-redact-inst-data.patch
+ Do not expose sensitive data gathered from the CSP
-------------------------------------------------------------------
Thu Feb 23 13:38:43 UTC 2023 - Robert Schweikert <rjschwei@suse.com>
@ -1642,7 +1668,7 @@ Wed Jun 2 12:13:54 UTC 2021 - Robert Schweikert <rjschwei@suse.com>
- Add cloud-init-log-file-mode.patch (bsc#1183939)
+ Change log file creation mode to 640
- Add cloud-init-no-pwd-in-log.patch (bsc#1184758)
- Add cloud-init-no-pwd-in-log.patch (bsc#1184758, CVE-2021-3429)
+ Do not write the generated password to the log file
- Add cloud-init-purge-cache-py-ver-change.patch

View File

@ -26,6 +26,7 @@ Url: https://github.com/canonical/cloud-init
Group: System/Management
Source0: %{name}-%{version}.tar.gz
Source1: rsyslog-cloud-init.cfg
Source2: hidesensitivedata
Patch1: datasourceLocalDisk.patch
# FIXME (lp#1849296)
Patch2: cloud-init-break-resolv-symlink.patch
@ -37,6 +38,9 @@ Patch4: cloud-init-no-tempnet-oci.patch
Patch5: cloud-init-fix-ca-test.patch
# FIXME (lp#1812117)
Patch6: cloud-init-write-routes.patch
Patch7: cloud-init-cve-2023-1786-redact-instance-data-json-main.patch
# FIXME https://github.com/canonical/cloud-init/pull/2148
Patch8: cloud-init-power-rhel-only.patch
BuildRequires: fdupes
BuildRequires: filesystem
# pkg-config is needed to find correct systemd unit dir
@ -50,6 +54,7 @@ BuildRequires: python3-setuptools
BuildRequires: python3-Jinja2
BuildRequires: python3-PyYAML
BuildRequires: python3-configobj >= 5.0.2
BuildRequires: python3-flake8
BuildRequires: python3-httpretty
BuildRequires: python3-jsonpatch
BuildRequires: python3-jsonschema
@ -84,7 +89,6 @@ Requires: python3-oauthlib
Requires: python3-pyserial
Requires: python3-PyYAML
Requires: python3-requests
Requires: python3-responses
Requires: python3-serial
Requires: python3-setuptools
Requires: python3-xml
@ -142,6 +146,8 @@ Documentation and examples for cloud-init tools
%patch4
%patch5
%patch6
%patch7
%patch8
# patch in the full version to version.py
version_pys=$(find . -name version.py -type f)
@ -154,6 +160,7 @@ python3 setup.py build
%check
make unittest
make flake8
%install
python3 setup.py install --root=%{buildroot} --prefix=%{_prefix} --install-lib=%{python3_sitelib} --init-system=%{initsys}
@ -185,6 +192,8 @@ mkdir -p %{buildroot}/%{_sysconfdir}/rsyslog.d
mkdir -p %{buildroot}/usr/lib/udev/rules.d/
cp -a %{SOURCE1} %{buildroot}/%{_sysconfdir}/rsyslog.d/21-cloudinit.conf
mv %{buildroot}/lib/udev/rules.d/66-azure-ephemeral.rules %{buildroot}/usr/lib/udev/rules.d/
mkdir -p %{buildroot}%{_sbindir}
install -m 755 %{SOURCE2} %{buildroot}%{_sbindir}
# remove debian/ubuntu specific profile.d file (bnc#779553)
rm -f %{buildroot}%{_sysconfdir}/profile.d/Z99-cloud-locale-test.sh
@ -194,6 +203,9 @@ rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.debian.*
rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.redhat.*
rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.ubuntu.*
%post
/usr/sbin/hidesensitivedata
# remove duplicate files
%if 0%{?suse_version}
%fdupes %{buildroot}%{python3_sitelib}
@ -205,6 +217,7 @@ rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.ubuntu.*
%{_bindir}/cloud-id
%{_bindir}/cloud-init
%{_bindir}/cloud-init-per
%{_sbindir}/hidesensitivedata
%dir %{_sysconfdir}/cloud
%dir %{_sysconfdir}/cloud/clean.d
%{_sysconfdir}/cloud/clean.d/README

View File

@ -1,6 +1,6 @@
--- cloudinit/sources/DataSourceLocalDisk.py 2016/11/25 19:01:00 1.1
+++ cloudinit/sources/DataSourceLocalDisk.py 2016/11/26 20:42:02
@@ -0,0 +1,101 @@
--- /dev/null
+++ cloudinit/sources/DataSourceLocalDisk.py
@@ -0,0 +1,107 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2016 SUSE Linux GmbH
@ -51,17 +51,22 @@
+
+ # Check to see if the seed dir has data.
+ try:
+ seeded = util.pathprefix2dict(self.seed_dir, ['user-data','meta-data'],['vendor-data'])
+ seeded = util.pathprefix2dict(
+ self.seed_dir, ['user-data', 'meta-data'], ['vendor-data']
+ )
+ found.append(self.seed_dir)
+ mydata = _merge_new_seed(mydata, seeded)
+ except ValueError as e:
+ except ValueError:
+ pass
+
+ try:
+ seeded = util.pathprefix2dict('/cloud-init-config', ['user-data','meta-data'],['vendor-data'])
+ seeded = util.pathprefix2dict(
+ '/cloud-init-config', ['user-data', 'meta-data'],
+ ['vendor-data']
+ )
+ found.append('/cloud-init-config')
+ mydata = _merge_new_seed(mydata, seeded)
+ except ValueError as e:
+ except ValueError:
+ return False
+
+ # Merge in the defaults
@ -78,6 +83,7 @@
+ # quickly (local check only) if self.instance_id is still valid
+ return sources.instance_id_matches_system_uuid(self.get_instance_id())
+
+
+def _merge_new_seed(cur, seeded):
+ ret = cur.copy()
+

36
hidesensitivedata Normal file
View File

@ -0,0 +1,36 @@
#!/usr/bin/python3
import json
import os
import sys
from pathlib import Path
from cloudinit.atomic_helper import write_json
from cloudinit.sources import (
DataSource,
process_instance_metadata,
redact_sensitive_keys,
)
from cloudinit.stages import Init
init = Init()
log_file = init.cfg["def_log_file"]
if os.path.exists(log_file):
os.chmod(log_file, 0o640)
rundir = init.paths.run_dir
instance_data_path = Path(rundir, "instance-data.json")
if not os.path.exists(str(instance_data_path)):
sys.exit(0)
instance_json = json.load(instance_data_path.open(encoding="utf-8"))
sensitive_keys = DataSource.sensitive_metadata_keys
processed_json = process_instance_metadata(
instance_json, sensitive_keys=sensitive_keys
)
redacted_json = redact_sensitive_keys(processed_json)
write_json(str(instance_data_path), redacted_json)