Bug 1147057 - SELinux is preventing /usr/bin/qemu-system-x86_64;5424e9e4 (deleted) from 'ioctl' accesses on the chr_file /dev/net/tun.
Summary: SELinux is preventing /usr/bin/qemu-system-x86_64;5424e9e4 (deleted) from 'io...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: libvirt
Version: 21
Hardware: x86_64
OS: Unspecified
high
high
Target Milestone: ---
Assignee: Michal Privoznik
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard: abrt_hash:c9164795b6033279fe5aef828cf...
: 1016326 1144482 1146320 1146859 1149500 1149600 (view as bug list)
Depends On:
Blocks: TRACKER-bugs-affecting-libguestfs 1148012
TreeView+ depends on / blocked
 
Reported: 2014-09-26 17:48 UTC by Adam Williamson
Modified: 2014-10-16 14:12 UTC (History)
28 users (show)

Fixed In Version: libvirt-1.2.9-3.fc21
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2014-10-12 05:02:20 UTC
Type: ---


Attachments (Terms of Use)

Description Adam Williamson 2014-09-26 17:48:30 UTC
Description of problem:
More virt-manager /dev/net/tun stuff; I think this one happens when I run two VMs at once.
SELinux is preventing /usr/bin/qemu-system-x86_64;5424e9e4 (deleted) from 'ioctl' accesses on the chr_file /dev/net/tun.

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

If you believe that qemu-system-x86_64;5424e9e4 (deleted) should be allowed ioctl access on the tun chr_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:c663,c669
Target Context                system_u:object_r:tun_tap_device_t:s0:c155,c1021
Target Objects                /dev/net/tun [ chr_file ]
Source                        qemu-system-x86
Source Path                   /usr/bin/qemu-system-x86_64;5424e9e4 (deleted)
Port                          <Unknown>
Host                          (removed)
Source RPM Packages           
Target RPM Packages           
Policy RPM                    selinux-policy-3.13.1-82.fc21.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     (removed)
Platform                      Linux (removed) 3.17.0-0.rc5.git5.2.fc22.1.x86_64
                              #1 SMP Fri Sep 19 20:35:24 UTC 2014 x86_64 x86_64
Alert Count                   1
First Seen                    2014-09-26 10:47:29 PDT
Last Seen                     2014-09-26 10:47:29 PDT
Local ID                      e52078ab-713d-456f-93cf-39a2d3a91653

Raw Audit Messages
type=AVC msg=audit(1411753649.89:8982): avc:  denied  { ioctl } for  pid=7865 comm="qemu-system-x86" path="/dev/net/tun" dev="devtmpfs" ino=14343 scontext=system_u:system_r:svirt_t:s0:c663,c669 tcontext=system_u:object_r:tun_tap_device_t:s0:c155,c1021 tclass=chr_file permissive=0


type=SYSCALL msg=audit(1411753649.89:8982): arch=x86_64 syscall=ioctl success=no exit=EACCES a0=1b a1=400454d0 a2=f a3=0 items=0 ppid=1 pid=7865 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=2F7573722F62696E2F71656D752D73797374656D2D7838365F36343B3534323465396534202864656C6574656429 subj=system_u:system_r:svirt_t:s0:c663,c669 key=(null)

Hash: qemu-system-x86,svirt_t,tun_tap_device_t,chr_file,ioctl

Version-Release number of selected component:
selinux-policy-3.13.1-82.fc21.noarch

Additional info:
reporter:       libreport-2.2.3
hashmarkername: setroubleshoot
kernel:         3.17.0-0.rc5.git5.2.fc22.1.x86_64
type:           libreport

Comment 1 Ross M Karchner 2014-09-27 00:24:20 UTC
Description of problem:
attempted to create a new box in gnome-boxes, got this selinux warning 

Version-Release number of selected component:
selinux-policy-3.13.1-82.fc21.noarch

Additional info:
reporter:       libreport-2.2.3
hashmarkername: setroubleshoot
kernel:         3.16.3-300.fc21.x86_64
type:           libreport

Comment 2 Simo Sorce 2014-09-27 16:39:49 UTC
Description of problem:
started a virtual machine, setroubleshoot warns of issues
the virtual machine can't access the network

Version-Release number of selected component:
selinux-policy-3.13.1-82.fc21.noarch

Additional info:
reporter:       libreport-2.2.3
hashmarkername: setroubleshoot
kernel:         3.16.3-300.fc21.x86_64
type:           libreport

Comment 3 Dawid Zamirski 2014-10-02 17:06:19 UTC
Description of problem:
Started a VM via virt-manager that has a NIC configured to connect via a bridge adapter.

