mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	can: gs_usb: gs_can_open(): fix race dev->can.state condition
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: d08e973a77 ("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>
			
			
This commit is contained in:
		
							parent
							
								
									a09721dd47
								
							
						
					
					
						commit
						5440428b3d
					
				
					 1 changed files with 2 additions and 2 deletions
				
			
		| 
						 | 
					@ -824,6 +824,7 @@ static int gs_can_open(struct net_device *netdev)
 | 
				
			||||||
		flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
 | 
							flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* finally start device */
 | 
						/* finally start device */
 | 
				
			||||||
 | 
						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);
 | 
				
			||||||
	dm->flags = cpu_to_le32(flags);
 | 
						dm->flags = cpu_to_le32(flags);
 | 
				
			||||||
	rc = usb_control_msg(interface_to_usbdev(dev->iface),
 | 
						rc = usb_control_msg(interface_to_usbdev(dev->iface),
 | 
				
			||||||
| 
						 | 
					@ -835,13 +836,12 @@ 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);
 | 
				
			||||||
 | 
							dev->can.state = CAN_STATE_STOPPED;
 | 
				
			||||||
		return rc;
 | 
							return rc;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kfree(dm);
 | 
						kfree(dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev->can.state = CAN_STATE_ERROR_ACTIVE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue