Skip to content

Commit

Permalink
Merge tag 'usb-4.14-rc5' 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 a handful of USB driver fixes for 4.14-rc5.

  There is the "usual" usb-serial fixes and device ids, USB gadget
  fixes, and some more fixes found by the fuzz testing that is happening
  on the USB layer right now.

  All of these have been in my tree this week with no reported issues"

* tag 'usb-4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: usbtest: fix NULL pointer dereference
  usb: gadget: configfs: Fix memory leak of interface directory data
  usb: gadget: composite: Fix use-after-free in usb_composite_overwrite_options
  usb: misc: usbtest: Fix overflow in usbtest_do_ioctl()
  usb: renesas_usbhs: Fix DMAC sequence for receiving zero-length packet
  USB: dummy-hcd: Fix deadlock caused by disconnect detection
  usb: phy: tegra: Fix phy suspend for UDC
  USB: serial: console: fix use-after-free after failed setup
  USB: serial: console: fix use-after-free on disconnect
  USB: serial: qcserial: add Dell DW5818, DW5819
  USB: serial: cp210x: add support for ELV TFD500
  USB: serial: cp210x: fix partnum regression
  USB: serial: option: add support for TP-Link LTE module
  USB: serial: ftdi_sio: add id for Cypress WICED dev board
  • Loading branch information
Linus Torvalds committed Oct 15, 2017
2 parents 7a23c5a + 2d30408 commit 7a263b1
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 27 deletions.
5 changes: 5 additions & 0 deletions drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended);
static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_gadget_strings *gstr = cdev->driver->strings[0];
struct usb_string *dev_str = gstr->strings;

/* composite_disconnect() must already have been called
* by the underlying peripheral controller driver!
Expand All @@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)

composite_dev_cleanup(cdev);

if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";

kfree(cdev->def_manufacturer);
kfree(cdev);
set_gadget_data(gadget, NULL);
Expand Down
15 changes: 8 additions & 7 deletions drivers/usb/gadget/configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = {
NULL
};

int usb_os_desc_prepare_interf_dir(struct config_group *parent,
int n_interf,
struct usb_os_desc **desc,
char **names,
struct module *owner)
struct config_group *usb_os_desc_prepare_interf_dir(
struct config_group *parent,
int n_interf,
struct usb_os_desc **desc,
char **names,
struct module *owner)
{
struct config_group *os_desc_group;
struct config_item_type *os_desc_type, *interface_type;
Expand All @@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,

char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
if (!vlabuf)
return -ENOMEM;
return ERR_PTR(-ENOMEM);

os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
Expand All @@ -1184,7 +1185,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
configfs_add_default_group(&d->group, os_desc_group);
}

return 0;
return os_desc_group;
}
EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);

Expand Down
11 changes: 6 additions & 5 deletions drivers/usb/gadget/configfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

void unregister_gadget_item(struct config_item *item);

int usb_os_desc_prepare_interf_dir(struct config_group *parent,
int n_interf,
struct usb_os_desc **desc,
char **names,
struct module *owner);
struct config_group *usb_os_desc_prepare_interf_dir(
struct config_group *parent,
int n_interf,
struct usb_os_desc **desc,
char **names,
struct module *owner);

static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item)
{
Expand Down
12 changes: 10 additions & 2 deletions drivers/usb/gadget/function/f_rndis.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
free_netdev(opts->net);
}

kfree(opts->rndis_interf_group); /* single VLA chunk */
kfree(opts);
}

Expand All @@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
struct f_rndis_opts *opts;
struct usb_os_desc *descs[1];
char *names[1];
struct config_group *rndis_interf_group;

opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts)
Expand All @@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void)
names[0] = "rndis";
config_group_init_type_name(&opts->func_inst.group, "",
&rndis_func_type);
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
names, THIS_MODULE);
rndis_interf_group =
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
names, THIS_MODULE);
if (IS_ERR(rndis_interf_group)) {
rndis_free_inst(&opts->func_inst);
return ERR_CAST(rndis_interf_group);
}
opts->rndis_interf_group = rndis_interf_group;

return &opts->func_inst;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/function/u_rndis.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct f_rndis_opts {
bool bound;
bool borrowed_net;

struct config_group *rndis_interf_group;
struct usb_os_desc rndis_os_desc;
char rndis_ext_compat_id[16];

Expand Down
9 changes: 6 additions & 3 deletions drivers/usb/gadget/udc/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd)
static void set_link_state(struct dummy_hcd *dum_hcd)
{
struct dummy *dum = dum_hcd->dum;
unsigned int power_bit;

dum_hcd->active = 0;
if (dum->pullup)
Expand All @@ -429,17 +430,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
return;

set_link_state_by_speed(dum_hcd);
power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);

if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
dum_hcd->active)
dum_hcd->resuming = 0;

