summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorPádraig Brady <pbrady@redhat.com>2012-11-23 14:59:13 +0000
committerThierry Carrez <thierry@openstack.org>2012-12-11 16:21:34 +0100
commit9d2ea970422591f8cdc394001be9a2deca499a5f (patch)
tree5934b57d87d536815eb20b2df0dd1a655510cc38 /nova
parentec6550f2d9636635683f0fd50a0d4e51849765df (diff)
downloadnova-9d2ea970422591f8cdc394001be9a2deca499a5f.tar.gz
nova-9d2ea970422591f8cdc394001be9a2deca499a5f.tar.xz
nova-9d2ea970422591f8cdc394001be9a2deca499a5f.zip
Don't leak info from libvirt LVM backed instances
* nova/virt/libvirt/utils.py (remove_logical_volumes): Overwrite each logical volume with zero (clear_logical_volume): LV obfuscation implementation. (logical_volume_size): A utility function used by clear_logical_volume() Fixes bug: 1070539 Change-Id: I4e1024de8dfe9b0be3b0d6437c836d2042862f85
Diffstat (limited to 'nova')
-rw-r--r--nova/virt/libvirt/utils.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py
index 523d4def3..4b53664b8 100644
--- a/nova/virt/libvirt/utils.py
+++ b/nova/virt/libvirt/utils.py
@@ -172,8 +172,55 @@ def logical_volume_info(path):
return dict(zip(*info))
+def logical_volume_size(path):
+ """Get logical volume size in bytes.
+
+ :param path: logical volume path
+ """
+ # TODO(p-draigbrady) POssibly replace with the more general
+ # use of blockdev --getsize64 in future
+ out, _err = execute('lvs', '-o', 'lv_size', '--noheadings', '--units',
+ 'b', '--nosuffix', path, run_as_root=True)
+
+ return int(out)
+
+
+def clear_logical_volume(path):
+ """Obfuscate the logical volume.
+
+ :param path: logical volume path
+ """
+ # TODO(p-draigbrady): We currently overwrite with zeros
+ # but we may want to make this configurable in future
+ # for more or less security conscious setups.
+
+ vol_size = logical_volume_size(path)
+ bs = 1024 * 1024
+ direct_flags = ('oflag=direct',)
+ remaining_bytes = vol_size
+
+ # The loop caters for versions of dd that
+ # don't support the iflag=count_bytes option.
+ while remaining_bytes:
+ zero_blocks = remaining_bytes / bs
+ seek_blocks = (vol_size - remaining_bytes) / bs
+ zero_cmd = ('dd', 'bs=%s' % bs,
+ 'if=/dev/zero', 'of=%s' % path,
+ 'seek=%s' % seek_blocks, 'count=%s' % zero_blocks)
+ zero_cmd += direct_flags
+ if zero_blocks:
+ utils.execute(*zero_cmd, run_as_root=True)
+ remaining_bytes %= bs
+ bs /= 1024 # Limit to 3 iterations
+ direct_flags = () # Only use O_DIRECT with initial block size
+
+
def remove_logical_volumes(*paths):
"""Remove one or more logical volume."""
+
+ for path in paths:
+ clear_logical_volume(path)
+
if paths:
lvremove = ('lvremove', '-f') + paths
execute(*lvremove, attempts=3, run_as_root=True)