Bug 1323501

Summary: svirt_t needs to read access for udev_var_run_t
Product: [Fedora] Fedora Reporter: javiertury
Component: selinux-policyAssignee: Lukas Vrabec <lvrabec>
Status: CLOSED EOL QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: high    
Version: 26CC: amit, amit.shah, berrange, bugzilla, cfergeau, crobinso, dominick.grift, dwalsh, dwmw2, hdegoede, itamar, javiertury, kraxel, lvrabec, marcioadriano.sistemas, mgrepl, pbonzini, plautrba, rjones, virt-maint
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-05-29 11:52:48 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:
Attachments:
Description Flags
Virsh DumpXML Output
none
var log libvirt qemu test.log
none
dmesg -w output none

Description javiertury 2016-04-03 17:34:27 UTC
Description of problem:

Configuring a usb device on virt-manager and later launching that vm creates a selinux denial. It seems that selinux is denying qemu access to usb2 devices connected to the computer.


The actual SELinux warning:

SELinux is preventing /usr/bin/qemu-system-x86_64 from read access on the file +usb:2-1:1.0.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that qemu-system-x86_64 should be allowed read access on the +usb:2-1:1.0 file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep qemu-system-x86 /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp

Additional Information:
Source Context                system_u:system_r:svirt_t:s0:c138,c204
Target Context                system_u:object_r:udev_var_run_t:s0
Target Objects                +usb:2-1:1.0 [ file ]
Source                        qemu-system-x86
Source Path                   /usr/bin/qemu-system-x86_64
Port                          <Unknown>
Host                          localhost.localdomain
Source RPM Packages           qemu-system-x86-2.4.1-8.fc23.x86_64
Target RPM Packages           
Policy RPM                    selinux-policy-3.13.1-158.11.fc23.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     localhost.localdomain
Platform                      Linux localhost.localdomain 4.4.6-300.fc23.x86_64
                              #1 SMP Wed Mar 16 22:10:37 UTC 2016 x86_64 x86_64
Alert Count                   14
First Seen                    2016-04-03 19:15:46 CEST
Last Seen                     2016-04-03 19:15:46 CEST
Local ID                      fdc1a665-fa98-40de-b7ac-a48df7ae08fc

Raw Audit Messages
type=AVC msg=audit(1459703746.723:2281): avc:  denied  { read } for  pid=24530 comm="qemu-system-x86" name="+usb:2-1:1.0" dev="tmpfs" ino=21548 scontext=system_u:system_r:svirt_t:s0:c138,c204 tcontext=system_u:object_r:udev_var_run_t:s0 tclass=file permissive=0


type=SYSCALL msg=audit(1459703746.723:2281): arch=x86_64 syscall=open success=no exit=EACCES a0=7ffcea4c54e0 a1=80000 a2=1b6 a3=80000 items=0 ppid=1 pid=24530 auid=4294967295 uid=107 gid=107 euid=107 suid=107 fsuid=107 egid=107 sgid=107 fsgid=107 tty=(none) ses=4294967295 comm=qemu-system-x86 exe=/usr/bin/qemu-system-x86_64 subj=system_u:system_r:svirt_t:s0:c138,c204 key=(null)

Hash: qemu-system-x86,svirt_t,udev_var_run_t,file,read

Comment 1 Cole Robinson 2016-04-08 22:10:04 UTC
Does this reproduce every time the VM is started?

Please provide:

* lsusb output before starting the VM
* sudo virsh dumpxml $vmname
* /var/log/libvirt/qemu/vmname.log

Comment 2 javiertury 2016-04-09 12:38:10 UTC
Created attachment 1145399 [details]
Virsh DumpXML Output

Comment 3 javiertury 2016-04-09 12:40:31 UTC
$ lsusb
Bus 002 Device 003: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
Bus 002 Device 004: ID 0781:5571 SanDisk Corp. Cruzer Fit
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 064e:d20c Suyin Corp. 
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

The devices I attached are the Ralink and SanDisk devices.

Previously I mistakenly opened a bug report on virt-manager before realizing that it was a selinux denial on qemu: https://bugzilla.redhat.com/show_bug.cgi?id=1323268

It describes how the machine was created with virt-manager and how it is started. Also in that bug report I detailed a workaround that may provide some insight.

