diff options
| author | Pádraig Brady <pbrady@redhat.com> | 2012-11-23 14:59:13 +0000 |
|---|---|---|
| committer | Thierry Carrez <thierry@openstack.org> | 2012-12-11 16:21:34 +0100 |
| commit | 9d2ea970422591f8cdc394001be9a2deca499a5f (patch) | |
| tree | 5934b57d87d536815eb20b2df0dd1a655510cc38 /nova | |
| parent | ec6550f2d9636635683f0fd50a0d4e51849765df (diff) | |
| download | nova-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.py | 47 |
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) |
