Skip to content

Commit

Permalink
Merge tag 'usb-4.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

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
  • Loading branch information
torvalds committed Dec 15, 2017
2 parents a84ec72 + 48a4ff1 commit c36c7a7
Show file tree
Hide file tree
Showing 18 changed files with 144 additions and 99 deletions.
4 changes: 3 additions & 1 deletion drivers/usb/core/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/dwc2/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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 */
Expand Down
42 changes: 2 additions & 40 deletions drivers/usb/dwc2/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
29 changes: 19 additions & 10 deletions drivers/usb/dwc2/params.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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) >>
Expand All @@ -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;
}
Expand Down
5 changes: 4 additions & 1 deletion drivers/usb/dwc3/dwc3-of-simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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,
},
};

Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
{
const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
struct dwc3 *dwc = dep->dwc;
u32 timeout = 500;
u32 timeout = 1000;
u32 reg;

int cmd_status = 0;
Expand Down Expand Up @@ -912,7 +912,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
*/
if (speed == USB_SPEED_HIGH) {
struct usb_ep *ep = &dep->endpoint;
unsigned int mult = ep->mult - 1;
unsigned int mult = 2;
unsigned int maxp = usb_endpoint_maxp(ep->desc);

if (length <= (2 * maxp))
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,8 @@ choice
controller, and the relevant drivers for each function declared
by the device.

endchoice

source "drivers/usb/gadget/legacy/Kconfig"

endchoice

endif # USB_GADGET
12 changes: 1 addition & 11 deletions drivers/usb/gadget/legacy/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
# both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG).
#

menuconfig USB_GADGET_LEGACY
bool "Legacy USB Gadget Support"
help
Legacy USB gadgets are USB gadgets that do not use the USB gadget
configfs interface.

if USB_GADGET_LEGACY

config USB_ZERO
tristate "Gadget Zero (DEVELOPMENT)"
select USB_LIBCOMPOSITE
Expand Down Expand Up @@ -487,7 +479,7 @@ endif
# or video class gadget drivers), or specific hardware, here.
config USB_G_WEBCAM
tristate "USB Webcam Gadget"
depends on VIDEO_DEV
depends on VIDEO_V4L2
select USB_LIBCOMPOSITE
select VIDEOBUF2_VMALLOC
select USB_F_UVC
Expand All @@ -498,5 +490,3 @@ config USB_G_WEBCAM

Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_webcam".

endif
15 changes: 11 additions & 4 deletions drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,10 +971,9 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
return 0;
}

xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags);
if (!xhci->devs[slot_id])
dev = kzalloc(sizeof(*dev), flags);
if (!dev)
return 0;
dev = xhci->devs[slot_id];

/* Allocate the (output) device context that will be used in the HC. */
dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags);
Expand Down Expand Up @@ -1015,9 +1014,17 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,

trace_xhci_alloc_virt_device(dev);

xhci->devs[slot_id] = dev;

return 1;
fail:
xhci_free_virt_device(xhci, slot_id);

if (dev->in_ctx)
xhci_free_container_ctx(xhci, dev->in_ctx);
if (dev->out_ctx)
xhci_free_container_ctx(xhci, dev->out_ctx);
kfree(dev);

return 0;
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3112,7 +3112,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
{
u32 maxp, total_packet_count;

/* MTK xHCI is mostly 0.97 but contains some features from 1.0 */
/* MTK xHCI 0.96 contains some features from 1.0 */
if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST))
return ((td_total_len - transferred) >> 10);

Expand All @@ -3121,8 +3121,8 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
trb_buff_len == td_total_len)
return 0;

/* for MTK xHCI, TD size doesn't include this TRB */
if (xhci->quirks & XHCI_MTK_HOST)
/* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */
if ((xhci->quirks & XHCI_MTK_HOST) && (xhci->hci_version < 0x100))
trb_buff_len = 0;

maxp = usb_endpoint_maxp(&urb->ep->desc);
Expand Down
10 changes: 9 additions & 1 deletion drivers/usb/musb/da8xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,15 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci)
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
del_timer(&musb->dev_timer);
} else {
} else if (!(musb->int_usb & MUSB_INTR_BABBLE)) {
/*
* When babble condition happens, drvvbus interrupt
* is also generated. Ignore this drvvbus interrupt
* and let babble interrupt handler recovers the
* controller; otherwise, the host-mode flag is lost
* due to the MUSB_DEV_MODE() call below and babble
* recovery logic will not be called.
*/
musb->is_active = 0;
MUSB_DEV_MODE(musb);
otg->default_a = 0;
Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/storage/unusual_devs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,13 @@ UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0116,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA ),

/* Reported by David Kozub <[email protected]> */
UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
"JMicron",
"JMS567",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA),

/*
* Reported by Alexandre Oliva <[email protected]>
* JMicron responds to USN and several other SCSI ioctls with a
Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/storage/unusual_uas.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),

/* Reported-by: David Kozub <[email protected]> */
UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
"JMicron",
"JMS567",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA),

/* Reported-by: Hans de Goede <[email protected]> */
UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
"VIA",
Expand Down
Loading

0 comments on commit c36c7a7

Please sign in to comment.