Bug 1411394

Summary: libvirtd crashes when attaching raw LUKS volumes
Product: Red Hat Enterprise Linux 7 Reporter: Jaroslav Reznik <jreznik>
Component: libvirtAssignee: John Ferlan <jferlan>
Status: CLOSED ERRATA QA Contact: yisun
Severity: urgent Docs Contact:
Priority: high    
Version: 7.3CC: bugzilla, dyuan, jdenemar, jferlan, jsuchane, rbalakri, rh-bugzilla, snagar, xuzhang
Target Milestone: rcKeywords: Regression, ZStream
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-2.0.0-10.el7_3.5 Doc Type: Bug Fix
Doc Text:
Cause: The libvirt code assumed that for any domain disk device found to be LUKS encrypted, the device would have a libvirt secret associated with the device in order to provide the key to unlock the device. Consequence: When attempting to access the secret libvirt would core. Fix: Add a check to ensure that not only is there encryption, but there is a secret before trying to access the secret object in order to pass the secret along with the disk. Result: After the patch, it is possible to attach a LUKS encrypted disk and no libvirt secret associated with the disk. This would force the application to perform the unlock.
Story Points: ---
Clone Of: 1405269 Environment:
Last Closed: 2017-03-02 17:30:51 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1405269    
Bug Blocks:    

Description Jaroslav Reznik 2017-01-09 15:44:19 UTC
This bug has been copied from bug #1405269 and has been proposed
to be backported to 7.3 z-stream (EUS).

Comment 7 yisun 2017-02-13 08:52:29 UTC
Test with:
libvirt-2.0.0-10.el7_3.5.x86_64
qemu-kvm-rhev-2.6.0-28.el7_3.5.x86_64

Test steps:
1. create a luks img (with lv and with local file)
2. attach the img to vm with disk's xml without indicate <encryption> part
3. check the disk in vm
4. detach the virtual disk
5. create a libvirt secret with correct password
6. attach the img to vm with <encryption>
7. check the disk in vm
8. detach the virtual disk and check the img is still in luks format with "qemu-img info"


Scenario 1: use lv as virtual disk source

===== In host =====
root@localhost~  ## pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.
root@localhost~  ## vgcreate vg1 /dev/sdb
  Volume group "vg1" successfully created
root@localhost~  ## lvcreate vg1  /dev/sdb --size 10M
  Rounding up size to full physical extent 12.00 MiB
  Logical volume "lvol0" created.
root@localhost~  ## lvdisplay
  --- Logical volume ---
  LV Path                /dev/vg1/lvol0
  LV Name                lvol0
  VG Name                vg1
  LV UUID                CfHO1T-wqVQ-8Qcy-xY5r-jxsi-gYuU-grp4qS
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2017-02-13 14:47:45 +0800
  LV Status              available
  # open                 0
  LV Size                12.00 MiB
  Current LE             3
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:3

root@localhost~  ## cryptsetup luksFormat /dev/vg1/lvol0
WARNING!
========
This will overwrite data on /dev/vg1/lvol0 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:

root@localhost~  ## cat /tmp/disk.xml
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
      <source dev='/dev/vg1/lvol0'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <serial>drive-scsi0-0-0-1</serial>
      <alias name='virtio-disk1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </disk>

root@localhost~  ## virsh start avocado-vt-vm1
Domain avocado-vt-vm1 started


root@localhost~  ## virsh attach-device avocado-vt-vm1 /tmp/disk.xml
Device attached successfully


root@localhost~  ## virsh console avocado-vt-vm1

===== In guest =====
[root@localhost ~]# lsblk | grep vdb
vdb           252:16   0  12M  0 disk

[root@localhost ~]# mount /dev/vdb /mnt
mount: unknown filesystem type 'crypto_LUKS'

===== In host =====
root@localhost~  ## virsh detach-device avocado-vt-vm1 /tmp/disk.xml
Device detached successfully

root@localhost~  ## virsh domblklist avocado-vt-vm1
Target     Source
------------------------------------------------
vda        /var/lib/libvirt/images/RHEL-7.3-latest.qcow2

root@localhost~  ## cat /tmp/secret.xml
      <secret ephemeral='no' private='yes'>
         <description>LUKS Secret</description>
         <uuid>f981dd17-143f-45bc-88e6-ed1fe20ce9da</uuid>
         <usage type='volume'>
            <volume>/dev/vg1/lvol0</volume>
         </usage>
      </secret>

root@localhost~  ## virsh secret-define /tmp/secret.xml
Secret f981dd17-143f-45bc-88e6-ed1fe20ce9da created

root@localhost~  ## MYSECRET=`printf %s "1qaz@WSX" | base64`
root@localhost~  ## virsh secret-set-value f981dd17-143f-45bc-88e6-ed1fe20ce9da $MYSECRET
Secret value set


root@localhost/tmp  ## cat /tmp/disk.xml
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
      <source dev='/dev/vg1/lvol0'/>
      <backingStore/>
      <target dev='sdb' bus='virtio'/>
      <encryption format='luks'>
          <secret type='passphrase' uuid='f981dd17-143f-45bc-88e6-ed1fe20ce9da'/>
      </encryption>
      <serial>drive-scsi0-0-0-1</serial>
      <alias name='virtio-disk1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </disk>

root@localhost~  ## virsh attach-device avocado-vt-vm1 /tmp/disk.xml
Device attached successfully

root@localhost~  ## virsh console avocado-vt-vm1
Connected to domain avocado-vt-vm1
Escape character is ^]

===== In guest =====
[root@localhost ~]# lsblk | grep vdb
vdb           252:16   0  10M  0 disk

