diff --git a/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch b/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch new file mode 100644 index 0000000..d52f188 --- /dev/null +++ b/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch @@ -0,0 +1,145 @@ +From bcce526443723e7cf3272f67c4d34b6925b63209 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Laine Stump +Date: Sun, 13 Sep 2020 10:26:25 -0400 +Subject: [PATCH] conf: properly clear out autogenerated macvtap names when + formatting/parsing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Back when macvtap support was added in commit 315baab9443 in Feb. 2010 +(libvirt-0.7.7), it was setup to autogenerate a name for the device if +one wasn't supplied, in the pattern "macvtap%d" (or "macvlan%d"), +similar to the way an unspecified standard tap device name will lead +to an autogenerated "vnet%d". + +As a matter of fact, in commit ca1b7cc8e45 added in May 2010, the code +was changed to *always* ignore a supplied device name for macvtap +interfaces by deleting *any* name immediately during the +parsing (this was intended to prevent one domain which had failed to +completely start from deleting the macvtap device of another domain +which had subsequently been provided the same device name (this will +seem mildly ironic later). This was later fixed to only clear the +device name when inactive XML was being parsed. HOWEVER - this was +only done if the xml was - autogenerated +names were not cleared for (which could +also result in a macvtap device). + +Although the names of "vnetX" tap devices had always been +automatically cleared when parsing (see commit d1304583d +from July 2008 (!)), at the time macvtap support was added, both vnetX +and macvtapX device names were always included when formatting the +XML. + +Then in commit a8be259d0cc (July 2011, libvirt-0.9.4), +formatting was changed to also clear out "vnetX" device names during +XML formatting as well. However the same treatment wasn't given to +"macvtapX". + +Now in 2020, there has been a report that a failed migration leads to +the macvtap device of some other unrelated guest on the destination +host losing its network connectivity. It was determined that this was +due to the domain XML in the migration containing a macvtap device +name, e.g. "macvtap0", that was already in use by the other guest on +the destination. Normally this wouldn't be a problem, because libvirt +would see that the device was already in use, and then find a +different unused name. But in this case, other external problems were +causing the migration to fail prior to selecting a macvtap device and +successfully opening it, and during error recovery, qemuProcessStop() +was called, which went through all def->nets objects and (if they were +macvtap) deleted the device specified in net->ifname; since libvirt +hadn't gotten to the point of replacing the incoming "macvtap0" with +the name of a device it actually created for this guest, that meant +that "macvtap0" was deleted, *even though it was currently in use by a +different guest*! + +Whew! + +So, it turns out that when formatting "migratable" XML, "vnetX" +devices are omitted, just as when formatting "inactive" XML. By making +the code in both interface parsing and formatting consistent for +"vnetX", "macvtapX", and "macvlanX", we can thus make sure that the +autogenerated (and unneeded / completely *not* wanted) macvtap device +name will not be sent with the migration XML. This way when a +migration fails, net->ifname will be NULL, and libvirt won't have any +device to try and (erroneously) delete. + +Signed-off-by: Laine Stump +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 282d135ddbb7203565cd5527b451469b14953994) + +https://bugzilla.redhat.com/1868549 + +Conflicts: src/conf/domain_conf.c - glib is now used upstream. Also + upstream has added managed_tap, which changes the context of one + hunk, and the position+context+exact content of another. + +Signed-off-by: Laine Stump +Message-Id: <20200913142625.21235-1-laine@redhat.com> +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 26 +++++++++++--------------- + 1 file changed, 11 insertions(+), 15 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 8bd527cfa1..75d099fdc7 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -11411,13 +11411,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + } else if (!ifname && + virXMLNodeNameEqual(cur, "target")) { + ifname = virXMLPropString(cur, "dev"); +- if (ifname && +- (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && +- (STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) || +- (prefix && STRPREFIX(ifname, prefix)))) { +- /* An auto-generated target name, blank it out */ +- VIR_FREE(ifname); +- } + } else if ((!ifname_guest || !ifname_guest_actual) && + virXMLNodeNameEqual(cur, "guest")) { + ifname_guest = virXMLPropString(cur, "dev"); +@@ -11708,14 +11701,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + + def->data.direct.linkdev = dev; + dev = NULL; +- +- if (ifname && +- flags & VIR_DOMAIN_DEF_PARSE_INACTIVE && +- (STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || +- STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX))) { +- VIR_FREE(ifname); +- } +- + break; + + case VIR_DOMAIN_NET_TYPE_HOSTDEV: +@@ -11757,6 +11742,15 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + def->domain_name = domain_name; + domain_name = NULL; + } ++ if (ifname && ++ (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && ++ (STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || ++ (prefix && STRPREFIX(ifname, prefix)))) { ++ /* An auto-generated target name, blank it out */ ++ VIR_FREE(ifname); ++ } + if (ifname != NULL) { + def->ifname = ifname; + ifname = NULL; +@@ -25394,6 +25388,8 @@ virDomainNetDefFormat(virBufferPtr buf, + if (def->ifname && + !((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) && + (STRPREFIX(def->ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(def->ifname, prefix))))) { + /* Skip auto-generated target names for inactive config. */ + virBufferEscapeString(buf, "\n", def->ifname); +-- +2.28.0 + diff --git a/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch b/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch new file mode 100644 index 0000000..2f854f5 --- /dev/null +++ b/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch @@ -0,0 +1,42 @@ +From 0293adf3792eeb797c498feefa178309d28c4803 Mon Sep 17 00:00:00 2001 +Message-Id: <0293adf3792eeb797c498feefa178309d28c4803@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 30 Sep 2020 17:38:15 +0200 +Subject: [PATCH] qemu: agent: set ifname to NULL after freeing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Signed-off-by: Ján Tomko +Reported-by: Ilja Van Sprundel +Fixes: 0977b8aa071de550e1a013d35e2c72615e65d520 +Reviewed-by: Mauro Matteo Cascella +(cherry picked from commit a63b48c5ecef077bf0f909a85f453a605600cf05) +Signed-off-by: Ján Tomko + +Conflicts: src/qemu/qemu_agent.c + Commit ee247e1d which switched virStringListFree + to g_strfreev is missing downstream. +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_agent.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c +index d6fd02a4b6..35bef8636d 100644 +--- a/src/qemu/qemu_agent.c ++++ b/src/qemu/qemu_agent.c +@@ -2055,6 +2055,7 @@ qemuAgentGetInterfaces(qemuAgentPtr mon, + + /* Has to be freed for each interface. */ + virStringListFree(ifname); ++ ifname = NULL; + + /* as well as IP address which - moreover - + * can be presented multiple times */ +-- +2.28.0 + diff --git a/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch b/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch new file mode 100644 index 0000000..59b6ef0 --- /dev/null +++ b/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch @@ -0,0 +1,104 @@ +From 08f8c359dd6a090c1d5668df9f09159c53b55366 Mon Sep 17 00:00:00 2001 +Message-Id: <08f8c359dd6a090c1d5668df9f09159c53b55366@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 30 Sep 2020 17:38:13 +0200 +Subject: [PATCH] rpc: add support for filtering @acls by uint params +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Add a new field to @acl annotations for filtering by +unsigned int parameters. + +Signed-off-by: Ján Tomko +(cherry picked from commit 50864dcda191eb35732dbd80fb6ca251a6bba923) +Signed-off-by: Ján Tomko +Message-Id: <92146976a682e6cc7e1490bcc542e9155a0207fb.1601480224.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/remote/remote_protocol.x | 3 +++ + src/rpc/gendispatch.pl | 21 ++++++++++++++++++++- + 2 files changed, 23 insertions(+), 1 deletion(-) + +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 52b92334fa..c370755f68 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -3591,6 +3591,7 @@ enum remote_procedure { + * + * - @acl: : + * - @acl: :: ++ * - @acl: :::: + * + * Declare the access control requirements for the API. May be repeated + * multiple times, if multiple rules are required. +@@ -3600,6 +3601,8 @@ enum remote_procedure { + * is one of the permissions in access/viraccessperm.h + * indicates the rule only applies if the named flag + * is set in the API call ++ * and can be used to check an unsigned int parameter ++ * against value + * + * - @aclfilter: : + * +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index c243ac200f..cec3736066 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2093,10 +2093,12 @@ elsif ($mode eq "client") { + my @acl; + foreach (@{$acl}) { + my @bits = split /:/; +- push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2] } ++ push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2], ++ param => $bits[3], value => $bits[4] } + } + + my $checkflags = 0; ++ my $paramtocheck = undef; + for (my $i = 1 ; $i <= $#acl ; $i++) { + if ($acl[$i]->{object} ne $acl[0]->{object}) { + die "acl for '$call->{ProcName}' cannot check different objects"; +@@ -2104,6 +2106,9 @@ elsif ($mode eq "client") { + if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) { + $checkflags = 1; + } ++ if (defined $acl[$i]->{param}) { ++ $paramtocheck = $acl[$i]->{param}; ++ } + } + + my $apiname = $prefix . $call->{ProcName}; +@@ -2137,6 +2142,9 @@ elsif ($mode eq "client") { + if ($checkflags) { + push @argdecls, "unsigned int flags"; + } ++ if (defined $paramtocheck) { ++ push @argdecls, "unsigned int " . $paramtocheck; ++ } + + my $ret; + my $pass; +@@ -2195,6 +2203,17 @@ elsif ($mode eq "client") { + } + print " "; + } ++ if (defined $acl->{param}) { ++ my $param = $acl->{param}; ++ my $value = $acl->{value}; ++ if ($value =~ /^\!/) { ++ $value = substr $value, 1; ++ print "($param != ($value)) &&\n"; ++ } else { ++ print "($param == ($value)) &&\n"; ++ } ++ print " "; ++ } + print "(rv = $method(" . join(", ", @argvars, $perm) . ")) <= 0) {\n"; + print " virObjectUnref(mgr);\n"; + if ($action eq "Ensure") { +-- +2.28.0 + diff --git a/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch b/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch new file mode 100644 index 0000000..79cc7a1 --- /dev/null +++ b/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch @@ -0,0 +1,51 @@ +From 2d684ee7a1544d9f84727302cb0e174842f0eb9c Mon Sep 17 00:00:00 2001 +Message-Id: <2d684ee7a1544d9f84727302cb0e174842f0eb9c@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 30 Sep 2020 17:38:12 +0200 +Subject: [PATCH] rpc: gendispatch: handle empty flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Prepare for omission of the in remote_protocol.x +@acl annotations: + @acl: :: +so that we can add more fields after, e.g.: + @acl: ::: + +Signed-off-by: Ján Tomko +(cherry picked from commit 955029bd0ad7ef96000f529ac38204a8f4a96401) +Signed-off-by: Ján Tomko +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/rpc/gendispatch.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index a8b9f5aeca..c243ac200f 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2101,7 +2101,7 @@ elsif ($mode eq "client") { + if ($acl[$i]->{object} ne $acl[0]->{object}) { + die "acl for '$call->{ProcName}' cannot check different objects"; + } +- if (defined $acl[$i]->{flags}) { ++ if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) { + $checkflags = 1; + } + } +@@ -2185,7 +2185,7 @@ elsif ($mode eq "client") { + my $method = "virAccessManagerCheck" . $object; + my $space = ' ' x length($method); + print " if ("; +- if (defined $acl->{flags}) { ++ if (defined $acl->{flags} && length $acl->{flags}) { + my $flags = $acl->{flags}; + if ($flags =~ /^\!/) { + $flags = substr $flags, 1; +-- +2.28.0 + diff --git a/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch b/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch new file mode 100644 index 0000000..c440b2c --- /dev/null +++ b/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch @@ -0,0 +1,74 @@ +From 9c54ef7c05dce6b67d6f7ff8ba8b414612bbaed1 Mon Sep 17 00:00:00 2001 +Message-Id: <9c54ef7c05dce6b67d6f7ff8ba8b414612bbaed1@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 30 Sep 2020 17:38:14 +0200 +Subject: [PATCH] rpc: require write acl for guest agent in + virDomainInterfaceAddresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Add a requirement for domain:write if source is set to +VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT. + +Signed-off-by: Ján Tomko +Reported-by: Ilja Van Sprundel +(cherry picked from commit e4116eaa44cb366b59f7fe98f4b88d04c04970ad) +Signed-off-by: Ján Tomko + +Conflicts: src/lxc/lxc_driver.c + The LXC implementation of the API was introduced + in libvirt 6.1.0, so it's not present downstream. + src/qemu/qemu_driver.c + Commit 5910b180 is not present downstream. +Message-Id: <7db63b4388d8b1fd096892e1465abcff99c6696a.1601480224.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/libxl/libxl_driver.c | 2 +- + src/qemu/qemu_driver.c | 2 +- + src/remote/remote_protocol.x | 1 + + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index 1eb63c5b64..d157a78bef 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -6199,7 +6199,7 @@ libxlDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = libxlDomObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 449d869f98..223583b5a7 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -20687,7 +20687,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = qemuDomObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index c370755f68..78208e5855 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -5997,6 +5997,7 @@ enum remote_procedure { + /** + * @generate: none + * @acl: domain:read ++ * @acl: domain:write::source:VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT + */ + REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353, + +-- +2.28.0 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 9195d8f..5b85981 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -253,7 +253,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 4.5.0 -Release: 36%{?dist}.2%{?extra_release} +Release: 36%{?dist}.3%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -647,6 +647,11 @@ Patch381: libvirt-util-Rework-virStringListAdd.patch Patch382: libvirt-qemu-Create-multipath-targets-for-PRs.patch Patch383: libvirt-util-Move-virIsDevMapperDevice-to-virdevmapper.c.patch Patch384: libvirt-virDevMapperGetTargetsImpl-Check-for-dm-major-properly.patch +Patch385: libvirt-rpc-gendispatch-handle-empty-flags.patch +Patch386: libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch +Patch387: libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch +Patch388: libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch +Patch389: libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2549,6 +2554,13 @@ exit 0 %changelog +* Tue Oct 20 2020 Jiri Denemark - 4.5.0-36.el7_9.3 +- rpc: gendispatch: handle empty flags (CVE-2020-25637) +- rpc: add support for filtering @acls by uint params (CVE-2020-25637) +- rpc: require write acl for guest agent in virDomainInterfaceAddresses (CVE-2020-25637) +- qemu: agent: set ifname to NULL after freeing (CVE-2020-25637) +- conf: properly clear out autogenerated macvtap names when formatting/parsing (rhbz#1868549) + * Wed Jul 22 2020 Jiri Denemark - 4.5.0-36.el7_9.2 - Rebuild to correct invalid dist tag