|
|
3ec523 |
From c414cb524bdbc3555a5332fe75b40f8cf3ded0f4 Mon Sep 17 00:00:00 2001
|
|
|
3ec523 |
From: Michal Privoznik <mprivozn@redhat.com>
|
|
|
3ec523 |
Date: Thu, 18 Sep 2014 15:17:29 +0200
|
|
|
3ec523 |
Subject: [PATCH] virSecuritySELinuxSetTapFDLabel: Temporarily revert to old
|
|
|
3ec523 |
behavior
|
|
|
3ec523 |
|
|
|
3ec523 |
https://bugzilla.redhat.com/show_bug.cgi?id=1141879
|
|
|
3ec523 |
|
|
|
3ec523 |
A long time ago I've implemented support for so called multiqueue
|
|
|
3ec523 |
net. The idea was to let guest network traffic be processed by
|
|
|
3ec523 |
multiple host CPUs and thus increasing performance. However, this
|
|
|
3ec523 |
behavior is enabled by QEMU via special ioctl() iterated over the
|
|
|
3ec523 |
all tap FDs passed in by libvirt. Unfortunately, SELinux comes in
|
|
|
3ec523 |
and disallows the ioctl() call because the /dev/net/tun has label
|
|
|
3ec523 |
system_u:object_r:tun_tap_device_t:s0 and 'attach_queue' ioctl()
|
|
|
3ec523 |
is not allowed on tun_tap_device_t type. So after discussion with
|
|
|
3ec523 |
a SELinux developer we've decided that the FDs passed to the QEMU
|
|
|
3ec523 |
should be labelled with svirt_t type and SELinux policy will
|
|
|
3ec523 |
allow the ioctl(). Therefore I've made a patch
|
|
|
3ec523 |
(cf976d9dcf4e592261b14f03572) that does exactly this. The patch
|
|
|
3ec523 |
was fixed then by a4431931393aeb1ac5893f121151fa3df4fde612 and
|
|
|
3ec523 |
b635b7a1af0e64754016d758376f382470bc11e7. However, things are not
|
|
|
3ec523 |
that easy - even though the API to label FD is called
|
|
|
3ec523 |
(fsetfilecon_raw) the underlying file is labelled too! So
|
|
|
3ec523 |
effectively we are mangling /dev/net/tun label. Yes, that broke
|
|
|
3ec523 |
dozen of other application from openvpn, or boxes, to qemu
|
|
|
3ec523 |
running other domains.
|
|
|
3ec523 |
|
|
|
3ec523 |
The best solution would be if SELinux provides a way to label an
|
|
|
3ec523 |
FD only, which could be then labeled when passed to the qemu.
|
|
|
3ec523 |
However that's a long path to go and we should fix this
|
|
|
3ec523 |
regression AQAP. So I went to talk to the SELinux developer again
|
|
|
3ec523 |
and we agreed on temporary solution that:
|
|
|
3ec523 |
|
|
|
3ec523 |
1) All the three patches are reverted
|
|
|
3ec523 |
2) SELinux temporarily allows 'attach_queue' on the
|
|
|
3ec523 |
tun_tap_device_t
|
|
|
3ec523 |
|
|
|
3ec523 |
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
3ec523 |
(cherry picked from commit ba7468dbb13f552a9177d01ea8bad155f9877bc3)
|
|
|
3ec523 |
---
|
|
|
3ec523 |
src/security/security_selinux.c | 34 ++++++++++++++++++++++++++++++++--
|
|
|
3ec523 |
1 file changed, 32 insertions(+), 2 deletions(-)
|
|
|
3ec523 |
|
|
|
3ec523 |
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
|
|
3ec523 |
index e8c13db..c078cab 100644
|
|
|
3ec523 |
--- a/src/security/security_selinux.c
|
|
|
3ec523 |
+++ b/src/security/security_selinux.c
|
|
|
3ec523 |
@@ -2330,17 +2330,47 @@ virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
3ec523 |
}
|
|
|
3ec523 |
|
|
|
3ec523 |
static int
|
|
|
3ec523 |
-virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
|
|
3ec523 |
+virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
|
|
|
3ec523 |
virDomainDefPtr def,
|
|
|
3ec523 |
int fd)
|
|
|
3ec523 |
{
|
|
|
3ec523 |
+ struct stat buf;
|
|
|
3ec523 |
+ security_context_t fcon = NULL;
|
|
|
3ec523 |
virSecurityLabelDefPtr secdef;
|
|
|
3ec523 |
+ char *str = NULL;
|
|
|
3ec523 |
+ int rc = -1;
|
|
|
3ec523 |
|
|
|
3ec523 |
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
|
|
3ec523 |
if (!secdef || !secdef->label)
|
|
|
3ec523 |
return 0;
|
|
|
3ec523 |
|
|
|
3ec523 |
- return virSecuritySELinuxFSetFilecon(fd, secdef->imagelabel);
|
|
|
3ec523 |
+ if (fstat(fd, &buf) < 0) {
|
|
|
3ec523 |
+ virReportSystemError(errno, _("cannot stat tap fd %d"), fd);
|
|
|
3ec523 |
+ goto cleanup;
|
|
|
3ec523 |
+ }
|
|
|
3ec523 |
+
|
|
|
3ec523 |
+ if ((buf.st_mode & S_IFMT) != S_IFCHR) {
|
|
|
3ec523 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
3ec523 |
+ _("tap fd %d is not character device"), fd);
|
|
|
3ec523 |
+ goto cleanup;
|
|
|
3ec523 |
+ }
|
|
|
3ec523 |
+
|
|
|
3ec523 |
+ if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) {
|
|
|
3ec523 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
3ec523 |
+ _("cannot lookup default selinux label for tap fd %d"), fd);
|
|
|
3ec523 |
+ goto cleanup;
|
|
|
3ec523 |
+ }
|
|
|
3ec523 |
+
|
|
|
3ec523 |
+ if (!(str = virSecuritySELinuxContextAddRange(secdef->label, fcon))) {
|
|
|
3ec523 |
+ goto cleanup;
|
|
|
3ec523 |
+ } else {
|
|
|
3ec523 |
+ rc = virSecuritySELinuxFSetFilecon(fd, str);
|
|
|
3ec523 |
+ }
|
|
|
3ec523 |
+
|
|
|
3ec523 |
+ cleanup:
|
|
|
3ec523 |
+ freecon(fcon);
|
|
|
3ec523 |
+ VIR_FREE(str);
|
|
|
3ec523 |
+ return rc;
|
|
|
3ec523 |
}
|
|
|
3ec523 |
|
|
|
3ec523 |
static char *
|