Skip to content

Commit c7b70a6

Browse files
committed
Merge tag 'usb-4.19-final' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
I wrote: "USB fixes for 4.19-final Here are a small number of last-minute USB driver fixes Included here are: - spectre fix for usb storage gadgets - xhci fixes - cdc-acm fixes - usbip fixes for reported problems All of these have been in linux-next with no reported issues." * tag 'usb-4.19-final' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: gadget: storage: Fix Spectre v1 vulnerability USB: fix the usbfs flag sanitization for control transfers usb: xhci: pci: Enable Intel USB role mux on Apollo Lake platforms usb: roles: intel_xhci: Fix Unbalanced pm_runtime_enable cdc-acm: correct counting of UART states in serial state notification cdc-acm: do not reset notification buffer index upon urb unlinking cdc-acm: fix race between reset and control messaging usb: usbip: Fix BUG: KASAN: slab-out-of-bounds in vhci_hub_control() selftests: usbip: add wait after attach and before checking port status
2 parents b2a205f + 9ae24af commit c7b70a6

File tree

7 files changed

+65
-27
lines changed

7 files changed

+65
-27
lines changed

drivers/usb/class/cdc-acm.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,17 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
310310

311311
if (difference & ACM_CTRL_DSR)
312312
acm->iocount.dsr++;
313-
if (difference & ACM_CTRL_BRK)
314-
acm->iocount.brk++;
315-
if (difference & ACM_CTRL_RI)
316-
acm->iocount.rng++;
317313
if (difference & ACM_CTRL_DCD)
318314
acm->iocount.dcd++;
319-
if (difference & ACM_CTRL_FRAMING)
315+
if (newctrl & ACM_CTRL_BRK)
316+
acm->iocount.brk++;
317+
if (newctrl & ACM_CTRL_RI)
318+
acm->iocount.rng++;
319+
if (newctrl & ACM_CTRL_FRAMING)
320320
acm->iocount.frame++;
321-
if (difference & ACM_CTRL_PARITY)
321+
if (newctrl & ACM_CTRL_PARITY)
322322
acm->iocount.parity++;
323-
if (difference & ACM_CTRL_OVERRUN)
323+
if (newctrl & ACM_CTRL_OVERRUN)
324324
acm->iocount.overrun++;
325325
spin_unlock_irqrestore(&acm->read_lock, flags);
326326

@@ -355,7 +355,6 @@ static void acm_ctrl_irq(struct urb *urb)
355355
case -ENOENT:
356356
case -ESHUTDOWN:
357357
/* this urb is terminated, clean up */
358-
acm->nb_index = 0;
359358
dev_dbg(&acm->control->dev,
360359
"%s - urb shutting down with status: %d\n",
361360
__func__, status);
@@ -1642,6 +1641,7 @@ static int acm_pre_reset(struct usb_interface *intf)
16421641
struct acm *acm = usb_get_intfdata(intf);
16431642

16441643
clear_bit(EVENT_RX_STALL, &acm->flags);
1644+
acm->nb_index = 0; /* pending control transfers are lost */
16451645

16461646
return 0;
16471647
}