Comment 4 javiertury 2016-04-09 12:55:19 UTC
Created attachment 1145401 [details]
var log libvirt qemu test.log

Comment 5 Cole Robinson 2016-04-09 13:45:41 UTC
Can you isolate which device is causing the issue? Try removing the wireless device, see if VM startup works/doesn't through an selinux avc, and vice versa

Also I'd be curious to see the dmesg -w output when reproducing the issue

Comment 6 javiertury 2016-04-09 15:17:32 UTC
The denial happens with any usb. I've just tried unplugging each of them and removing the corresponding "USB Host Device" entry before launching the VM. The selinux denial happened on both occasions.

I'm attaching a commented "dmesg -w" log.

Comment 7 javiertury 2016-04-09 15:18:18 UTC
Created attachment 1145426 [details]
dmesg -w output

Comment 8 Cole Robinson 2016-04-13 22:53:17 UTC
I'm seeing this too on f24 at least. I don't know what part of the process is now accessing udev files under /run, but they seem to be legitimate accesses. For me, qemu is trying to read this file for my thumbdrive:

$ cat /run/udev/data/c189\:2
I:2255605192
E:ID_VENDOR=SanDisk_Corporation
E:ID_VENDOR_ENC=SanDisk\x20Corporation
E:ID_VENDOR_ID=0781
E:ID_MODEL=U3_Cruzer_Micro
E:ID_MODEL_ENC=U3\x20Cruzer\x20Micro
E:ID_MODEL_ID=5406
E:ID_REVISION=0010
E:ID_SERIAL=SanDisk_Corporation_U3_Cruzer_Micro_000015793C63B99F
E:ID_SERIAL_SHORT=000015793C63B99F
E:ID_BUS=usb
E:ID_USB_INTERFACES=:080650:
E:ID_VENDOR_FROM_DATABASE=SanDisk Corp.
E:ID_MODEL_FROM_DATABASE=Cruzer Micro U3
E:ID_DRIVE_THUMB=1

So I think the selinux policy needs to let svirt_t read udev_var_run_t

Comment 9 Lukas Vrabec 2016-04-14 12:49:55 UTC
*** Bug 1326895 has been marked as a duplicate of this bug. ***

Comment 10 Daniel Berrangé 2016-04-14 14:03:08 UTC
This seems really dubious to me - I really don't think QEMU should be accessing udev_var_run_t files. Rather than just allow this in selinux, I think we need to investigate why this access is being triggered by QEMU and ideally remove it.

Comment 11 Cole Robinson 2016-04-14 14:53:24 UTC
It's basically qemu -> libusb -> udev... udev APIs are reading their own files. So seems legit to me


#0  0x00007fffeb1a11e0 in open64 () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007fffeb12303e in __GI__IO_file_open (fp=fp@entry=0x5555586d9ad0, filename=<optimized out>, posix_mode=<optimized out>, prot=prot@entry=438, read_write=8, is32not64=is32not64@entry=1) at fileops.c:221
#2  0x00007fffeb123275 in _IO_new_file_fopen (fp=fp@entry=0x5555586d9ad0, filename=filename@entry=0x7fffffffd9a0 "/run/udev/data/c189:4", mode=<optimized out>, mode@entry=0x7ffff7f0a8fe "re", is32not64=is32not64@entry=1) at fileops.c:328
#3  0x00007fffeb117364 in __fopen_internal (filename=0x7fffffffd9a0 "/run/udev/data/c189:4", mode=0x7ffff7f0a8fe "re", is32=1) at iofopen.c:86
#4  0x00007ffff7efd31a in read_full_file (fn=<optimized out>, contents=0x7fffffffda00, size=0x7fffffffda08) at src/basic/fileio.c:286
#5  0x00007ffff7f041b2 in device_read_db_aux.constprop.10 (device=0x5555586d7350, force=false) at src/libsystemd/sd-device/sd-device.c:1281
#6  0x00007ffff7f01aeb in sd_device_get_is_initialized () at src/libsystemd/sd-device/sd-device.c:1345
#7  0x00007ffff7f01aeb in sd_device_get_is_initialized (device=0x5555586d7350, initialized=0x7fffffffdb64) at src/libsystemd/sd-device/sd-device.c:1354
#8  0x00007ffff7f03888 in enumerator_scan_dir_and_add_devices.lto_priv.55 (enumerator=enumerator@entry=0x5555584c6970, basedir=basedir@entry=0x7ffff7f0ace6 "bus", subdir1=subdir1@entry=0x5555586c73eb "usb", subdir2=subdir2@entry=0x7ffff7f0ad08 "devices") at src/libsystemd/sd-device/device-enumerator.c:524
#9  0x00007ffff7f03c18 in enumerator_scan_dir.lto_priv.56 (enumerator=0x5555584c6970, basedir=0x7ffff7f0ace6 "bus", subdir=0x7ffff7f0ad08 "devices", subsystem=0x0) at src/libsystemd/sd-device/device-enumerator.c:611
#10 0x00007ffff7efe12c in udev_enumerate_scan_devices (enumerator=0x5555584c6970) at src/libsystemd/sd-device/device-enumerator.c:823
#11 0x00007ffff7efe12c in udev_enumerate_scan_devices (enumerator=0x5555584c6970) at src/libsystemd/sd-device/device-enumerator.c:861
#12 0x00007ffff7efe12c in udev_enumerate_scan_devices (udev_enumerate=udev_enumerate@entry=0x5555584c6910) at src/libudev/libudev-enumerate.c:404
#13 0x00007fffec790efb in linux_udev_scan_devices (ctx=ctx@entry=0x5555586c5c80) at os/linux_udev.c:270
#14 0x00007fffec78ebb3 in op_init (ctx=0x5555586c5c80) at os/linux_usbfs.c:501
#15 0x00007fffec78ebb3 in op_init (ctx=0x5555586c5c80) at os/linux_usbfs.c:453
#16 0x00007fffec786d9d in libusb_init (context=context@entry=0x555555fd3a08 <ctx>) at core.c:2054
#17 0x00005555559204ec in usb_host_init () at hw/usb/host-libusb.c:234
#18 0x0000555555920fd2 in usb_host_auto_check (unused=<optimized out>) at hw/usb/host-libusb.c:1552
#19 0x00005555558f30f1 in usb_qdev_realize (errp=0x7fffffffdfd0, dev=0x5555584c4130) at hw/usb/bus.c:125
#20 0x00005555558f30f1 in usb_qdev_realize (qdev=0x5555584c4130, errp=0x7fffffffe010) at hw/usb/bus.c:262
#21 0x000055555585bdd4 in device_set_realized (obj=0x5555584c4130, value=<optimized out>, errp=0x7fffffffe108) at hw/core/qdev.c:1066
#22 0x0000555555963021 in property_set_bool (obj=0x5555584c4130, v=<optimized out>, name=<optimized out>, opaque=0x5555584c59c0, errp=0x7fffffffe108) at qom/object.c:1853
#23 0x0000555555966dd7 in object_property_set_qobject (obj=0x5555584c4130, value=<optimized out>, name=0x555555a6a7ed "realized", errp=0x7fffffffe108) at qom/qom-qobject.c:26
#24 0x0000555555964c70 in object_property_set_bool (obj=0x5555584c4130, value=<optimized out>, name=0x555555a6a7ed "realized", errp=0x7fffffffe108) at qom/object.c:1150
#25 0x00005555558f33cb in usbdevice_create (cmdline=<optimized out>) at hw/usb/bus.c:729
#26 0x00005555557f7091 in usb_device_add (devname=0x7fffffffe792 "host:001.005") at vl.c:1401
#27 0x00005555557f70ae in usb_parse (cmdline=0x7fffffffe792 "host:001.005") at vl.c:1444
#28 0x00005555557f82a0 in foreach_device_config (type=0, func=0x5555557f70a0 <usb_parse>) at vl.c:2498
#29 0x00005555556d8326 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4534

Comment 12 Daniel Berrangé 2016-04-14 15:08:28 UTC
So the issue here is that when QEMU initializes libusb, it is scanning the entire udev database to identify devices. This is really not something it should do by default as there's absolutely no reason for this when we're telling QEMU exactly what USB device it should be using. As such IMHO it is right for svirt to deny access to this. Assuming this is not actually breaking something from a functional POV, but just triggering AVC denials in audit log, then I think we should a) make this a dontaudit item, and b) get libusb fixed so it doesn't scan for devices unless the app using libusb actually needs this.

