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 <wesley.hershberger@canonical.com> --- 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