Skip to content

Commit 65e349f

Browse files
committed
Merge tag 'linux-can-fixes-for-6.1-20221207' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2022-12-07 The 1st patch is by Oliver Hartkopp and fixes a potential NULL pointer deref found by syzbot in the AF_CAN protocol. The next 2 patches are by Jiri Slaby and Max Staudt and add the missing flush_work() before freeing the underlying memory in the slcan and can327 driver. The last patch is by Frank Jungclaus and target the esd_usb driver and fixes the CAN error counters, allowing them to return to zero. * tag 'linux-can-fixes-for-6.1-20221207' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can: can: esd_usb: Allow REC and TEC to return to zero can: can327: flush TX_work on ldisc .close() can: slcan: fix freed work crash can: af_can: fix NULL pointer dereference in can_rcv_filter ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 87a3988 + 918ee49 commit 65e349f

File tree

4 files changed

+25
-14
lines changed

4 files changed

+25
-14
lines changed

drivers/net/can/can327.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -796,9 +796,9 @@ static int can327_netdev_close(struct net_device *dev)
796796

797797
netif_stop_queue(dev);
798798

799-
/* Give UART one final chance to flush. */
800-
clear_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
801-
flush_work(&elm->tx_work);
799+
/* We don't flush the UART TX queue here, as we want final stop
800+
* commands (like the above dummy char) to be flushed out.
801+
*/
802802

803803
can_rx_offload_disable(&elm->offload);
804804
elm->can.state = CAN_STATE_STOPPED;
@@ -1069,12 +1069,15 @@ static void can327_ldisc_close(struct tty_struct *tty)
10691069
{
10701070
struct can327 *elm = (struct can327 *)tty->disc_data;
10711071

1072-
/* unregister_netdev() calls .ndo_stop() so we don't have to.
1073-
* Our .ndo_stop() also flushes the TTY write wakeup handler,
1074-
* so we can safely set elm->tty = NULL after this.
1075-
*/
1072+
/* unregister_netdev() calls .ndo_stop() so we don't have to. */
10761073
unregister_candev(elm->dev);
10771074

1075+
/* Give UART one final chance to flush.
1076+
* No need to clear TTY_DO_WRITE_WAKEUP since .write_wakeup() is
1077+
* serialised against .close() and will not be called once we return.
1078+
*/
1079+
flush_work(&elm->tx_work);
1080+
10781081
/* Mark channel as dead */
10791082
spin_lock_bh(&elm->lock);
10801083
tty->disc_data = NULL;

drivers/net/can/slcan/slcan-core.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -864,12 +864,14 @@ static void slcan_close(struct tty_struct *tty)
864864
{
865865
struct slcan *sl = (struct slcan *)tty->disc_data;
866866

867-
/* unregister_netdev() calls .ndo_stop() so we don't have to.
868-
* Our .ndo_stop() also flushes the TTY write wakeup handler,
869-
* so we can safely set sl->tty = NULL after this.
870-
*/
871867
unregister_candev(sl->dev);
872868

869+
/*
870+
* The netdev needn't be UP (so .ndo_stop() is not called). Hence make
871+
* sure this is not running before freeing it up.
872+
*/
873+
flush_work(&sl->tx_work);
874+
873875
/* Mark channel as dead */
874876
spin_lock_bh(&sl->lock);
875877
tty->disc_data = NULL;

drivers/net/can/usb/esd_usb.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
234234
u8 rxerr = msg->msg.rx.data[2];
235235
u8 txerr = msg->msg.rx.data[3];
236236

237+
netdev_dbg(priv->netdev,
238+
"CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
239+
msg->msg.rx.dlc, state, ecc, rxerr, txerr);
240+
237241
skb = alloc_can_err_skb(priv->netdev, &cf);
238242
if (skb == NULL) {
239243
stats->rx_dropped++;
@@ -260,6 +264,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
260264
break;
261265
default:
262266
priv->can.state = CAN_STATE_ERROR_ACTIVE;
267+
txerr = 0;
268+
rxerr = 0;
263269
break;
264270
}
265271
} else {

net/can/af_can.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
677677
static int can_rcv(struct sk_buff *skb, struct net_device *dev,
678678
struct packet_type *pt, struct net_device *orig_dev)
679679
{
680-
if (unlikely(dev->type != ARPHRD_CAN || (!can_is_can_skb(skb)))) {
680+
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_can_skb(skb))) {
681681
pr_warn_once("PF_CAN: dropped non conform CAN skbuff: dev type %d, len %d\n",
682682
dev->type, skb->len);
683683

@@ -692,7 +692,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
692692
static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
693693
struct packet_type *pt, struct net_device *orig_dev)
694694
{
695-
if (unlikely(dev->type != ARPHRD_CAN || (!can_is_canfd_skb(skb)))) {
695+
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canfd_skb(skb))) {
696696
pr_warn_once("PF_CAN: dropped non conform CAN FD skbuff: dev type %d, len %d\n",
697697
dev->type, skb->len);
698698

@@ -707,7 +707,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
707707
static int canxl_rcv(struct sk_buff *skb, struct net_device *dev,
708708
struct packet_type *pt, struct net_device *orig_dev)
709709
{
710-
if (unlikely(dev->type != ARPHRD_CAN || (!can_is_canxl_skb(skb)))) {
710+
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canxl_skb(skb))) {
711711
pr_warn_once("PF_CAN: dropped non conform CAN XL skbuff: dev type %d, len %d\n",
712712
dev->type, skb->len);
713713

0 commit comments

Comments
 (0)