Re: [PATCH v2 3/6] powerpc/xive: fix use-after-free of xive_ipis
From: Cédric Le Goater <clg@kaod.org>
Date: 2026-07-26 16:57:26
Also in:
linux-mm, linux-rdma, lkml
On 7/24/26 04:28, Gou Hao wrote:
quoted hunk ↗ jump to hunk
When irq_domain_alloc_irqs() fails in xive_init_ipis(), the error path frees the global xive_ipis array via kfree(). However, xive_smp_probe() ignores the error return and proceeds to call xive_setup_cpu_ipi(), which dereferences the already-freed xive_ipis pointer, resulting in a use-after-free. Propagate the error from xive_init_ipis() through xive_smp_probe() and check it in both pnv_smp_probe() and pSeries_smp_probe() so that IPI setup is aborted cleanly on failure. Fixes: 7dcc37b3eff9 ("powerpc/xive: Map one IPI interrupt per node") Signed-off-by: Gou Hao <redacted> Reviewed-by: Wentao Guan <redacted> Reviewed-by: jiazhenyuan <redacted> --- arch/powerpc/platforms/powernv/smp.c | 8 +++++--- arch/powerpc/platforms/pseries/smp.c | 8 +++++--- arch/powerpc/sysdev/xive/common.c | 6 +++++- 3 files changed, 15 insertions(+), 7 deletions(-)diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 8f41ef364fc6f..b1201dbafcaf6 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c@@ -332,10 +332,12 @@ static void pnv_cause_ipi(int cpu) static void __init pnv_smp_probe(void) { - if (xive_enabled()) - xive_smp_probe(); - else + if (xive_enabled()) { + if (xive_smp_probe() < 0) + return; + } else { xics_smp_probe(); + } if (cpu_has_feature(CPU_FTR_DBELL)) { ic_cause_ipi = smp_ops->cause_ipi;diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index db99725e752bd..14cd0634eeca8 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c@@ -194,10 +194,12 @@ static int pseries_cause_nmi_ipi(int cpu) static __init void pSeries_smp_probe(void) { - if (xive_enabled()) - xive_smp_probe(); - else + if (xive_enabled()) { + if (xive_smp_probe() < 0) + return; + } else { xics_smp_probe(); + } /* No doorbell facility, must use the interrupt controller for IPIs */ if (!cpu_has_feature(CPU_FTR_DBELL))diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index f9a1229cede73..bb6ce07c1699e 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c@@ -1256,10 +1256,14 @@ noinstr static void xive_cleanup_cpu_ipi(unsigned int cpu, struct xive_cpu *xc) int __init xive_smp_probe(void) { + int ret; + smp_ops->cause_ipi = xive_cause_ipi; /* Register the IPI */ - xive_init_ipis(); + ret = xive_init_ipis(); + if (ret < 0) + return ret;
the cause_ipi handler assignment should be moved when we know
IPIs have been allocated. Here :
smp_ops->cause_ipi = xive_cause_ipi;
/* Allocate and setup IPI for the boot CPU */ xive_setup_cpu_ipi(smp_processor_id());
Thanks, C.