drivers/usb/core/devio.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,8 +1474,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
14741474
u = 0;
14751475
switch (uurb->type) {
14761476
case USBDEVFS_URB_TYPE_CONTROL:
1477-
if (is_in)
1478-
allow_short = true;
14791477
if (!usb_endpoint_xfer_control(&ep->desc))
14801478
return -EINVAL;
14811479
/* min 8 byte setup packet */
@@ -1505,6 +1503,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
15051503
is_in = 0;
15061504
uurb->endpoint &= ~USB_DIR_IN;
15071505
}
1506+
if (is_in)
1507+
allow_short = true;
15081508
snoop(&ps->dev->dev, "control urb: bRequestType=%02x "
15091509
"bRequest=%02x wValue=%04x "
15101510
"wIndex=%04x wLength=%04x\n",

drivers/usb/gadget/function/f_mass_storage.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@
221221
#include <linux/usb/gadget.h>
222222
#include <linux/usb/composite.h>
223223

224+
#include <linux/nospec.h>
225+
224226
#include "configfs.h"
225227

226228

@@ -3152,6 +3154,7 @@ static struct config_group *fsg_lun_make(struct config_group *group,
31523154
fsg_opts = to_fsg_opts(&group->cg_item);
31533155
if (num >= FSG_MAX_LUNS)
31543156
return ERR_PTR(-ERANGE);
3157+
num = array_index_nospec(num, FSG_MAX_LUNS);
31553158

31563159
mutex_lock(&fsg_opts->lock);
31573160
if (fsg_opts->refcnt || fsg_opts->common->luns[num]) {

drivers/usb/host/xhci-pci.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
179179
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
180180
}
181181
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
182-
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
182+
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)
183183
xhci->quirks |= XHCI_SSIC_PORT_UNUSED;
184+
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
185+
(pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
186+
pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI))
184187
xhci->quirks |= XHCI_INTEL_USB_ROLE_SW;
185-
}
186188
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
187189
(pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
188190
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||

drivers/usb/roles/intel-xhci-usb-role-switch.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ static int intel_xhci_usb_remove(struct platform_device *pdev)
161161
{
162162
struct intel_xhci_usb_data *data = platform_get_drvdata(pdev);
163163

164+
pm_runtime_disable(&pdev->dev);
165+
164166
usb_role_switch_unregister(data->role_sw);
165167
return 0;
166168
}

drivers/usb/usbip/vhci_hcd.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,9 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
318318
struct vhci_hcd *vhci_hcd;
319319
struct vhci *vhci;
320320
int retval = 0;
321-
int rhport;
321+
int rhport = -1;
322322
unsigned long flags;
323+
bool invalid_rhport = false;
323324

324325
u32 prev_port_status[VHCI_HC_PORTS];
325326

@@ -334,9 +335,19 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
334335
usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue,
335336
wIndex);
336337

337-
if (wIndex > VHCI_HC_PORTS)
338-
pr_err("invalid port number %d\n", wIndex);
339-
rhport = wIndex - 1;
338+
/*
339+
* wIndex can be 0 for some request types (typeReq). rhport is
340+
* in valid range when wIndex >= 1 and < VHCI_HC_PORTS.
341+
*
342+
* Reference port_status[] only with valid rhport when
343+
* invalid_rhport is false.
344+
*/
345+
if (wIndex < 1 || wIndex > VHCI_HC_PORTS) {
346+
invalid_rhport = true;
347+
if (wIndex > VHCI_HC_PORTS)
348+
pr_err("invalid port number %d\n", wIndex);
349+
} else
350+
rhport = wIndex - 1;
340351

341352
vhci_hcd = hcd_to_vhci_hcd(hcd);
342353
vhci = vhci_hcd->vhci;
@@ -345,17 +356,20 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
345356

346357
/* store old status and compare now and old later */
347358
if (usbip_dbg_flag_vhci_rh) {
348-
memcpy(prev_port_status, vhci_hcd->port_status,
349-
sizeof(prev_port_status));
359+
if (!invalid_rhport)
360+
memcpy(prev_port_status, vhci_hcd->port_status,
361+
sizeof(prev_port_status));
350362
}
351363

