Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c36c7a7c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some USB fixes for 4.15-rc4.

  There is the usual handful gadget/dwc2/dwc3 fixes as always, for
  reported issues. But the most important things in here is the core fix
  from Alan Stern to resolve a nasty security bug (my first attempt is
  reverted, Alan's was much cleaner), as well as a number of usbip fixes
  from Shuah Khan to resolve those reported security issues.

  All of these have been in linux-next with no reported issues"

* tag 'usb-4.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: core: prevent malicious bNumInterfaces overflow
  Revert "USB: core: only clean up what we allocated"
  USB: core: only clean up what we allocated
  Revert "usb: gadget: allow to enable legacy drivers without USB_ETH"
  usb: gadget: webcam: fix V4L2 Kconfig dependency
  usb: dwc2: Fix TxFIFOn sizes and total TxFIFO size issues
  usb: dwc3: gadget: Fix PCM1 for ISOC EP with ep->mult less than 3
  usb: dwc3: of-simple: set dev_pm_ops
  usb: dwc3: of-simple: fix missing clk_disable_unprepare
  usb: dwc3: gadget: Wait longer for controller to end command processing
  usb: xhci: fix TDS for MTK xHCI1.1
  xhci: Don't add a virt_dev to the devs array before it's fully allocated
  usbip: fix stub_send_ret_submit() vulnerability to null transfer_buffer
  usbip: prevent vhci_hcd driver from leaking a socket pointer address
  usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input
  usbip: fix stub_rx: get_pipe() to validate endpoint number
  tools/usbip: fixes potential (minor) "buffer overflow" (detected on recent gcc with -Werror)
  USB: uas and storage: Add US_FL_BROKEN_FUA for another JMicron JMS567 ID
  usb: musb: da8xx: fix babble condition handling
parents a84ec723 48a4ff1c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -555,6 +555,9 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
	unsigned iad_num = 0;

	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
	nintf = nintf_orig = config->desc.bNumInterfaces;
	config->desc.bNumInterfaces = 0;	// Adjusted later

	if (config->desc.bDescriptorType != USB_DT_CONFIG ||
	    config->desc.bLength < USB_DT_CONFIG_SIZE ||
	    config->desc.bLength > size) {
@@ -568,7 +571,6 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
	buffer += config->desc.bLength;
	size -= config->desc.bLength;

	nintf = nintf_orig = config->desc.bNumInterfaces;
	if (nintf > USB_MAXINTERFACES) {
		dev_warn(ddev, "config %d has too many interfaces: %d, "
		    "using maximum allowed: %d\n",
+4 −0
Original line number Diff line number Diff line
@@ -537,6 +537,7 @@ struct dwc2_core_params {
 *                       2 - Internal DMA
 * @power_optimized     Are power optimizations enabled?
 * @num_dev_ep          Number of device endpoints available
 * @num_dev_in_eps      Number of device IN endpoints available
 * @num_dev_perio_in_ep Number of device periodic IN endpoints
 *                      available
 * @dev_token_q_depth   Device Mode IN Token Sequence Learning Queue
@@ -565,6 +566,7 @@ struct dwc2_core_params {
 *                       2 - 8 or 16 bits
 * @snpsid:             Value from SNPSID register
 * @dev_ep_dirs:        Direction of device endpoints (GHWCFG1)
 * @g_tx_fifo_size[]	Power-on values of TxFIFO sizes
 */
struct dwc2_hw_params {
	unsigned op_mode:3;
@@ -586,12 +588,14 @@ struct dwc2_hw_params {
	unsigned fs_phy_type:2;
	unsigned i2c_enable:1;
	unsigned num_dev_ep:4;
	unsigned num_dev_in_eps : 4;
	unsigned num_dev_perio_in_ep:4;
	unsigned total_fifo_size:16;
	unsigned power_optimized:1;
	unsigned utmi_phy_data_width:2;
	u32 snpsid;
	u32 dev_ep_dirs;
	u32 g_tx_fifo_size[MAX_EPS_CHANNELS];
};

/* Size of control and EP0 buffers */
+2 −40
Original line number Diff line number Diff line
@@ -195,55 +195,18 @@ int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
{
	if (hsotg->hw_params.en_multiple_tx_fifo)
		/* In dedicated FIFO mode we need count of IN EPs */
		return (dwc2_readl(hsotg->regs + GHWCFG4)  &
			GHWCFG4_NUM_IN_EPS_MASK) >> GHWCFG4_NUM_IN_EPS_SHIFT;
		return hsotg->hw_params.num_dev_in_eps;
	else
		/* In shared FIFO mode we need count of Periodic IN EPs */
		return hsotg->hw_params.num_dev_perio_in_ep;
}

/**
 * dwc2_hsotg_ep_info_size - return Endpoint Info Control block size in DWORDs
 */
static int dwc2_hsotg_ep_info_size(struct dwc2_hsotg *hsotg)
{
	int val = 0;
	int i;
	u32 ep_dirs;

	/*
	 * Don't need additional space for ep info control registers in
	 * slave mode.
	 */
	if (!using_dma(hsotg)) {
		dev_dbg(hsotg->dev, "Buffer DMA ep info size 0\n");
		return 0;
	}

	/*
	 * Buffer DMA mode - 1 location per endpoit
	 * Descriptor DMA mode - 4 locations per endpoint
	 */
	ep_dirs = hsotg->hw_params.dev_ep_dirs;

	for (i = 0; i <= hsotg->hw_params.num_dev_ep; i++) {
		val += ep_dirs & 3 ? 1 : 2;
		ep_dirs >>= 2;
	}

	if (using_desc_dma(hsotg))
		val = val * 4;

	return val;
}

/**
 * dwc2_hsotg_tx_fifo_total_depth - return total FIFO depth available for
 * device mode TX FIFOs
 */
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
{
	int ep_info_size;
	int addr;
	int tx_addr_max;
	u32 np_tx_fifo_size;
@@ -252,8 +215,7 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
				hsotg->params.g_np_tx_fifo_size);

	/* Get Endpoint Info Control block size in DWORDs. */
	ep_info_size = dwc2_hsotg_ep_info_size(hsotg);
	tx_addr_max = hsotg->hw_params.total_fifo_size - ep_info_size;
	tx_addr_max = hsotg->hw_params.total_fifo_size;

	addr = hsotg->params.g_rx_fifo_size + np_tx_fifo_size;
	if (tx_addr_max <= addr)
+19 −10
Original line number Diff line number Diff line
@@ -484,8 +484,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
	}

	for (fifo = 1; fifo <= fifo_count; fifo++) {
		dptxfszn = (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) &
			FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT;
		dptxfszn = hsotg->hw_params.g_tx_fifo_size[fifo];

		if (hsotg->params.g_tx_fifo_size[fifo] < min ||
		    hsotg->params.g_tx_fifo_size[fifo] >  dptxfszn) {
@@ -609,6 +608,7 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
	struct dwc2_hw_params *hw = &hsotg->hw_params;
	bool forced;
	u32 gnptxfsiz;
	int fifo, fifo_count;

	if (hsotg->dr_mode == USB_DR_MODE_HOST)
		return;
@@ -617,6 +617,14 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)

	gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);

	fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);

	for (fifo = 1; fifo <= fifo_count; fifo++) {
		hw->g_tx_fifo_size[fifo] =
			(dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) &
			 FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT;
	}

	if (forced)
		dwc2_clear_force_mode(hsotg);

@@ -661,14 +669,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
	hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
	grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);

	/*
	 * Host specific hardware parameters. Reading these parameters
	 * requires the controller to be in host mode. The mode will
	 * be forced, if necessary, to read these values.
	 */
	dwc2_get_host_hwparams(hsotg);
	dwc2_get_dev_hwparams(hsotg);

	/* hwcfg1 */
	hw->dev_ep_dirs = hwcfg1;

@@ -711,6 +711,8 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
	hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
	hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
				  GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
	hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >>
			     GHWCFG4_NUM_IN_EPS_SHIFT;
	hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
	hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
	hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
@@ -719,6 +721,13 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
	/* fifo sizes */
	hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
				GRXFSIZ_DEPTH_SHIFT;
	/*
	 * Host specific hardware parameters. Reading these parameters
	 * requires the controller to be in host mode. The mode will
	 * be forced, if necessary, to read these values.
	 */
	dwc2_get_host_hwparams(hsotg);
	dwc2_get_dev_hwparams(hsotg);

	return 0;
}
+4 −1
Original line number Diff line number Diff line
@@ -51,8 +51,10 @@ static int dwc3_of_simple_clk_init(struct dwc3_of_simple *simple, int count)

		clk = of_clk_get(np, i);
		if (IS_ERR(clk)) {
			while (--i >= 0)
			while (--i >= 0) {
				clk_disable_unprepare(simple->clks[i]);
				clk_put(simple->clks[i]);
			}
			return PTR_ERR(clk);
		}

@@ -203,6 +205,7 @@ static struct platform_driver dwc3_of_simple_driver = {
	.driver		= {
		.name	= "dwc3-of-simple",
		.of_match_table = of_dwc3_simple_match,
		.pm	= &dwc3_of_simple_dev_pm_ops,
	},
};

Loading