This is a note to let you know that I've just added the patch titled
USB: Increase usbfs transfer limit
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-increase-usbfs-transfer-limit.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 Mon Sep 17 00:00:00 2001
From: Mateusz Berezecki <mateuszb(a)fastmail.fm>
Date: Wed, 21 Dec 2016 09:19:14 -0800
Subject: USB: Increase usbfs transfer limit
From: Mateusz Berezecki <mateuszb(a)fastmail.fm>
commit 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 upstream.
Promote a variable keeping track of USB transfer memory usage to a
wider data type and allow for higher bandwidth transfers from a large
number of USB devices connected to a single host.
Signed-off-by: Mateusz Berezecki <mateuszb(a)fastmail.fm>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/devio.c | 43 ++++++++++++++++---------------------------
1 file changed, 16 insertions(+), 27 deletions(-)
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -134,42 +134,35 @@ enum snoop_when {
#define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0)
/* Limit on the total amount of memory we can allocate for transfers */
-static unsigned usbfs_memory_mb = 16;
+static u32 usbfs_memory_mb = 16;
module_param(usbfs_memory_mb, uint, 0644);
MODULE_PARM_DESC(usbfs_memory_mb,
"maximum MB allowed for usbfs buffers (0 = no limit)");
-/* Hard limit, necessary to avoid arithmetic overflow */
-#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000)
-
-static atomic_t usbfs_memory_usage; /* Total memory currently allocated */
+static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */
/* Check whether it's okay to allocate more memory for a transfer */
-static int usbfs_increase_memory_usage(unsigned amount)
+static int usbfs_increase_memory_usage(u64 amount)
{
- unsigned lim;
+ u64 lim;
- /*
- * Convert usbfs_memory_mb to bytes, avoiding overflows.
- * 0 means use the hard limit (effectively unlimited).
- */
lim = ACCESS_ONCE(usbfs_memory_mb);
- if (lim == 0 || lim > (USBFS_XFER_MAX >> 20))
- lim = USBFS_XFER_MAX;
- else
- lim <<= 20;
+ lim <<= 20;
- atomic_add(amount, &usbfs_memory_usage);
- if (atomic_read(&usbfs_memory_usage) <= lim)
- return 0;
- atomic_sub(amount, &usbfs_memory_usage);
- return -ENOMEM;
+ atomic64_add(amount, &usbfs_memory_usage);
+
+ if (lim > 0 && atomic64_read(&usbfs_memory_usage) > lim) {
+ atomic64_sub(amount, &usbfs_memory_usage);
+ return -ENOMEM;
+ }
+
+ return 0;
}
/* Memory for a transfer is being deallocated */
-static void usbfs_decrease_memory_usage(unsigned amount)
+static void usbfs_decrease_memory_usage(u64 amount)
{
- atomic_sub(amount, &usbfs_memory_usage);
+ atomic64_sub(amount, &usbfs_memory_usage);
}
static int connected(struct usb_dev_state *ps)
@@ -1191,7 +1184,7 @@ static int proc_bulk(struct usb_dev_stat
if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))
return -EINVAL;
len1 = bulk.len;
- if (len1 >= USBFS_XFER_MAX)
+ if (len1 >= (INT_MAX - sizeof(struct urb)))
return -EINVAL;
ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb));
if (ret)
@@ -1584,10 +1577,6 @@ static int proc_do_submiturb(struct usb_
return -EINVAL;
}
- if (uurb->buffer_length >= USBFS_XFER_MAX) {
- ret = -EINVAL;
- goto error;
- }
if (uurb->buffer_length > 0 &&
!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
uurb->buffer, uurb->buffer_length)) {
Patches currently in stable-queue which might be from mateuszb(a)fastmail.fm are
queue-4.9/usb-increase-usbfs-transfer-limit.patch
This is a note to let you know that I've just added the patch titled
usb: hub: Cycle HUB power when initialization fails
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-hub-cycle-hub-power-when-initialization-fails.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 973593a960ddac0f14f0d8877d2d0abe0afda795 Mon Sep 17 00:00:00 2001
From: Mike Looijmans <mike.looijmans(a)topic.nl>
Date: Thu, 9 Nov 2017 13:16:46 +0100
Subject: usb: hub: Cycle HUB power when initialization fails
From: Mike Looijmans <mike.looijmans(a)topic.nl>
commit 973593a960ddac0f14f0d8877d2d0abe0afda795 upstream.
Sometimes the USB device gets confused about the state of the initialization and
the connection fails. In particular, the device thinks that it's already set up
and running while the host thinks the device still needs to be configured. To
work around this issue, power-cycle the hub's output to issue a sort of "reset"
to the device. This makes the device restart its state machine and then the
initialization succeeds.
This fixes problems where the kernel reports a list of errors like this:
usb 1-1.3: device not accepting address 19, error -71
The end result is a non-functioning device. After this patch, the sequence
becomes like this:
usb 1-1.3: new high-speed USB device number 18 using ci_hdrc
usb 1-1.3: device not accepting address 18, error -71
usb 1-1.3: new high-speed USB device number 19 using ci_hdrc
usb 1-1.3: device not accepting address 19, error -71
usb 1-1-port3: attempt power cycle
usb 1-1.3: new high-speed USB device number 21 using ci_hdrc
usb-storage 1-1.3:1.2: USB Mass Storage device detected
Signed-off-by: Mike Looijmans <mike.looijmans(a)topic.nl>
Acked-by: Alan Stern <stern(a)rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/hub.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4925,6 +4925,15 @@ loop:
usb_put_dev(udev);
if ((status == -ENOTCONN) || (status == -ENOTSUPP))
break;
+
+ /* When halfway through our retry count, power-cycle the port */
+ if (i == (SET_CONFIG_TRIES / 2) - 1) {
+ dev_info(&port_dev->dev, "attempt power cycle\n");
+ usb_hub_set_port_power(hdev, hub, port1, false);
+ msleep(2 * hub_power_on_good_delay(hub));
+ usb_hub_set_port_power(hdev, hub, port1, true);
+ msleep(hub_power_on_good_delay(hub));
+ }
}
if (hub->hdev->parent ||
!hcd->driver->port_handed_over ||
Patches currently in stable-queue which might be from mike.looijmans(a)topic.nl are
queue-4.9/i2c-i2c-cadence-initialize-configuration-before-probing-devices.patch
queue-4.9/usb-hub-cycle-hub-power-when-initialization-fails.patch
This is a note to let you know that I've just added the patch titled
usb: host: fix incorrect updating of offset
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-host-fix-incorrect-updating-of-offset.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1d5a31582ef046d3b233f0da1a68ae26519b2f0a Mon Sep 17 00:00:00 2001
From: Colin Ian King <colin.king(a)canonical.com>
Date: Tue, 7 Nov 2017 16:45:04 +0000
Subject: usb: host: fix incorrect updating of offset
From: Colin Ian King <colin.king(a)canonical.com>
commit 1d5a31582ef046d3b233f0da1a68ae26519b2f0a upstream.
The variable temp is incorrectly being updated, instead it should
be offset otherwise the loop just reads the same capability value
and loops forever. Thanks to Alan Stern for pointing out the
correct fix to my original fix. Fix also cleans up clang warning:
drivers/usb/host/ehci-dbg.c:840:4: warning: Value stored to 'temp'
is never read
Fixes: d49d43174400 ("USB: misc ehci updates")
Signed-off-by: Colin Ian King <colin.king(a)canonical.com>
Acked-by: Alan Stern <stern(a)rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/host/ehci-dbg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -837,7 +837,7 @@ static ssize_t fill_registers_buffer(str
default: /* unknown */
break;
}
- temp = (cap >> 8) & 0xff;
+ offset = (cap >> 8) & 0xff;
}
}
#endif
Patches currently in stable-queue which might be from colin.king(a)canonical.com are
queue-4.9/staging-rtl8188eu-avoid-a-null-dereference-on-pmlmepriv.patch
queue-4.9/usb-host-fix-incorrect-updating-of-offset.patch
queue-4.9/net-sctp-fix-array-overrun-read-on-sctp_timer_tbl.patch
This is a note to let you know that I've just added the patch titled
USB: devio: Prevent integer overflow in proc_do_submiturb()
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 Mon Sep 17 00:00:00 2001
From: Dan Carpenter <dan.carpenter(a)oracle.com>
Date: Fri, 22 Sep 2017 23:43:25 +0300
Subject: USB: devio: Prevent integer overflow in proc_do_submiturb()
From: Dan Carpenter <dan.carpenter(a)oracle.com>
commit 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 upstream.
There used to be an integer overflow check in proc_do_submiturb() but
we removed it. It turns out that it's still required. The
uurb->buffer_length variable is a signed integer and it's controlled by
the user. It can lead to an integer overflow when we do:
num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE);
If we strip away the macro then that line looks like this:
num_sgs = (uurb->buffer_length + USB_SG_SIZE - 1) / USB_SG_SIZE;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It's the first addition which can overflow.
Fixes: 1129d270cbfb ("USB: Increase usbfs transfer limit")
Signed-off-by: Dan Carpenter <dan.carpenter(a)oracle.com>
Acked-by: Alan Stern <stern(a)rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/devio.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -139,6 +139,9 @@ module_param(usbfs_memory_mb, uint, 0644
MODULE_PARM_DESC(usbfs_memory_mb,
"maximum MB allowed for usbfs buffers (0 = no limit)");
+/* Hard limit, necessary to avoid arithmetic overflow */
+#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000)
+
static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */
/* Check whether it's okay to allocate more memory for a transfer */
@@ -1459,6 +1462,8 @@ static int proc_do_submiturb(struct usb_
USBDEVFS_URB_ZERO_PACKET |
USBDEVFS_URB_NO_INTERRUPT))
return -EINVAL;
+ if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX)
+ return -EINVAL;
if (uurb->buffer_length > 0 && !uurb->buffer)
return -EINVAL;
if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
Patches currently in stable-queue which might be from dan.carpenter(a)oracle.com are
queue-4.9/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch
This is a note to let you know that I've just added the patch titled
USB: core: Add type-specific length check of BOS descriptors
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-core-add-type-specific-length-check-of-bos-descriptors.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 81cf4a45360f70528f1f64ba018d61cb5767249a Mon Sep 17 00:00:00 2001
From: Masakazu Mokuno <masakazu.mokuno(a)gmail.com>
Date: Fri, 10 Nov 2017 01:25:50 +0900
Subject: USB: core: Add type-specific length check of BOS descriptors
From: Masakazu Mokuno <masakazu.mokuno(a)gmail.com>
commit 81cf4a45360f70528f1f64ba018d61cb5767249a upstream.
As most of BOS descriptors are longer in length than their header
'struct usb_dev_cap_header', comparing solely with it is not sufficient
to avoid out-of-bounds access to BOS descriptors.
This patch adds descriptor type specific length check in
usb_get_bos_descriptor() to fix the issue.
Signed-off-by: Masakazu Mokuno <masakazu.mokuno(a)gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/config.c | 28 ++++++++++++++++++++++++----
include/uapi/linux/usb/ch9.h | 3 +++
2 files changed, 27 insertions(+), 4 deletions(-)
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -900,14 +900,25 @@ void usb_release_bos_descriptor(struct u
}
}
+static const __u8 bos_desc_len[256] = {
+ [USB_CAP_TYPE_WIRELESS_USB] = USB_DT_USB_WIRELESS_CAP_SIZE,
+ [USB_CAP_TYPE_EXT] = USB_DT_USB_EXT_CAP_SIZE,
+ [USB_SS_CAP_TYPE] = USB_DT_USB_SS_CAP_SIZE,
+ [USB_SSP_CAP_TYPE] = USB_DT_USB_SSP_CAP_SIZE(1),
+ [CONTAINER_ID_TYPE] = USB_DT_USB_SS_CONTN_ID_SIZE,
+ [USB_PTM_CAP_TYPE] = USB_DT_USB_PTM_ID_SIZE,
+};
+
/* Get BOS descriptor set */
int usb_get_bos_descriptor(struct usb_device *dev)
{
struct device *ddev = &dev->dev;
struct usb_bos_descriptor *bos;
struct usb_dev_cap_header *cap;
+ struct usb_ssp_cap_descriptor *ssp_cap;
unsigned char *buffer;
- int length, total_len, num, i;
+ int length, total_len, num, i, ssac;
+ __u8 cap_type;
int ret;
bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL);
@@ -960,7 +971,13 @@ int usb_get_bos_descriptor(struct usb_de
dev->bos->desc->bNumDeviceCaps = i;
break;
}
+ cap_type = cap->bDevCapabilityType;
length = cap->bLength;
+ if (bos_desc_len[cap_type] && length < bos_desc_len[cap_type]) {
+ dev->bos->desc->bNumDeviceCaps = i;
+ break;
+ }
+
total_len -= length;
if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
@@ -968,7 +985,7 @@ int usb_get_bos_descriptor(struct usb_de
continue;
}
- switch (cap->bDevCapabilityType) {
+ switch (cap_type) {
case USB_CAP_TYPE_WIRELESS_USB:
/* Wireless USB cap descriptor is handled by wusb */
break;
@@ -981,8 +998,11 @@ int usb_get_bos_descriptor(struct usb_de
(struct usb_ss_cap_descriptor *)buffer;
break;
case USB_SSP_CAP_TYPE:
- dev->bos->ssp_cap =
- (struct usb_ssp_cap_descriptor *)buffer;
+ ssp_cap = (struct usb_ssp_cap_descriptor *)buffer;
+ ssac = (le32_to_cpu(ssp_cap->bmAttributes) &
+ USB_SSP_SUBLINK_SPEED_ATTRIBS) + 1;
+ if (length >= USB_DT_USB_SSP_CAP_SIZE(ssac))
+ dev->bos->ssp_cap = ssp_cap;
break;
case CONTAINER_ID_TYPE:
dev->bos->ss_id =
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -854,6 +854,8 @@ struct usb_wireless_cap_descriptor { /*
__u8 bReserved;
} __attribute__((packed));
+#define USB_DT_USB_WIRELESS_CAP_SIZE 11
+
/* USB 2.0 Extension descriptor */
#define USB_CAP_TYPE_EXT 2
@@ -1046,6 +1048,7 @@ struct usb_ptm_cap_descriptor {
__u8 bDevCapabilityType;
} __attribute__((packed));
+#define USB_DT_USB_PTM_ID_SIZE 3
/*
* The size of the descriptor for the Sublink Speed Attribute Count
* (SSAC) specified in bmAttributes[4:0].
Patches currently in stable-queue which might be from masakazu.mokuno(a)gmail.com are
queue-4.9/usb-core-add-type-specific-length-check-of-bos-descriptors.patch
This is a note to let you know that I've just added the patch titled
usb: xhci: fix panic in xhci_free_virt_devices_depth_first
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-xhci-fix-panic-in-xhci_free_virt_devices_depth_first.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 80e457699a8dbdd70f2d26911e46f538645c55fc Mon Sep 17 00:00:00 2001
From: Yu Chen <chenyu56(a)huawei.com>
Date: Fri, 1 Dec 2017 13:41:20 +0200
Subject: usb: xhci: fix panic in xhci_free_virt_devices_depth_first
From: Yu Chen <chenyu56(a)huawei.com>
commit 80e457699a8dbdd70f2d26911e46f538645c55fc upstream.
Check vdev->real_port 0 to avoid panic
[ 9.261347] [<ffffff800884a390>] xhci_free_virt_devices_depth_first+0x58/0x108
[ 9.261352] [<ffffff800884a814>] xhci_mem_cleanup+0x1bc/0x570
[ 9.261355] [<ffffff8008842de8>] xhci_stop+0x140/0x1c8
[ 9.261365] [<ffffff80087ed304>] usb_remove_hcd+0xfc/0x1d0
[ 9.261369] [<ffffff80088551c4>] xhci_plat_remove+0x6c/0xa8
[ 9.261377] [<ffffff80086e928c>] platform_drv_remove+0x2c/0x70
[ 9.261384] [<ffffff80086e6ea0>] __device_release_driver+0x80/0x108
[ 9.261387] [<ffffff80086e7a1c>] device_release_driver+0x2c/0x40
[ 9.261392] [<ffffff80086e5f28>] bus_remove_device+0xe0/0x120
[ 9.261396] [<ffffff80086e2e34>] device_del+0x114/0x210
[ 9.261399] [<ffffff80086e9e00>] platform_device_del+0x30/0xa0
[ 9.261403] [<ffffff8008810bdc>] dwc3_otg_work+0x204/0x488
[ 9.261407] [<ffffff80088133fc>] event_work+0x304/0x5b8
[ 9.261414] [<ffffff80080e31b0>] process_one_work+0x148/0x490
[ 9.261417] [<ffffff80080e3548>] worker_thread+0x50/0x4a0
[ 9.261421] [<ffffff80080e9ea0>] kthread+0xe8/0x100
[ 9.261427] [<ffffff8008083680>] ret_from_fork+0x10/0x50
The problem can occur if xhci_plat_remove() is called shortly after
xhci_plat_probe(). While xhci_free_virt_devices_depth_first been
called before the device has been setup and get real_port initialized.
The problem occurred on Hikey960 and was reproduced by Guenter Roeck
on Kevin with chromeos-4.4.
Fixes: ee8665e28e8d ("xhci: free xhci virtual devices with leaf nodes first")
Cc: Guenter Roeck <groeck(a)google.com>
Reviewed-by: Guenter Roeck <groeck(a)chromium.org>
Tested-by: Guenter Roeck <linux(a)roeck-us.net>
Signed-off-by: Fan Ning <fanning4(a)hisilicon.com>
Signed-off-by: Li Rui <lirui39(a)hisilicon.com>
Signed-off-by: yangdi <yangdi10(a)hisilicon.com>
Signed-off-by: Yu Chen <chenyu56(a)huawei.com>
Signed-off-by: Mathias Nyman <mathias.nyman(a)linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/host/xhci-mem.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -981,6 +981,12 @@ void xhci_free_virt_devices_depth_first(
if (!vdev)
return;
+ if (vdev->real_port == 0 ||
+ vdev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) {
+ xhci_dbg(xhci, "Bad vdev->real_port.\n");
+ goto out;
+ }
+
tt_list_head = &(xhci->rh_bw[vdev->real_port - 1].tts);
list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
/* is this a hub device that added a tt_info to the tts list */
@@ -994,6 +1000,7 @@ void xhci_free_virt_devices_depth_first(
}
}
}
+out:
/* we are now at a leaf device */
xhci_free_virt_device(xhci, slot_id);
}
Patches currently in stable-queue which might be from chenyu56(a)huawei.com are
queue-4.4/usb-xhci-fix-panic-in-xhci_free_virt_devices_depth_first.patch
queue-4.4/usb-dwc2-error-out-of-dwc2_hsotg_ep_disable-if-we-re-in-host-mode.patch
queue-4.4/usb-dwc2-fix-udc-state-tracking.patch
This is a note to let you know that I've just added the patch titled
USB: usbfs: Filter flags passed in from user space
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-usbfs-filter-flags-passed-in-from-user-space.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 446f666da9f019ce2ffd03800995487e79a91462 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum(a)suse.com>
Date: Thu, 23 Nov 2017 16:39:52 +0100
Subject: USB: usbfs: Filter flags passed in from user space
From: Oliver Neukum <oneukum(a)suse.com>
commit 446f666da9f019ce2ffd03800995487e79a91462 upstream.
USBDEVFS_URB_ISO_ASAP must be accepted only for ISO endpoints.
Improve sanity checking.
Reported-by: Andrey Konovalov <andreyknvl(a)google.com>
Signed-off-by: Oliver Neukum <oneukum(a)suse.com>
Acked-by: Alan Stern <stern(a)rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/devio.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1293,14 +1293,18 @@ static int proc_do_submiturb(struct usb_
int number_of_packets = 0;
unsigned int stream_id = 0;
void *buf;
-
- if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP |
- USBDEVFS_URB_SHORT_NOT_OK |
+ unsigned long mask = USBDEVFS_URB_SHORT_NOT_OK |
USBDEVFS_URB_BULK_CONTINUATION |
USBDEVFS_URB_NO_FSBR |
USBDEVFS_URB_ZERO_PACKET |
- USBDEVFS_URB_NO_INTERRUPT))
- return -EINVAL;
+ USBDEVFS_URB_NO_INTERRUPT;
+ /* USBDEVFS_URB_ISO_ASAP is a special case */
+ if (uurb->type == USBDEVFS_URB_TYPE_ISO)
+ mask |= USBDEVFS_URB_ISO_ASAP;
+
+ if (uurb->flags & ~mask)
+ return -EINVAL;
+
if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX)
return -EINVAL;
if (uurb->buffer_length > 0 && !uurb->buffer)
Patches currently in stable-queue which might be from oneukum(a)suse.com are
queue-4.4/usb-usbfs-filter-flags-passed-in-from-user-space.patch
This is a note to let you know that I've just added the patch titled
USB: Increase usbfs transfer limit
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-increase-usbfs-transfer-limit.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 Mon Sep 17 00:00:00 2001
From: Mateusz Berezecki <mateuszb(a)fastmail.fm>
Date: Wed, 21 Dec 2016 09:19:14 -0800
Subject: USB: Increase usbfs transfer limit
From: Mateusz Berezecki <mateuszb(a)fastmail.fm>
commit 1129d270cbfbb7e2b1ec3dede4a13930bdd10e41 upstream.
Promote a variable keeping track of USB transfer memory usage to a
wider data type and allow for higher bandwidth transfers from a large
number of USB devices connected to a single host.
Signed-off-by: Mateusz Berezecki <mateuszb(a)fastmail.fm>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/devio.c | 43 ++++++++++++++++---------------------------
1 file changed, 16 insertions(+), 27 deletions(-)
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -113,42 +113,35 @@ enum snoop_when {
#define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0)
/* Limit on the total amount of memory we can allocate for transfers */
-static unsigned usbfs_memory_mb = 16;
+static u32 usbfs_memory_mb = 16;
module_param(usbfs_memory_mb, uint, 0644);
MODULE_PARM_DESC(usbfs_memory_mb,
"maximum MB allowed for usbfs buffers (0 = no limit)");
-/* Hard limit, necessary to avoid arithmetic overflow */
-#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000)
-
-static atomic_t usbfs_memory_usage; /* Total memory currently allocated */
+static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */
/* Check whether it's okay to allocate more memory for a transfer */
-static int usbfs_increase_memory_usage(unsigned amount)
+static int usbfs_increase_memory_usage(u64 amount)
{
- unsigned lim;
+ u64 lim;
- /*
- * Convert usbfs_memory_mb to bytes, avoiding overflows.
- * 0 means use the hard limit (effectively unlimited).
- */
lim = ACCESS_ONCE(usbfs_memory_mb);
- if (lim == 0 || lim > (USBFS_XFER_MAX >> 20))
- lim = USBFS_XFER_MAX;
- else
- lim <<= 20;
+ lim <<= 20;
- atomic_add(amount, &usbfs_memory_usage);
- if (atomic_read(&usbfs_memory_usage) <= lim)
- return 0;
- atomic_sub(amount, &usbfs_memory_usage);
- return -ENOMEM;
+ atomic64_add(amount, &usbfs_memory_usage);
+
+ if (lim > 0 && atomic64_read(&usbfs_memory_usage) > lim) {
+ atomic64_sub(amount, &usbfs_memory_usage);
+ return -ENOMEM;
+ }
+
+ return 0;
}
/* Memory for a transfer is being deallocated */
-static void usbfs_decrease_memory_usage(unsigned amount)
+static void usbfs_decrease_memory_usage(u64 amount)
{
- atomic_sub(amount, &usbfs_memory_usage);
+ atomic64_sub(amount, &usbfs_memory_usage);
}
static int connected(struct usb_dev_state *ps)
@@ -1077,7 +1070,7 @@ static int proc_bulk(struct usb_dev_stat
if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))
return -EINVAL;
len1 = bulk.len;
- if (len1 >= USBFS_XFER_MAX)
+ if (len1 >= (INT_MAX - sizeof(struct urb)))
return -EINVAL;
ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb));
if (ret)
@@ -1424,10 +1417,6 @@ static int proc_do_submiturb(struct usb_
return -EINVAL;
}
- if (uurb->buffer_length >= USBFS_XFER_MAX) {
- ret = -EINVAL;
- goto error;
- }
if (uurb->buffer_length > 0 &&
!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
uurb->buffer, uurb->buffer_length)) {
Patches currently in stable-queue which might be from mateuszb(a)fastmail.fm are
queue-4.4/usb-increase-usbfs-transfer-limit.patch
This is a note to let you know that I've just added the patch titled
usb: hub: Cycle HUB power when initialization fails
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-hub-cycle-hub-power-when-initialization-fails.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 973593a960ddac0f14f0d8877d2d0abe0afda795 Mon Sep 17 00:00:00 2001
From: Mike Looijmans <mike.looijmans(a)topic.nl>
Date: Thu, 9 Nov 2017 13:16:46 +0100
Subject: usb: hub: Cycle HUB power when initialization fails
From: Mike Looijmans <mike.looijmans(a)topic.nl>
commit 973593a960ddac0f14f0d8877d2d0abe0afda795 upstream.
Sometimes the USB device gets confused about the state of the initialization and
the connection fails. In particular, the device thinks that it's already set up
and running while the host thinks the device still needs to be configured. To
work around this issue, power-cycle the hub's output to issue a sort of "reset"
to the device. This makes the device restart its state machine and then the
initialization succeeds.
This fixes problems where the kernel reports a list of errors like this:
usb 1-1.3: device not accepting address 19, error -71
The end result is a non-functioning device. After this patch, the sequence
becomes like this:
usb 1-1.3: new high-speed USB device number 18 using ci_hdrc
usb 1-1.3: device not accepting address 18, error -71
usb 1-1.3: new high-speed USB device number 19 using ci_hdrc
usb 1-1.3: device not accepting address 19, error -71
usb 1-1-port3: attempt power cycle
usb 1-1.3: new high-speed USB device number 21 using ci_hdrc
usb-storage 1-1.3:1.2: USB Mass Storage device detected
Signed-off-by: Mike Looijmans <mike.looijmans(a)topic.nl>
Acked-by: Alan Stern <stern(a)rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/core/hub.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4858,6 +4858,15 @@ loop:
usb_put_dev(udev);
if ((status == -ENOTCONN) || (status == -ENOTSUPP))
break;
+
+ /* When halfway through our retry count, power-cycle the port */
+ if (i == (SET_CONFIG_TRIES / 2) - 1) {
+ dev_info(&port_dev->dev, "attempt power cycle\n");
+ usb_hub_set_port_power(hdev, hub, port1, false);
+ msleep(2 * hub_power_on_good_delay(hub));
+ usb_hub_set_port_power(hdev, hub, port1, true);
+ msleep(hub_power_on_good_delay(hub));
+ }
}
if (hub->hdev->parent ||
!hcd->driver->port_handed_over ||
Patches currently in stable-queue which might be from mike.looijmans(a)topic.nl are
queue-4.4/usb-hub-cycle-hub-power-when-initialization-fails.patch
This is a note to let you know that I've just added the patch titled
usb: host: fix incorrect updating of offset
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
usb-host-fix-incorrect-updating-of-offset.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1d5a31582ef046d3b233f0da1a68ae26519b2f0a Mon Sep 17 00:00:00 2001
From: Colin Ian King <colin.king(a)canonical.com>
Date: Tue, 7 Nov 2017 16:45:04 +0000
Subject: usb: host: fix incorrect updating of offset
From: Colin Ian King <colin.king(a)canonical.com>
commit 1d5a31582ef046d3b233f0da1a68ae26519b2f0a upstream.
The variable temp is incorrectly being updated, instead it should
be offset otherwise the loop just reads the same capability value
and loops forever. Thanks to Alan Stern for pointing out the
correct fix to my original fix. Fix also cleans up clang warning:
drivers/usb/host/ehci-dbg.c:840:4: warning: Value stored to 'temp'
is never read
Fixes: d49d43174400 ("USB: misc ehci updates")
Signed-off-by: Colin Ian King <colin.king(a)canonical.com>
Acked-by: Alan Stern <stern(a)rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/usb/host/ehci-dbg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -851,7 +851,7 @@ static ssize_t fill_registers_buffer(str
default: /* unknown */
break;
}
- temp = (cap >> 8) & 0xff;
+ offset = (cap >> 8) & 0xff;
}
}
#endif
Patches currently in stable-queue which might be from colin.king(a)canonical.com are
queue-4.4/usb-host-fix-incorrect-updating-of-offset.patch
queue-4.4/net-sctp-fix-array-overrun-read-on-sctp_timer_tbl.patch