Bug 1441589

Summary: libvirtd will crash when attaching an USB disk to a non-existed bus
Product: Red Hat Enterprise Linux 7 Reporter: Pei Zhang <pzhang>
Component: libvirtAssignee: Ján Tomko <jtomko>
Status: CLOSED ERRATA QA Contact: jiyan <jiyan>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.4CC: dyuan, hhan, jtomko, lmen, rbalakri, xuzhang
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Unspecified   
Whiteboard:
Fixed In Version: libvirt-3.2.0-3.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-08-02 00:05:54 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Pei Zhang 2017-04-12 09:37:32 UTC
Description of problem:
libvirtd will crash when attaching an usb disk to a non-existed controller 

Version-Release number of selected component (if applicable):
libvirt-3.2.0-2.el7.x86_64
qemu-kvm-rhev-2.8.0-6.el7.x86_64

How reproducible:
100%

Steps to Reproduce:
1. Prepare a guest with USB controller 
# virsh dumpxml r74|grep usb -A 5
...
    <controller type='usb' index='0' model='ich9-ehci1'>
      <alias name='usb'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <alias name='usb'/>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <alias name='usb'/>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
...

2. Prepare an usb disk with specific address as following :
# cat vudisk.xml 
<disk type='block' device='disk' snapshot='no'>
      <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>
      <source dev="/dev/sdb"/>	
      <target dev='sda' bus='usb'/>
      <address type='usb' bus='1' port='0'/>
</disk>

3. Attach above disk to guest will crash libvirtd

# virsh attach-device r74 vudisk.xml 
error: Disconnected from qemu:///system due to I/O error
error: Failed to attach device from vudisk.xml
error: End of file while reading data: Input/output error

4. Change the port in address from 0 to 1, do attach again, it will report an error

# cat vudisk.xml 
<disk type='block' device='disk' snapshot='no'>
      <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>
      <source dev="/dev/sdb"/>	
      <target dev='sda' bus='usb'/>
      <address type='usb' bus='1' port='1'/>
</disk>

# virsh attach-device r74 vudisk.xml 
error: Failed to attach device from vudisk.xml
error: XML error: Missing USB bus 1

Actual results:
As step 3, libvirtd will crash when attaching an usb disk to a non-existed USB controller.

Expected results:
Report an error as step4. 

Additional info:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f757b57b700 (LWP 8742)]
virBitmapNextClearBit (bitmap=0x79726f6d65, pos=0, pos@entry=-1) at util/virbitmap.c:1011
1011	    if (pos >= bitmap->max_bit)
(gdb) bt 
#0  virBitmapNextClearBit (bitmap=0x79726f6d65, pos=0, pos@entry=-1) at util/virbitmap.c:1011
#1  0x00007f758c1e8ae5 in virDomainUSBAddressFindFreePort (hub=0x7f7528000ec0, portpath=portpath@entry=0x7f757b57a7b0, level=level@entry=0) at conf/domain_addr.c:1912
#2  0x00007f758c1ebcef in virDomainUSBAddressAssignFromBus (addrs=addrs@entry=0x7f7528001180, info=info@entry=0x7f755c002c18, bus=bus@entry=1) at conf/domain_addr.c:1981
#3  0x00007f758c1ebea8 in virDomainUSBAddressAssign (addrs=addrs@entry=0x7f7528001180, info=info@entry=0x7f755c002c18) at conf/domain_addr.c:2018
#4  0x00007f758c1ebfa3 in virDomainUSBAddressEnsure (addrs=0x7f7528001180, info=info@entry=0x7f755c002c18) at conf/domain_addr.c:2096
#5  0x00007f7568c90188 in qemuDomainAttachUSBMassStorageDevice (disk=0x7f755c002ae0, vm=0x7f75241d9b00, driver=0x7f7524161f90) at qemu/qemu_hotplug.c:762
#6  qemuDomainAttachDeviceDiskLive (conn=conn@entry=0x7f75740013b0, driver=driver@entry=0x7f7524161f90, vm=vm@entry=0x7f75241d9b00, dev=dev@entry=0x7f755c002960)
    at qemu/qemu_hotplug.c:905
#7  0x00007f7568d09e2b in qemuDomainAttachDeviceLive (driver=0x7f7524161f90, conn=0x7f75740013b0, dev=0x7f755c002960, vm=0x7f75241d9b00) at qemu/qemu_driver.c:7264
#8  qemuDomainAttachDeviceLiveAndConfig (flags=<optimized out>, xml=<optimized out>, driver=0x7f7524161f90, vm=0x7f75241d9b00, conn=<optimized out>)
    at qemu/qemu_driver.c:8073
#9  qemuDomainAttachDeviceFlags (dom=<optimized out>, xml=<optimized out>, flags=1) at qemu/qemu_driver.c:8129
#10 0x00007f758c287d06 in virDomainAttachDevice (domain=domain@entry=0x7f755c0008c0, 
    xml=0x7f755c000a40 "<disk type='block' device='disk' snapshot='no'>\n      <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>\n      <source dev=\"/dev/sdb\"/>\t\n      <target dev='sda' bus='usb'/>"...) at libvirt-domain.c:8096
#11 0x0000558583226392 in remoteDispatchDomainAttachDevice (server=0x55858519d170, msg=0x55858519f100, args=0x7f755c000900, rerr=0x7f757b57ac50, client=<optimized out>)
    at remote_dispatch.h:3458
