Introduce a read-only `tapfd` element for interfaces of type network,
bridge, direct, and ethernet, which contains the path in `/dev` to the
backing tapfd for that interface. The element is only included when the
domain is being formatted for internal consumption
(VIR_DOMAIN_DEF_FORMAT_STATUS) and is not accepted in user-provided XML
(!VIR_DOMAIN_DEF_PARSE_INACTIVE).

This is used by the AppArmor security driver when re-generating profiles.

Partial-Resolves: #692
Bug-Ubuntu: https://bugs.launchpad.net/bugs/2126574
Signed-off-by: Wesley Hershberger <[email protected]>
---
 src/conf/domain_conf.c           | 10 ++++++++++
 src/conf/domain_conf.h           |  1 +
 src/qemu/qemu_command.c          |  9 +++++++++
 src/security/security_apparmor.c |  1 +
 src/security/virt-aa-helper.c    |  5 +++++
 5 files changed, 26 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 541dad5bdc..bfeed3dc96 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2936,6 +2936,9 @@ virDomainNetDefFree(virDomainNetDef *def)
     g_free(def->virtio);
     g_free(def->coalesce);
     g_free(def->sourceDev);
+    if (def->tapfdpath) {
+        g_free(def->tapfdpath);
+    }
 
     virNetDevIPInfoClear(&def->guestIP);
     virNetDevIPInfoClear(&def->hostIP);
@@ -10427,6 +10430,10 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
             return NULL;
     }
 
+    if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) {
+        def->tapfdpath = virXPathString("string(./tapfd/@path)", ctxt);
+    }
+
     if (virNetworkPortOptionsParseXML(ctxt, &def->isolatedPort) < 0)
         return NULL;
 
@@ -25596,6 +25603,9 @@ virDomainNetDefFormat(virBuffer *buf,
     if (def->mtu)
         virBufferAsprintf(buf, "<mtu size='%u'/>\n", def->mtu);
 
+    if (def->tapfdpath && (flags & VIR_DOMAIN_DEF_FORMAT_STATUS))
+        virBufferAsprintf(buf, "<tapfd path='%s'/>\n", def->tapfdpath);
+
     virDomainNetDefCoalesceFormatXML(buf, def->coalesce);
 
     virDomainDeviceInfoFormat(buf, &def->info, flags | 
VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cb35ff06bd..cadbc3e36d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1201,6 +1201,7 @@ struct _virDomainNetDef {
     char *downscript;
     char *domain_name; /* backend domain name */
     char *ifname; /* interface name on the host (<target dev='x'/>) */
+    char *tapfdpath; /* Path for the device's tapfd in /dev on the host */
     virTristateBool managed_tap;
     virNetDevIPInfo hostIP;
     char *ifname_guest_actual;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 98229d7cf9..96352821d7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8880,9 +8880,18 @@ qemuBuildInterfaceConnect(virDomainObj *vm,
 
         for (i = 0; i < tapfdSize; i++) {
             g_autofree char *name = g_strdup_printf("tapfd-%s%zu", 
net->info.alias, i);
+            g_autofree char *procpath = NULL;
             int fd = tapfd[i]; /* we want to keep the array intact for 
security labeling*/
 
             netpriv->tapfds = g_slist_prepend(netpriv->tapfds, 
qemuFDPassDirectNew(name, &fd));
+
+            /* Include tapfd path in the domstatus XML */
+            procpath = g_strdup_printf("/proc/self/fd/%d", tapfd[i]);
+
+            if (virFileResolveLink(procpath, &net->tapfdpath) < 0) {
+                /* it's a deleted file, presumably.  Ignore? */
+                VIR_WARN("could not find path for descriptor %s, skipping", 
procpath);
+            }
         }
 
         netpriv->tapfds = g_slist_reverse(netpriv->tapfds);
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 68ac39611f..13dbce67c3 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -156,6 +156,7 @@ load_profile(virSecurityManager *mgr G_GNUC_UNUSED,
 
     if (virDomainDefFormatInternal(def, NULL, &buf,
                                    VIR_DOMAIN_DEF_FORMAT_SECURE |
+                                   VIR_DOMAIN_DEF_FORMAT_STATUS |
                                    VIR_DOMAIN_DEF_FORMAT_VOLUME_TRANSLATED) < 
0)
         return -1;
 
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 9598b95432..7920162cdc 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1174,6 +1174,11 @@ get_files(vahControl * ctl)
                                      vhu->type) != 0)
                 return -1;
         }
+
+        if (net->tapfdpath) {
+            if (vah_add_file(&buf, net->tapfdpath, "rwk") != 0)
+                return -1;
+        }
     }
 
     for (i = 0; i < ctl->def->nmems; i++) {

-- 
2.51.0

Reply via email to