Hi,


I'm attempting to attach and expose a USB device (WiFi adapter for testing) to an LXC container with SELinux enabled. But when enabling the XML snippet, the container fails to start with this error:


2018-01-12 19:24:31.914+0000: 2181: error : virSecuritySELinuxSetFileconHelper:1182 : unable to set security context 'system_u:object_r:svirt_sandbox_file_t:s0:c139,c284' on '//var/run/libvirt/lxc/lxc_0.dev/bus/usb//dev/bus/usb/002/002': No such file or directory

Failure in libvirt_lxc startup: unable to set security context 'system_u:object_r:svirt_sandbox_file_t:s0:c139,c284' on '//var/run/libvirt/lxc/lxc_0.dev/bus/usb//dev/bus/usb/002/002': No such file or directory


The XML snippet for attaching USB device:


    <hostdev mode='subsystem' type='usb' managed='yes'>
      <source>                                         
        <vendor id='0x05ac'/>                          
        <product id='0x1006'/>                         
      </source>                                        
      <address type='usb' bus='2' port='2'/>           
    </hostdev>                                        

SELinux snippet (using the dynamic label for the moment):

 <seclabel type='dynamic' model='selinux' relabel='yes'/>


Running it on CentOS 7.2 and I've tried the distro from the package manager (1.3.3.3), as well as downloaded and compiled the latest stable from libvirt.org (3.10?) and came to the same error each time.


Did a small dive into the code after realizing that the path just doesn't seem right.


Path (seems to have an unusual and incorrect concatenation of folders) :

//var/run/libvirt/lxc/lxc_0.dev/bus/usb//dev/bus/usb/002/002


"vroot" seems to be declared by the LXC controller (src/lxc/lxc_controller.c) as such:

if (virAsprintf(&vroot, "/%s/%s.dev/bus/usb/",  
                LXC_STATE_DIR, vmDef->name) < 0)
    goto cleanup;                              


Then upon setting up security for all of the container's attached devices, we call virUSBDeviceNew to setup the attached USB device and give us the path to apply a context to. Since vroot is present, we get this weird path when running through this (src/util/virusb.c):


if (virAsprintf(&dev->path, "%s" USB_DEVFS "%03d/%03d",
                vroot ? vroot : "",                    
                dev->bus, dev->dev) < 0) {             
    virUSBDeviceFree(dev);                             
    return NULL;                                       
}

Note:                                            
# define USB_DEVFS "/dev/bus/usb/"

Should we just be blindly appending this definition if vroot is present, making the path incorrect?

If this isn't a bug, I propose the following change:
if (virAsprintf(&dev->path, "%s"  "%03d/%03d",
                vroot ? vroot : USB_DEVFS,                    
                dev->bus, dev->dev) < 0) {             
    virUSBDeviceFree(dev);                             
    return NULL;                                       
}

Would kindly appreciate any feedback on whether this is a bug or maybe I'm missing something and is the reason why it's written this way.

Thanks,
Randy