Skip to content

Commit 186a1f6

Browse files
authored
Merge pull request #34 from stackhpc/yoga-cve-2024-32498
yoga: Backport fixes for CVE-2024-32498
2 parents 134b3e5 + 543b1f3 commit 186a1f6

File tree

8 files changed

+515
-35
lines changed

8 files changed

+515
-35
lines changed

glance/async_/flows/base_import.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,16 @@ def execute(self, image_id):
181181
'bfile': backing_file}
182182
raise RuntimeError(msg)
183183

184+
try:
185+
data_file = metadata['format-specific']['data']['data-file']
186+
except KeyError:
187+
data_file = None
188+
if data_file is not None:
189+
msg = _("File %(path)s has invalid data-file "
190+
"%(dfile)s, aborting.") % {"path": path,
191+
"dfile": data_file}
192+
raise RuntimeError(msg)
193+
184194
return path
185195

186196
def revert(self, image_id, result, **kwargs):

glance/async_/flows/plugins/image_conversion.py

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from taskflow import task
2727

2828
from glance.async_ import utils
29+
from glance.common import format_inspector
2930
from glance.i18n import _, _LI
3031

3132
LOG = logging.getLogger(__name__)
@@ -88,8 +89,43 @@ def _execute(self, action, file_path, **kwargs):
8889
'target': target_format}
8990
self.dest_path = dest_path
9091

92+
# Backport fixup due to lack of
93+
# Ic51c5fd87caf04d38aeaf758ad2d0e2f28098e4d in Yoga:
94+
#source_format = action.image_disk_format
95+
source_format = action._image.disk_format
96+
inspector_cls = format_inspector.get_inspector(source_format)
97+
if not inspector_cls:
98+
# We cannot convert from disk_format types that qemu-img doesn't
99+
# support (like iso, ploop, etc). The ones it supports overlaps
100+
# with the ones we have inspectors for, so reject conversion for
101+
# any format we don't have an inspector for.
102+
raise RuntimeError(
103+
'Unable to convert from format %s' % source_format)
104+
105+
# Use our own cautious inspector module (if we have one for this
106+
# format) to make sure a file is the format the submitter claimed
107+
# it is and that it passes some basic safety checks _before_ we run
108+
# qemu-img on it.
109+
# See https://bugs.launchpad.net/nova/+bug/2059809 for details.
110+
try:
111+
inspector = inspector_cls.from_file(src_path)
112+
if not inspector.safety_check():
113+
LOG.error('Image failed %s safety check; aborting conversion',
114+
source_format)
115+
raise RuntimeError('Image has disallowed configuration')
116+
except RuntimeError:
117+
raise
118+
except format_inspector.ImageFormatError as e:
119+
LOG.error('Image claimed to be %s format failed format '
120+
'inspection: %s', source_format, e)
121+
raise RuntimeError('Image format detection failed')
122+
except Exception as e:
123+
LOG.exception('Unknown error inspecting image format: %s', e)
124+
raise RuntimeError('Unable to inspect image')
125+
91126
try:
92127
stdout, stderr = putils.trycmd("qemu-img", "info",
128+
"-f", source_format,
93129
"--output=json",
94130
src_path,
95131
prlimit=utils.QEMU_IMG_PROC_LIMITS,
@@ -106,13 +142,10 @@ def _execute(self, action, file_path, **kwargs):
106142
raise RuntimeError(stderr)
107143

108144
metadata = json.loads(stdout)
109-
try:
110-
source_format = metadata['format']
111-
except KeyError:
112-
msg = ("Failed to do introspection as part of image "
113-
"conversion for %(iid)s: Source format not reported")
114-
LOG.error(msg, {'iid': self.image_id})
115-
raise RuntimeError(msg)
145+
if metadata.get('format') != source_format:
146+
LOG.error('Image claiming to be %s reported as %s by qemu-img',
147+
source_format, metadata.get('format', 'unknown'))
148+
raise RuntimeError('Image metadata disagrees about format')
116149

117150
virtual_size = metadata.get('virtual-size', 0)
118151
action.set_image_attribute(virtual_size=virtual_size)
@@ -122,6 +155,14 @@ def _execute(self, action, file_path, **kwargs):
122155
raise RuntimeError(
123156
'QCOW images with backing files are not allowed')
124157

158+
try:
159+
data_file = metadata['format-specific']['data']['data-file']
160+
except KeyError:
161+
data_file = None
162+
if data_file is not None:
163+
raise RuntimeError(
164+
'QCOW images with data-file set are not allowed')
165+
125166
if metadata.get('format') == 'vmdk':
126167
create_type = metadata.get(
127168
'format-specific', {}).get(

0 commit comments

Comments
 (0)