Commit 46b55620 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-fixes-for-5.18-20220331' of...

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: default avatarJakub Kicinski <kuba@kernel.org>
parents ff8376ad 50d34a0d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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 {
+1 −1
Original line number Diff line number Diff line
@@ -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) \
+0 −1
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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);
+16 −11
Original line number Diff line number Diff line
@@ -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 */
Loading