Skip to content

Commit 46b5562

Browse files
committed
Merge tag 'linux-can-fixes-for-5.18-20220331' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2022-03-31 The first patch is by Oliver Hartkopp and fixes MSG_PEEK feature in the CAN ISOTP protocol (broken in net-next for v5.18 only). Tom Rix's patch for the mcp251xfd driver fixes the propagation of an error value in case of an error. A patch by me for the m_can driver fixes a use-after-free in the xmit handler for m_can IP cores v3.0.x. Hangyu Hua contributes 3 patches fixing the same double free in the error path of the xmit handler in the ems_usb, usb_8dev and mcba_usb USB CAN driver. Pavel Skripkin contributes a patch for the mcba_usb driver to properly check the endpoint type. The last patch is by me and fixes a mem leak in the gs_usb, which was introduced in net-next for v5.18. * tag 'linux-can-fixes-for-5.18-20220331' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can: can: gs_usb: gs_make_candev(): fix memory leak for devices with extended bit timing configuration can: mcba_usb: properly check endpoint type can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error path can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path can: m_can: m_can_tx_handler(): fix use after free of skb can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value can: isotp: restore accidentally removed MSG_PEEK feature ==================== Link: https://lore.kernel.org/r/ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents ff8376a + 50d34a0 commit 46b5562

7 files changed

Lines changed: 37 additions & 32 deletions

File tree

drivers/net/can/m_can/m_can.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,8 +1637,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
16371637
if (err)
16381638
goto out_fail;
16391639

1640-
can_put_echo_skb(skb, dev, 0, 0);
1641-
16421640
if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) {
16431641
cccr = m_can_read(cdev, M_CAN_CCCR);
16441642
cccr &= ~CCCR_CMR_MASK;
@@ -1655,6 +1653,9 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
16551653
m_can_write(cdev, M_CAN_CCCR, cccr);
16561654
}
16571655
m_can_write(cdev, M_CAN_TXBTIE, 0x1);
1656+
1657+
can_put_echo_skb(skb, dev, 0, 0);
1658+
16581659
m_can_write(cdev, M_CAN_TXBAR, 0x1);
16591660
/* End of xmit function for version 3.0.x */
16601661
} else {

drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,7 +1786,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
17861786
out_kfree_buf_rx:
17871787
kfree(buf_rx);
17881788

1789-
return 0;
1789+
return err;
17901790
}
17911791

17921792
#define MCP251XFD_QUIRK_ACTIVE(quirk) \

drivers/net/can/usb/ems_usb.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,6 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
819819

820820
usb_unanchor_urb(urb);
821821
usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
822-
dev_kfree_skb(skb);
823822

824823
atomic_dec(&dev->active_tx_urbs);
825824

drivers/net/can/usb/gs_usb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,8 @@ static struct gs_can *gs_make_candev(unsigned int channel,
10921092
dev->data_bt_const.brp_inc = le32_to_cpu(bt_const_extended->dbrp_inc);
10931093

10941094
dev->can.data_bittiming_const = &dev->data_bt_const;
1095+
1096+
kfree(bt_const_extended);
10951097
}
10961098

10971099
SET_NETDEV_DEV(netdev, &intf->dev);

drivers/net/can/usb/mcba_usb.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@
3333
#define MCBA_USB_RX_BUFF_SIZE 64
3434
#define MCBA_USB_TX_BUFF_SIZE (sizeof(struct mcba_usb_msg))
3535

36-
/* MCBA endpoint numbers */
37-
#define MCBA_USB_EP_IN 1
38-
#define MCBA_USB_EP_OUT 1
39-
4036
/* Microchip command id */
4137
#define MBCA_CMD_RECEIVE_MESSAGE 0xE3
4238
#define MBCA_CMD_I_AM_ALIVE_FROM_CAN 0xF5
@@ -83,6 +79,8 @@ struct mcba_priv {
8379
atomic_t free_ctx_cnt;
8480
void *rxbuf[MCBA_MAX_RX_URBS];
8581
dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS];
82+
int rx_pipe;
83+
int tx_pipe;
8684
};
8785

