[PATCH] can: kvaser_pciefd: fix use-after-free in bec poll timer
From: Fan Wu
Date: Tue Aug 18 2026 - 02:40:27 EST
The bec poll timer is rearmed from the interrupt handler, so the
timer_delete() call in kvaser_pciefd_remove() neither waits for a
callback that is already running nor stops the handler from rearming
the timer until the interrupt is freed later in the same function.
The timer can therefore still be pending or running when free_candev()
frees the CAN device, causing a use-after-free in
kvaser_pciefd_bec_poll_timer().
Use timer_shutdown_sync() instead, which waits for a running callback
and makes a later rearm a no-op. Also drain the timer in
kvaser_pciefd_teardown_can_ctrls(), which frees the CAN devices on the
probe error paths.
This issue was found by an in-house static analysis tool.
Fixes: 26ad340e582d ("can: kvaser_pciefd: Add driver for Kvaser PCIEcan devices")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@xxxxxxxxxx>
---
drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c | 1 +1 +
1 file changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c b/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c
index d8c9bfb20..a0597db72 100644
@@ -1739,6 +1739,7 @@
iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG);
kvaser_pciefd_pwm_stop(can);
kvaser_pciefd_devlink_port_unregister(can);
+ timer_shutdown_sync(&can->bec_poll_timer);
free_candev(can->can.dev);
}
}
@@ -1879,7 +1880,7 @@
struct kvaser_pciefd_can *can = pcie->can[i];
unregister_candev(can->can.dev);
- timer_delete(&can->bec_poll_timer);
+ timer_shutdown_sync(&can->bec_poll_timer);
kvaser_pciefd_pwm_stop(can);
kvaser_pciefd_devlink_port_unregister(can);
}