Skip to content

Commit 0ecdd78

Browse files
committed
Merge tag 'usb-5.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are a number of small USB driver fixes for 5.4-rc5. More "fun" with some of the misc USB drivers as found by syzbot, and there are a number of other small bugfixes in here for reported issues. All have been in linux-next for a while with no reported issues" * tag 'usb-5.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: cdns3: Error out if USB_DR_MODE_UNKNOWN in cdns3_core_init_role() USB: ldusb: fix read info leaks USB: serial: ti_usb_3410_5052: clean up serial data access USB: serial: ti_usb_3410_5052: fix port-close races USB: usblp: fix use-after-free on disconnect usb: udc: lpc32xx: fix bad bit shift operation usb: cdns3: Fix dequeue implementation. USB: legousbtower: fix a signedness bug in tower_probe() USB: legousbtower: fix memleak on disconnect USB: ldusb: fix memleak on disconnect
2 parents 992cb10 + 9794476 commit 0ecdd78

File tree

7 files changed

+47
-44
lines changed

7 files changed

+47
-44
lines changed

drivers/usb/cdns3/core.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
166166
goto err;
167167

168168
switch (cdns->dr_mode) {
169-
case USB_DR_MODE_UNKNOWN:
170169
case USB_DR_MODE_OTG:
171170
ret = cdns3_hw_role_switch(cdns);
172171
if (ret)
@@ -182,6 +181,9 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
182181
if (ret)
183182
goto err;
184183
break;
184+
default:
185+
ret = -EINVAL;
186+
goto err;
185187
}
186188

187189
return ret;

drivers/usb/cdns3/gadget.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,14 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
11451145
request = cdns3_next_request(&priv_ep->pending_req_list);
11461146
priv_req = to_cdns3_request(request);
11471147

1148+
trb = priv_ep->trb_pool + priv_ep->dequeue;
1149+
1150+
/* Request was dequeued and TRB was changed to TRB_LINK. */
1151+
if (TRB_FIELD_TO_TYPE(trb->control) == TRB_LINK) {
1152+
trace_cdns3_complete_trb(priv_ep, trb);
1153+
cdns3_move_deq_to_next_trb(priv_req);
1154+
}
1155+
11481156
/* Re-select endpoint. It could be changed by other CPU during
11491157
* handling usb_gadget_giveback_request.
11501158
*/
@@ -2067,6 +2075,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
20672075
struct usb_request *req, *req_temp;
20682076
struct cdns3_request *priv_req;
20692077
struct cdns3_trb *link_trb;
2078+
u8 req_on_hw_ring = 0;
20702079
unsigned long flags;
20712080
int ret = 0;
20722081

@@ -2083,8 +2092,10 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
20832092

20842093
list_for_each_entry_safe(req, req_temp, &priv_ep->pending_req_list,
20852094
list) {
2086-
if (request == req)
2095+
if (request == req) {
2096+
req_on_hw_ring = 1;
20872097
goto found;
2098+
}
20882099
}
20892100

20902101
list_for_each_entry_safe(req, req_temp, &priv_ep->deferred_req_list,
@@ -2096,27 +2107,21 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
20962107
goto not_found;
20972108

20982109
found:
2099-
2100-
if (priv_ep->wa1_trb == priv_req->trb)
2101-
cdns3_wa1_restore_cycle_bit(priv_ep);
2102-
21032110
link_trb = priv_req->trb;
2104-
cdns3_move_deq_to_next_trb(priv_req);
2105-
cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET);
2106-
2107-
/* Update ring */
2108-
request = cdns3_next_request(&priv_ep->deferred_req_list);
2109-
if (request) {
2110-
priv_req = to_cdns3_request(request);
21112111

2112+
/* Update ring only if removed request is on pending_req_list list */
2113+
if (req_on_hw_ring) {
21122114
link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma +
21132115
(priv_req->start_trb * TRB_SIZE));
21142116
link_trb->control = (link_trb->control & TRB_CYCLE) |
2115-
TRB_TYPE(TRB_LINK) | TRB_CHAIN | TRB_TOGGLE;
2116-
} else {
2117-
priv_ep->flags |= EP_UPDATE_EP_TRBADDR;
2117+
TRB_TYPE(TRB_LINK) | TRB_CHAIN;
2118+
2119+
if (priv_ep->wa1_trb == priv_req->trb)
2120+
cdns3_wa1_restore_cycle_bit(priv_ep);
21182121
}
21192122

2123+
cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET);
2124+
21202125
not_found:
21212126
spin_unlock_irqrestore(&priv_dev->lock, flags);
21222127
return ret;

drivers/usb/class/usblp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ static void usblp_cleanup(struct usblp *usblp)
445445
kfree(usblp->readbuf);
446446
kfree(usblp->device_id_string);
447447
kfree(usblp->statusbuf);
448+
usb_put_intf(usblp->intf);
448449
kfree(usblp);
449450
}
450451