8886
/* CAN frame */
@@ -268,10 +266,8 @@ static netdev_tx_t mcba_usb_xmit(struct mcba_priv *priv,
268266

269267
memcpy(buf, usb_msg, MCBA_USB_TX_BUFF_SIZE);
270268

271-
usb_fill_bulk_urb(urb, priv->udev,
272-
usb_sndbulkpipe(priv->udev, MCBA_USB_EP_OUT), buf,
273-
MCBA_USB_TX_BUFF_SIZE, mcba_usb_write_bulk_callback,
274-
ctx);
269+
usb_fill_bulk_urb(urb, priv->udev, priv->tx_pipe, buf, MCBA_USB_TX_BUFF_SIZE,
270+
mcba_usb_write_bulk_callback, ctx);
275271

276272
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
277273
usb_anchor_urb(urb, &priv->tx_submitted);
@@ -364,7 +360,6 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
364360
xmit_failed:
365361
can_free_echo_skb(priv->netdev, ctx->ndx, NULL);
366362
mcba_usb_free_ctx(ctx);
367-
dev_kfree_skb(skb);
368363
stats->tx_dropped++;
369364

370365
return NETDEV_TX_OK;
@@ -608,7 +603,7 @@ static void mcba_usb_read_bulk_callback(struct urb *urb)
608603
resubmit_urb:
609604

610605
usb_fill_bulk_urb(urb, priv->udev,
611-
usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_OUT),
606+
priv->rx_pipe,
612607
urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE,
613608
mcba_usb_read_bulk_callback, priv);
614609

@@ -653,7 +648,7 @@ static int mcba_usb_start(struct mcba_priv *priv)
653648
urb->transfer_dma = buf_dma;
654649

655650
usb_fill_bulk_urb(urb, priv->udev,
656-
usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN),
651+
priv->rx_pipe,
657652
buf, MCBA_USB_RX_BUFF_SIZE,
658653
mcba_usb_read_bulk_callback, priv);
659654
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -807,6 +802,13 @@ static int mcba_usb_probe(struct usb_interface *intf,
807802
struct mcba_priv *priv;
808803
int err;
809804
struct usb_device *usbdev = interface_to_usbdev(intf);
805+
struct usb_endpoint_descriptor *in, *out;
806+
807+
err = usb_find_common_endpoints(intf->cur_altsetting, &in, &out, NULL, NULL);
808+
if (err) {
809+
dev_err(&intf->dev, "Can't find endpoints\n");
810+
return err;
811+
}
810812

811813
netdev = alloc_candev(sizeof(struct mcba_priv), MCBA_MAX_TX_URBS);
812814
if (!netdev) {
@@ -852,6 +854,9 @@ static int mcba_usb_probe(struct usb_interface *intf,
852854
goto cleanup_free_candev;
853855
}
854856

857+
priv->rx_pipe = usb_rcvbulkpipe(priv->udev, in->bEndpointAddress);
858+
priv->tx_pipe = usb_sndbulkpipe(priv->udev, out->bEndpointAddress);
859+
855860
devm_can_led_init(netdev);
856861

857862
/* Start USB dev only if we have successfully registered CAN device */

drivers/net/can/usb/usb_8dev.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,20 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
663663
atomic_inc(&priv->active_tx_urbs);
664664

665665
err = usb_submit_urb(urb, GFP_ATOMIC);
666-
if (unlikely(err))
667-
goto failed;
668-
else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
666+
if (unlikely(err)) {
667+
can_free_echo_skb(netdev, context->echo_index, NULL);
668+
669+
usb_unanchor_urb(urb);
670+
usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
671+
672+
atomic_dec(&priv->active_tx_urbs);
673+
674+
if (err == -ENODEV)
675+
netif_device_detach(netdev);
676+
else
677+
netdev_warn(netdev, "failed tx_urb %d\n", err);
678+
stats->tx_dropped++;
679+
} else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
669680
/* Slow down tx path */
670681
netif_stop_queue(netdev);
671682

@@ -684,19 +695,6 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
684695

685696
return NETDEV_TX_BUSY;
686697

687-
failed:
688-
can_free_echo_skb(netdev, context->echo_index, NULL);
689-
690-
usb_unanchor_urb(urb);
691-
usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
692-
693-
atomic_dec(&priv->active_tx_urbs);
694-
695-
if (err == -ENODEV)
696-
netif_device_detach(netdev);
697-
else
698-
netdev_warn(netdev, "failed tx_urb %d\n", err);
699-
700698
nomembuf:
701699
usb_free_urb(urb);
702700

net/can/isotp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
10501050
int noblock = flags & MSG_DONTWAIT;
10511051
int ret = 0;
10521052

1053-
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC))
1053+
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK))
10541054
return -EINVAL;
10551055

10561056
if (!so->bound)

0 commit comments

Comments
 (0)