Version-Release number of selected component:
selinux-policy-3.13.1-84.fc21.noarch

Additional info:
reporter:       libreport-2.2.3
hashmarkername: setroubleshoot
kernel:         3.16.3-302.fc21.x86_64
type:           libreport

Comment 4 Miroslav Grepl 2014-10-03 09:49:10 UTC
*** Bug 1146320 has been marked as a duplicate of this bug. ***

Comment 5 Miroslav Grepl 2014-10-03 09:51:35 UTC
The problem is the tun_tap_device_t has MCS assigned.

Comment 6 Miroslav Grepl 2014-10-06 09:17:30 UTC
*** Bug 1149600 has been marked as a duplicate of this bug. ***

Comment 7 Michal Privoznik 2014-10-07 14:57:11 UTC
Patch proposed upstream:

https://www.redhat.com/archives/libvir-list/2014-October/msg00228.html

Comment 8 Cole Robinson 2014-10-07 15:35:31 UTC
*** Bug 1016326 has been marked as a duplicate of this bug. ***

Comment 9 Cole Robinson 2014-10-07 15:41:30 UTC
*** Bug 1144482 has been marked as a duplicate of this bug. ***

Comment 10 Cole Robinson 2014-10-07 15:41:32 UTC
*** Bug 1146859 has been marked as a duplicate of this bug. ***

Comment 11 Cole Robinson 2014-10-07 15:42:39 UTC
*** Bug 1149500 has been marked as a duplicate of this bug. ***

Comment 12 Simo Sorce 2014-10-08 16:53:30 UTC
Is there any workaround I can use until the problem is fixed ?
It is blocking my work with multiple VMs, as one gets access to the network and all others don't.

