After the call to can_put_echo_skb() in acc_start_xmit() the skb should be considered invalid and not accessed anymore, but acc_txq_put() will access the skb's data. So far acc_txq_put() first loads the CAN data into the controller then starts the TX. Move the start-TX functionality into the acc_txq_start() function. In acc_start_xmit(), first load the data into the controller using acc_txq_put(), then can_put_echo_skb() and finally start the TX with acc_txq_start(). Link: https://patch.msgid.link/20260929-esd-fix-skb-deref-v2-1-542e3e19fb25@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/esd/esdacc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/esd/esdacc.c b/drivers/net/can/esd/esdacc.c index 73e66f9a3781..05d41ed34a02 100644 --- a/drivers/net/can/esd/esdacc.c +++ b/drivers/net/can/esd/esdacc.c @@ -62,14 +62,17 @@ static void acc_resetmode_leave(struct acc_core *core) acc_resetmode_entered(core); } -static void acc_txq_put(struct acc_core *core, u32 acc_id, u32 acc_dlc, - const void *data) +static void acc_txq_put(struct acc_core *core, u32 acc_dlc, const void *data) { acc_write32_noswap(core, ACC_CORE_OF_TXFIFO_DATA_1, *((const u32 *)(data + 4))); acc_write32_noswap(core, ACC_CORE_OF_TXFIFO_DATA_0, *((const u32 *)data)); acc_write32(core, ACC_CORE_OF_TXFIFO_DLC, acc_dlc); +} + +static void acc_txq_start(struct acc_core *core, u32 acc_id) +{ /* CAN id must be written at last. This write starts TX. */ acc_write32(core, ACC_CORE_OF_TXFIFO_ID, acc_id); } @@ -287,11 +290,12 @@ netdev_tx_t acc_start_xmit(struct sk_buff *skb, struct net_device *netdev) acc_id = cf->can_id & CAN_SFF_MASK; } - can_put_echo_skb(skb, netdev, core->tx_fifo_head, 0); + acc_txq_put(core, acc_dlc, cf->data); + can_put_echo_skb(skb, netdev, core->tx_fifo_head, 0); core->tx_fifo_head = acc_tx_fifo_next(core, tx_fifo_head); - acc_txq_put(core, acc_id, acc_dlc, cf->data); + acc_txq_start(core, acc_id); return NETDEV_TX_OK; } -- 2.53.0