fix CVE-2023-1786
This commit is contained in:
parent
34d34f17fb
commit
bcadb2788d
@ -0,0 +1,138 @@
|
||||
From a378b7e4f47375458651c0972e7cd813f6fe0a6b Mon Sep 17 00:00:00 2001
|
||||
From: James Falcon <james.falcon@canonical.com>
|
||||
Date: Wed, 26 Apr 2023 15:11:55 -0500
|
||||
Subject: [PATCH] Make user/vendor data sensitive and remove log permissions
|
||||
(#2144)
|
||||
|
||||
Because user data and vendor data may contain sensitive information,
|
||||
this commit ensures that any user data or vendor data written to
|
||||
instance-data.json gets redacted and is only available to root user.
|
||||
|
||||
Also, modify the permissions of cloud-init.log to be 640, so that
|
||||
sensitive data leaked to the log isn't world readable.
|
||||
Additionally, remove the logging of user data and vendor data to
|
||||
cloud-init.log from the Vultr datasource.
|
||||
|
||||
LP: #2013967
|
||||
CVE: CVE-2023-1786
|
||||
---
|
||||
cloudinit/sources/__init__.py | 28 +++++++++++++++++++++++++---
|
||||
cloudinit/stages.py | 4 +++-
|
||||
cloudinit/sources/tests/test_init.py | 27 ++++++++++++++++++++++++++-
|
||||
3 files changed, 49 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
|
||||
index 90521ba2..9d91512f 100644
|
||||
--- a/cloudinit/sources/__init__.py
|
||||
+++ b/cloudinit/sources/__init__.py
|
||||
@@ -111,7 +111,10 @@ def process_instance_metadata(metadata, key_path="", sensitive_keys=()):
|
||||
sub_key_path = key_path + '/' + key
|
||||
else:
|
||||
sub_key_path = key
|
||||
- if key in sensitive_keys or sub_key_path in sensitive_keys:
|
||||
+ if (
|
||||
+ key.lower() in sensitive_keys
|
||||
+ or sub_key_path.lower() in sensitive_keys
|
||||
+ ):
|
||||
md_copy['sensitive_keys'].append(sub_key_path)
|
||||
if isinstance(val, str) and val.startswith('ci-b64:'):
|
||||
md_copy['base64_encoded_keys'].append(sub_key_path)
|
||||
@@ -133,6 +136,12 @@ def redact_sensitive_keys(metadata, redact_value=REDACT_SENSITIVE_VALUE):
|
||||
|
||||
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)
|
||||
@@ -140,9 +149,14 @@ def redact_sensitive_keys(metadata, redact_value=REDACT_SENSITIVE_VALUE):
|
||||
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
|
||||
|
||||
|
||||
@@ -215,7 +229,18 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
|
||||
|
||||
# N-tuple of keypaths or keynames redact from instance-data.json for
|
||||
# non-root users
|
||||
- sensitive_metadata_keys = ('security-credentials',)
|
||||
+ sensitive_metadata_keys = (
|
||||
+ "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",
|
||||
+ )
|
||||
|
||||
def __init__(self, sys_cfg, distro, paths, ud_proc=None):
|
||||
self.sys_cfg = sys_cfg
|
||||
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||
index 65f952e7..509d8f7f 100644
|
||||
--- a/cloudinit/stages.py
|
||||
+++ b/cloudinit/stages.py
|
||||
@@ -203,7 +203,9 @@ class Init(object):
|
||||
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 = {}
|
||||
diff --git a/cloudinit/sources/tests/test_init.py b/cloudinit/sources/tests/test_init.py
|
||||
index 96e4dd90..005a571b 100644
|
||||
--- a/cloudinit/sources/tests/test_init.py
|
||||
+++ b/cloudinit/sources/tests/test_init.py
|
||||
@@ -329,9 +329,24 @@ class TestDataSource(CiTestCase):
|
||||
'local-hostname': 'test-subclass-hostname',
|
||||
'region': 'myregion',
|
||||
'some': {'security-credentials': {
|
||||
- 'cred1': 'sekret', 'cred2': 'othersekret'}}})
|
||||
+ 'cred1': 'sekret', 'cred2': 'othersekret'
|
||||
+ }
|
||||
+ },
|
||||
+ },
|
||||
+ )
|
||||
self.assertEqual(
|
||||
- ('security-credentials',), datasource.sensitive_metadata_keys)
|
||||
+ (
|
||||
+ "merged_cfg",
|
||||
+ "security-credentials",
|
||||
+ "userdata",
|
||||
+ "user-data",
|
||||
+ "user_data",
|
||||
+ "vendordata",
|
||||
+ "vendor-data",
|
||||
+ "ds/vendor_data",
|
||||
+ ),
|
||||
+ datasource.sensitive_metadata_keys,
|
||||
+ )
|
||||
datasource.get_data()
|
||||
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
||||
sensitive_json_file = self.tmp_path(INSTANCE_JSON_SENSITIVE_FILE, tmp)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
28
backport-Create-the-log-file-with-640-permissions-858.patch
Normal file
28
backport-Create-the-log-file-with-640-permissions-858.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 29ac50f2b9e7634fc59fc161d77d27e970ae8080 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Schweikert <rjschwei@suse.com>
|
||||
Date: Wed, 2 Jun 2021 17:10:32 -0400
|
||||
Subject: [PATCH] - Create the log file with 640 permissions (#858)
|
||||
|
||||
Security scanners are often simple minded and complain on arbitrary
|
||||
settings such as file permissions. For /var/log/* having world read is
|
||||
one of these cases.
|
||||
---
|
||||
cloudinit/stages.py | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||
index bbded1e9..3688be2e 100644
|
||||
--- a/cloudinit/stages.py
|
||||
+++ b/cloudinit/stages.py
|
||||
@@ -156,7 +156,7 @@ class Init(object):
|
||||
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, preserve_mode=True)
|
||||
+ util.ensure_file(log_file, mode=0o640, preserve_mode=True)
|
||||
perms = self.cfg.get('syslog_fix_perms')
|
||||
if not perms:
|
||||
perms = {}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
From f5b3ad741679cd42d2c145e574168dafe3ac15c1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Watkins <oddbloke@ubuntu.com>
|
||||
Date: Fri, 23 Oct 2020 15:20:18 -0400
|
||||
Subject: [PATCH] stages: don't reset permissions of cloud-init.log every boot
|
||||
(#624)
|
||||
|
||||
ensure_file needed modification to support doing this, so this commit
|
||||
also includes the following changes:
|
||||
|
||||
test_util: add tests for util.ensure_file
|
||||
util: add preserve_mode parameter to ensure_file
|
||||
util: add (partial) type annotations to ensure_file
|
||||
|
||||
LP: #1900837
|
||||
---
|
||||
cloudinit/stages.py | 2 +-
|
||||
cloudinit/tests/test_util.py | 45 ++++++++++++++++++++++++
|
||||
cloudinit/util.py | 8 +++--
|
||||
3 files changed, 52 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||
index 765f4aab..0cce6e80 100644
|
||||
--- a/cloudinit/stages.py
|
||||
+++ b/cloudinit/stages.py
|
||||
@@ -148,7 +148,7 @@ class Init(object):
|
||||
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)
|
||||
+ util.ensure_file(log_file, preserve_mode=True)
|
||||
perms = self.cfg.get('syslog_fix_perms')
|
||||
if not perms:
|
||||
perms = {}
|
||||
diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py
|
||||
index 096a3037..77714928 100644
|
||||
--- a/cloudinit/tests/test_util.py
|
||||
+++ b/cloudinit/tests/test_util.py
|
||||
@@ -771,4 +771,49 @@ class TestRedirectOutputPreexecFn:
|
||||
|
||||
assert 0 == m_setgid.call_count
|
||||
|
||||
+@mock.patch("cloudinit.util.write_file")
|
||||
+class TestEnsureFile:
|
||||
+ """Tests for ``cloudinit.util.ensure_file``."""
|
||||
+
|
||||
+ def test_parameters_passed_through(self, m_write_file):
|
||||
+ """Test the parameters in the signature are passed to write_file."""
|
||||
+ util.ensure_file(
|
||||
+ mock.sentinel.path,
|
||||
+ mode=mock.sentinel.mode,
|
||||
+ preserve_mode=mock.sentinel.preserve_mode,
|
||||
+ )
|
||||
+
|
||||
+ assert 1 == m_write_file.call_count
|
||||
+ args, kwargs = m_write_file.call_args
|
||||
+ assert (mock.sentinel.path,) == args
|
||||
+ assert mock.sentinel.mode == kwargs["mode"]
|
||||
+ assert mock.sentinel.preserve_mode == kwargs["preserve_mode"]
|
||||
+
|
||||
+ @pytest.mark.parametrize(
|
||||
+ "kwarg,expected",
|
||||
+ [
|
||||
+ # Files should be world-readable by default
|
||||
+ ("mode", 0o644),
|
||||
+ # The previous behaviour of not preserving mode should be retained
|
||||
+ ("preserve_mode", False),
|
||||
+ ],
|
||||
+ )
|
||||
+ def test_defaults(self, m_write_file, kwarg, expected):
|
||||
+ """Test that ensure_file defaults appropriately."""
|
||||
+ util.ensure_file(mock.sentinel.path)
|
||||
+
|
||||
+ assert 1 == m_write_file.call_count
|
||||
+ _args, kwargs = m_write_file.call_args
|
||||
+ assert expected == kwargs[kwarg]
|
||||
+
|
||||
+ def test_static_parameters_are_passed(self, m_write_file):
|
||||
+ """Test that the static write_files parameters are passed correctly."""
|
||||
+ util.ensure_file(mock.sentinel.path)
|
||||
+
|
||||
+ assert 1 == m_write_file.call_count
|
||||
+ _args, kwargs = m_write_file.call_args
|
||||
+ assert "" == kwargs["content"]
|
||||
+ assert "ab" == kwargs["omode"]
|
||||
+
|
||||
+
|
||||
# vi: ts=4 expandtab
|
||||
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
||||
index e47f1cf6..83727544 100644
|
||||
--- a/cloudinit/util.py
|
||||
+++ b/cloudinit/util.py
|
||||
@@ -1804,8 +1804,10 @@ def append_file(path, content):
|
||||
write_file(path, content, omode="ab", mode=None)
|
||||
|
||||
|
||||
-def ensure_file(path, mode=0o644):
|
||||
- write_file(path, content='', omode="ab", mode=mode)
|
||||
+def ensure_file(path, mode=0o644, preserve_mode=False):
|
||||
+ write_file(
|
||||
+ path, content="", omode="ab", mode=mode, copy_mode=preserve_mode
|
||||
+ )
|
||||
|
||||
|
||||
def safe_int(possible_int):
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: cloud-init
|
||||
Version: 19.4
|
||||
Release: 12
|
||||
Release: 13
|
||||
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
|
||||
@ -20,6 +20,9 @@ Patch9: backport-testing-add-additional-mocks-to-test_net-tests-1356.patch
|
||||
Patch10:fix-a-small-unitest-error.patch
|
||||
Patch11: backport-CVE-2022-2084.patch
|
||||
Patch12: remove-schema-errors-from-log-for-cloudinit-config-cc_.patch
|
||||
Patch13: backport-stages-don-t-reset-permissions-of-cloud-init.log-eve.patch
|
||||
Patch14: backport-Create-the-log-file-with-640-permissions-858.patch
|
||||
Patch15: backport-CVE-2023-1786-Make-user-vendor-data-sensitive-and-remove-log-permi.patch
|
||||
|
||||
Patch9000: Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch
|
||||
|
||||
@ -128,6 +131,9 @@ fi
|
||||
%exclude /usr/share/doc/*
|
||||
|
||||
%changelog
|
||||
* Wed May 24 2023 fuanan <fuanan3@h-partners.com> - 19.4-13
|
||||
- fix CVE-2023-1786
|
||||
|
||||
* Sun May 14 2023 shixuantong <shixuantong1@huawei.com> - 19.4-12
|
||||
- fix CVE-2022-2084
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user