linux-can-fixes-for-5.18-20220331
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEBsvAIBsPu6mG7thcrX5LkNig010FAmJFXq0THG1rbEBwZW5n dXRyb25peC5kZQAKCRCtfkuQ2KDTXc+GB/9hPO+0SN80Fz93rDE8M6wI1rY6famJ mqcaNmSDGuX9jMxC3CLugw8rckfXKb0kicjq8xLqAU7PX67h4nShnZCmHq+4RnJW AZIV4sUOgeMcDohMPY0b8BIyS1JDwjR2L9vrFjeJm/BlDC2mkbRC2pXr6Pq9Xg4Y aBaNA94v9UMQvTdPK8UmHOvl3M6gPV3ggBiCRM5xxnYGkrQFApgtCsXMvizbBUGS tNLEOGYD/YAZKAiZfEnaTKqklUCGPdm4vuiP+4F9+2ovBK38CiiJSx/fF6aLkZy+ RdLpjrsqjva1cPSxaE3tAm45KOF5vm3hrBGWgslJz+0CN+tBWy/Q2G4s =yO1B -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
46b556205d
@ -1637,8 +1637,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
|
||||
if (err)
|
||||
goto out_fail;
|
||||
|
||||
can_put_echo_skb(skb, dev, 0, 0);
|
||||
|
||||
if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) {
|
||||
cccr = m_can_read(cdev, M_CAN_CCCR);
|
||||
cccr &= ~CCCR_CMR_MASK;
|
||||
@ -1655,6 +1653,9 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
|
||||
m_can_write(cdev, M_CAN_CCCR, cccr);
|
||||
}
|
||||
m_can_write(cdev, M_CAN_TXBTIE, 0x1);
|
||||
|
||||
can_put_echo_skb(skb, dev, 0, 0);
|
||||
|
||||
m_can_write(cdev, M_CAN_TXBAR, 0x1);
|
||||
/* End of xmit function for version 3.0.x */
|
||||
} else {
|
||||
|
@ -1786,7 +1786,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id,
|
||||
out_kfree_buf_rx:
|
||||
kfree(buf_rx);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
#define MCP251XFD_QUIRK_ACTIVE(quirk) \
|
||||
|
@ -819,7 +819,6 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
||||
|
||||
usb_unanchor_urb(urb);
|
||||
usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
atomic_dec(&dev->active_tx_urbs);
|
||||
|
||||
|
@ -1092,6 +1092,8 @@ static struct gs_can *gs_make_candev(unsigned int channel,
|
||||
dev->data_bt_const.brp_inc = le32_to_cpu(bt_const_extended->dbrp_inc);
|
||||
|
||||
dev->can.data_bittiming_const = &dev->data_bt_const;
|
||||
|
||||
kfree(bt_const_extended);
|
||||
}
|
||||
|
||||
SET_NETDEV_DEV(netdev, &intf->dev);
|
||||
|
@ -33,10 +33,6 @@
|
||||
#define MCBA_USB_RX_BUFF_SIZE 64
|
||||
#define MCBA_USB_TX_BUFF_SIZE (sizeof(struct mcba_usb_msg))
|
||||
|
||||
/* MCBA endpoint numbers */
|
||||
#define MCBA_USB_EP_IN 1
|
||||
#define MCBA_USB_EP_OUT 1
|
||||
|
||||
/* Microchip command id */
|
||||
#define MBCA_CMD_RECEIVE_MESSAGE 0xE3
|
||||
#define MBCA_CMD_I_AM_ALIVE_FROM_CAN 0xF5
|
||||
@ -83,6 +79,8 @@ struct mcba_priv {
|
||||
atomic_t free_ctx_cnt;
|
||||
void *rxbuf[MCBA_MAX_RX_URBS];
|
||||
dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS];
|
||||
int rx_pipe;
|
||||
int tx_pipe;
|
||||
};
|
||||
|
||||
/* CAN frame */
|
||||
@ -268,10 +266,8 @@ static netdev_tx_t mcba_usb_xmit(struct mcba_priv *priv,
|
||||
|
||||
memcpy(buf, usb_msg, MCBA_USB_TX_BUFF_SIZE);
|
||||
|
||||
usb_fill_bulk_urb(urb, priv->udev,
|
||||
usb_sndbulkpipe(priv->udev, MCBA_USB_EP_OUT), buf,
|
||||
MCBA_USB_TX_BUFF_SIZE, mcba_usb_write_bulk_callback,
|
||||
ctx);
|
||||
usb_fill_bulk_urb(urb, priv->udev, priv->tx_pipe, buf, MCBA_USB_TX_BUFF_SIZE,
|
||||
mcba_usb_write_bulk_callback, ctx);
|
||||
|
||||
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
usb_anchor_urb(urb, &priv->tx_submitted);
|
||||
@ -364,7 +360,6 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
|
||||
xmit_failed:
|
||||
can_free_echo_skb(priv->netdev, ctx->ndx, NULL);
|
||||
mcba_usb_free_ctx(ctx);
|
||||
dev_kfree_skb(skb);
|
||||
stats->tx_dropped++;
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
@ -608,7 +603,7 @@ static void mcba_usb_read_bulk_callback(struct urb *urb)
|
||||
resubmit_urb:
|
||||
|
||||
usb_fill_bulk_urb(urb, priv->udev,
|
||||
usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_OUT),
|
||||
priv->rx_pipe,
|
||||
urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE,
|
||||
mcba_usb_read_bulk_callback, priv);
|
||||
|
||||
@ -653,7 +648,7 @@ static int mcba_usb_start(struct mcba_priv *priv)
|
||||
urb->transfer_dma = buf_dma;
|
||||
|
||||
usb_fill_bulk_urb(urb, priv->udev,
|
||||
usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN),
|
||||
priv->rx_pipe,
|
||||
buf, MCBA_USB_RX_BUFF_SIZE,
|
||||
mcba_usb_read_bulk_callback, priv);
|
||||
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
@ -807,6 +802,13 @@ static int mcba_usb_probe(struct usb_interface *intf,
|
||||
struct mcba_priv *priv;
|
||||
int err;
|
||||
struct usb_device *usbdev = interface_to_usbdev(intf);
|
||||
struct usb_endpoint_descriptor *in, *out;
|
||||
|
||||
err = usb_find_common_endpoints(intf->cur_altsetting, &in, &out, NULL, NULL);
|
||||
if (err) {
|
||||
dev_err(&intf->dev, "Can't find endpoints\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
netdev = alloc_candev(sizeof(struct mcba_priv), MCBA_MAX_TX_URBS);
|
||||
if (!netdev) {
|
||||
@ -852,6 +854,9 @@ static int mcba_usb_probe(struct usb_interface *intf,
|
||||
goto cleanup_free_candev;
|
||||
}
|
||||
|
||||
priv->rx_pipe = usb_rcvbulkpipe(priv->udev, in->bEndpointAddress);
|
||||
priv->tx_pipe = usb_sndbulkpipe(priv->udev, out->bEndpointAddress);
|
||||
|
||||
devm_can_led_init(netdev);
|
||||
|
||||
/* Start USB dev only if we have successfully registered CAN device */
|
||||
|
@ -663,9 +663,20 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
|
||||
atomic_inc(&priv->active_tx_urbs);
|
||||
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (unlikely(err))
|
||||
goto failed;
|
||||
else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
|
||||
if (unlikely(err)) {
|
||||
can_free_echo_skb(netdev, context->echo_index, NULL);
|
||||
|
||||
usb_unanchor_urb(urb);
|
||||
usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
|
||||
|
||||
atomic_dec(&priv->active_tx_urbs);
|
||||
|
||||
if (err == -ENODEV)
|
||||
netif_device_detach(netdev);
|
||||
else
|
||||
netdev_warn(netdev, "failed tx_urb %d\n", err);
|
||||
stats->tx_dropped++;
|
||||
} else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
|
||||
/* Slow down tx path */
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
@ -684,19 +695,6 @@ nofreecontext:
|
||||
|
||||
return NETDEV_TX_BUSY;
|
||||
|
||||
failed:
|
||||
can_free_echo_skb(netdev, context->echo_index, NULL);
|
||||
|
||||
usb_unanchor_urb(urb);
|
||||
usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
|
||||
|
||||
atomic_dec(&priv->active_tx_urbs);
|
||||
|
||||
if (err == -ENODEV)
|
||||
netif_device_detach(netdev);
|
||||
else
|
||||
netdev_warn(netdev, "failed tx_urb %d\n", err);
|
||||
|
||||
nomembuf:
|
||||
usb_free_urb(urb);
|
||||
|
||||
|
@ -1050,7 +1050,7 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
|
||||
int noblock = flags & MSG_DONTWAIT;
|
||||
int ret = 0;
|
||||
|
||||
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC))
|
||||
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK))
|
||||
return -EINVAL;
|
||||
|
||||
if (!so->bound)
|
||||
|
Loading…
Reference in New Issue
Block a user