[PATCH net v3 3/4] net: dsa: microchip: Ensure a ksz_irq is initialized before freeing it

Bastien Curutchet (Schneider Electric) posted 4 patches 2 months, 3 weeks ago
There is a newer version of this series
[PATCH net v3 3/4] net: dsa: microchip: Ensure a ksz_irq is initialized before freeing it
Posted by Bastien Curutchet (Schneider Electric) 2 months, 3 weeks ago
Sometimes ksz_irq_free() can be called on uninitialized ksz_irq (for
example when ksz_ptp_irq_setup() fails). It leads to freeing
uninitialized IRQ numbers and/or domains.

Ensure that IRQ numbers or domains aren't null before freeing them.
In our case the IRQ number of an initialized ksz_irq is never 0. Indeed,
it's either the device's IRQ number and we enter the IRQ setup only when
this dev->irq is strictly positive, or a virtual IRQ assigned with
irq_create_mapping() which returns strictly positive IRQ numbers.

Fixes: cc13ab18b201 ("net: dsa: microchip: ptp: enable interrupt for timestamping")
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
--
Regarding the Fixes tag here, IMO before cc13ab18b201 it was safe to
not check the domain and the IRQ number because I don't see any path
where ksz_irq_free() would be called on a non-initialized ksz_irq
---
 drivers/net/dsa/microchip/ksz_common.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 3a4516d32aa5f99109853ed400e64f8f7e2d8016..c5f8821a3a0ab7b50ddc31cc0a2f28220fe57c84 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2858,14 +2858,17 @@ static void ksz_irq_free(struct ksz_irq *kirq)
 {
 	int irq, virq;
 
-	free_irq(kirq->irq_num, kirq);
+	if (kirq->irq_num)
+		free_irq(kirq->irq_num, kirq);
 
-	for (irq = 0; irq < kirq->nirqs; irq++) {
-		virq = irq_find_mapping(kirq->domain, irq);
-		irq_dispose_mapping(virq);
-	}
+	if (kirq->domain) {
+		for (irq = 0; irq < kirq->nirqs; irq++) {
+			virq = irq_find_mapping(kirq->domain, irq);
+			irq_dispose_mapping(virq);
+		}
 
-	irq_domain_remove(kirq->domain);
+		irq_domain_remove(kirq->domain);
+	}
 }
 
 static irqreturn_t ksz_irq_thread_fn(int irq, void *dev_id)

-- 
2.51.1
Re: [PATCH net v3 3/4] net: dsa: microchip: Ensure a ksz_irq is initialized before freeing it
Posted by Andrew Lunn 2 months, 3 weeks ago
On Fri, Nov 14, 2025 at 08:20:22AM +0100, Bastien Curutchet (Schneider Electric) wrote:
> Sometimes ksz_irq_free() can be called on uninitialized ksz_irq (for
> example when ksz_ptp_irq_setup() fails). It leads to freeing
> uninitialized IRQ numbers and/or domains.
> 
> Ensure that IRQ numbers or domains aren't null before freeing them.
> In our case the IRQ number of an initialized ksz_irq is never 0. Indeed,
> it's either the device's IRQ number and we enter the IRQ setup only when
> this dev->irq is strictly positive, or a virtual IRQ assigned with
> irq_create_mapping() which returns strictly positive IRQ numbers.
> 
> Fixes: cc13ab18b201 ("net: dsa: microchip: ptp: enable interrupt for timestamping")
> Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
> --
> Regarding the Fixes tag here, IMO before cc13ab18b201 it was safe to
> not check the domain and the IRQ number because I don't see any path
> where ksz_irq_free() would be called on a non-initialized ksz_irq

I would say the caller is wrong, not ksz_irq_free().

Functions like this come in pairs: ksz_irq_setup() & ksz_irq_free().
_free() should not be called if _setup() was not successful.

Please take a look if you can fix the caller. If the change is big,
maybe we need this as a minimal fix for net, but make the bigger
change in net-next?

Thanks
	Andrew
Re: [PATCH net v3 3/4] net: dsa: microchip: Ensure a ksz_irq is initialized before freeing it
Posted by Bastien Curutchet 2 months, 3 weeks ago
Hi Andrew,

On 11/14/25 4:00 PM, Andrew Lunn wrote:
> On Fri, Nov 14, 2025 at 08:20:22AM +0100, Bastien Curutchet (Schneider Electric) wrote:
>> Sometimes ksz_irq_free() can be called on uninitialized ksz_irq (for
>> example when ksz_ptp_irq_setup() fails). It leads to freeing
>> uninitialized IRQ numbers and/or domains.
>>
>> Ensure that IRQ numbers or domains aren't null before freeing them.
>> In our case the IRQ number of an initialized ksz_irq is never 0. Indeed,
>> it's either the device's IRQ number and we enter the IRQ setup only when
>> this dev->irq is strictly positive, or a virtual IRQ assigned with
>> irq_create_mapping() which returns strictly positive IRQ numbers.
>>
>> Fixes: cc13ab18b201 ("net: dsa: microchip: ptp: enable interrupt for timestamping")
>> Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
>> --
>> Regarding the Fixes tag here, IMO before cc13ab18b201 it was safe to
>> not check the domain and the IRQ number because I don't see any path
>> where ksz_irq_free() would be called on a non-initialized ksz_irq
> 
> I would say the caller is wrong, not ksz_irq_free().
> 
> Functions like this come in pairs: ksz_irq_setup() & ksz_irq_free().
> _free() should not be called if _setup() was not successful.
> 
> Please take a look if you can fix the caller. If the change is big,
> maybe we need this as a minimal fix for net, but make the bigger
> change in net-next?

Ok, I'll look at it, I think the change won't be that big.

Best regards,
Bastien