Reject qcow files with data-file attributes

Change-Id: I6326a3e85c1ba4cb1da944a4323769f2399ed2c1
Closes-Bug: #2059809
(cherry picked from commit 2ca29af4433e9fa99a0a48e230d8d25d6eaa4a87)
(cherry picked from commit c3586f3a122f6cb0663217b12b52203e74e2e4fa)
(cherry picked from commit a92c438fb5ba55440b38cae7c8b4361b58daa9dd)
(cherry picked from commit dba3bdb458)
(cherry picked from commit 6a38aef8ba)
This commit is contained in:
Dan Smith 2024-04-01 08:06:31 -07:00 committed by Lajos Katona
parent 33cc158311
commit f7f7249b34
4 changed files with 67 additions and 0 deletions

View File

@ -181,6 +181,16 @@ class _ImportToFS(task.Task):
'bfile': backing_file} 'bfile': backing_file}
raise RuntimeError(msg) raise RuntimeError(msg)
try:
data_file = metadata['format-specific']['data']['data-file']
except KeyError:
data_file = None
if data_file is not None:
msg = _("File %(path)s has invalid data-file "
"%(dfile)s, aborting.") % {"path": path,
"dfile": data_file}
raise RuntimeError(msg)
return path return path
def revert(self, image_id, result, **kwargs): def revert(self, image_id, result, **kwargs):

View File

@ -122,6 +122,14 @@ class _ConvertImage(task.Task):
raise RuntimeError( raise RuntimeError(
'QCOW images with backing files are not allowed') 'QCOW images with backing files are not allowed')
try:
data_file = metadata['format-specific']['data']['data-file']
except KeyError:
data_file = None
if data_file is not None:
raise RuntimeError(
'QCOW images with data-file set are not allowed')
if metadata.get('format') == 'vmdk': if metadata.get('format') == 'vmdk':
create_type = metadata.get( create_type = metadata.get(
'format-specific', {}).get( 'format-specific', {}).get(

View File

@ -185,6 +185,22 @@ class TestConvertImageTask(test_utils.BaseTestCase):
self.assertEqual('QCOW images with backing files are not allowed', self.assertEqual('QCOW images with backing files are not allowed',
str(e)) str(e))
def test_image_convert_invalid_qcow_data_file(self):
data = {'format': 'qcow2',
'format-specific': {
'data': {
'data-file': '/etc/hosts',
},
}}
convert = self._setup_image_convert_info_fail()
with mock.patch.object(processutils, 'execute') as exc_mock:
exc_mock.return_value = json.dumps(data), ''
e = self.assertRaises(RuntimeError,
convert.execute, 'file:///test/path.qcow')
self.assertEqual('QCOW images with data-file set are not allowed',
str(e))
def _test_image_convert_invalid_vmdk(self): def _test_image_convert_invalid_vmdk(self):
data = {'format': 'vmdk', data = {'format': 'vmdk',
'format-specific': { 'format-specific': {

View File

@ -178,6 +178,39 @@ class TestImportTask(test_utils.BaseTestCase):
self.assertFalse(os.path.exists(tmp_image_path)) self.assertFalse(os.path.exists(tmp_image_path))
self.assertTrue(os.path.exists(image_path)) self.assertTrue(os.path.exists(image_path))
def test_import_flow_invalid_data_file(self):
self.config(engine_mode='serial',
group='taskflow_executor')
img_factory = mock.MagicMock()
executor = taskflow_executor.TaskExecutor(
self.context,
self.task_repo,
self.img_repo,
img_factory)
self.task_repo.get.return_value = self.task
def create_image(*args, **kwargs):
kwargs['image_id'] = UUID1
return self.img_factory.new_image(*args, **kwargs)
self.img_repo.get.return_value = self.image
img_factory.new_image.side_effect = create_image
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = io.BytesIO(b"TEST_IMAGE")
with mock.patch.object(putils, 'trycmd') as tmock:
out = json.dumps({'format-specific':
{'data': {'data-file': 'somefile'}}})
tmock.return_value = (out, '')
e = self.assertRaises(RuntimeError,
executor.begin_processing,
self.task.task_id)
self.assertIn('somefile', str(e))
def test_import_flow_revert_import_to_fs(self): def test_import_flow_revert_import_to_fs(self):
self.config(engine_mode='serial', group='taskflow_executor') self.config(engine_mode='serial', group='taskflow_executor')