From d6726ab8cbf8cfbaae1066a6836e45ac1d59d461 Mon Sep 17 00:00:00 2001 From: "Justin M. Forbes" Date: Thu, 29 Oct 2020 10:32:46 -0500 Subject: Fix CVE-2020-27675 (rhbz 1891114 1891115) Signed-off-by: Justin M. Forbes --- ...avoid-removing-an-event-channel-while-han.patch | 161 +++++++++++++++++++++ kernel.spec | 4 + 2 files changed, 165 insertions(+) create mode 100644 0001-xen-events-avoid-removing-an-event-channel-while-han.patch diff --git a/0001-xen-events-avoid-removing-an-event-channel-while-han.patch b/0001-xen-events-avoid-removing-an-event-channel-while-han.patch new file mode 100644 index 000000000..cd4ac3df3 --- /dev/null +++ b/0001-xen-events-avoid-removing-an-event-channel-while-han.patch @@ -0,0 +1,161 @@ +From 073d0552ead5bfc7a3a9c01de590e924f11b5dd2 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Mon, 7 Sep 2020 15:47:27 +0200 +Subject: [PATCH] xen/events: avoid removing an event channel while handling it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Today it can happen that an event channel is being removed from the +system while the event handling loop is active. This can lead to a +race resulting in crashes or WARN() splats when trying to access the +irq_info structure related to the event channel. + +Fix this problem by using a rwlock taken as reader in the event +handling loop and as writer when deallocating the irq_info structure. + +As the observed problem was a NULL dereference in evtchn_from_irq() +make this function more robust against races by testing the irq_info +pointer to be not NULL before dereferencing it. + +And finally make all accesses to evtchn_to_irq[row][col] atomic ones +in order to avoid seeing partial updates of an array element in irq +handling. Note that irq handling can be entered only for event channels +which have been valid before, so any not populated row isn't a problem +in this regard, as rows are only ever added and never removed. + +This is XSA-331. + +Cc: stable@vger.kernel.org +Reported-by: Marek Marczykowski-Górecki +Reported-by: Jinoh Kang +Signed-off-by: Juergen Gross +Reviewed-by: Stefano Stabellini +Reviewed-by: Wei Liu +--- + drivers/xen/events/events_base.c | 41 ++++++++++++++++++++++++++++---- + 1 file changed, 36 insertions(+), 5 deletions(-) + +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index 6f02c18fa65c..407741ece084 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_X86 + #include +@@ -71,6 +72,23 @@ const struct evtchn_ops *evtchn_ops; + */ + static DEFINE_MUTEX(irq_mapping_update_lock); + ++/* ++ * Lock protecting event handling loop against removing event channels. ++ * Adding of event channels is no issue as the associated IRQ becomes active ++ * only after everything is setup (before request_[threaded_]irq() the handler ++ * can't be entered for an event, as the event channel will be unmasked only ++ * then). ++ */ ++static DEFINE_RWLOCK(evtchn_rwlock); ++ ++/* ++ * Lock hierarchy: ++ * ++ * irq_mapping_update_lock ++ * evtchn_rwlock ++ * IRQ-desc lock ++ */ ++ + static LIST_HEAD(xen_irq_list_head); + + /* IRQ <-> VIRQ mapping. */ +@@ -105,7 +123,7 @@ static void clear_evtchn_to_irq_row(unsigned row) + unsigned col; + + for (col = 0; col < EVTCHN_PER_ROW; col++) +- evtchn_to_irq[row][col] = -1; ++ WRITE_ONCE(evtchn_to_irq[row][col], -1); + } + + static void clear_evtchn_to_irq_all(void) +@@ -142,7 +160,7 @@ static int set_evtchn_to_irq(evtchn_port_t evtchn, unsigned int irq) + clear_evtchn_to_irq_row(row); + } + +- evtchn_to_irq[row][col] = irq; ++ WRITE_ONCE(evtchn_to_irq[row][col], irq); + return 0; + } + +@@ -152,7 +170,7 @@ int get_evtchn_to_irq(evtchn_port_t evtchn) + return -1; + if (evtchn_to_irq[EVTCHN_ROW(evtchn)] == NULL) + return -1; +- return evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)]; ++ return READ_ONCE(evtchn_to_irq[EVTCHN_ROW(evtchn)][EVTCHN_COL(evtchn)]); + } + + /* Get info for IRQ */ +@@ -261,10 +279,14 @@ static void xen_irq_info_cleanup(struct irq_info *info) + */ + evtchn_port_t evtchn_from_irq(unsigned irq) + { +- if (WARN(irq >= nr_irqs, "Invalid irq %d!\n", irq)) ++ const struct irq_info *info = NULL; ++ ++ if (likely(irq < nr_irqs)) ++ info = info_for_irq(irq); ++ if (!info) + return 0; + +- return info_for_irq(irq)->evtchn; ++ return info->evtchn; + } + + unsigned int irq_from_evtchn(evtchn_port_t evtchn) +@@ -440,16 +462,21 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi) + static void xen_free_irq(unsigned irq) + { + struct irq_info *info = info_for_irq(irq); ++ unsigned long flags; + + if (WARN_ON(!info)) + return; + ++ write_lock_irqsave(&evtchn_rwlock, flags); ++ + list_del(&info->list); + + set_info_for_irq(irq, NULL); + + WARN_ON(info->refcnt > 0); + ++ write_unlock_irqrestore(&evtchn_rwlock, flags); ++ + kfree(info); + + /* Legacy IRQ descriptors are managed by the arch. */ +@@ -1233,6 +1260,8 @@ static void __xen_evtchn_do_upcall(void) + struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); + int cpu = smp_processor_id(); + ++ read_lock(&evtchn_rwlock); ++ + do { + vcpu_info->evtchn_upcall_pending = 0; + +@@ -1243,6 +1272,8 @@ static void __xen_evtchn_do_upcall(void) + virt_rmb(); /* Hypervisor can set upcall pending. */ + + } while (vcpu_info->evtchn_upcall_pending); ++ ++ read_unlock(&evtchn_rwlock); + } + + void xen_evtchn_do_upcall(struct pt_regs *regs) +-- +2.28.0 + diff --git a/kernel.spec b/kernel.spec index f802fcf4d..b3a3a6949 100644 --- a/kernel.spec +++ b/kernel.spec @@ -892,6 +892,9 @@ Patch130: arm64-dts-allwinner-h5-OrangePi-PC2-Fix-ethernet-node.patch # https://patchwork.kernel.org/project/linux-arm-kernel/patch/20201023194902.368239-1-jernej.skrabec@siol.net/ Patch131: arm64-dts-allwinner-h6-Pine-H64-Fix-ethernet-node.patch +# CVE-2020-27675 rhbz 1891114 1891115 +Patch132: 0001-xen-events-avoid-removing-an-event-channel-while-han.patch + # END OF PATCH DEFINITIONS %endif @@ -3007,6 +3010,7 @@ fi %changelog * Thu Oct 29 07:55:22 CDT 2020 Justin M. Forbes - 5.8.17-200 - Linux v5.8.17 +- Fix CVE-2020-27675 (rhbz 1891114 1891115) * Wed Oct 28 2020 Peter Robinson - Fixes for AllWinner wired network issues due to Realtek PHY driver change (rhbz 1889090) -- cgit