Comment 13 Michal Privoznik 2014-10-09 07:47:09 UTC
(In reply to Simo Sorce from comment #12)
> Is there any workaround I can use until the problem is fixed ?
> It is blocking my work with multiple VMs, as one gets access to the network
> and all others don't.

I'd say the only workaround is disabling SELinux driver in libvirt completely. 

  security_driver = ""

in qemu.conf.

Comment 14 Michal Privoznik 2014-10-09 07:48:25 UTC
However, I've pushed the patch upstream:

commit ebc05263960f41065fa7d882959ea754b9281ab1
Author:     Michal Privoznik <mprivozn@redhat.com>
AuthorDate: Tue Oct 7 16:22:17 2014 +0200
Commit:     Michal Privoznik <mprivozn@redhat.com>
CommitDate: Wed Oct 8 15:15:58 2014 +0200

    security_selinux: Don't relabel /dev/net/tun
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1147057
    
    The code for relabelling the TAP FD is there due to a race. When
    libvirt creates a /dev/tapN device it's labeled as
    'system_u:object_r:device_t:s0' by default. Later, when
    udev/systemd reacts to this device, it's relabelled to the
    expected label 'system_u:object_r:tun_tap_device_t:s0'. Hence, we
    have a code that relabels the device, to cut the race down. For
    more info see ae368ebfcc4.
    
    But the problem is, the relabel function is called on all TUN/TAP
    devices. Yes, on /dev/net/tun too. This is however a special kind
    of device - other processes uses it too. We shouldn't touch it's
    label then.
    
    Ideally, there would an API in SELinux that would label just the
    passed FD and not the underlying path. That way, we wouldn't need
    to care as we would be not labeling /dev/net/tun but the FD
    passed to the domain. Unfortunately, there's no such API so we
    have to workaround until then.
    
    Tested-by: Richard W.M. Jones <rjones@redhat.com>
    Signed-off-by: Michal Privoznik <mprivozn@redhat.com>

Comment 15 Fedora Update System 2014-10-09 17:57:47 UTC
libvirt-1.2.9-3.fc21 has been submitted as an update for Fedora 21.
https://admin.fedoraproject.org/updates/libvirt-1.2.9-3.fc21

Comment 16 Miroslav Grepl 2014-10-10 07:16:20 UTC
Michal,
I did one more look and see we had AVCs related to /dev/net/tun. Just found the libvirt should create /dev/net/tunX for which we could have MCS label? Am i wrong with /dev/net/tunX?

Comment 17 Fedora Update System 2014-10-11 06:59:11 UTC
Package libvirt-1.2.9-3.fc21:
* should fix your issue,
* was pushed to the Fedora 21 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing libvirt-1.2.9-3.fc21'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2014-12639/libvirt-1.2.9-3.fc21
then log in and leave karma (feedback).

Comment 18 Fedora Update System 2014-10-12 05:02:20 UTC
libvirt-1.2.9-3.fc21 has been pushed to the Fedora 21 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 19 Michal Privoznik 2014-10-15 10:40:52 UTC
(In reply to Miroslav Grepl from comment #16)
> Michal,
> I did one more look and see we had AVCs related to /dev/net/tun. Just found
> the libvirt should create /dev/net/tunX for which we could have MCS label?
> Am i wrong with /dev/net/tunX?

Well, there's no reason to make libvirt create /dev/net/tunX. The way that tun/tap devices work is that open()-ing them creates you a tap device that can be managed by the usual network tools (e.g. they can be plugged into a bridge). Moreover, the open() will give you a FD to which you can send/receive from data. Enforcing libvirt to create a /dev/net/tunX per domain is just workarounding missing SELinux API. And remember, it's not only libvirt that would need to do that. There are other application - like vpnc - that create TUN devices. They would need to implement the same workaround. We should do the right thing and introduce the SELinux API that would label just the passed FD and not the underlying path. Honestly, I wonder why there's no such API yet.

Comment 20 Miroslav Grepl 2014-10-15 10:54:23 UTC
(In reply to Michal Privoznik from comment #19)
> (In reply to Miroslav Grepl from comment #16)
> > Michal,
> > I did one more look and see we had AVCs related to /dev/net/tun. Just found
> > the libvirt should create /dev/net/tunX for which we could have MCS label?
> > Am i wrong with /dev/net/tunX?
> 
> Well, there's no reason to make libvirt create /dev/net/tunX. The way that
> tun/tap devices work is that open()-ing them creates you a tap device that
> can be managed by the usual network tools (e.g. they can be plugged into a
> bridge). Moreover, the open() will give you a FD to which you can
> send/receive from data. Enforcing libvirt to create a /dev/net/tunX per
> domain is just workarounding missing SELinux API. And remember, it's not
> only libvirt that would need to do that. There are other application - like
> vpnc - that create TUN devices. They would need to implement the same
> workaround. We should do the right thing and introduce the SELinux API that
> would label just the passed FD and not the underlying path. Honestly, I
> wonder why there's no such API yet.

Well I don't think it is so easy just label passed FD. CC-ing pmoore.

Comment 21 Michal Privoznik 2014-10-15 11:16:25 UTC
(In reply to Miroslav Grepl from comment #20)
> (In reply to Michal Privoznik from comment #19)
> > (In reply to Miroslav Grepl from comment #16)
> > > Michal,
> > > I did one more look and see we had AVCs related to /dev/net/tun. Just found
> > > the libvirt should create /dev/net/tunX for which we could have MCS label?
> > > Am i wrong with /dev/net/tunX?
> > 
> > Well, there's no reason to make libvirt create /dev/net/tunX. The way that
> > tun/tap devices work is that open()-ing them creates you a tap device that
> > can be managed by the usual network tools (e.g. they can be plugged into a
> > bridge). Moreover, the open() will give you a FD to which you can
> > send/receive from data. Enforcing libvirt to create a /dev/net/tunX per
> > domain is just workarounding missing SELinux API. And remember, it's not
> > only libvirt that would need to do that. There are other application - like
> > vpnc - that create TUN devices. They would need to implement the same
> > workaround. We should do the right thing and introduce the SELinux API that
> > would label just the passed FD and not the underlying path. Honestly, I
> > wonder why there's no such API yet.
> 
> Well I don't think it is so easy just label passed FD. CC-ing pmoore.

Why not? SELinux is already able to do that. I mean, it would require the kernel to cache the labels as they can't be stored in the XATTRs, but this is already implemented. For instance calling fsetfilecon() over an FD that is a pipe will label the FD only.

The reason why I'm so demanding for the API is, that it would be future proof. One of the aims is, that libvirt will (in not so distant future and in this galaxy) open all the files for qemu and then just pass the FDs. However, currently it's not possible for all the resources, so for instance on disks, libvirt actually needs to touch the selinux label defined on the file. And then, when the domain is shut down and libvirt does the cleanup, the best what we can do is 'restorecon $file'. However, if the API would label only the FD, we would not need to even bother. Moreover, there are some files we rather not re-label that we do open and pass to qemu currently: pci config files. Anyway, lets see what Paul thinks.

Comment 22 Paul Moore 2014-10-16 14:12:52 UTC
While sockets do have associated file descriptors they are not, they behave very differently from files.  Because of the differences relabeling sockets once they are created is not allowed, and never will be, as it could result in the relabeling of data that has already been "sent" under a different label.


Note You need to log in before you can comment on or make changes to this bug.