Disallow backing files when uploading volumes to image
Volumes with a header referencing a backing file can leak
file data into the destination image when uploading a
volume to an image.
Halt the upload process if the volume data references a
backing file to prevent this.
Closes-Bug: #1415087
Change-Id: Iab9718794e7f7e8444015712cfa08c46848ebf78
(cherry picked from commit b1143ee453
)
This commit is contained in:
parent
f8149fc83f
commit
9634b76ba5
|
@ -344,6 +344,20 @@ def upload_volume(context, image_service, image_meta, volume_path,
|
|||
with temporary_file() as tmp:
|
||||
LOG.debug("%s was %s, converting to %s",
|
||||
image_id, volume_format, image_meta['disk_format'])
|
||||
|
||||
data = qemu_img_info(volume_path, run_as_root=run_as_root)
|
||||
backing_file = data.backing_file
|
||||
fmt = data.file_format
|
||||
if backing_file is not None:
|
||||
# Disallow backing files as a security measure.
|
||||
# This prevents a user from writing an image header into a raw
|
||||
# volume with a backing file pointing to data they wish to
|
||||
# access.
|
||||
raise exception.ImageUnacceptable(
|
||||
image_id=image_id,
|
||||
reason=_("fmt=%(fmt)s backed by:%(backing_file)s")
|
||||
% {'fmt': fmt, 'backing_file': backing_file})
|
||||
|
||||
convert_image(volume_path, tmp, image_meta['disk_format'],
|
||||
run_as_root=run_as_root)
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ class TestUploadVolume(test.TestCase):
|
|||
mock_os.name = 'posix'
|
||||
data = mock_info.return_value
|
||||
data.file_format = mock.sentinel.disk_format
|
||||
data.backing_file = None
|
||||
temp_file = mock_temp.return_value.__enter__.return_value
|
||||
|
||||
output = image_utils.upload_volume(ctxt, image_service, image_meta,
|
||||
|
@ -391,7 +392,8 @@ class TestUploadVolume(test.TestCase):
|
|||
temp_file,
|
||||
mock.sentinel.disk_format,
|
||||
run_as_root=True)
|
||||
mock_info.assert_called_once_with(temp_file, run_as_root=True)
|
||||
mock_info.assert_called_with(temp_file, run_as_root=True)
|
||||
self.assertEqual(mock_info.call_count, 2)
|
||||
mock_open.assert_called_once_with(temp_file, 'rb')
|
||||
image_service.update.assert_called_once_with(
|
||||
ctxt, image_meta['id'], {},
|
||||
|
@ -470,6 +472,7 @@ class TestUploadVolume(test.TestCase):
|
|||
mock_os.name = 'posix'
|
||||
data = mock_info.return_value
|
||||
data.file_format = mock.sentinel.other_disk_format
|
||||
data.backing_file = None
|
||||
temp_file = mock_temp.return_value.__enter__.return_value
|
||||
|
||||
self.assertRaises(exception.ImageUnacceptable,
|
||||
|
@ -479,7 +482,8 @@ class TestUploadVolume(test.TestCase):
|
|||
temp_file,
|
||||
mock.sentinel.disk_format,
|
||||
run_as_root=True)
|
||||
mock_info.assert_called_once_with(temp_file, run_as_root=True)
|
||||
mock_info.assert_called_with(temp_file, run_as_root=True)
|
||||
self.assertEqual(mock_info.call_count, 2)
|
||||
self.assertFalse(image_service.update.called)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue