Re: [PATCH v4 3/6] irqchip/gic-v3-its: Fix leak in its_vpe_irq_domain_alloc()
From: Marc Zyngier
Date: Mon Jul 13 2026 - 16:56:57 EST
On Mon, 13 Jul 2026 14:05:06 +0100,
Kemeng Shi <shikemeng@xxxxxxxxxxxxxxx> wrote:
>
> 在 2026/7/6 16:36:52, Marc Zyngier 写道:
> > On Fri, 03 Jul 2026 02:44:53 +0100,
> > Kemeng Shi <shikemeng@xxxxxxxxxxxxxxx> wrote:
> >>
> >> 在 2026/7/3 6:12:57, Marc Zyngier 写道:
> >>>> When its_irq_gic_domain_alloc() fails, the following
> >>>> its_vpe_irq_domain_free() skips calling its_vep_teardown() for the
> >>>> corresponding irq. Call its_vpe_teardown() when its_irq_gic_domain_alloc()
> >>>> is failedto avoid the leak issue.
> >>>>
> >>>> Fixes: 7d75bbb4bc1ad ("irqchip/gic-v3-its: Add VPE irq domain allocation/teardown")
> >>>> Signed-off-by: Kemeng Shi <shikemeng@xxxxxxxxxxxxxxx>
> >>>> ---
> >>>> drivers/irqchip/irq-gic-v3-its.c | 4 +++-
> >>>> 1 file changed, 3 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> >>>> index 3e4edcb64065..8968bedefdba 100644
> >>>> --- a/drivers/irqchip/irq-gic-v3-its.c
> >>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
> >>>> @@ -4666,8 +4666,10 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
> >>>> break;
> >>>> err = its_irq_gic_domain_alloc(domain, virq + i,
> >>>> vm->vpes[i]->vpe_db_lpi);
> >>>> - if (err)
> >>>> + if (err) {
> >>>> + its_vpe_teardown(vm->vpes[i]);
> >>>> break;
> >>>> + }
> >>> There is already a spot for error handling in this function, we don't
> >>> need a second one.
> >> When its_irq_gic_domain_alloc() fails at index i, its_vpe_init(vpes[i])
> >> has already succeeded but the exisiting its_vpe_irq_domain_free(domain, virq, i)
> >> only tears down VPEs with index [0, i - 1], so its_vpe_teardown(vpes[i]) is still
> >> needed.
> >> So I guess you mean we can increase index when its_irq_gic_domain_alloc() fails to
> >> free the resource with existing error handling?
> >> Please correct me if I'm miss anything.
> >
> > What I mean is this.
> >
> > M.
> >
> > diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> > index b57d81ad33a0a..4b1a3b497d7c4 100644
> > --- a/drivers/irqchip/irq-gic-v3-its.c
> > +++ b/drivers/irqchip/irq-gic-v3-its.c
> > @@ -4674,8 +4674,10 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
> > irqd_set_resend_when_in_progress(irq_get_irq_data(virq + i));
> > }
> >
> > - if (err)
> > + if (err) {
> > + its_vpe_teardown(vm->vpes[i]);
> When its_vpe_init() fails, the error path calls its_vpe_teardown(vm->vpes[i]) on
> an uninitialized vpe, which may cause a NULL dereference by access NULL vpt_page in
> its_vpe_teardown(vm->vpes[i])->its_free_pending_table(vpe->vpt_page)->page_address(pt).
>
> To reuse the existing spot, something like a flag to indicate whether its_vpe_init()
> succeeded should be added. Maybe we can keep change of this patch which seems simpler.
This is becoming a bit tedious.
It's not like a managing the life cycle of a pointer and checking for
its validity is particularly hard, is it?
M.
--
Jazz isn't dead. It just smells funny.