]> git.itanic.dy.fi Git - linux-stable/commitdiff
can: gs_usb: gs_can_open(): fix race dev->can.state condition
authorMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 20 Sep 2022 09:40:56 +0000 (11:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Sep 2022 09:02:56 +0000 (11:02 +0200)
[ Upstream commit 5440428b3da65408dba0241985acb7a05258b85e ]

The dev->can.state is set to CAN_STATE_ERROR_ACTIVE, after the device
has been started. On busy networks the CAN controller might receive
CAN frame between and go into an error state before the dev->can.state
is assigned.

Assign dev->can.state before starting the controller to close the race
window.

Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices")
Link: https://lore.kernel.org/all/20220920195216.232481-1-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/can/usb/gs_usb.c

index 2101b2fab7df83fafdebaa467a9b240e02949c28..62ca4964a863aba6c334d314d6057d0a85752e40 100644 (file)
@@ -686,6 +686,7 @@ static int gs_can_open(struct net_device *netdev)
                flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
 
        /* finally start device */
+       dev->can.state = CAN_STATE_ERROR_ACTIVE;
        dm->mode = cpu_to_le32(GS_CAN_MODE_START);
        dm->flags = cpu_to_le32(flags);
        rc = usb_control_msg(interface_to_usbdev(dev->iface),
@@ -702,13 +703,12 @@ static int gs_can_open(struct net_device *netdev)
        if (rc < 0) {
                netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
                kfree(dm);
+               dev->can.state = CAN_STATE_STOPPED;
                return rc;
        }
 
        kfree(dm);
 
-       dev->can.state = CAN_STATE_ERROR_ACTIVE;
-
        parent->active_channels++;
        if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
                netif_start_queue(netdev);