Re: [PATCH v3] net: fman: fix use-after-free on IRQF_SHARED handler after probe failure
From: 赵金明
Date: Fri Jun 26 2026 - 05:54:31 EST
Hi,
The analysis is logically correct. Since fman is zero-initialized by
kzalloc_obj(), both fman->cfg and fman->fpm_regs are NULL when
devm_request_irq() registers the shared IRQ handler. The guard in
fman_irq():
if (!is_init_done(fman->cfg))
return IRQ_NONE;
does not protect against this case because is_init_done(NULL) returns
true, so the handler would proceed to dereference the NULL
fpm_regs pointer via ioread32be().
However, this is a pre-existing issue unrelated to the UAF fix in this
patch. The window is very short -- between devm_request_irq() and the
completion of fman_init() -- and would require another device on the
same shared IRQ line to fire an interrupt during that interval.
If this should be addressed, I will send a separate patch for it.
The current patch is focused solely on the post-IRQ-registration UAF
on error paths.
Please let me know if you would like me to handle this separately.
Best regards,
ZhaoJinming
>This is an AI-generated review of your patch. The human sending this
>email has considered the AI review valid, or at least plausible.
>Full review at: https://sashiko.dev
>---
>net: fman: fix use-after-free on IRQF_SHARED handler after probe failure
>
>This patch fixes a use-after-free in the error path of read_dts_node(). It
>manually releases the registered IRQ handlers before freeing the fman
>structure, preventing the devres cleanup from leaving a registered IRQ
>pointing to freed memory.
>
>> diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
>> index 013273a2de32f..ba2338da0cea1 100644
>> --- a/drivers/net/ethernet/freescale/fman/fman.c
>> +++ b/drivers/net/ethernet/freescale/fman/fman.c
>[ ... ]
>> @@ -2786,7 +2790,7 @@ static struct fman *read_dts_node(struct platform_device *of_dev)
>>? if (err < 0) {
>>? dev_err(&of_dev->dev, "%s: irq %d allocation failed (error = %d)\n",
>>? __func__, fman->dts_params.err_irq, err);
>> - goto fman_free;
>> + goto free_main_irq;
>
>[Severity: High]
>This is a pre-existing issue, but since we are modifying the IRQ error
>handling here, could the shared interrupt handler crash if it fires during
>this setup phase?
>
>Just before this snippet in read_dts_node(), devm_request_irq() is called
>with IRQF_SHARED while fman is still partially initialized. Since fman was
>allocated with kzalloc_obj(), fman->cfg and fman->fpm_regs are NULL.
>
>If a shared interrupt fires immediately, fman_irq() is called:
>
>drivers/net/ethernet/freescale/fman/fman.c:fman_irq() {
>??????? ...
>??????? if (!is_init_done(fman->cfg))
>??????????????? return IRQ_NONE;
>
>??????? fpm_rg = fman->fpm_regs;
>??????? pending = ioread32be(&fpm_rg->fm_npi);
>??????? ...
>}
>
>Since fman->cfg is NULL, is_init_done() behaves like this:
>
>drivers/net/ethernet/freescale/fman/fman.c:is_init_done() {
>??????? if (!cfg)
>??????????????? return true;
>??????? ...
>}
>
>Would this cause fman_irq() to bypass the early return, proceed with a NULL
>fpm_rg pointer, and dereference it during the ioread32be() call?
>
>>? }
>>? }
>