#12 remoteDispatchDomainAttachDeviceHelper (server=0x55858519d170, client=<optimized out>, msg=0x55858519f100, rerr=0x7f757b57ac50, args=0x7f755c000900, ret=0x7f755c0009a0)
    at remote_dispatch.h:3434
#13 0x00007f758c2f1222 in virNetServerProgramDispatchCall (msg=0x55858519f100, client=0x5585851c74e0, server=0x55858519d170, prog=0x5585851b5f70)
    at rpc/virnetserverprogram.c:437
#14 virNetServerProgramDispatch (prog=0x5585851b5f70, server=server@entry=0x55858519d170, client=0x5585851c74e0, msg=0x55858519f100) at rpc/virnetserverprogram.c:307
#15 0x0000558583236edd in virNetServerProcessMsg (msg=<optimized out>, prog=<optimized out>, client=<optimized out>, srv=0x55858519d170) at rpc/virnetserver.c:148
#16 virNetServerHandleJob (jobOpaque=<optimized out>, opaque=0x55858519d170) at rpc/virnetserver.c:169
#17 0x00007f758c1d7251 in virThreadPoolWorker (opaque=opaque@entry=0x55858519c080) at util/virthreadpool.c:167
#18 0x00007f758c1d65d8 in virThreadHelper (data=<optimized out>) at util/virthread.c:206
#19 0x00007f75895e1dc5 in start_thread (arg=0x7f757b57b700) at pthread_create.c:308
#20 0x00007f75893107ad in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

Comment 2 Ján Tomko 2017-04-12 10:49:22 UTC
Upstream patch:
https://www.redhat.com/archives/libvir-list/2017-April/msg00596.html

Comment 3 Ján Tomko 2017-04-13 09:53:51 UTC
Pushed upstream as:
commit b003b9781b6ae633cfe4fdf6b9620ca246fa2432
Author:     Ján Tomko <jtomko>
CommitDate: 2017-04-13 10:45:28 +0200

    qemu: do not crash on USB address with no port and invalid bus
    
    Properly error out when the user requests a port from a bus
    that does not have a controller present in the domain XML.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1441589

git describe: v3.2.0-140-gb003b97

Comment 6 jiyan 2017-04-24 03:20:36 UTC
In this bug,it occurs that libvirtd will crash when attaching an usb disk to a non-existed controller by using disk label in vudisk.xml,then I verified the hostdev label,and it occurs,too.So in version libvirt-3.2.0-3.el7, it is verified,too.

Version-Release number of selected component
libvirt-3.2.0-2.el7.x86_64
qemu-kvm-rhev-2.8.0-6.el7.x86_64

Steps to Reproduce by using hostdev label in vudisk.xml:
1.Prepare a guest with USB controller
...
    <controller type='usb' index='0' model='ich9-ehci1'>
      <alias name='usb'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <alias name='usb'/>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <alias name='usb'/>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <alias name='usb'/>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
    </controller>
...

2. Prepare an usb disk with specific address as following :
# cat vudisk.xml 
<hostdev mode='subsystem' type='usb' managed='yes'>
   <source>
       <vendor id='0x058f'/>
       <product id='0x6387'/>
   </source>
<address type='usb' bus='1' port='0'/>
</hostdev>

3. Attach above disk to guest will crash libvirtd
# virsh attach-device rhel-qcow2 vudisk.xml
error: Disconnected from qemu:///system due to I/O error
error: Failed to attach device from vhostdev1.xml
error: End of file while reading data: Input/output error


Step to Verify in libvirt-3.2.0-3.el7

Version-Release number of selected component
libvirt-3.2.0-3.el7.x86_64
qemu-kvm-rhev-2.8.0-6.el7.x86_64

Steps to Reproduce by using hostdev label in vudisk.xml:
1.Prepare a guest with USB controller
...
    <controller type='usb' index='0' model='ich9-ehci1'>
      <alias name='usb'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <alias name='usb'/>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <alias name='usb'/>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <alias name='usb'/>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
    </controller>
...

2. Prepare an usb disk with specific address as following :
# cat vdisk2.xml 
<disk type='block' device='disk'>
      <driver name='qemu' type='raw'/>
      <source dev="/dev/sdb"/>	
      <target dev='vda' bus='usb'/>
      <address type='usb' bus='1' port='0'/>
</disk>

# cat vhostdev2.xml 
<hostdev mode='subsystem' type='usb' managed='yes'>
   <source>
       <vendor id='0x058f'/>
       <product id='0x6387'/>
       <address bus='1' device='3' />
   </source>
   <address type='usb' bus='1' port='0'/>
</hostdev>

3. Attach above disk to guest,it reports an error as expected.
# virsh attach-device rhel1 vdisk2.xml 
error: Failed to attach device from vdisk2.xml
error: XML error: USB bus 1 requested but no controller with that index is present

# virsh attach-device rhel1 vhostdev2.xml 
error: Failed to attach device from vhostdev2.xml
error: XML error: USB bus 1 requested but no controller with that index is present

Comment 7 errata-xmlrpc 2017-08-02 00:05:54 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://access.redhat.com/errata/RHEA-2017:1846

Comment 8 errata-xmlrpc 2017-08-02 01:30:05 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://access.redhat.com/errata/RHEA-2017:1846