]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Label all TAP FDs
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 13 Aug 2014 14:08:03 +0000 (16:08 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 20 Aug 2014 07:42:24 +0000 (09:42 +0200)
https://bugzilla.redhat.com/show_bug.cgi?id=1095636

When starting up the domain the domain's NICs are allocated. As of
1f24f682 (v1.0.6) we are able to use multiqueue feature on virtio
NICs. It breaks network processing into multiple queues which can be
processed in parallel by different host CPUs. The queues are, however,
created by opening /dev/net/tun several times. Unfortunately, only the
first FD in the row is labelled so when turning the multiqueue feature
on in the guest, qemu will get AVC denial. Make sure we label all the
FDs needed.

Moreover, the default label of /dev/net/tun doesn't allow
attaching a queue:

    type=AVC msg=audit(1399622478.790:893): avc:  denied  { attach_queue }
    for  pid=7585 comm="qemu-kvm"
    scontext=system_u:system_r:svirt_t:s0:c638,c877
    tcontext=system_u:system_r:virtd_t:s0-s0:c0.c1023
    tclass=tun_socket

And as suggested by SELinux maintainers, the tun FD should be labeled
as svirt_t. Therefore, we don't need to adjust any range (as done
previously by Guannan in ae368ebf) rather set the seclabel of the
domain directly.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_command.c
src/qemu/qemu_hotplug.c
src/security/security_selinux.c

index 84d8e4427df2bb66360e68059ec69e60a857c591..903dafdb79149ba1b645b590e690c5826e67ac25 100644 (file)
@@ -192,10 +192,6 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
         vmop, cfg->stateDir,
         virDomainNetGetActualBandwidth(net));
     if (rc >= 0) {
-        if (virSecurityManagerSetTapFDLabel(driver->securityManager,
-                                            def, rc) < 0)
-            goto error;
-
         virDomainAuditNetDevice(def, net, res_ifname, true);
         VIR_FREE(net->ifname);
         net->ifname = res_ifname;
@@ -203,17 +199,6 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
 
     virObjectUnref(cfg);
     return rc;
-
- error:
-    ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
-                     res_ifname, &net->mac,
-                     virDomainNetGetActualDirectDev(net),
-                     virDomainNetGetActualDirectMode(net),
-                     virDomainNetGetActualVirtPortProfile(net),
-                     cfg->stateDir));
-    VIR_FREE(res_ifname);
-    virObjectUnref(cfg);
-    return -1;
 }
 
 
@@ -7201,6 +7186,9 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
     }
 
     for (i = 0; i < tapfdSize; i++) {
+        if (virSecurityManagerSetTapFDLabel(driver->securityManager,
+                                            def, tapfd[i]) < 0)
+            goto cleanup;
         virCommandPassFD(cmd, tapfd[i],
                          VIR_COMMAND_PASS_FD_CLOSE_PARENT);
         if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0)
index bf43a41978afbda4d704401e50dd7a6d108be885..a364c527d4598536b2fd5814aeda341911d9e78b 100644 (file)
@@ -948,6 +948,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
             goto cleanup;
     }
 
+    for (i = 0; i < tapfdSize; i++) {
+        if (virSecurityManagerSetTapFDLabel(driver->securityManager,
+                                            vm->def, tapfd[i]) < 0)
+            goto cleanup;
+    }
+
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) ||
         virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
index c078cab72fea898cb501241fe05a7f13135820e4..5d184935c5840f82f8ff0cc5e51e1d3f0a5334b1 100644 (file)
@@ -2330,47 +2330,17 @@ virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
 }
 
 static int
-virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
+virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
                                 virDomainDefPtr def,
                                 int fd)
 {
-    struct stat buf;
-    security_context_t fcon = NULL;
     virSecurityLabelDefPtr secdef;
-    char *str = NULL;
-    int rc = -1;
 
     secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
     if (!secdef || !secdef->label)
         return 0;
 
-    if (fstat(fd, &buf) < 0) {
-        virReportSystemError(errno, _("cannot stat tap fd %d"), fd);
-        goto cleanup;
-    }
-
-    if ((buf.st_mode & S_IFMT) != S_IFCHR) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("tap fd %d is not character device"), fd);
-        goto cleanup;
-    }
-
-    if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("cannot lookup default selinux label for tap fd %d"), fd);
-        goto cleanup;
-    }
-
-    if (!(str = virSecuritySELinuxContextAddRange(secdef->label, fcon))) {
-        goto cleanup;
-    } else {
-        rc = virSecuritySELinuxFSetFilecon(fd, str);
-    }
-
- cleanup:
-    freecon(fcon);
-    VIR_FREE(str);
-    return rc;
+    return virSecuritySELinuxFSetFilecon(fd, secdef->label);
 }
 
 static char *