| From d31c937c566005dedf41a60c6b5bd5e7b26f221b Mon Sep 17 00:00:00 2001 |
| From: Eric Harney <eharney@redhat.com> |
| Date: Tue, 31 Mar 2015 19:48:17 -0400 |
| Subject: [PATCH] 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 9634b76ba5886d6c2f2128d550cb005dabf48213) |
| Conflicts: |
| cinder/tests/test_image_utils.py (backport to old tests) |
| --- |
| cinder/image/image_utils.py | 14 ++++++++++++++ |
| cinder/tests/test_image_utils.py | 13 +++++++++++++ |
| 2 files changed, 27 insertions(+) |
| |
| diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py |
| index 160dfe7..cac0072 100644 |
| --- a/cinder/image/image_utils.py |
| +++ b/cinder/image/image_utils.py |
| @@ -312,6 +312,20 @@ def upload_volume(context, image_service, image_meta, volume_path, |
| with fileutils.remove_path_on_error(tmp): |
| LOG.debug("%s was %s, converting to %s" % |
| (image_id, volume_format, image_meta['disk_format'])) |
| + |
| + data = qemu_img_info(volume_path) |
| + 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'], |
| bps_limit=CONF.volume_copy_bps_limit) |
| |
| diff --git a/cinder/tests/test_image_utils.py b/cinder/tests/test_image_utils.py |
| index 86168c0..2cf571a 100644 |
| --- a/cinder/tests/test_image_utils.py |
| +++ b/cinder/tests/test_image_utils.py |
| @@ -462,6 +462,10 @@ def test_upload_volume(self, mock_stat, bps_limit=0): |
| volume_utils.setup_blkio_cgroup(mox.IgnoreArg(), mox.IgnoreArg(), |
| bps_limit).AndReturn(prefix) |
| |
| + utils.execute( |
| + 'env', 'LC_ALL=C', 'qemu-img', 'info', |
| + mox.IgnoreArg(), run_as_root=True).AndReturn( |
| + (TEST_RET, 'ignored')) |
| utils.execute(*cmd, run_as_root=True) |
| utils.execute( |
| 'env', 'LC_ALL=C', 'qemu-img', 'info', |
| @@ -497,6 +501,11 @@ def test_upload_volume_with_bps_limit(self, mock_stat): |
| |
| volume_utils.setup_blkio_cgroup(mox.IgnoreArg(), mox.IgnoreArg(), |
| bps_limit).AndReturn(prefix) |
| + |
| + utils.execute( |
| + 'env', 'LC_ALL=C', 'qemu-img', 'info', |
| + mox.IgnoreArg(), run_as_root=True).AndReturn( |
| + (TEST_RET, 'ignored')) |
| utils.execute(*cmd, run_as_root=True) |
| utils.execute( |
| 'env', 'LC_ALL=C', 'qemu-img', 'info', |
| @@ -534,6 +543,10 @@ def test_upload_volume_on_error(self, mock_stat): |
| m.StubOutWithMock(utils, 'execute') |
| m.StubOutWithMock(volume_utils, 'check_for_odirect_support') |
| |
| + utils.execute( |
| + 'env', 'LC_ALL=C', 'qemu-img', 'info', |
| + mox.IgnoreArg(), run_as_root=True).AndReturn( |
| + (TEST_RET, 'ignored')) |
| utils.execute('qemu-img', 'convert', '-O', 'qcow2', |
| mox.IgnoreArg(), mox.IgnoreArg(), run_as_root=True) |
| utils.execute( |