提交 103108cb 编写于 作者: M Marc Kleine-Budde

can: gs_usb: gs_can_open(): initialize time counter before starting device

On busy networks the CAN controller might receive CAN frames directly
after starting it but before the timecounter is setup. This will lead
to NULL pointer deref while converting the converting the CAN frame's
timestamp with the timecounter.

Close the race window by setting up the timecounter before starting
the CAN controller.

Fixes: 45dfa45f ("can: gs_usb: add RX and TX hardware timestamp support")
Link: https://lore.kernel.org/all/20220921081329.385509-1-mkl@pengutronix.de
Cc: John Whittington <git@jbrengineering.co.uk
Tested-by: NJohn Whittington <git@jbrengineering.co.uk>
Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
上级 29a8c9ec
...@@ -972,6 +972,10 @@ static int gs_can_open(struct net_device *netdev) ...@@ -972,6 +972,10 @@ static int gs_can_open(struct net_device *netdev)
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
flags |= GS_CAN_MODE_HW_TIMESTAMP; flags |= GS_CAN_MODE_HW_TIMESTAMP;
/* start polling timestamp */
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
gs_usb_timestamp_init(dev);
/* finally start device */ /* finally start device */
dev->can.state = CAN_STATE_ERROR_ACTIVE; dev->can.state = CAN_STATE_ERROR_ACTIVE;
dm->mode = cpu_to_le32(GS_CAN_MODE_START); dm->mode = cpu_to_le32(GS_CAN_MODE_START);
...@@ -985,16 +989,14 @@ static int gs_can_open(struct net_device *netdev) ...@@ -985,16 +989,14 @@ static int gs_can_open(struct net_device *netdev)
if (rc < 0) { if (rc < 0) {
netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
kfree(dm); kfree(dm);
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
gs_usb_timestamp_stop(dev);
dev->can.state = CAN_STATE_STOPPED; dev->can.state = CAN_STATE_STOPPED;
return rc; return rc;
} }
kfree(dm); kfree(dm);
/* start polling timestamp */
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
gs_usb_timestamp_init(dev);
parent->active_channels++; parent->active_channels++;
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
netif_start_queue(netdev); netif_start_queue(netdev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册