Blob Blame History Raw
From: Sebastian Ott <sebott@linux.ibm.com>
Date: Mon, 13 Aug 2018 11:26:46 +0200
Subject: s390/pci: fix out of bounds access during irq setup
Patch-mainline: v4.19-rc1
Git-commit: 866f3576a72b2233a76dffb80290f8086dc49e17
References: bnc#1108323, LTC#171068

Description:  s390/pci: fix out of bounds access during irq setup
Symptom:      random oopses on systems using NVMe devices
Problem:      During interrupt setup we allocate interrupt vectors,
              walk the list of msi descriptors, and fill in the message
              data. Requesting more interrupts than supported on s390
              can lead to an out of bounds access.
Solution:     When we restrict the number of interrupts we should also
              stop walking the msi list after all supported interrupts
              are handled.
Reproduction: Have a machine with a PCI function whose driver requests
              more interrupts than the architectural maximum. Currently
              this is only possible with a machine that supports 64 CPUs
              (or more) with a NVMe function attached and a kernel
              containing upstream commit: 16ccfff28976 ("nvme: pci: pass
              max vectors as num_possible_cpus() to pci_alloc_irq_vectors")

Upstream-Description:

              s390/pci: fix out of bounds access during irq setup

              During interrupt setup we allocate interrupt vectors, walk the list of msi
              descriptors, and fill in the message data. Requesting more interrupts than
              supported on s390 can lead to an out of bounds access.

              When we restrict the number of interrupts we should also stop walking the
              msi list after all supported interrupts are handled.

              Cc: stable@vger.kernel.org
              Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
              Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>


Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 arch/s390/pci/pci.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -421,6 +421,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 	hwirq = 0;
 	for_each_pci_msi_entry(msi, pdev) {
 		rc = -EIO;
+		if (hwirq >= msi_vecs)
+			break;
 		irq = irq_alloc_desc(0);	/* Alloc irq on node 0 */
 		if (irq < 0)
 			return -ENOMEM;