Commit 85187378 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some small USB driver fixes for 5.17-rc4 that resolve some
  reported issues and add new device ids:

   - usb-serial new device ids

   - ulpi cleanup fixes

   - f_fs use-after-free fix

   - dwc3 driver fixes

   - ax88179_178a usb network driver fix

   - usb gadget fixes

  There is a revert at the end of this series to resolve a build problem
  that 0-day found yesterday. Most of these have been in linux-next,
  except for the last few, and all have now passed 0-day tests"

* tag 'usb-5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  Revert "usb: dwc2: drd: fix soft connect when gadget is unconfigured"
  usb: dwc2: drd: fix soft connect when gadget is unconfigured
  usb: gadget: rndis: check size of RNDIS_MSG_SET command
  USB: gadget: validate interface OS descriptor requests
  usb: core: Unregister device on component_add() failure
  net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup
  usb: dwc3: gadget: Prevent core from processing stale TRBs
  USB: serial: cp210x: add CPI Bulk Coin Recycler id
  USB: serial: cp210x: add NCR Retail IO box id
  USB: serial: ftdi_sio: add support for Brainboxes US-159/235/320
  usb: gadget: f_uac2: Define specific wTerminalType
  usb: gadget: udc: renesas_usb3: Fix host to USB_ROLE_NONE transition
  usb: raw-gadget: fix handling of dual-direction-capable endpoints
  usb: usb251xb: add boost-up property support
  usb: ulpi: Call of_node_put correctly
  usb: ulpi: Move of_node_put to ulpi_dev_release
  USB: serial: option: add ZTE MF286D modem
  USB: serial: ch341: add support for GW Instek USB2.0-Serial devices
  usb: f_fs: Fix use-after-free for epfile
  usb: dwc3: xilinx: fix uninitialized return value
parents a4fd49cd 736e8d89
Loading
Loading
Loading
Loading
+39 −29
Original line number Diff line number Diff line
@@ -1468,58 +1468,68 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
	u16 hdr_off;
	u32 *pkt_hdr;

	/* This check is no longer done by usbnet */
	if (skb->len < dev->net->hard_header_len)
	/* At the end of the SKB, there's a header telling us how many packets
	 * are bundled into this buffer and where we can find an array of
	 * per-packet metadata (which contains elements encoded into u16).
	 */
	if (skb->len < 4)
		return 0;

	skb_trim(skb, skb->len - 4);
	rx_hdr = get_unaligned_le32(skb_tail_pointer(skb));

	pkt_cnt = (u16)rx_hdr;
	hdr_off = (u16)(rx_hdr >> 16);

	if (pkt_cnt == 0)
		return 0;

	/* Make sure that the bounds of the metadata array are inside the SKB
	 * (and in front of the counter at the end).
	 */
	if (pkt_cnt * 2 + hdr_off > skb->len)
		return 0;
	pkt_hdr = (u32 *)(skb->data + hdr_off);

	while (pkt_cnt--) {
	/* Packets must not overlap the metadata array */
	skb_trim(skb, hdr_off);

	for (; ; pkt_cnt--, pkt_hdr++) {
		u16 pkt_len;

		le32_to_cpus(pkt_hdr);
		pkt_len = (*pkt_hdr >> 16) & 0x1fff;

		/* Check CRC or runt packet */
		if ((*pkt_hdr & AX_RXHDR_CRC_ERR) ||
		    (*pkt_hdr & AX_RXHDR_DROP_ERR)) {
			skb_pull(skb, (pkt_len + 7) & 0xFFF8);
			pkt_hdr++;
			continue;
		}
		if (pkt_len > skb->len)
			return 0;

		if (pkt_cnt == 0) {
			skb->len = pkt_len;
			/* Skip IP alignment pseudo header */
			skb_pull(skb, 2);
			skb_set_tail_pointer(skb, skb->len);
			skb->truesize = pkt_len + sizeof(struct sk_buff);
			ax88179_rx_checksum(skb, pkt_hdr);
			return 1;
		}
		/* Check CRC or runt packet */
		if (((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) == 0) &&
		    pkt_len >= 2 + ETH_HLEN) {
			bool last = (pkt_cnt == 0);

			if (last) {
				ax_skb = skb;
			} else {
				ax_skb = skb_clone(skb, GFP_ATOMIC);
		if (ax_skb) {
				if (!ax_skb)
					return 0;
			}
			ax_skb->len = pkt_len;
			/* Skip IP alignment pseudo header */
			skb_pull(ax_skb, 2);
			skb_set_tail_pointer(ax_skb, ax_skb->len);
			ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
			ax88179_rx_checksum(ax_skb, pkt_hdr);

			if (last)
				return 1;

			usbnet_skb_return(dev, ax_skb);
		} else {
			return 0;
		}

		skb_pull(skb, (pkt_len + 7) & 0xFFF8);
		pkt_hdr++;
		/* Trim this packet away from the SKB */
		if (!skb_pull(skb, (pkt_len + 7) & 0xFFF8))
			return 0;
	}
	return 1;
}

static struct sk_buff *
+7 −3
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ static const struct attribute_group *ulpi_dev_attr_groups[] = {

static void ulpi_dev_release(struct device *dev)
{
	of_node_put(dev->of_node);
	kfree(to_ulpi_dev(dev));
}

@@ -247,12 +248,16 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
		return ret;

	ret = ulpi_read_id(ulpi);
	if (ret)
	if (ret) {
		of_node_put(ulpi->dev.of_node);
		return ret;
	}

	ret = device_register(&ulpi->dev);
	if (ret)
	if (ret) {
		put_device(&ulpi->dev);
		return ret;
	}

	dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
		ulpi->id.vendor, ulpi->id.product);
@@ -299,7 +304,6 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface);
 */
void ulpi_unregister_interface(struct ulpi *ulpi)
{
	of_node_put(ulpi->dev.of_node);
	device_unregister(&ulpi->dev);
}
EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
+6 −3
Original line number Diff line number Diff line
@@ -602,11 +602,14 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
		return retval;
	}

	find_and_link_peer(hub, port1);

	retval = component_add(&port_dev->dev, &connector_ops);
	if (retval)
	if (retval) {
		dev_warn(&port_dev->dev, "failed to add component\n");
		device_unregister(&port_dev->dev);
		return retval;
	}

	find_and_link_peer(hub, port1);

	/*
	 * Enable runtime pm and hold a refernce that hub_configure()
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
	struct device		*dev = priv_data->dev;
	struct reset_control	*crst, *hibrst, *apbrst;
	struct phy		*usb3_phy;
	int			ret;
	int			ret = 0;
	u32			reg;

	usb3_phy = devm_phy_optional_get(dev, "usb3-phy");
+13 −0
Original line number Diff line number Diff line
@@ -1291,6 +1291,19 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
	if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
		trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(stream_id);

	/*
	 * As per data book 4.2.3.2TRB Control Bit Rules section
	 *
	 * The controller autonomously checks the HWO field of a TRB to determine if the
	 * entire TRB is valid. Therefore, software must ensure that the rest of the TRB
	 * is valid before setting the HWO field to '1'. In most systems, this means that
	 * software must update the fourth DWORD of a TRB last.
	 *
	 * However there is a possibility of CPU re-ordering here which can cause
	 * controller to observe the HWO bit set prematurely.
	 * Add a write memory barrier to prevent CPU re-ordering.
	 */
	wmb();
	trb->ctrl |= DWC3_TRB_CTRL_HWO;

	dwc3_ep_inc_enq(dep);
Loading