Codebase list glance / 6dae3df
* Removed patch applied upstream: - CVE-2022-47951-Enforce_image_safety_during_image_conversion.patch Thomas Goirand 1 year, 1 month ago
3 changed file(s) with 2 addition(s) and 142 deletion(s). Raw diff Collapse all Expand all
22 * New upstream release.
33 * Removed (build-)depends versions when satisfied in Bookworm.
44 * Removed lsb-base depends.
5 * Removed patch applied upstream:
6 - CVE-2022-47951-Enforce_image_safety_during_image_conversion.patch
57
68 -- Thomas Goirand <zigo@debian.org> Mon, 06 Mar 2023 16:46:16 +0100
79
+0
-141
debian/patches/CVE-2022-47951-Enforce_image_safety_during_image_conversion.patch less more
0 From 4967ab6935cfd0274ae801ac943d01909a236a0a Mon Sep 17 00:00:00 2001
1 From: Dan Smith <dansmith@redhat.com>
2 Date: Mon, 19 Dec 2022 15:00:35 +0000
3 Subject: [PATCH] Enforce image safety during image_conversion
4
5 This does two things:
6
7 1. It makes us check that the QCOW backing_file is unset on those
8 types of images. Nova and Cinder do this already to prevent an
9 arbitrary (and trivial to accomplish) host file exposure exploit.
10 2. It makes us restrict VMDK files to only allowed subtypes. These
11 files can name arbitrary files on disk as extents, providing the
12 same sort of attack. Default that list to just the types we believe
13 are actually useful for openstack, and which are monolithic.
14
15 The configuration option to specify allowed subtypes is added in
16 glance's config and not in the import options so that we can extend
17 this check later to image ingest. The format_inspector can tell us
18 what the type and subtype is, and we could reject those images early
19 and even in the case where image_conversion is not enabled.
20
21 Closes-Bug: #1996188
22 Change-Id: Idf561f6306cebf756c787d8eefdc452ce44bd5e0
23 (cherry picked from commit 0d6282a01691cecc2798f7858b181c4bb30f850c)
24 ---
25
26 diff --git a/glance/async_/flows/plugins/image_conversion.py b/glance/async_/flows/plugins/image_conversion.py
27 index 32c7b7f..e977764 100644
28 --- a/glance/async_/flows/plugins/image_conversion.py
29 +++ b/glance/async_/flows/plugins/image_conversion.py
30 @@ -116,6 +116,29 @@
31 virtual_size = metadata.get('virtual-size', 0)
32 action.set_image_attribute(virtual_size=virtual_size)
33
34 + if 'backing-filename' in metadata:
35 + LOG.warning('Refusing to process QCOW image with a backing file')
36 + raise RuntimeError(
37 + 'QCOW images with backing files are not allowed')
38 +
39 + if metadata.get('format') == 'vmdk':
40 + create_type = metadata.get(
41 + 'format-specific', {}).get(
42 + 'data', {}).get('create-type')
43 + allowed = CONF.image_format.vmdk_allowed_types
44 + if not create_type:
45 + raise RuntimeError(_('Unable to determine VMDK create-type'))
46 + if not len(allowed):
47 + LOG.warning(_('Refusing to process VMDK file as '
48 + 'vmdk_allowed_types is empty'))
49 + raise RuntimeError(_('Image is a VMDK, but no VMDK createType '
50 + 'is specified'))
51 + if create_type not in allowed:
52 + LOG.warning(_('Refusing to process VMDK file with create-type '
53 + 'of %r which is not in allowed set of: %s'),
54 + create_type, ','.join(allowed))
55 + raise RuntimeError(_('Invalid VMDK create-type specified'))
56 +
57 if source_format == target_format:
58 LOG.debug("Source is already in target format, "
59 "not doing conversion for %s", self.image_id)
60 diff --git a/glance/common/config.py b/glance/common/config.py
61 index dd7e1b6..7891dac 100644
62 --- a/glance/common/config.py
63 +++ b/glance/common/config.py
64 @@ -99,6 +99,18 @@
65 "image attribute"),
66 deprecated_opts=[cfg.DeprecatedOpt('disk_formats',
67 group='DEFAULT')]),
68 + cfg.ListOpt('vmdk_allowed_types',
69 + default=['streamOptimized', 'monolithicSparse'],
70 + help=_("A list of strings describing allowed VMDK "
71 + "'create-type' subformats that will be allowed. "
72 + "This is recommended to only include "
73 + "single-file-with-sparse-header variants to avoid "
74 + "potential host file exposure due to processing named "
75 + "extents. If this list is empty, then no VDMK image "
76 + "types allowed. Note that this is currently only "
77 + "checked during image conversion (if enabled), and "
78 + "limits the types of VMDK images we will convert "
79 + "from.")),
80 ]
81 task_opts = [
82 cfg.IntOpt('task_time_to_live',
83 diff --git a/glance/tests/unit/async_/flows/plugins/test_image_conversion.py b/glance/tests/unit/async_/flows/plugins/test_image_conversion.py
84 index 77d68ac..a60e2e1 100644
85 --- a/glance/tests/unit/async_/flows/plugins/test_image_conversion.py
86 +++ b/glance/tests/unit/async_/flows/plugins/test_image_conversion.py
87 @@ -172,6 +172,53 @@
88 # Make sure we did not update the image
89 self.img_repo.save.assert_not_called()
90
91 + def test_image_convert_invalid_qcow(self):
92 + data = {'format': 'qcow2',
93 + 'backing-filename': '/etc/hosts'}
94 +
95 + convert = self._setup_image_convert_info_fail()
96 + with mock.patch.object(processutils, 'execute') as exc_mock:
97 + exc_mock.return_value = json.dumps(data), ''
98 + e = self.assertRaises(RuntimeError,
99 + convert.execute, 'file:///test/path.qcow')
100 + self.assertEqual('QCOW images with backing files are not allowed',
101 + str(e))
102 +
103 + def _test_image_convert_invalid_vmdk(self):
104 + data = {'format': 'vmdk',
105 + 'format-specific': {
106 + 'data': {
107 + 'create-type': 'monolithicFlat',
108 + }}}
109 +
110 + convert = self._setup_image_convert_info_fail()
111 + with mock.patch.object(processutils, 'execute') as exc_mock:
112 + exc_mock.return_value = json.dumps(data), ''
113 + convert.execute('file:///test/path.vmdk')
114 +
115 + def test_image_convert_invalid_vmdk(self):
116 + e = self.assertRaises(RuntimeError,
117 + self._test_image_convert_invalid_vmdk)
118 + self.assertEqual('Invalid VMDK create-type specified', str(e))
119 +
120 + def test_image_convert_valid_vmdk_no_types(self):
121 + with mock.patch.object(CONF.image_format, 'vmdk_allowed_types',
122 + new=[]):
123 + # We make it past the VMDK check and fail because our file
124 + # does not exist
125 + e = self.assertRaises(RuntimeError,
126 + self._test_image_convert_invalid_vmdk)
127 + self.assertEqual('Image is a VMDK, but no VMDK createType is '
128 + 'specified', str(e))
129 +
130 + def test_image_convert_valid_vmdk(self):
131 + with mock.patch.object(CONF.image_format, 'vmdk_allowed_types',
132 + new=['monolithicSparse', 'monolithicFlat']):
133 + # We make it past the VMDK check and fail because our file
134 + # does not exist
135 + self.assertRaises(FileNotFoundError,
136 + self._test_image_convert_invalid_vmdk)
137 +
138 def test_image_convert_fails(self):
139 convert = self._setup_image_convert_info_fail()
140 with mock.patch.object(processutils, 'execute') as exc_mock:
00 sql_conn-registry.patch
11 missing-files.patch
2 CVE-2022-47951-Enforce_image_safety_during_image_conversion.patch