@@ -1113,7 +1114,7 @@ static int usblp_probe(struct usb_interface *intf,
11131114
init_waitqueue_head(&usblp->wwait);
11141115
init_usb_anchor(&usblp->urbs);
11151116
usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
1116-
usblp->intf = intf;
1117+
usblp->intf = usb_get_intf(intf);
11171118

11181119
/* Malloc device ID string buffer to the largest expected length,
11191120
* since we can re-query it on an ioctl and a dynamic string
@@ -1198,6 +1199,7 @@ static int usblp_probe(struct usb_interface *intf,
11981199
kfree(usblp->readbuf);
11991200
kfree(usblp->statusbuf);
12001201
kfree(usblp->device_id_string);
1202+
usb_put_intf(usblp->intf);
12011203
kfree(usblp);
12021204
abort_ret:
12031205
return retval;

drivers/usb/gadget/udc/lpc32xx_udc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,11 +1177,11 @@ static void udc_pop_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes)
11771177
tmp = readl(USBD_RXDATA(udc->udp_baseaddr));
11781178

11791179
bl = bytes - n;
1180-
if (bl > 3)
1181-
bl = 3;
1180+
if (bl > 4)
1181+
bl = 4;
11821182

11831183
for (i = 0; i < bl; i++)
1184-
data[n + i] = (u8) ((tmp >> (n * 8)) & 0xFF);
1184+
data[n + i] = (u8) ((tmp >> (i * 8)) & 0xFF);
11851185
}
11861186
break;
11871187

drivers/usb/misc/ldusb.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,7 @@ static int ld_usb_release(struct inode *inode, struct file *file)
380380
goto exit;
381381
}
382382

383-
if (mutex_lock_interruptible(&dev->mutex)) {
384-
retval = -ERESTARTSYS;
385-
goto exit;
386-
}
383+
mutex_lock(&dev->mutex);
387384

388385
if (dev->open_count != 1) {
389386
retval = -ENODEV;
@@ -467,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
467464

468465
/* wait for data */
469466
spin_lock_irq(&dev->rbsl);
470-
if (dev->ring_head == dev->ring_tail) {
467+
while (dev->ring_head == dev->ring_tail) {
471468
dev->interrupt_in_done = 0;
472469
spin_unlock_irq(&dev->rbsl);
473470
if (file->f_flags & O_NONBLOCK) {
@@ -477,12 +474,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
477474
retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
478475
if (retval < 0)
479476
goto unlock_exit;
480-
} else {
481-
spin_unlock_irq(&dev->rbsl);
477+
478+
spin_lock_irq(&dev->rbsl);
482479
}
480+
spin_unlock_irq(&dev->rbsl);
483481

484482
/* actual_buffer contains actual_length + interrupt_in_buffer */
485483
actual_buffer = (size_t *)(dev->ring_buffer + dev->ring_tail * (sizeof(size_t)+dev->interrupt_in_endpoint_size));
484+
if (*actual_buffer > dev->interrupt_in_endpoint_size) {
485+
retval = -EIO;
486+
goto unlock_exit;
487+
}
486488
bytes_to_read = min(count, *actual_buffer);
487489
if (bytes_to_read < *actual_buffer)
488490
dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n",
@@ -693,10 +695,9 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
693695
dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
694696

695697
dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint);
696-
dev->ring_buffer =
697-
kmalloc_array(ring_buffer_size,
698-
sizeof(size_t) + dev->interrupt_in_endpoint_size,
699-
GFP_KERNEL);
698+
dev->ring_buffer = kcalloc(ring_buffer_size,
699+
sizeof(size_t) + dev->interrupt_in_endpoint_size,
700+
GFP_KERNEL);
700701
if (!dev->ring_buffer)
701702
goto error;
702703
dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);

drivers/usb/misc/legousbtower.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,7 @@ static int tower_release (struct inode *inode, struct file *file)
419419
goto exit;
420420
}
421421

422-
if (mutex_lock_interruptible(&dev->lock)) {
423-
retval = -ERESTARTSYS;
424-
goto exit;
425-
}
422+
mutex_lock(&dev->lock);
426423

427424
if (dev->open_count != 1) {
428425
dev_dbg(&dev->udev->dev, "%s: device not opened exactly once\n",
@@ -881,7 +878,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
881878
get_version_reply,
882879
sizeof(*get_version_reply),
883880
1000);
884-
if (result < sizeof(*get_version_reply)) {
881+
if (result != sizeof(*get_version_reply)) {
885882
if (result >= 0)
886883
result = -EIO;
887884
dev_err(idev, "get version request failed: %d\n", result);

drivers/usb/serial/ti_usb_3410_5052.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,6 @@ static void ti_close(struct usb_serial_port *port)
776776
struct ti_port *tport;
777777
int port_number;
778778
int status;
779-
int do_unlock;
780779
unsigned long flags;
781780

782781
tdev = usb_get_serial_data(port->serial);
@@ -800,16 +799,13 @@ static void ti_close(struct usb_serial_port *port)
800799
"%s - cannot send close port command, %d\n"
801800
, __func__, status);
802801

803-
/* if mutex_lock is interrupted, continue anyway */
804-
do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock);
805-
--tport->tp_tdev->td_open_port_count;
806-
if (tport->tp_tdev->td_open_port_count <= 0) {
802+
mutex_lock(&tdev->td_open_close_lock);
803+
--tdev->td_open_port_count;
804+
if (tdev->td_open_port_count == 0) {
807805
/* last port is closed, shut down interrupt urb */
808806
usb_kill_urb(port->serial->port[0]->interrupt_in_urb);
809-
tport->tp_tdev->td_open_port_count = 0;
810807
}
811-
if (do_unlock)
812-
mutex_unlock(&tdev->td_open_close_lock);
808+
mutex_unlock(&tdev->td_open_close_lock);
813809
}
814810

815811

0 commit comments

Comments
 (0)