[root@localhost ~]# mkfs.ext4 /dev/vdb -F
[root@localhost ~]# mount /dev/vdb /mnt
[root@localhost ~]# echo "test" > /mnt/test.txt
[root@localhost ~]# sync
[root@localhost ~]# cat /mnt/test.txt
test

===== In host =====
root@localhost~  ## virsh detach-device avocado-vt-vm1 /tmp/disk.xml
Device detached successfully

root@localhost~  ## virsh domblklist avocado-vt-vm1
Target     Source
------------------------------------------------
vda        /var/lib/libvirt/images/RHEL-7.3-latest.qcow2

root@localhost~  ## qemu-img info /dev/vg1/lvol0
image: /dev/vg1/lvol0
file format: luks
virtual size: 10M (10485760 bytes)
disk size: 0
encrypted: yes







Scenario 2: Use a local img as virtual disk source
===== In host =====
root@localhost~  ## qemu-img create -f luks --object secret,id=sec0,data=cmVkaGF0,format=base64 -o key-secret=sec0 /var/lib/libvirt/images/disk.luks 1G
Formatting '/var/lib/libvirt/images/disk.luks', fmt=luks size=1073741824 key-secret=sec0

root@localhost~  ## cat /tmp/file.disk
 <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
      <source file='/var/lib/libvirt/images/disk.luks'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <serial>drive-scsi0-0-0-1</serial>
      <alias name='virtio-disk1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
 </disk>

root@localhost~  ## virsh start avocado-vt-vm1
Domain avocado-vt-vm1 started

root@localhost~  ## virsh attach-device avocado-vt-vm1 /tmp/file.disk
Device attached successfully

root@localhost~  ## virsh console avocado-vt-vm1
Connected to domain avocado-vt-vm1
Escape character is ^]

===== In guest =====
[root@localhost ~]# lsblk | grep vdb
vdb           252:16   0   1G  0 disk

[root@localhost ~]# mount /dev/vdb /mnt
mount: unknown filesystem type 'crypto_LUKS'

===== In host =====
root@localhost~  ## virsh detach-device avocado-vt-vm1 /tmp/file.disk
Device detached successfully

root@localhost~  ## virsh domblklist avocado-vt-vm1
Target     Source
------------------------------------------------
vda        /var/lib/libvirt/images/RHEL-7.3-latest.qcow2


root@localhost~  ## cat /tmp/secret.xml
      <secret ephemeral='no' private='yes'>
         <description>LUKS Secret</description>
         <uuid>f981dd17-143f-45bc-88e6-ed1fe20ce9da</uuid>
         <usage type='volume'>
            <volume>/var/lib/libvirt/images/luks.disk</volume>
         </usage>
      </secret>

root@localhost~  ## virsh secret-define /tmp/secret.xml
Secret f981dd17-143f-45bc-88e6-ed1fe20ce9da created

root@localhost~  ## MYSECRET=`printf %s "redhat" | base64`
root@localhost~  ## virsh secret-set-value f981dd17-143f-45bc-88e6-ed1fe20ce9da $MYSECRET
Secret value set

root@localhost~  ## cat /tmp/file.disk
 <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
      <source file='/var/lib/libvirt/images/disk.luks'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <encryption format='luks'>
        <secret type='passphrase' uuid='f981dd17-143f-45bc-88e6-ed1fe20ce9da'/>
      </encryption>
      <serial>drive-scsi0-0-0-1</serial>
      <alias name='virtio-disk1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
 </disk>

root@localhost~  ## virsh attach-device avocado-vt-vm1 /tmp/file.disk
Device attached successfully

root@localhost~  ## virsh console avocado-vt-vm1
Connected to domain avocado-vt-vm1
Escape character is ^]

===== In guest =====
[root@localhost ~]# lsblk | grep vdb
vdb           252:16   0   1G  0 disk

[root@localhost ~]# mkfs.ext4 /dev/vdb -F
[root@localhost ~]# echo "testtest" > /mnt/test.txt
[root@localhost ~]# sync
[root@localhost ~]# cat /mnt/test.txt
testtest

===== In host =====
root@localhost~  ## qemu-img info /var/lib/libvirt/images/disk.luks
image: /var/lib/libvirt/images/disk.luks
file format: luks
virtual size: 1.0G (1073741824 bytes)
disk size: 49M
encrypted: yes

root@localhost~  ## virsh detach-device avocado-vt-vm1 /tmp/file.disk
Device detached successfully

root@localhost~  ## virsh domblklist avocado-vt-vm1
Target     Source
------------------------------------------------
vda        /var/lib/libvirt/images/RHEL-7.3-latest.qcow2

Comment 8 bugzilla 2017-02-15 18:41:22 UTC
It looks like you have this working with libvirt-2.0.0-10.el7_3.5.x86_64 .

Is <backingStore/> necessary as part of the fix for future attachments when we upgrade to _3.5?

-Eric

Comment 9 yisun 2017-02-16 03:15:35 UTC
(In reply to bugzilla from comment #8)
> It looks like you have this working with libvirt-2.0.0-10.el7_3.5.x86_64 .
> 
> Is <backingStore/> necessary as part of the fix for future attachments when
> we upgrade to _3.5?
> 
> -Eric

Hi Erice, 
It's not necessary to add the <backingStore/> in the xml file which you'll attach to vm. But it'll be auto filled into vm's xml if you **virsh dumpxml** the vm after attachment. Anyway, it's not related to this bug.

Comment 11 errata-xmlrpc 2017-03-02 17:30:51 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2017-0397.html