[PATCH 2/7] s390/pci: fix use-after-free race in zpci floating interrupt cleanup

Tobias Schumacher <[email protected]>
Newsgroups org.kernel.vger.linux-s390,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
The interrupt handler reads zpci_ibv[si] without synchronization while
concurrent teardown can release this memory, creating a race:
- handler reads the pointer,
- then teardown frees memory,
- then handler uses the freed pointer.
Fix by protecting array access with RCU synchronization.

Fixes: f770950a4709 ("s390/pci: Migrate s390 IRQ logic to IRQ domain API")
Cc: [email protected]
Signed-off-by: Tobias Schumacher <[email protected]>
---
 arch/s390/pci/pci_irq.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c
index c9520a16ca75..94b03d16006b 100644
--- a/arch/s390/pci/pci_irq.c
+++ b/arch/s390/pci/pci_irq.c
@@ -278,8 +278,14 @@ static void zpci_floating_irq_handler(struct airq_struct *airq,
 			continue;
 		}
 
+		rcu_read_lock();
+
 		/* Scan the adapter interrupt vector for this device. */
-		aibv = zpci_ibv[si];
+		aibv = rcu_dereference(zpci_ibv[si]);
+		if (!aibv) {
+			rcu_read_unlock();
+			continue;
+		}
 		for (ai = 0;;) {
 			ai = airq_iv_scan(aibv, ai, airq_iv_end(aibv));
 			if (ai == -1UL)
@@ -291,6 +297,7 @@ static void zpci_floating_irq_handler(struct airq_struct *airq,
 			generic_handle_domain_irq(msi_domain, hwirq);
 			airq_iv_unlock(aibv, ai);
 		}
+		rcu_read_unlock();
 	}
 }
 
@@ -346,9 +353,12 @@ static void zpci_msi_teardown_directed(struct zpci_dev *zdev)
 
 static void zpci_msi_teardown_floating(struct zpci_dev *zdev)
 {
+	airq_iv_free_bit(zpci_sbv, zdev->aisb);
+	zpci_ibv[zdev->aisb] = NULL;
+	synchronize_rcu();
+
 	airq_iv_release(zdev->aibv);
 	zdev->aibv = NULL;
-	airq_iv_free_bit(zpci_sbv, zdev->aisb);
 	zdev->aisb = -1UL;
 	zdev->msi_first_bit = -1U;
 	zdev->msi_nr_irqs = 0;

-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.