Commit 45c0c970 authored by Daniel Néri's avatar Daniel Néri Committed by Leo

main/xen: fix XSA-360

Fixes IRQ vector leak on x86 systems running HVM guests with PCI pass
through devices.
parent 0f474461
Pipeline #69199 passed with stages
in 7 minutes and 6 seconds
......@@ -2,7 +2,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=xen
pkgver=4.13.2
pkgrel=3
pkgrel=4
pkgdesc="Xen hypervisor"
url="https://www.xenproject.org/"
arch="x86_64 armhf aarch64" # enable armv7 when builds with gcc8
......@@ -208,6 +208,8 @@ options="!strip"
# - CVE-2020-29479 XSA-353
# - CVE-2020-29570 XSA-358
# - CVE-2020-29571 XSA-359
# 4.13.2-r4:
# - CVE-????-????? XSA-360
case "$CARCH" in
x86*)
......@@ -314,6 +316,8 @@ source="https://downloads.xenproject.org/release/$pkgname/$pkgver/$pkgname-$pkgv
xsa359.patch
xsa360-4.14.patch
xenstored.initd
xenstored.confd
xenconsoled.initd
......@@ -599,6 +603,7 @@ b1791c36e0eb0ae6bb89c0529922775e6b9c0ec66cfd99a203bc56ff0ddb071e98ae39e81d4f4d57
c458c962d9ae45c2fce049e6094923f72dfc87e0a20ef083371215cfe8345f437f556c4efadac841432db8421457eb0a6dea5d93ff148aff2466795125c759e1 xsa353.patch
0f7dcfa0115ac7e353bb0f645845b839fd628bdb553f8a5c5f03f2b5808515e255bcc6173b6b946a8901f62a80dcf9cf94f4039cd66e04315bd2ba849e585fde xsa358-4.14.patch
a842b086044a2936b71f77afb6a30aa8eb336dda467d94ab2656936434f7a1301522f2c2d6a90ebb87d39aca16d3b9d875d36b0b14492420aca1782116ecc398 xsa359.patch
f39ae56876f61ed224073985dda83037e75e6f2ab0cd0b0f920186812c6d1e6ec52494b3fd0f25cd9d6606d85061a6555cb952719d084cf8e256ef93080b75f9 xsa360-4.14.patch
52c43beb2596d645934d0f909f2d21f7587b6898ed5e5e7046799a8ed6d58f7a09c5809e1634fa26152f3fd4f3e7cfa07da7076f01b4a20cc8f5df8b9cb77e50 xenstored.initd
093f7fbd43faf0a16a226486a0776bade5dc1681d281c5946a3191c32d74f9699c6bf5d0ab8de9d1195a2461165d1660788e92a3156c9b3c7054d7b2d52d7ff0 xenstored.confd
3c86ed48fbee0af4051c65c4a3893f131fa66e47bf083caf20c9b6aa4b63fdead8832f84a58d0e27964bc49ec8397251b34e5be5c212c139f556916dc8da9523 xenconsoled.initd
......
From: Roger Pau Monne <roger.pau@citrix.com>
Subject: x86/dpci: do not remove pirqs from domain tree on unbind
A fix for a previous issue removed the pirqs from the domain tree when
they are unbound in order to prevent shared pirqs from triggering a
BUG_ON in __pirq_guest_unbind if they are unbound multiple times. That
caused free_domain_pirqs to no longer unmap the pirqs because they
are gone from the domain pirq tree, thus leaving stale unbound pirqs
after domain destruction if the domain had mapped dpci pirqs after
shutdown.
Take a different approach to fix the original issue, instead of
removing the pirq from d->pirq_tree clear the flags of the dpci pirq
struct to signal that the pirq is now unbound. This prevents calling
pirq_guest_unbind multiple times for the same pirq without having to
remove it from the domain pirq tree.
This is XSA-360.
Fixes: 5b58dad089 ('x86/pass-through: avoid double IRQ unbind during domain cleanup')
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1331,7 +1331,7 @@ void (pirq_cleanup_check)(struct pirq *p
}
if ( radix_tree_delete(&d->pirq_tree, pirq->pirq) != pirq )
- BUG_ON(!d->is_dying);
+ BUG();
}
/* Flush all ready EOIs from the top of this CPU's pending-EOI stack. */
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -862,6 +862,10 @@ static int pci_clean_dpci_irq(struct dom
{
struct dev_intx_gsi_link *digl, *tmp;
+ if ( !pirq_dpci->flags )
+ /* Already processed. */
+ return 0;
+
pirq_guest_unbind(d, dpci_pirq(pirq_dpci));
if ( pt_irq_need_timer(pirq_dpci->flags) )
@@ -872,15 +876,10 @@ static int pci_clean_dpci_irq(struct dom
list_del(&digl->list);
xfree(digl);
}
+ /* Note the pirq is now unbound. */
+ pirq_dpci->flags = 0;
- radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq);
-
- if ( !pt_pirq_softirq_active(pirq_dpci) )
- return 0;
-
- domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci;
-
- return -ERESTART;
+ return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0;
}
static int pci_clean_dpci_irqs(struct domain *d)
@@ -897,18 +896,8 @@ static int pci_clean_dpci_irqs(struct do
hvm_irq_dpci = domain_get_irq_dpci(d);
if ( hvm_irq_dpci != NULL )
{
- int ret = 0;
-
- if ( hvm_irq_dpci->pending_pirq_dpci )
- {
- if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) )
- ret = -ERESTART;
- else
- hvm_irq_dpci->pending_pirq_dpci = NULL;
- }
+ int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
- if ( !ret )
- ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
if ( ret )
{
spin_unlock(&d->event_lock);
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -160,8 +160,6 @@ struct hvm_irq_dpci {
DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
/* Record of mapped Links */
uint8_t link_cnt[NR_LINK];
- /* Clean up: Entry with a softirq invocation pending / in progress. */
- struct hvm_pirq_dpci *pending_pirq_dpci;
};
/* Machine IRQ to guest device/intx mapping. */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment