summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQingshuang Fu <fuqingshuang@kylinos.cn>2026-06-18 10:13:52 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:41:32 +0200
commit83d7ec14b0938ad8cae008058fd6f912f4a9a312 (patch)
treec22decafc36c4e30d01b16a11d2f12fd0e4e9565
parent9c0fb5c09ae5bd68dc0038692af8127029cb0385 (diff)
downloadlinux-83d7ec14b0938ad8cae008058fd6f912f4a9a312.tar.gz
linux-83d7ec14b0938ad8cae008058fd6f912f4a9a312.zip
irqchip/imgpdc: Fix resource leak, add missing chained handler cleanup on remove
commit 37738fdf2ab1e504d1c63ce5bc0aeb6452d8f057 upstream. The driver allocates domain generic chips using irq_alloc_domain_generic_chips() during probe and sets up chained handlers using irq_set_chained_handler_and_data(). However, on driver removal, the generic chips are not freed and the chained handlers are not removed. The generic chips remain on the global gc_list and may later be accessed by generic interrupt chip suspend, resume, or shutdown callbacks after the driver has been removed, potentially resulting in a use-after-free and kernel crash. The chained handlers that were installed in probe for peripheral and syswake interrupts are also left dangling, which can lead to spurious interrupts accessing freed memory. Fix these issues by: - Setting IRQ_DOMAIN_FLAG_DESTROY_GC flag in domain->flags, so the core code automatically removes generic chips when irq_domain_remove() is called - Clearing all chained handlers with NULL in pdc_intc_remove() Fixes: b6ef9161e43a ("irq-imgpdc: add ImgTec PDC irqchip driver") Signed-off-by: Qingshuang Fu <fuqingshuang@kylinos.cn> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260618021352.661773-1-fffsqian@163.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/irqchip/irq-imgpdc.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c
index 5831be454673..e5c5a7fd1552 100644
--- a/drivers/irqchip/irq-imgpdc.c
+++ b/drivers/irqchip/irq-imgpdc.c
@@ -378,6 +378,7 @@ static int pdc_intc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "cannot add IRQ domain\n");
return -ENOMEM;
}
+ priv->domain->flags |= IRQ_DOMAIN_FLAG_DESTROY_GC;
/*
* Set up 2 generic irq chips with 2 chip types.
@@ -465,6 +466,11 @@ static int pdc_intc_remove(struct platform_device *pdev)
{
struct pdc_intc_priv *priv = platform_get_drvdata(pdev);
+ for (unsigned int i = 0; i < priv->nr_perips; ++i)
+ irq_set_chained_handler_and_data(priv->perip_irqs[i], NULL, NULL);
+
+ irq_set_chained_handler_and_data(priv->syswake_irq, NULL, NULL);
+
irq_domain_remove(priv->domain);
return 0;
}