352364
switch (typeReq) {
353365
case ClearHubFeature:
354366
usbip_dbg_vhci_rh(" ClearHubFeature\n");
355367
break;
356368
case ClearPortFeature:
357-
if (rhport < 0)
369+
if (invalid_rhport) {
370+
pr_err("invalid port number %d\n", wIndex);
358371
goto error;
372+
}
359373
switch (wValue) {
360374
case USB_PORT_FEAT_SUSPEND:
361375
if (hcd->speed == HCD_USB3) {
@@ -415,9 +429,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
415429
break;
416430
case GetPortStatus:
417431
usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
418-
if (wIndex < 1) {
432+
if (invalid_rhport) {
419433
pr_err("invalid port number %d\n", wIndex);
420434
retval = -EPIPE;
435+
goto error;
421436
}
422437

423438
/* we do not care about resume. */
@@ -513,16 +528,20 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
513528
goto error;
514529
}
515530

516-
if (rhport < 0)
531+
if (invalid_rhport) {
532+
pr_err("invalid port number %d\n", wIndex);
517533
goto error;
534+
}
518535

519536
vhci_hcd->port_status[rhport] |= USB_PORT_STAT_SUSPEND;
520537
break;
521538
case USB_PORT_FEAT_POWER:
522539
usbip_dbg_vhci_rh(
523540
" SetPortFeature: USB_PORT_FEAT_POWER\n");
524-
if (rhport < 0)
541+
if (invalid_rhport) {
542+
pr_err("invalid port number %d\n", wIndex);
525543
goto error;
544+
}
526545
if (hcd->speed == HCD_USB3)
527546
vhci_hcd->port_status[rhport] |= USB_SS_PORT_STAT_POWER;
528547
else
@@ -531,8 +550,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
531550
case USB_PORT_FEAT_BH_PORT_RESET:
532551
usbip_dbg_vhci_rh(
533552
" SetPortFeature: USB_PORT_FEAT_BH_PORT_RESET\n");
534-
if (rhport < 0)
553+
if (invalid_rhport) {
554+
pr_err("invalid port number %d\n", wIndex);
535555
goto error;
556+
}
536557
/* Applicable only for USB3.0 hub */
537558
if (hcd->speed != HCD_USB3) {
538559
pr_err("USB_PORT_FEAT_BH_PORT_RESET req not "
@@ -543,8 +564,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
543564
case USB_PORT_FEAT_RESET:
544565
usbip_dbg_vhci_rh(
545566
" SetPortFeature: USB_PORT_FEAT_RESET\n");
546-
if (rhport < 0)
567+
if (invalid_rhport) {
568+
pr_err("invalid port number %d\n", wIndex);
547569
goto error;
570+
}
548571
/* if it's already enabled, disable */
549572
if (hcd->speed == HCD_USB3) {
550573
vhci_hcd->port_status[rhport] = 0;
@@ -565,8 +588,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
565588
default:
566589
usbip_dbg_vhci_rh(" SetPortFeature: default %d\n",
567590
wValue);
568-
if (rhport < 0)
591+
if (invalid_rhport) {
592+
pr_err("invalid port number %d\n", wIndex);
569593
goto error;
594+
}
570595
if (hcd->speed == HCD_USB3) {
571596
if ((vhci_hcd->port_status[rhport] &
572597
USB_SS_PORT_STAT_POWER) != 0) {
@@ -608,7 +633,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
608633
if (usbip_dbg_flag_vhci_rh) {
609634
pr_debug("port %d\n", rhport);
610635
/* Only dump valid port status */
611-
if (rhport >= 0) {
636+
if (!invalid_rhport) {
612637
dump_port_status_diff(prev_port_status[rhport],
613638
vhci_hcd->port_status[rhport],
614639
hcd->speed == HCD_USB3);
@@ -618,8 +643,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
618643

619644
spin_unlock_irqrestore(&vhci->lock, flags);
620645

621-
if ((vhci_hcd->port_status[rhport] & PORT_C_MASK) != 0)
646+
if (!invalid_rhport &&
647+
(vhci_hcd->port_status[rhport] & PORT_C_MASK) != 0) {
622648
usb_hcd_poll_rh_status(hcd);
649+
}
623650

624651
return retval;
625652
}

tools/testing/selftests/drivers/usb/usbip/usbip_test.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ echo "Import devices from localhost - should work"
141141
src/usbip attach -r localhost -b $busid;
142142
echo "=============================================================="
143143

144+
# Wait for sysfs file to be updated. Without this sleep, usbip port
145+
# shows no imported devices.
146+
sleep 3;
147+
144148
echo "List imported devices - expect to see imported devices";
145149
src/usbip port;
146150
echo "=============================================================="

0 commit comments

Comments
 (0)