Comment 13 Cole Robinson 2016-04-14 15:11:56 UTC
(In reply to Daniel Berrange from comment #12)
> So the issue here is that when QEMU initializes libusb, it is scanning the
> entire udev database to identify devices. This is really not something it
> should do by default as there's absolutely no reason for this when we're
> telling QEMU exactly what USB device it should be using. As such IMHO it is
> right for svirt to deny access to this. Assuming this is not actually
> breaking something from a functional POV, but just triggering AVC denials in
> audit log, then I think we should a) make this a dontaudit item, and b) get
> libusb fixed so it doesn't scan for devices unless the app using libusb
> actually needs this.

ccing gerd and hans for their thoughts

Comment 14 Gerd Hoffmann 2016-04-14 15:36:07 UTC
(In reply to Daniel Berrange from comment #12)
> So the issue here is that when QEMU initializes libusb, it is scanning the
> entire udev database to identify devices. This is really not something it
> should do by default as there's absolutely no reason for this when we're
> telling QEMU exactly what USB device it should be using.

Ahem, no.  We get the vendorid and productid.

Then qemu goes look at all usb devices to figure which one matches, like this:

        n = libusb_get_device_list(ctx, &devs);
        for (i = 0; i < n; i++) {
            libusb_get_device_descriptor(devs[i], &ddesc);
            /* check ddesc.idVendor and ddesc.idProduct here */

Possibly we can do it without opening the device (to read the device descriptor) and get the ids from udev or sysfs instead.  Not sure libvirt has interfaces for that though given it is portable to non-linux systems.

> As such IMHO it is
> right for svirt to deny access to this. Assuming this is not actually
> breaking something from a functional POV,

It shouldn't cause breakage.  In theory svirt should only deny access to devices which qemu would skip anyway because the ids don't match.

> but just triggering AVC denials in
> audit log, then I think we should a) make this a dontaudit item,

Agree.

> and b) get
> libusb fixed so it doesn't scan for devices unless the app using libusb
> actually needs this.

Not sure we can do this, see above.

Hans?

