[PATCH] can: sja1000: ems_pci: fix UAF in channel cleanup

From: Guangshuo Li

Date: Mon Oct 26 2026 - 08:29:09 EST


When a CAN channel is absent or register_sja1000dev() fails, the
driver frees the network device but leaves its pointer in the
card->net_dev array.

The cleanup path iterates over card->channels, which counts only
successfully registered channels, while the array is indexed by
physical channel number. This mismatch can cause the cleanup path
to access an already-freed network device and skip registered
devices at higher array indices.

Set the array entries to NULL after freeing their devices and
iterate over the entire array during cleanup. This prevents
use-after-free and ensures that all registered channels are
properly released.

This issue was found by our static analysis tool under development.

Fixes: a61a8423c71d ("can: SJA1000 driver for EMS PCI cards")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Guangshuo Li <lgs201920130244@xxxxxxxxx>
---
drivers/net/can/sja1000/ems_pci.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c
index 986fc8786fac..ff680486a299 100644
--- a/drivers/net/can/sja1000/ems_pci.c
+++ b/drivers/net/can/sja1000/ems_pci.c
@@ -213,7 +213,7 @@ static void ems_pci_del_card(struct pci_dev *pdev)
struct net_device *dev;
int i = 0;

- for (i = 0; i < card->channels; i++) {
+ for (i = 0; i < ARRAY_SIZE(card->net_dev); i++) {
dev = card->net_dev[i];

if (!dev)
@@ -399,6 +399,7 @@ static int ems_pci_add_card(struct pci_dev *pdev,
"Registering device failed: %pe\n",
ERR_PTR(err));
free_sja1000dev(dev);
+ card->net_dev[i] = NULL;
goto failure_cleanup;
}

@@ -408,6 +409,7 @@ static int ems_pci_add_card(struct pci_dev *pdev,
i + 1, priv->reg_base, dev->irq);
} else {
free_sja1000dev(dev);
+ card->net_dev[i] = NULL;
}
}

--
2.43.0