Skip to content

Commit 7a263b1

Browse files
committed
Merge tag 'usb-4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/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
2 parents 7a23c5a + 2d30408 commit 7a263b1

File tree

15 files changed

+86
-27
lines changed

15 files changed

+86
-27
lines changed

drivers/usb/gadget/composite.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended);
20262026
static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
20272027
{
20282028
struct usb_composite_dev *cdev = get_gadget_data(gadget);
2029+
struct usb_gadget_strings *gstr = cdev->driver->strings[0];
2030+
struct usb_string *dev_str = gstr->strings;
20292031

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

20462048
composite_dev_cleanup(cdev);
20472049

2050+
if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer)
2051+
dev_str[USB_GADGET_MANUFACTURER_IDX].s = "";
2052+
20482053
kfree(cdev->def_manufacturer);
20492054
kfree(cdev);
20502055
set_gadget_data(gadget, NULL);

drivers/usb/gadget/configfs.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = {
11431143
NULL
11441144
};
11451145

1146-
int usb_os_desc_prepare_interf_dir(struct config_group *parent,
1147-
int n_interf,
1148-
struct usb_os_desc **desc,
1149-
char **names,
1150-
struct module *owner)
1146+
struct config_group *usb_os_desc_prepare_interf_dir(
1147+
struct config_group *parent,
1148+
int n_interf,
1149+
struct usb_os_desc **desc,
1150+
char **names,
1151+
struct module *owner)
11511152
{
11521153
struct config_group *os_desc_group;
11531154
struct config_item_type *os_desc_type, *interface_type;
@@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
11591160

11601161
char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
11611162
if (!vlabuf)
1162-
return -ENOMEM;
1163+
return ERR_PTR(-ENOMEM);
11631164

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

1187-
return 0;
1188+
return os_desc_group;
11881189
}
11891190
EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
11901191

drivers/usb/gadget/configfs.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
void unregister_gadget_item(struct config_item *item);
77

8-
int usb_os_desc_prepare_interf_dir(struct config_group *parent,
9-
int n_interf,
10-
struct usb_os_desc **desc,
11-
char **names,
12-
struct module *owner);
8+
struct config_group *usb_os_desc_prepare_interf_dir(
9+
struct config_group *parent,
10+
int n_interf,
11+
struct usb_os_desc **desc,
12+
char **names,
13+
struct module *owner);
1314

1415
static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item)
1516
{

drivers/usb/gadget/function/f_rndis.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
908908
free_netdev(opts->net);
909909
}
910910

911+
kfree(opts->rndis_interf_group); /* single VLA chunk */
911912
kfree(opts);
912913
}
913914

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

920922
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
921923
if (!opts)
@@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void)
940942
names[0] = "rndis";
941943
config_group_init_type_name(&opts->func_inst.group, "",
942944
&rndis_func_type);
943-
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
944-
names, THIS_MODULE);
945+
rndis_interf_group =
946+
usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
947+
names, THIS_MODULE);
948+
if (IS_ERR(rndis_interf_group)) {
949+
rndis_free_inst(&opts->func_inst);
950+
return ERR_CAST(rndis_interf_group);
951+
}
952+
opts->rndis_interf_group = rndis_interf_group;
945953

946954
return &opts->func_inst;
947955
}

drivers/usb/gadget/function/u_rndis.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct f_rndis_opts {
2626
bool bound;
2727
bool borrowed_net;
2828

29+
struct config_group *rndis_interf_group;
2930
struct usb_os_desc rndis_os_desc;
3031
char rndis_ext_compat_id[16];
3132

drivers/usb/gadget/udc/dummy_hcd.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd)
419419
static void set_link_state(struct dummy_hcd *dum_hcd)
420420
{
421421
struct dummy *dum = dum_hcd->dum;
422+
unsigned int power_bit;
422423

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

431432
set_link_state_by_speed(dum_hcd);
433+
power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
434+
USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
432435

433436
if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
434437
dum_hcd->active)
435438
dum_hcd->resuming = 0;
436439