/* Currently !connected or in reset */
if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
if ((dum_hcd->port_status & power_bit) == 0 ||
(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
unsigned disconnect = USB_PORT_STAT_CONNECTION &
unsigned int disconnect = power_bit &
dum_hcd->old_status & (~dum_hcd->port_status);
unsigned reset = USB_PORT_STAT_RESET &
unsigned int reset = USB_PORT_STAT_RESET &
(~dum_hcd->old_status) & dum_hcd->port_status;

/* Report reset and disconnect events to the driver */
Expand Down
10 changes: 8 additions & 2 deletions drivers/usb/misc/usbtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
return tmp;
}

if (in) {
if (in)
dev->in_pipe = usb_rcvbulkpipe(udev,
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
if (out)
dev->out_pipe = usb_sndbulkpipe(udev,
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
}

if (iso_in) {
dev->iso_in = &iso_in->desc;
dev->in_iso_pipe = usb_rcvisocpipe(udev,
Expand Down Expand Up @@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
int status = 0;
struct urb *urbs[param->sglen];

if (!param->sglen || param->iterations > UINT_MAX / param->sglen)
return -EINVAL;

memset(&context, 0, sizeof(context));
context.count = param->iterations * param->sglen;
context.dev = dev;
Expand Down Expand Up @@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param)

if (param->iterations <= 0)
return -EINVAL;
if (param->sglen > MAX_SGLEN)
return -EINVAL;
/*
* Just a bunch of test cases that every HCD is expected to handle.
*
Expand Down
17 changes: 17 additions & 0 deletions drivers/usb/phy/phy-tegra-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
unsigned long val;
void __iomem *base = phy->regs;

/*
* The USB driver may have already initiated the phy clock
* disable so wait to see if the clock turns off and if not
* then proceed with gating the clock.
*/
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0)
return;

if (phy->is_legacy_phy) {
val = readl(base + USB_SUSP_CTRL);
val |= USB_SUSP_SET;
Expand All @@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
unsigned long val;
void __iomem *base = phy->regs;

/*
* The USB driver may have already initiated the phy clock
* enable so wait to see if the clock turns on and if not
* then proceed with ungating the clock.
*/
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
USB_PHY_CLK_VALID) == 0)
return;

if (phy->is_legacy_phy) {
val = readl(base + USB_SUSP_CTRL);
val |= USB_SUSP_CLR;
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/renesas_usbhs/fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work)
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);

usbhs_pipe_running(pipe, 1);
usbhsf_dma_start(pipe, fifo);
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
dma_async_issue_pending(chan);
usbhsf_dma_start(pipe, fifo);
usbhs_pipe_enable(pipe);

xfer_work_end:
Expand Down
3 changes: 2 additions & 1 deletion drivers/usb/serial/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char *options)
tty_kref_put(tty);
reset_open_count:
port->port.count = 0;
info->port = NULL;
usb_autopm_put_interface(serial->interface);
error_get_interface:
usb_serial_put(serial);
Expand Down Expand Up @@ -265,7 +266,7 @@ static struct console usbcons = {

void usb_serial_console_disconnect(struct usb_serial *serial)
{
if (serial->port[0] == usbcons_info.port) {
if (serial->port[0] && serial->port[0] == usbcons_info.port) {
usb_serial_console_exit();
usb_serial_put(serial);
}
Expand Down
13 changes: 7 additions & 6 deletions drivers/usb/serial/cp210x.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
{ USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
Expand Down Expand Up @@ -352,6 +353,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define CP210X_PARTNUM_CP2104 0x04
#define CP210X_PARTNUM_CP2105 0x05
#define CP210X_PARTNUM_CP2108 0x08
#define CP210X_PARTNUM_UNKNOWN 0xFF

/* CP210X_GET_COMM_STATUS returns these 0x13 bytes */
struct cp210x_comm_status {
Expand Down Expand Up @@ -1491,8 +1493,11 @@ static int cp210x_attach(struct usb_serial *serial)
result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST,
CP210X_GET_PARTNUM, &priv->partnum,
sizeof(priv->partnum));
if (result < 0)
goto err_free_priv;
if (result < 0) {
dev_warn(&serial->interface->dev,
"querying part number failed\n");
priv->partnum = CP210X_PARTNUM_UNKNOWN;
}

usb_set_serial_data(serial, priv);

Expand All @@ -1505,10 +1510,6 @@ static int cp210x_attach(struct usb_serial *serial)
}

return 0;
err_free_priv:
kfree(priv);

return result;
}

static void cp210x_disconnect(struct usb_serial *serial)
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/serial/ftdi_sio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
{ USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) },
{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) },
{ } /* Terminating entry */
};

Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/serial/ftdi_sio_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,13 @@
#define ADI_GNICE_PID 0xF000
#define ADI_GNICEPLUS_PID 0xF001

/*
* Cypress WICED USB UART
*/
#define CYPRESS_VID 0x04B4
#define CYPRESS_WICED_BT_USB_PID 0x009B
#define CYPRESS_WICED_WL_USB_PID 0xF900

/*
* Microchip Technology, Inc.
*
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/serial/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb);

/* TP-LINK Incorporated products */
#define TPLINK_VENDOR_ID 0x2357
#define TPLINK_PRODUCT_LTE 0x000D
#define TPLINK_PRODUCT_MA180 0x0201

/* Changhong products */
Expand Down Expand Up @@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) },
{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) },
{ USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */
{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/serial/qcserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = {
{DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
{DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */
{DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */
{DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */
{DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */
{DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */
{DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */

/* Huawei devices */
{DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
Expand Down

0 comments on commit 7a263b1

Please sign in to comment.