Re: [PATCH v1] genirq/msi: fix crash when handling Multi-MSI
From: Marc Zyngier
Date: Mon Jan 17 2022 - 05:00:07 EST
On Mon, 17 Jan 2022 09:27:59 +0000,
Tong Zhang <ztong0001@xxxxxxxxx> wrote:
>
> pci_msi_domain_check_cap() could return 1 when domain does not support
> multi MSI and user request multi MSI. This positive value will be used by
> __pci_enable_msi_range(). In previous refactor, this positive value is
> handled as error case which will cause kernel crash.
>
> [ 1.197953] BUG: KASAN: use-after-free in __pci_enable_msi_range+0x234/0x320
> [ 1.198327] Freed by task 1:
> [ 1.198327] kfree+0x8f/0x2b0
> [ 1.198327] msi_free_msi_descs_range+0xf5/0x130
> [ 1.198327] msi_domain_alloc_irqs_descs_locked+0x8d/0xa0
> [ 1.198327] __pci_enable_msi_range+0x1a4/0x320
> [ 1.198327] pci_alloc_irq_vectors_affinity+0x135/0x1a0
> [ 1.198327] pcie_port_device_register+0x4a1/0x5c0
> [ 1.198327] pcie_portdrv_probe+0x50/0x100
I'm sorry, but you'll have to be a bit clearer in your commit message,
because I cannot relate what you describe with the patch.
The real issue seems to be that a domain_alloc_irqs callback can
return a positive, non-zero value, and I don't think this is expected.
How about this instead? If I am barking up the wrong tree, please
provide a more accurate description of the problem you are seeing.
Thanks,
M.
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 2bdfce5edafd..da8bb6135627 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -878,8 +878,10 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
virq = __irq_domain_alloc_irqs(domain, -1, desc->nvec_used,
dev_to_node(dev), &arg, false,
desc->affinity);
- if (virq < 0)
- return msi_handle_pci_fail(domain, desc, allocated);
+ if (virq < 0) {
+ ret = msi_handle_pci_fail(domain, desc, allocated);
+ return ret < 0 ? ret : 0;
+ }
for (i = 0; i < desc->nvec_used; i++) {
irq_set_msi_desc_off(virq, i, desc);
--
Without deviation from the norm, progress is not possible.