437440
/* Currently !connected or in reset */
438-
if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
441+
if ((dum_hcd->port_status & power_bit) == 0 ||
439442
(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
440-
unsigned disconnect = USB_PORT_STAT_CONNECTION &
443+
unsigned int disconnect = power_bit &
441444
dum_hcd->old_status & (~dum_hcd->port_status);
442-
unsigned reset = USB_PORT_STAT_RESET &
445+
unsigned int reset = USB_PORT_STAT_RESET &
443446
(~dum_hcd->old_status) & dum_hcd->port_status;
444447

445448
/* Report reset and disconnect events to the driver */

drivers/usb/misc/usbtest.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
202202
return tmp;
203203
}
204204

205-
if (in) {
205+
if (in)
206206
dev->in_pipe = usb_rcvbulkpipe(udev,
207207
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
208+
if (out)
208209
dev->out_pipe = usb_sndbulkpipe(udev,
209210
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
210-
}
211+
211212
if (iso_in) {
212213
dev->iso_in = &iso_in->desc;
213214
dev->in_iso_pipe = usb_rcvisocpipe(udev,
@@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
19641965
int status = 0;
19651966
struct urb *urbs[param->sglen];
19661967

1968+
if (!param->sglen || param->iterations > UINT_MAX / param->sglen)
1969+
return -EINVAL;
1970+
19671971
memset(&context, 0, sizeof(context));
19681972
context.count = param->iterations * param->sglen;
19691973
context.dev = dev;
@@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param)
20872091

20882092
if (param->iterations <= 0)
20892093
return -EINVAL;
2094+
if (param->sglen > MAX_SGLEN)
2095+
return -EINVAL;
20902096
/*
20912097
* Just a bunch of test cases that every HCD is expected to handle.
20922098
*

drivers/usb/phy/phy-tegra-usb.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
329329
unsigned long val;
330330
void __iomem *base = phy->regs;
331331

332+
/*
333+
* The USB driver may have already initiated the phy clock
334+
* disable so wait to see if the clock turns off and if not
335+
* then proceed with gating the clock.
336+
*/
337+
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0)
338+
return;
339+
332340
if (phy->is_legacy_phy) {
333341
val = readl(base + USB_SUSP_CTRL);
334342
val |= USB_SUSP_SET;
@@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
351359
unsigned long val;
352360
void __iomem *base = phy->regs;
353361

362+
/*
363+
* The USB driver may have already initiated the phy clock
364+
* enable so wait to see if the clock turns on and if not
365+
* then proceed with ungating the clock.
366+
*/
367+
if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
368+
USB_PHY_CLK_VALID) == 0)
369+
return;
370+
354371
if (phy->is_legacy_phy) {
355372
val = readl(base + USB_SUSP_CTRL);
356373
val |= USB_SUSP_CLR;

drivers/usb/renesas_usbhs/fifo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,9 +857,9 @@ static void xfer_work(struct work_struct *work)
857857
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
858858

859859
usbhs_pipe_running(pipe, 1);
860-
usbhsf_dma_start(pipe, fifo);
861860
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
862861
dma_async_issue_pending(chan);
862+
usbhsf_dma_start(pipe, fifo);
863863
usbhs_pipe_enable(pipe);
864864

865865
xfer_work_end:

drivers/usb/serial/console.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char *options)
186186
tty_kref_put(tty);
187187
reset_open_count:
188188
port->port.count = 0;
189+
info->port = NULL;
189190
usb_autopm_put_interface(serial->interface);
190191
error_get_interface:
191192
usb_serial_put(serial);
@@ -265,7 +266,7 @@ static struct console usbcons = {
265266

266267
void usb_serial_console_disconnect(struct usb_serial *serial)
267268
{
268-
if (serial->port[0] == usbcons_info.port) {
269+
if (serial->port[0] && serial->port[0] == usbcons_info.port) {
269270
usb_serial_console_exit();
270271
usb_serial_put(serial);
271272
}

drivers/usb/serial/cp210x.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = {
177177
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
178178
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
179179
{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
180+
{ USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */
180181
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
181182
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
182183
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
@@ -352,6 +353,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
352353
#define CP210X_PARTNUM_CP2104 0x04
353354
#define CP210X_PARTNUM_CP2105 0x05
354355
#define CP210X_PARTNUM_CP2108 0x08
356+
#define CP210X_PARTNUM_UNKNOWN 0xFF
355357

356358
/* CP210X_GET_COMM_STATUS returns these 0x13 bytes */
357359
struct cp210x_comm_status {
@@ -1491,8 +1493,11 @@ static int cp210x_attach(struct usb_serial *serial)
14911493
result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST,
14921494
CP210X_GET_PARTNUM, &priv->partnum,
14931495
sizeof(priv->partnum));
1494-
if (result < 0)
1495-
goto err_free_priv;
1496+
if (result < 0) {
1497+
dev_warn(&serial->interface->dev,
1498+
"querying part number failed\n");
1499+
priv->partnum = CP210X_PARTNUM_UNKNOWN;
1500+
}
14961501

14971502
usb_set_serial_data(serial, priv);
14981503

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

15071512
return 0;
1508-
err_free_priv:
1509-
kfree(priv);
1510-
1511-
return result;
15121513
}
15131514

15141515
static void cp210x_disconnect(struct usb_serial *serial)

drivers/usb/serial/ftdi_sio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = {
10151015
{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
10161016
{ USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
10171017
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
1018+
{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) },
1019+
{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) },
10181020
{ } /* Terminating entry */
10191021
};
10201022

drivers/usb/serial/ftdi_sio_ids.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,13 @@
609609
#define ADI_GNICE_PID 0xF000
610610
#define ADI_GNICEPLUS_PID 0xF001
611611

612+
/*
613+
* Cypress WICED USB UART
614+
*/
615+
#define CYPRESS_VID 0x04B4
616+
#define CYPRESS_WICED_BT_USB_PID 0x009B
617+
#define CYPRESS_WICED_WL_USB_PID 0xF900
618+
612619
/*
613620
* Microchip Technology, Inc.
614621
*

drivers/usb/serial/option.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb);
522522

523523
/* TP-LINK Incorporated products */
524524
#define TPLINK_VENDOR_ID 0x2357
525+
#define TPLINK_PRODUCT_LTE 0x000D
525526
#define TPLINK_PRODUCT_MA180 0x0201
526527

527528
/* Changhong products */
@@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = {
20112012
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
20122013
{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) },
20132014
{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) },
2015+
{ USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */
20142016
{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
20152017
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
20162018
{ USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */

drivers/usb/serial/qcserial.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = {
174174
{DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
175175
{DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */
176176
{DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */
177+
{DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */
178+
{DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */
179+
{DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */
180+
{DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */
177181

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

0 commit comments

Comments
 (0)