Comment 15 Daniel Berrangé 2016-04-14 15:41:51 UTC
(In reply to Gerd Hoffmann from comment #14)
> (In reply to Daniel Berrange from comment #12)
> > So the issue here is that when QEMU initializes libusb, it is scanning the
> > entire udev database to identify devices. This is really not something it
> > should do by default as there's absolutely no reason for this when we're
> > telling QEMU exactly what USB device it should be using.
> 
> Ahem, no.  We get the vendorid and productid.
> 
> Then qemu goes look at all usb devices to figure which one matches, like
> this:
> 
>         n = libusb_get_device_list(ctx, &devs);
>         for (i = 0; i < n; i++) {
>             libusb_get_device_descriptor(devs[i], &ddesc);
>             /* check ddesc.idVendor and ddesc.idProduct here */
> 
> Possibly we can do it without opening the device (to read the device
> descriptor) and get the ids from udev or sysfs instead.  Not sure libvirt
> has interfaces for that though given it is portable to non-linux systems.

Thats only if the mgmt app has invoked QEMU with a vendor+product ID. Libvirt won't do that, it'll always provide QEMU with the actual bus+device ID that it should use. We can't let QEMU auto-detect it from vendor+product, because we need to have applied SELinux labelling to the intended device before QEMU starts.  So in the context of usage from libvirt, QEMU should not need to scan all devices AFAICT.

Comment 16 Gerd Hoffmann 2016-04-14 16:34:06 UTC
> Thats only if the mgmt app has invoked QEMU with a vendor+product ID.
> Libvirt won't do that, it'll always provide QEMU with the actual bus+device
> ID that it should use. We can't let QEMU auto-detect it from vendor+product,
> because we need to have applied SELinux labelling to the intended device
> before QEMU starts.  So in the context of usage from libvirt, QEMU should
> not need to scan all devices AFAICT.

Ah, ok.  Didn't notice libvirt translates vendorid+productid to bus+device for qemu instead of passing things through as-is.  But given it needs to do it anyway
for labeling reasons it makes alot of sense indeed.

Todays code doesn't bother, usb-host goes scan all usb devices no matter how the device was specified.  But we can add a shortcut and skip the scan in case bus+device are given.

Comment 17 Gerd Hoffmann 2016-04-19 13:11:51 UTC
https://www.kraxel.org/cgit/qemu/log/?h=work/usb-host-scanning

Does that improve things?

Comment 18 javiertury 2016-04-19 17:06:15 UTC
I can't test. I downloaded and compiled it but it seems that I missed something or this new /usr/local/bin/qemu-system-x86_64 is not interchangeable. I was running qemu 2.4.1 before.

I keep getting errors about every single command line argument. First it was spice, so I deleted every spice argument. Currently I'm battling against this:

    'qxl-vga' is not a valid device model name

Changing the xml config to use /usr/local/bin/qemu-system-x86_64 gives me similar errors.

Comment 19 Cole Robinson 2016-04-19 17:26:58 UTC
Doesn't seem to fix things for me. I reproduced with libvirt, but you can also confirm with:

sudo strace -o foo ./x86_64-softmmu/qemu-system-x86_64 -usb -device usb-host,hostbus=1,hostaddr=3

Then check strace output for open("/run/udev/data/...

Also, I ran as non-root first which (expectedly) failed to access the USB device, but then qemu crashed on cleanup. This doesn't exist with -rc2 at least:

#0  0x0000555555a50ab2 in notifier_list_notify (list=<optimized out>, data=0x0) at util/notify.c:40
#1  0x00007fffe9592c08 in __run_exit_handlers (status=1, listp=0x7fffe99205d8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#2  0x00007fffe9592c55 in __GI_exit (status=<optimized out>) at exit.c:104
#3  0x00005555556ebc3c in main (opts=<optimized out>) at vl.c:907
#4  0x00005555556ebc3c in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:3859

Comment 20 Gerd Hoffmann 2016-04-20 13:38:02 UTC
Hmm, on RHEL-7 libusb doesn't look at /run/udev/data but checks the usb devices in /sys instead.  And it seems to do that when calling libusb_get_device_list(), no matter whenever I query the descriptors or not.

libusb doesn't provide a way to open a device by bus and addr directly, so there is no way around calling libusb_get_device_list().  So, not much we can do about the denials in qemu (with current libusb versions).

Pushed an update to the git branch which should fix the cleanup crash.

Comment 21 Cole Robinson 2016-04-20 19:00:55 UTC
IMO I think it should be okay for virt to read udev_var_run_t anyways... I mean, if it just contains device db data, and libudev itself wants to read those files, I don't see how it's any worse then letting svirt_t read sysfs_t which is already allowed

Comment 22 Lukas Vrabec 2016-04-22 12:15:12 UTC
There is also option to add dontaudit rules to selinux policy. SELinux will denied these actions but without logging these AVC msgs.

Comment 23 Cole Robinson 2016-05-18 01:02:08 UTC
*** Bug 1293710 has been marked as a duplicate of this bug. ***

Comment 24 Fedora End Of Life 2016-11-25 07:13:51 UTC
This message is a reminder that Fedora 23 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 23. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '23'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 23 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 25 Fedora End Of Life 2016-12-20 19:46:02 UTC
Fedora 23 changed to end-of-life (EOL) status on 2016-12-20. Fedora 23 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.

Comment 26 Fedora End Of Life 2017-02-28 09:56:57 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 26 development cycle.
Changing version to '26'.

Comment 27 Fedora End Of Life 2018-05-03 08:09:58 UTC
This message is a reminder that Fedora 26 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 26. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '26'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version'
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not
able to fix it before Fedora 26 is end of life. If you would still like
to see this bug fixed and are able to reproduce it against a later version
of Fedora, you are encouraged  change the 'version' to a later Fedora
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's
lifetime, sometimes those efforts are overtaken by events. Often a
more recent Fedora release includes newer upstream software that fixes
bugs or makes them obsolete.

Comment 28 Fedora End Of Life 2018-05-29 11:52:48 UTC
Fedora 26 changed to end-of-life (EOL) status on 2018-05-29. Fedora 26
is no longer maintained, which means that it will not receive any
further security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.