mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
Actually add the patches
This commit is contained in:
parent
d86c2f7d55
commit
2bec4f071d
76
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0001.patch
Normal file
76
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0001.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Tue, 26 Sep 2017 15:15:40 -0400
|
||||||
|
Subject: [PATCH] USB: dummy-hcd: fix infinite-loop resubmission bug
|
||||||
|
|
||||||
|
The dummy-hcd HCD/UDC emulator tries not to do too much work during
|
||||||
|
each timer interrupt. But it doesn't try very hard; currently all
|
||||||
|
it does is limit the total amount of bulk data transferred. Other
|
||||||
|
transfer types aren't limited, and URBs that transfer no data (because
|
||||||
|
of an error, perhaps) don't count toward the limit, even though on a
|
||||||
|
real USB bus they would consume at least a minimum overhead.
|
||||||
|
|
||||||
|
This means it's possible to get the driver stuck in an infinite loop,
|
||||||
|
for example, if the host class driver resubmits an URB every time it
|
||||||
|
completes (which is common for interrupt URBs). Each time the URB is
|
||||||
|
resubmitted it gets added to the end of the pending-URBs list, and
|
||||||
|
dummy-hcd doesn't stop until that list is empty. Andrey Konovalov was
|
||||||
|
able to trigger this failure mode using the syzkaller fuzzer.
|
||||||
|
|
||||||
|
This patch fixes the infinite-loop problem by restricting the URBs
|
||||||
|
handled during each timer interrupt to those that were already on the
|
||||||
|
pending list when the interrupt routine started. Newly added URBs
|
||||||
|
won't be processed until the next timer interrupt. The problem of
|
||||||
|
properly accounting for non-bulk bandwidth (as well as packet and
|
||||||
|
transaction overhead) is not addressed here.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/udc/dummy_hcd.c | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
index d515ec31afe44..b2ab9cc33fec4 100644
|
||||||
|
--- a/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
@@ -237,6 +237,8 @@ struct dummy_hcd {
|
||||||
|
|
||||||
|
struct usb_device *udev;
|
||||||
|
struct list_head urbp_list;
|
||||||
|
+ struct urbp *next_frame_urbp;
|
||||||
|
+
|
||||||
|
u32 stream_en_ep;
|
||||||
|
u8 num_stream[30 / 2];
|
||||||
|
|
||||||
|
@@ -1250,6 +1252,8 @@ static int dummy_urb_enqueue(
|
||||||
|
|
||||||
|
list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list);
|
||||||
|
urb->hcpriv = urbp;
|
||||||
|
+ if (!dum_hcd->next_frame_urbp)
|
||||||
|
+ dum_hcd->next_frame_urbp = urbp;
|
||||||
|
if (usb_pipetype(urb->pipe) == PIPE_CONTROL)
|
||||||
|
urb->error_count = 1; /* mark as a new urb */
|
||||||
|
|
||||||
|
@@ -1766,6 +1770,7 @@ static void dummy_timer(unsigned long _dum_hcd)
|
||||||
|
spin_unlock_irqrestore(&dum->lock, flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ dum_hcd->next_frame_urbp = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < DUMMY_ENDPOINTS; i++) {
|
||||||
|
if (!ep_info[i].name)
|
||||||
|
@@ -1782,6 +1787,10 @@ static void dummy_timer(unsigned long _dum_hcd)
|
||||||
|
int type;
|
||||||
|
int status = -EINPROGRESS;
|
||||||
|
|
||||||
|
+ /* stop when we reach URBs queued after the timer interrupt */
|
||||||
|
+ if (urbp == dum_hcd->next_frame_urbp)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
urb = urbp->urb;
|
||||||
|
if (urb->unlinked)
|
||||||
|
goto return_urb;
|
186
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0002.patch
Normal file
186
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0002.patch
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
From 520b72fc64debf8a86c3853b8e486aa5982188f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Thu, 21 Sep 2017 13:23:58 -0400
|
||||||
|
Subject: [PATCH] USB: gadgetfs: Fix crash caused by inadequate synchronization
|
||||||
|
|
||||||
|
The gadgetfs driver (drivers/usb/gadget/legacy/inode.c) was written
|
||||||
|
before the UDC and composite frameworks were adopted; it is a legacy
|
||||||
|
driver. As such, it expects that once bound to a UDC controller, it
|
||||||
|
will not be unbound until it unregisters itself.
|
||||||
|
|
||||||
|
However, the UDC framework does unbind function drivers while they are
|
||||||
|
still registered. When this happens, it can cause the gadgetfs driver
|
||||||
|
to misbehave or crash. For example, userspace can cause a crash by
|
||||||
|
opening the device file and doing an ioctl call before setting up a
|
||||||
|
configuration (found by Andrey Konovalov using the syzkaller fuzzer).
|
||||||
|
|
||||||
|
This patch adds checks and synchronization to prevent these bad
|
||||||
|
behaviors. It adds a udc_usage counter that the driver increments at
|
||||||
|
times when it is using a gadget interface without holding the private
|
||||||
|
spinlock. The unbind routine waits for this counter to go to 0 before
|
||||||
|
returning, thereby ensuring that the UDC is no longer in use.
|
||||||
|
|
||||||
|
The patch also adds a check in the dev_ioctl() routine to make sure
|
||||||
|
the driver is bound to a UDC before dereferencing the gadget pointer,
|
||||||
|
and it makes destroy_ep_files() synchronize with the endpoint I/O
|
||||||
|
routines, to prevent the user from accessing an endpoint data
|
||||||
|
structure after it has been removed.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 41 ++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 36 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index 956b3dc7c3a4d..5c28bee327e15 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -28,7 +28,7 @@
|
||||||
|
#include <linux/aio.h>
|
||||||
|
#include <linux/uio.h>
|
||||||
|
#include <linux/refcount.h>
|
||||||
|
-
|
||||||
|
+#include <linux/delay.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
|
||||||
|
@@ -116,6 +116,7 @@ enum ep0_state {
|
||||||
|
struct dev_data {
|
||||||
|
spinlock_t lock;
|
||||||
|
refcount_t count;
|
||||||
|
+ int udc_usage;
|
||||||
|
enum ep0_state state; /* P: lock */
|
||||||
|
struct usb_gadgetfs_event event [N_EVENT];
|
||||||
|
unsigned ev_next;
|
||||||
|
@@ -513,9 +514,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
|
||||||
|
INIT_WORK(&priv->work, ep_user_copy_worker);
|
||||||
|
schedule_work(&priv->work);
|
||||||
|
}
|
||||||
|
- spin_unlock(&epdata->dev->lock);
|
||||||
|
|
||||||
|
usb_ep_free_request(ep, req);
|
||||||
|
+ spin_unlock(&epdata->dev->lock);
|
||||||
|
put_ep(epdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -939,9 +940,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
struct usb_request *req = dev->req;
|
||||||
|
|
||||||
|
if ((retval = setup_req (ep, req, 0)) == 0) {
|
||||||
|
+ ++dev->udc_usage;
|
||||||
|
spin_unlock_irq (&dev->lock);
|
||||||
|
retval = usb_ep_queue (ep, req, GFP_KERNEL);
|
||||||
|
spin_lock_irq (&dev->lock);
|
||||||
|
+ --dev->udc_usage;
|
||||||
|
}
|
||||||
|
dev->state = STATE_DEV_CONNECTED;
|
||||||
|
|
||||||
|
@@ -1134,6 +1137,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
retval = setup_req (dev->gadget->ep0, dev->req, len);
|
||||||
|
if (retval == 0) {
|
||||||
|
dev->state = STATE_DEV_CONNECTED;
|
||||||
|
+ ++dev->udc_usage;
|
||||||
|
spin_unlock_irq (&dev->lock);
|
||||||
|
if (copy_from_user (dev->req->buf, buf, len))
|
||||||
|
retval = -EFAULT;
|
||||||
|
@@ -1145,6 +1149,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
GFP_KERNEL);
|
||||||
|
}
|
||||||
|
spin_lock_irq(&dev->lock);
|
||||||
|
+ --dev->udc_usage;
|
||||||
|
if (retval < 0) {
|
||||||
|
clean_req (dev->gadget->ep0, dev->req);
|
||||||
|
} else
|
||||||
|
@@ -1246,9 +1251,21 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value)
|
||||||
|
struct usb_gadget *gadget = dev->gadget;
|
||||||
|
long ret = -ENOTTY;
|
||||||
|
|
||||||
|
- if (gadget->ops->ioctl)
|
||||||
|
+ spin_lock_irq(&dev->lock);
|
||||||
|
+ if (dev->state == STATE_DEV_OPENED ||
|
||||||
|
+ dev->state == STATE_DEV_UNBOUND) {
|
||||||
|
+ /* Not bound to a UDC */
|
||||||
|
+ } else if (gadget->ops->ioctl) {
|
||||||
|
+ ++dev->udc_usage;
|
||||||
|
+ spin_unlock_irq(&dev->lock);
|
||||||
|
+
|
||||||
|
ret = gadget->ops->ioctl (gadget, code, value);
|
||||||
|
|
||||||
|
+ spin_lock_irq(&dev->lock);
|
||||||
|
+ --dev->udc_usage;
|
||||||
|
+ }
|
||||||
|
+ spin_unlock_irq(&dev->lock);
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1466,10 +1483,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
|
if (value < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ ++dev->udc_usage;
|
||||||
|
spin_unlock (&dev->lock);
|
||||||
|
value = usb_ep_queue (gadget->ep0, dev->req,
|
||||||
|
GFP_KERNEL);
|
||||||
|
spin_lock (&dev->lock);
|
||||||
|
+ --dev->udc_usage;
|
||||||
|
if (value < 0) {
|
||||||
|
clean_req (gadget->ep0, dev->req);
|
||||||
|
break;
|
||||||
|
@@ -1493,8 +1512,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
|
req->length = value;
|
||||||
|
req->zero = value < w_length;
|
||||||
|
|
||||||
|
+ ++dev->udc_usage;
|
||||||
|
spin_unlock (&dev->lock);
|
||||||
|
value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL);
|
||||||
|
+ spin_lock(&dev->lock);
|
||||||
|
+ --dev->udc_usage;
|
||||||
|
+ spin_unlock(&dev->lock);
|
||||||
|
if (value < 0) {
|
||||||
|
DBG (dev, "ep_queue --> %d\n", value);
|
||||||
|
req->status = 0;
|
||||||
|
@@ -1521,21 +1544,24 @@ static void destroy_ep_files (struct dev_data *dev)
|
||||||
|
/* break link to FS */
|
||||||
|
ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles);
|
||||||
|
list_del_init (&ep->epfiles);
|
||||||
|
+ spin_unlock_irq (&dev->lock);
|
||||||
|
+
|
||||||
|
dentry = ep->dentry;
|
||||||
|
ep->dentry = NULL;
|
||||||
|
parent = d_inode(dentry->d_parent);
|
||||||
|
|
||||||
|
/* break link to controller */
|
||||||
|
+ mutex_lock(&ep->lock);
|
||||||
|
if (ep->state == STATE_EP_ENABLED)
|
||||||
|
(void) usb_ep_disable (ep->ep);
|
||||||
|
ep->state = STATE_EP_UNBOUND;
|
||||||
|
usb_ep_free_request (ep->ep, ep->req);
|
||||||
|
ep->ep = NULL;
|
||||||
|
+ mutex_unlock(&ep->lock);
|
||||||
|
+
|
||||||
|
wake_up (&ep->wait);
|
||||||
|
put_ep (ep);
|
||||||
|
|
||||||
|
- spin_unlock_irq (&dev->lock);
|
||||||
|
-
|
||||||
|
/* break link to dcache */
|
||||||
|
inode_lock(parent);
|
||||||
|
d_delete (dentry);
|
||||||
|
@@ -1606,6 +1632,11 @@ gadgetfs_unbind (struct usb_gadget *gadget)
|
||||||
|
|
||||||
|
spin_lock_irq (&dev->lock);
|
||||||
|
dev->state = STATE_DEV_UNBOUND;
|
||||||
|
+ while (dev->udc_usage > 0) {
|
||||||
|
+ spin_unlock_irq(&dev->lock);
|
||||||
|
+ usleep_range(1000, 2000);
|
||||||
|
+ spin_lock_irq(&dev->lock);
|
||||||
|
+ }
|
||||||
|
spin_unlock_irq (&dev->lock);
|
||||||
|
|
||||||
|
destroy_ep_files (dev);
|
40
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0003.patch
Normal file
40
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0003.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
From 6e76c01e71551cb221c1f3deacb9dcd9a7346784 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Thu, 21 Sep 2017 16:12:01 -0400
|
||||||
|
Subject: [PATCH] USB: gadgetfs: fix copy_to_user while holding spinlock
|
||||||
|
|
||||||
|
The gadgetfs driver as a long-outstanding FIXME, regarding a call of
|
||||||
|
copy_to_user() made while holding a spinlock. This patch fixes the
|
||||||
|
issue by dropping the spinlock and using the dev->udc_usage mechanism
|
||||||
|
introduced by another recent patch to guard against status changes
|
||||||
|
while the lock isn't held.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index 684900fcfe24c..956b3dc7c3a4d 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -983,11 +983,14 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
retval = -EIO;
|
||||||
|
else {
|
||||||
|
len = min (len, (size_t)dev->req->actual);
|
||||||
|
-// FIXME don't call this with the spinlock held ...
|
||||||
|
+ ++dev->udc_usage;
|
||||||
|
+ spin_unlock_irq(&dev->lock);
|
||||||
|
if (copy_to_user (buf, dev->req->buf, len))
|
||||||
|
retval = -EFAULT;
|
||||||
|
else
|
||||||
|
retval = len;
|
||||||
|
+ spin_lock_irq(&dev->lock);
|
||||||
|
+ --dev->udc_usage;
|
||||||
|
clean_req (dev->gadget->ep0, dev->req);
|
||||||
|
/* NOTE userspace can't yet choose to stall */
|
||||||
|
}
|
264
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0004.patch
Normal file
264
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0004.patch
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
From f16443a034c7aa359ddf6f0f9bc40d01ca31faea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Tue, 13 Jun 2017 15:23:42 -0400
|
||||||
|
Subject: [PATCH] USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks
|
||||||
|
|
||||||
|
Using the syzkaller kernel fuzzer, Andrey Konovalov generated the
|
||||||
|
following error in gadgetfs:
|
||||||
|
|
||||||
|
> BUG: KASAN: use-after-free in __lock_acquire+0x3069/0x3690
|
||||||
|
> kernel/locking/lockdep.c:3246
|
||||||
|
> Read of size 8 at addr ffff88003a2bdaf8 by task kworker/3:1/903
|
||||||
|
>
|
||||||
|
> CPU: 3 PID: 903 Comm: kworker/3:1 Not tainted 4.12.0-rc4+ #35
|
||||||
|
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
> Workqueue: usb_hub_wq hub_event
|
||||||
|
> Call Trace:
|
||||||
|
> __dump_stack lib/dump_stack.c:16 [inline]
|
||||||
|
> dump_stack+0x292/0x395 lib/dump_stack.c:52
|
||||||
|
> print_address_description+0x78/0x280 mm/kasan/report.c:252
|
||||||
|
> kasan_report_error mm/kasan/report.c:351 [inline]
|
||||||
|
> kasan_report+0x230/0x340 mm/kasan/report.c:408
|
||||||
|
> __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:429
|
||||||
|
> __lock_acquire+0x3069/0x3690 kernel/locking/lockdep.c:3246
|
||||||
|
> lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855
|
||||||
|
> __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline]
|
||||||
|
> _raw_spin_lock+0x2f/0x40 kernel/locking/spinlock.c:151
|
||||||
|
> spin_lock include/linux/spinlock.h:299 [inline]
|
||||||
|
> gadgetfs_suspend+0x89/0x130 drivers/usb/gadget/legacy/inode.c:1682
|
||||||
|
> set_link_state+0x88e/0xae0 drivers/usb/gadget/udc/dummy_hcd.c:455
|
||||||
|
> dummy_hub_control+0xd7e/0x1fb0 drivers/usb/gadget/udc/dummy_hcd.c:2074
|
||||||
|
> rh_call_control drivers/usb/core/hcd.c:689 [inline]
|
||||||
|
> rh_urb_enqueue drivers/usb/core/hcd.c:846 [inline]
|
||||||
|
> usb_hcd_submit_urb+0x92f/0x20b0 drivers/usb/core/hcd.c:1650
|
||||||
|
> usb_submit_urb+0x8b2/0x12c0 drivers/usb/core/urb.c:542
|
||||||
|
> usb_start_wait_urb+0x148/0x5b0 drivers/usb/core/message.c:56
|
||||||
|
> usb_internal_control_msg drivers/usb/core/message.c:100 [inline]
|
||||||
|
> usb_control_msg+0x341/0x4d0 drivers/usb/core/message.c:151
|
||||||
|
> usb_clear_port_feature+0x74/0xa0 drivers/usb/core/hub.c:412
|
||||||
|
> hub_port_disable+0x123/0x510 drivers/usb/core/hub.c:4177
|
||||||
|
> hub_port_init+0x1ed/0x2940 drivers/usb/core/hub.c:4648
|
||||||
|
> hub_port_connect drivers/usb/core/hub.c:4826 [inline]
|
||||||
|
> hub_port_connect_change drivers/usb/core/hub.c:4999 [inline]
|
||||||
|
> port_event drivers/usb/core/hub.c:5105 [inline]
|
||||||
|
> hub_event+0x1ae1/0x3d40 drivers/usb/core/hub.c:5185
|
||||||
|
> process_one_work+0xc08/0x1bd0 kernel/workqueue.c:2097
|
||||||
|
> process_scheduled_works kernel/workqueue.c:2157 [inline]
|
||||||
|
> worker_thread+0xb2b/0x1860 kernel/workqueue.c:2233
|
||||||
|
> kthread+0x363/0x440 kernel/kthread.c:231
|
||||||
|
> ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:424
|
||||||
|
>
|
||||||
|
> Allocated by task 9958:
|
||||||
|
> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
|
||||||
|
> save_stack+0x43/0xd0 mm/kasan/kasan.c:513
|
||||||
|
> set_track mm/kasan/kasan.c:525 [inline]
|
||||||
|
> kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:617
|
||||||
|
> kmem_cache_alloc_trace+0x87/0x280 mm/slub.c:2745
|
||||||
|
> kmalloc include/linux/slab.h:492 [inline]
|
||||||
|
> kzalloc include/linux/slab.h:665 [inline]
|
||||||
|
> dev_new drivers/usb/gadget/legacy/inode.c:170 [inline]
|
||||||
|
> gadgetfs_fill_super+0x24f/0x540 drivers/usb/gadget/legacy/inode.c:1993
|
||||||
|
> mount_single+0xf6/0x160 fs/super.c:1192
|
||||||
|
> gadgetfs_mount+0x31/0x40 drivers/usb/gadget/legacy/inode.c:2019
|
||||||
|
> mount_fs+0x9c/0x2d0 fs/super.c:1223
|
||||||
|
> vfs_kern_mount.part.25+0xcb/0x490 fs/namespace.c:976
|
||||||
|
> vfs_kern_mount fs/namespace.c:2509 [inline]
|
||||||
|
> do_new_mount fs/namespace.c:2512 [inline]
|
||||||
|
> do_mount+0x41b/0x2d90 fs/namespace.c:2834
|
||||||
|
> SYSC_mount fs/namespace.c:3050 [inline]
|
||||||
|
> SyS_mount+0xb0/0x120 fs/namespace.c:3027
|
||||||
|
> entry_SYSCALL_64_fastpath+0x1f/0xbe
|
||||||
|
>
|
||||||
|
> Freed by task 9960:
|
||||||
|
> save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
|
||||||
|
> save_stack+0x43/0xd0 mm/kasan/kasan.c:513
|
||||||
|
> set_track mm/kasan/kasan.c:525 [inline]
|
||||||
|
> kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:590
|
||||||
|
> slab_free_hook mm/slub.c:1357 [inline]
|
||||||
|
> slab_free_freelist_hook mm/slub.c:1379 [inline]
|
||||||
|
> slab_free mm/slub.c:2961 [inline]
|
||||||
|
> kfree+0xed/0x2b0 mm/slub.c:3882
|
||||||
|
> put_dev+0x124/0x160 drivers/usb/gadget/legacy/inode.c:163
|
||||||
|
> gadgetfs_kill_sb+0x33/0x60 drivers/usb/gadget/legacy/inode.c:2027
|
||||||
|
> deactivate_locked_super+0x8d/0xd0 fs/super.c:309
|
||||||
|
> deactivate_super+0x21e/0x310 fs/super.c:340
|
||||||
|
> cleanup_mnt+0xb7/0x150 fs/namespace.c:1112
|
||||||
|
> __cleanup_mnt+0x1b/0x20 fs/namespace.c:1119
|
||||||
|
> task_work_run+0x1a0/0x280 kernel/task_work.c:116
|
||||||
|
> exit_task_work include/linux/task_work.h:21 [inline]
|
||||||
|
> do_exit+0x18a8/0x2820 kernel/exit.c:878
|
||||||
|
> do_group_exit+0x14e/0x420 kernel/exit.c:982
|
||||||
|
> get_signal+0x784/0x1780 kernel/signal.c:2318
|
||||||
|
> do_signal+0xd7/0x2130 arch/x86/kernel/signal.c:808
|
||||||
|
> exit_to_usermode_loop+0x1ac/0x240 arch/x86/entry/common.c:157
|
||||||
|
> prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline]
|
||||||
|
> syscall_return_slowpath+0x3ba/0x410 arch/x86/entry/common.c:263
|
||||||
|
> entry_SYSCALL_64_fastpath+0xbc/0xbe
|
||||||
|
>
|
||||||
|
> The buggy address belongs to the object at ffff88003a2bdae0
|
||||||
|
> which belongs to the cache kmalloc-1024 of size 1024
|
||||||
|
> The buggy address is located 24 bytes inside of
|
||||||
|
> 1024-byte region [ffff88003a2bdae0, ffff88003a2bdee0)
|
||||||
|
> The buggy address belongs to the page:
|
||||||
|
> page:ffffea0000e8ae00 count:1 mapcount:0 mapping: (null)
|
||||||
|
> index:0x0 compound_mapcount: 0
|
||||||
|
> flags: 0x100000000008100(slab|head)
|
||||||
|
> raw: 0100000000008100 0000000000000000 0000000000000000 0000000100170017
|
||||||
|
> raw: ffffea0000ed3020 ffffea0000f5f820 ffff88003e80efc0 0000000000000000
|
||||||
|
> page dumped because: kasan: bad access detected
|
||||||
|
>
|
||||||
|
> Memory state around the buggy address:
|
||||||
|
> ffff88003a2bd980: fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||||
|
> ffff88003a2bda00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||||
|
> >ffff88003a2bda80: fc fc fc fc fc fc fc fc fc fc fc fc fb fb fb fb
|
||||||
|
> ^
|
||||||
|
> ffff88003a2bdb00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||||
|
> ffff88003a2bdb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||||
|
> ==================================================================
|
||||||
|
|
||||||
|
What this means is that the gadgetfs_suspend() routine was trying to
|
||||||
|
access dev->lock after it had been deallocated. The root cause is a
|
||||||
|
race in the dummy_hcd driver; the dummy_udc_stop() routine can race
|
||||||
|
with the rest of the driver because it contains no locking. And even
|
||||||
|
when proper locking is added, it can still race with the
|
||||||
|
set_link_state() function because that function incorrectly drops the
|
||||||
|
private spinlock before invoking any gadget driver callbacks.
|
||||||
|
|
||||||
|
The result of this race, as seen above, is that set_link_state() can
|
||||||
|
invoke a callback in gadgetfs even after gadgetfs has been unbound
|
||||||
|
from dummy_hcd's UDC and its private data structures have been
|
||||||
|
deallocated.
|
||||||
|
|
||||||
|
include/linux/usb/gadget.h documents that the ->reset, ->disconnect,
|
||||||
|
->suspend, and ->resume callbacks may be invoked in interrupt context.
|
||||||
|
In general this is necessary, to prevent races with gadget driver
|
||||||
|
removal. This patch fixes dummy_hcd to retain the spinlock across
|
||||||
|
these calls, and it adds a spinlock acquisition to dummy_udc_stop() to
|
||||||
|
prevent the race.
|
||||||
|
|
||||||
|
The net2280 driver makes the same mistake of dropping the private
|
||||||
|
spinlock for its ->disconnect and ->reset callback invocations. The
|
||||||
|
patch fixes it too.
|
||||||
|
|
||||||
|
Lastly, since gadgetfs_suspend() may be invoked in interrupt context,
|
||||||
|
it cannot assume that interrupts are enabled when it runs. It must
|
||||||
|
use spin_lock_irqsave() instead of spin_lock_irq(). The patch fixes
|
||||||
|
that bug as well.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-and-tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 5 +++--
|
||||||
|
drivers/usb/gadget/udc/dummy_hcd.c | 13 ++++---------
|
||||||
|
drivers/usb/gadget/udc/net2280.c | 9 +--------
|
||||||
|
3 files changed, 8 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index 5ffd879f78868..684900fcfe24c 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -1679,9 +1679,10 @@ static void
|
||||||
|
gadgetfs_suspend (struct usb_gadget *gadget)
|
||||||
|
{
|
||||||
|
struct dev_data *dev = get_gadget_data (gadget);
|
||||||
|
+ unsigned long flags;
|
||||||
|
|
||||||
|
INFO (dev, "suspended from state %d\n", dev->state);
|
||||||
|
- spin_lock (&dev->lock);
|
||||||
|
+ spin_lock_irqsave(&dev->lock, flags);
|
||||||
|
switch (dev->state) {
|
||||||
|
case STATE_DEV_SETUP: // VERY odd... host died??
|
||||||
|
case STATE_DEV_CONNECTED:
|
||||||
|
@@ -1692,7 +1693,7 @@ gadgetfs_suspend (struct usb_gadget *gadget)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- spin_unlock (&dev->lock);
|
||||||
|
+ spin_unlock_irqrestore(&dev->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct usb_gadget_driver gadgetfs_driver = {
|
||||||
|
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
index ccabb51cb98da..7635fd7cc328c 100644
|
||||||
|
--- a/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
|
||||||
|
/* Report reset and disconnect events to the driver */
|
||||||
|
if (dum->driver && (disconnect || reset)) {
|
||||||
|
stop_activity(dum);
|
||||||
|
- spin_unlock(&dum->lock);
|
||||||
|
if (reset)
|
||||||
|
usb_gadget_udc_reset(&dum->gadget, dum->driver);
|
||||||
|
else
|
||||||
|
dum->driver->disconnect(&dum->gadget);
|
||||||
|
- spin_lock(&dum->lock);
|
||||||
|
}
|
||||||
|
} else if (dum_hcd->active != dum_hcd->old_active) {
|
||||||
|
- if (dum_hcd->old_active && dum->driver->suspend) {
|
||||||
|
- spin_unlock(&dum->lock);
|
||||||
|
+ if (dum_hcd->old_active && dum->driver->suspend)
|
||||||
|
dum->driver->suspend(&dum->gadget);
|
||||||
|
- spin_lock(&dum->lock);
|
||||||
|
- } else if (!dum_hcd->old_active && dum->driver->resume) {
|
||||||
|
- spin_unlock(&dum->lock);
|
||||||
|
+ else if (!dum_hcd->old_active && dum->driver->resume)
|
||||||
|
dum->driver->resume(&dum->gadget);
|
||||||
|
- spin_lock(&dum->lock);
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
dum_hcd->old_status = dum_hcd->port_status;
|
||||||
|
@@ -983,7 +976,9 @@ static int dummy_udc_stop(struct usb_gadget *g)
|
||||||
|
struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g);
|
||||||
|
struct dummy *dum = dum_hcd->dum;
|
||||||
|
|
||||||
|
+ spin_lock_irq(&dum->lock);
|
||||||
|
dum->driver = NULL;
|
||||||
|
+ spin_unlock_irq(&dum->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
|
||||||
|
index 6cf07857eacaa..f2cbd7f8005e1 100644
|
||||||
|
--- a/drivers/usb/gadget/udc/net2280.c
|
||||||
|
+++ b/drivers/usb/gadget/udc/net2280.c
|
||||||
|
@@ -2470,11 +2470,8 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
|
||||||
|
nuke(&dev->ep[i]);
|
||||||
|
|
||||||
|
/* report disconnect; the driver is already quiesced */
|
||||||
|
- if (driver) {
|
||||||
|
- spin_unlock(&dev->lock);
|
||||||
|
+ if (driver)
|
||||||
|
driver->disconnect(&dev->gadget);
|
||||||
|
- spin_lock(&dev->lock);
|
||||||
|
- }
|
||||||
|
|
||||||
|
usb_reinit(dev);
|
||||||
|
}
|
||||||
|
@@ -3348,8 +3345,6 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
|
||||||
|
BIT(PCI_RETRY_ABORT_INTERRUPT))
|
||||||
|
|
||||||
|
static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
|
||||||
|
-__releases(dev->lock)
|
||||||
|
-__acquires(dev->lock)
|
||||||
|
{
|
||||||
|
struct net2280_ep *ep;
|
||||||
|
u32 tmp, num, mask, scratch;
|
||||||
|
@@ -3390,14 +3385,12 @@ __acquires(dev->lock)
|
||||||
|
if (disconnect || reset) {
|
||||||
|
stop_activity(dev, dev->driver);
|
||||||
|
ep0_start(dev);
|
||||||
|
- spin_unlock(&dev->lock);
|
||||||
|
if (reset)
|
||||||
|
usb_gadget_udc_reset
|
||||||
|
(&dev->gadget, dev->driver);
|
||||||
|
else
|
||||||
|
(dev->driver->disconnect)
|
||||||
|
(&dev->gadget);
|
||||||
|
- spin_lock(&dev->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
89
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0005.patch
Normal file
89
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0005.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From f50b878fed33e360d01dcdc31a8eeb1815d033d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Thu, 8 Jun 2017 13:55:59 -0400
|
||||||
|
Subject: [PATCH] USB: gadget: fix GPF in gadgetfs
|
||||||
|
|
||||||
|
A NULL-pointer dereference bug in gadgetfs was uncovered by syzkaller:
|
||||||
|
|
||||||
|
> kasan: GPF could be caused by NULL-ptr deref or user memory access
|
||||||
|
> general protection fault: 0000 [#1] SMP KASAN
|
||||||
|
> Dumping ftrace buffer:
|
||||||
|
> (ftrace buffer empty)
|
||||||
|
> Modules linked in:
|
||||||
|
> CPU: 2 PID: 4820 Comm: syz-executor0 Not tainted 4.12.0-rc4+ #5
|
||||||
|
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
> task: ffff880039542dc0 task.stack: ffff88003bdd0000
|
||||||
|
> RIP: 0010:__list_del_entry_valid+0x7e/0x170 lib/list_debug.c:51
|
||||||
|
> RSP: 0018:ffff88003bdd6e50 EFLAGS: 00010246
|
||||||
|
> RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000010000
|
||||||
|
> RDX: 0000000000000000 RSI: ffffffff86504948 RDI: ffffffff86504950
|
||||||
|
> RBP: ffff88003bdd6e68 R08: ffff880039542dc0 R09: ffffffff8778ce00
|
||||||
|
> R10: ffff88003bdd6e68 R11: dffffc0000000000 R12: 0000000000000000
|
||||||
|
> R13: dffffc0000000000 R14: 1ffff100077badd2 R15: ffffffff864d2e40
|
||||||
|
> FS: 0000000000000000(0000) GS:ffff88006dc00000(0000) knlGS:0000000000000000
|
||||||
|
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
> CR2: 000000002014aff9 CR3: 0000000006022000 CR4: 00000000000006e0
|
||||||
|
> Call Trace:
|
||||||
|
> __list_del_entry include/linux/list.h:116 [inline]
|
||||||
|
> list_del include/linux/list.h:124 [inline]
|
||||||
|
> usb_gadget_unregister_driver+0x166/0x4c0 drivers/usb/gadget/udc/core.c:1387
|
||||||
|
> dev_release+0x80/0x160 drivers/usb/gadget/legacy/inode.c:1187
|
||||||
|
> __fput+0x332/0x7f0 fs/file_table.c:209
|
||||||
|
> ____fput+0x15/0x20 fs/file_table.c:245
|
||||||
|
> task_work_run+0x19b/0x270 kernel/task_work.c:116
|
||||||
|
> exit_task_work include/linux/task_work.h:21 [inline]
|
||||||
|
> do_exit+0x18a3/0x2820 kernel/exit.c:878
|
||||||
|
> do_group_exit+0x149/0x420 kernel/exit.c:982
|
||||||
|
> get_signal+0x77f/0x1780 kernel/signal.c:2318
|
||||||
|
> do_signal+0xd2/0x2130 arch/x86/kernel/signal.c:808
|
||||||
|
> exit_to_usermode_loop+0x1a7/0x240 arch/x86/entry/common.c:157
|
||||||
|
> prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline]
|
||||||
|
> syscall_return_slowpath+0x3ba/0x410 arch/x86/entry/common.c:263
|
||||||
|
> entry_SYSCALL_64_fastpath+0xbc/0xbe
|
||||||
|
> RIP: 0033:0x4461f9
|
||||||
|
> RSP: 002b:00007fdac2b1ecf8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca
|
||||||
|
> RAX: fffffffffffffe00 RBX: 00000000007080c8 RCX: 00000000004461f9
|
||||||
|
> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00000000007080c8
|
||||||
|
> RBP: 00000000007080a8 R08: 0000000000000000 R09: 0000000000000000
|
||||||
|
> R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
|
||||||
|
> R13: 0000000000000000 R14: 00007fdac2b1f9c0 R15: 00007fdac2b1f700
|
||||||
|
> Code: 00 00 00 00 ad de 49 39 c4 74 6a 48 b8 00 02 00 00 00 00 ad de
|
||||||
|
> 48 89 da 48 39 c3 74 74 48 c1 ea 03 48 b8 00 00 00 00 00 fc ff df <80>
|
||||||
|
> 3c 02 00 0f 85 92 00 00 00 48 8b 13 48 39 f2 75 66 49 8d 7c
|
||||||
|
> RIP: __list_del_entry_valid+0x7e/0x170 lib/list_debug.c:51 RSP: ffff88003bdd6e50
|
||||||
|
> ---[ end trace 30e94b1eec4831c8 ]---
|
||||||
|
> Kernel panic - not syncing: Fatal exception
|
||||||
|
|
||||||
|
The bug was caused by dev_release() failing to turn off its
|
||||||
|
gadget_registered flag after unregistering the gadget driver. As a
|
||||||
|
result, when a later user closed the device file before writing a
|
||||||
|
valid set of descriptors, dev_release() thought the gadget had been
|
||||||
|
registered and tried to unregister it, even though it had not been.
|
||||||
|
This led to the NULL pointer dereference.
|
||||||
|
|
||||||
|
The fix is simple: turn off the flag when the gadget is unregistered.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-and-tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index b9ca0a26cbd93..5ffd879f78868 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -1183,8 +1183,10 @@ dev_release (struct inode *inode, struct file *fd)
|
||||||
|
|
||||||
|
/* closing ep0 === shutdown all */
|
||||||
|
|
||||||
|
- if (dev->gadget_registered)
|
||||||
|
+ if (dev->gadget_registered) {
|
||||||
|
usb_gadget_unregister_driver (&gadgetfs_driver);
|
||||||
|
+ dev->gadget_registered = false;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* at this point "good" hardware has disconnected the
|
||||||
|
* device from USB; the host won't see it any more.
|
75
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0006.patch
Normal file
75
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0006.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From bb1107f7c6052c863692a41f78c000db792334bf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Hocko <mhocko@suse.com>
|
||||||
|
Date: Tue, 10 Jan 2017 16:57:27 -0800
|
||||||
|
Subject: [PATCH] mm, slab: make sure that KMALLOC_MAX_SIZE will fit into
|
||||||
|
MAX_ORDER
|
||||||
|
|
||||||
|
Andrey Konovalov has reported the following warning triggered by the
|
||||||
|
syzkaller fuzzer.
|
||||||
|
|
||||||
|
WARNING: CPU: 1 PID: 9935 at mm/page_alloc.c:3511 __alloc_pages_nodemask+0x159c/0x1e20
|
||||||
|
Kernel panic - not syncing: panic_on_warn set ...
|
||||||
|
CPU: 1 PID: 9935 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #34
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
Call Trace:
|
||||||
|
__alloc_pages_slowpath mm/page_alloc.c:3511
|
||||||
|
__alloc_pages_nodemask+0x159c/0x1e20 mm/page_alloc.c:3781
|
||||||
|
alloc_pages_current+0x1c7/0x6b0 mm/mempolicy.c:2072
|
||||||
|
alloc_pages include/linux/gfp.h:469
|
||||||
|
kmalloc_order+0x1f/0x70 mm/slab_common.c:1015
|
||||||
|
kmalloc_order_trace+0x1f/0x160 mm/slab_common.c:1026
|
||||||
|
kmalloc_large include/linux/slab.h:422
|
||||||
|
__kmalloc+0x210/0x2d0 mm/slub.c:3723
|
||||||
|
kmalloc include/linux/slab.h:495
|
||||||
|
ep_write_iter+0x167/0xb50 drivers/usb/gadget/legacy/inode.c:664
|
||||||
|
new_sync_write fs/read_write.c:499
|
||||||
|
__vfs_write+0x483/0x760 fs/read_write.c:512
|
||||||
|
vfs_write+0x170/0x4e0 fs/read_write.c:560
|
||||||
|
SYSC_write fs/read_write.c:607
|
||||||
|
SyS_write+0xfb/0x230 fs/read_write.c:599
|
||||||
|
entry_SYSCALL_64_fastpath+0x1f/0xc2
|
||||||
|
|
||||||
|
The issue is caused by a lack of size check for the request size in
|
||||||
|
ep_write_iter which should be fixed. It, however, points to another
|
||||||
|
problem, that SLUB defines KMALLOC_MAX_SIZE too large because the its
|
||||||
|
KMALLOC_SHIFT_MAX is (MAX_ORDER + PAGE_SHIFT) which means that the
|
||||||
|
resulting page allocator request might be MAX_ORDER which is too large
|
||||||
|
(see __alloc_pages_slowpath).
|
||||||
|
|
||||||
|
The same applies to the SLOB allocator which allows even larger sizes.
|
||||||
|
Make sure that they are capped properly and never request more than
|
||||||
|
MAX_ORDER order.
|
||||||
|
|
||||||
|
Link: http://lkml.kernel.org/r/20161220130659.16461-2-mhocko@kernel.org
|
||||||
|
Signed-off-by: Michal Hocko <mhocko@suse.com>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Acked-by: Christoph Lameter <cl@linux.com>
|
||||||
|
Cc: Alexei Starovoitov <ast@kernel.org>
|
||||||
|
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||||
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||||
|
---
|
||||||
|
include/linux/slab.h | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/linux/slab.h b/include/linux/slab.h
|
||||||
|
index 084b12bad1982..4c53635668154 100644
|
||||||
|
--- a/include/linux/slab.h
|
||||||
|
+++ b/include/linux/slab.h
|
||||||
|
@@ -226,7 +226,7 @@ static inline const char *__check_heap_object(const void *ptr,
|
||||||
|
* (PAGE_SIZE*2). Larger requests are passed to the page allocator.
|
||||||
|
*/
|
||||||
|
#define KMALLOC_SHIFT_HIGH (PAGE_SHIFT + 1)
|
||||||
|
-#define KMALLOC_SHIFT_MAX (MAX_ORDER + PAGE_SHIFT)
|
||||||
|
+#define KMALLOC_SHIFT_MAX (MAX_ORDER + PAGE_SHIFT - 1)
|
||||||
|
#ifndef KMALLOC_SHIFT_LOW
|
||||||
|
#define KMALLOC_SHIFT_LOW 3
|
||||||
|
#endif
|
||||||
|
@@ -239,7 +239,7 @@ static inline const char *__check_heap_object(const void *ptr,
|
||||||
|
* be allocated from the same page.
|
||||||
|
*/
|
||||||
|
#define KMALLOC_SHIFT_HIGH PAGE_SHIFT
|
||||||
|
-#define KMALLOC_SHIFT_MAX 30
|
||||||
|
+#define KMALLOC_SHIFT_MAX (MAX_ORDER + PAGE_SHIFT - 1)
|
||||||
|
#ifndef KMALLOC_SHIFT_LOW
|
||||||
|
#define KMALLOC_SHIFT_LOW 3
|
||||||
|
#endif
|
64
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0007.patch
Normal file
64
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0007.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
From faab50984fe6636e616c7cc3d30308ba391d36fd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Fri, 9 Dec 2016 15:17:46 -0500
|
||||||
|
Subject: [PATCH] USB: gadgetfs: fix unbounded memory allocation bug
|
||||||
|
|
||||||
|
Andrey Konovalov reports that fuzz testing with syzkaller causes a
|
||||||
|
KASAN warning in gadgetfs:
|
||||||
|
|
||||||
|
BUG: KASAN: slab-out-of-bounds in dev_config+0x86f/0x1190 at addr ffff88003c47e160
|
||||||
|
Write of size 65537 by task syz-executor0/6356
|
||||||
|
CPU: 3 PID: 6356 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #19
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
ffff88003c107ad8 ffffffff81f96aba ffffffff3dc11ef0 1ffff10007820eee
|
||||||
|
ffffed0007820ee6 ffff88003dc11f00 0000000041b58ab3 ffffffff8598b4c8
|
||||||
|
ffffffff81f96828 ffffffff813fb4a0 ffff88003b6eadc0 ffff88003c107738
|
||||||
|
Call Trace:
|
||||||
|
[< inline >] __dump_stack lib/dump_stack.c:15
|
||||||
|
[<ffffffff81f96aba>] dump_stack+0x292/0x398 lib/dump_stack.c:51
|
||||||
|
[<ffffffff817e4dec>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159
|
||||||
|
[< inline >] print_address_description mm/kasan/report.c:197
|
||||||
|
[<ffffffff817e5080>] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286
|
||||||
|
[<ffffffff817e5705>] kasan_report+0x35/0x40 mm/kasan/report.c:306
|
||||||
|
[< inline >] check_memory_region_inline mm/kasan/kasan.c:308
|
||||||
|
[<ffffffff817e3fb9>] check_memory_region+0x139/0x190 mm/kasan/kasan.c:315
|
||||||
|
[<ffffffff817e4044>] kasan_check_write+0x14/0x20 mm/kasan/kasan.c:326
|
||||||
|
[< inline >] copy_from_user arch/x86/include/asm/uaccess.h:689
|
||||||
|
[< inline >] ep0_write drivers/usb/gadget/legacy/inode.c:1135
|
||||||
|
[<ffffffff83228caf>] dev_config+0x86f/0x1190 drivers/usb/gadget/legacy/inode.c:1759
|
||||||
|
[<ffffffff817fdd55>] __vfs_write+0x5d5/0x760 fs/read_write.c:510
|
||||||
|
[<ffffffff817ff650>] vfs_write+0x170/0x4e0 fs/read_write.c:560
|
||||||
|
[< inline >] SYSC_write fs/read_write.c:607
|
||||||
|
[<ffffffff81803a5b>] SyS_write+0xfb/0x230 fs/read_write.c:599
|
||||||
|
[<ffffffff84f47ec1>] entry_SYSCALL_64_fastpath+0x1f/0xc2
|
||||||
|
|
||||||
|
Indeed, there is a comment saying that the value of len is restricted
|
||||||
|
to a 16-bit integer, but the code doesn't actually do this.
|
||||||
|
|
||||||
|
This patch fixes the warning. It replaces the comment with a
|
||||||
|
computation that forces the amount of data copied from the user in
|
||||||
|
ep0_write() to be no larger than the wLength size for the control
|
||||||
|
transfer, which is a 16-bit quantity.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index 48f1409b438ad..01ed3bc0c3c8e 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -1126,7 +1126,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
/* data and/or status stage for control request */
|
||||||
|
} else if (dev->state == STATE_DEV_SETUP) {
|
||||||
|
|
||||||
|
- /* IN DATA+STATUS caller makes len <= wLength */
|
||||||
|
+ len = min_t(size_t, len, dev->setup_wLength);
|
||||||
|
if (dev->setup_in) {
|
||||||
|
retval = setup_req (dev->gadget->ep0, dev->req, len);
|
||||||
|
if (retval == 0) {
|
64
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0008.patch
Normal file
64
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0008.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
From bcdbeb844773333d2d1c08004f3b3e25921040e5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Wed, 14 Dec 2016 14:55:56 -0500
|
||||||
|
Subject: [PATCH] USB: dummy-hcd: fix bug in stop_activity (handle ep0)
|
||||||
|
|
||||||
|
The stop_activity() routine in dummy-hcd is supposed to unlink all
|
||||||
|
active requests for every endpoint, among other things. But it
|
||||||
|
doesn't handle ep0. As a result, fuzz testing can generate a WARNING
|
||||||
|
like the following:
|
||||||
|
|
||||||
|
WARNING: CPU: 0 PID: 4410 at drivers/usb/gadget/udc/dummy_hcd.c:672 dummy_free_request+0x153/0x170
|
||||||
|
Modules linked in:
|
||||||
|
CPU: 0 PID: 4410 Comm: syz-executor Not tainted 4.9.0-rc7+ #32
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
ffff88006a64ed10 ffffffff81f96b8a ffffffff41b58ab3 1ffff1000d4c9d35
|
||||||
|
ffffed000d4c9d2d ffff880065f8ac00 0000000041b58ab3 ffffffff8598b510
|
||||||
|
ffffffff81f968f8 0000000041b58ab3 ffffffff859410e0 ffffffff813f0590
|
||||||
|
Call Trace:
|
||||||
|
[< inline >] __dump_stack lib/dump_stack.c:15
|
||||||
|
[<ffffffff81f96b8a>] dump_stack+0x292/0x398 lib/dump_stack.c:51
|
||||||
|
[<ffffffff812b808f>] __warn+0x19f/0x1e0 kernel/panic.c:550
|
||||||
|
[<ffffffff812b831c>] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585
|
||||||
|
[<ffffffff830fcb13>] dummy_free_request+0x153/0x170 drivers/usb/gadget/udc/dummy_hcd.c:672
|
||||||
|
[<ffffffff830ed1b0>] usb_ep_free_request+0xc0/0x420 drivers/usb/gadget/udc/core.c:195
|
||||||
|
[<ffffffff83225031>] gadgetfs_unbind+0x131/0x190 drivers/usb/gadget/legacy/inode.c:1612
|
||||||
|
[<ffffffff830ebd8f>] usb_gadget_remove_driver+0x10f/0x2b0 drivers/usb/gadget/udc/core.c:1228
|
||||||
|
[<ffffffff830ec084>] usb_gadget_unregister_driver+0x154/0x240 drivers/usb/gadget/udc/core.c:1357
|
||||||
|
|
||||||
|
This patch fixes the problem by iterating over all the endpoints in
|
||||||
|
the driver's ep array instead of iterating over the gadget's ep_list,
|
||||||
|
which explicitly leaves out ep0.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/udc/dummy_hcd.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
index 02b14e91ae6c5..c60abe3a68f9c 100644
|
||||||
|
--- a/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
|
||||||
|
@@ -330,7 +330,7 @@ static void nuke(struct dummy *dum, struct dummy_ep *ep)
|
||||||
|
/* caller must hold lock */
|
||||||
|
static void stop_activity(struct dummy *dum)
|
||||||
|
{
|
||||||
|
- struct dummy_ep *ep;
|
||||||
|
+ int i;
|
||||||
|
|
||||||
|
/* prevent any more requests */
|
||||||
|
dum->address = 0;
|
||||||
|
@@ -338,8 +338,8 @@ static void stop_activity(struct dummy *dum)
|
||||||
|
/* The timer is left running so that outstanding URBs can fail */
|
||||||
|
|
||||||
|
/* nuke any pending requests first, so driver i/o is quiesced */
|
||||||
|
- list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list)
|
||||||
|
- nuke(dum, ep);
|
||||||
|
+ for (i = 0; i < DUMMY_ENDPOINTS; ++i)
|
||||||
|
+ nuke(dum, &dum->ep[i]);
|
||||||
|
|
||||||
|
/* driver now does any non-usb quiescing necessary */
|
||||||
|
}
|
65
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0009.patch
Normal file
65
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0009.patch
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
From 1c069b057dcf64fada952eaa868d35f02bb0cfc2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Fri, 9 Dec 2016 15:24:24 -0500
|
||||||
|
Subject: [PATCH] USB: gadgetfs: fix checks of wTotalLength in config
|
||||||
|
descriptors
|
||||||
|
|
||||||
|
Andrey Konovalov's fuzz testing of gadgetfs showed that we should
|
||||||
|
improve the driver's checks for valid configuration descriptors passed
|
||||||
|
in by the user. In particular, the driver needs to verify that the
|
||||||
|
wTotalLength value in the descriptor is not too short (smaller
|
||||||
|
than USB_DT_CONFIG_SIZE). And the check for whether wTotalLength is
|
||||||
|
too large has to be changed, because the driver assumes there is
|
||||||
|
always enough room remaining in the buffer to hold a device descriptor
|
||||||
|
(at least USB_DT_DEVICE_SIZE bytes).
|
||||||
|
|
||||||
|
This patch adds the additional check and fixes the existing check. It
|
||||||
|
may do a little more than strictly necessary, but one extra check
|
||||||
|
won't hurt.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
CC: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 10 +++++++---
|
||||||
|
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index f1ca339426073..08e5ecc050795 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -1734,10 +1734,12 @@ static struct usb_gadget_driver gadgetfs_driver = {
|
||||||
|
* such as configuration notifications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static int is_valid_config (struct usb_config_descriptor *config)
|
||||||
|
+static int is_valid_config(struct usb_config_descriptor *config,
|
||||||
|
+ unsigned int total)
|
||||||
|
{
|
||||||
|
return config->bDescriptorType == USB_DT_CONFIG
|
||||||
|
&& config->bLength == USB_DT_CONFIG_SIZE
|
||||||
|
+ && total >= USB_DT_CONFIG_SIZE
|
||||||
|
&& config->bConfigurationValue != 0
|
||||||
|
&& (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0
|
||||||
|
&& (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0;
|
||||||
|
@@ -1787,7 +1789,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
/* full or low speed config */
|
||||||
|
dev->config = (void *) kbuf;
|
||||||
|
total = le16_to_cpu(dev->config->wTotalLength);
|
||||||
|
- if (!is_valid_config (dev->config) || total >= length)
|
||||||
|
+ if (!is_valid_config(dev->config, total) ||
|
||||||
|
+ total > length - USB_DT_DEVICE_SIZE)
|
||||||
|
goto fail;
|
||||||
|
kbuf += total;
|
||||||
|
length -= total;
|
||||||
|
@@ -1796,7 +1799,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
if (kbuf [1] == USB_DT_CONFIG) {
|
||||||
|
dev->hs_config = (void *) kbuf;
|
||||||
|
total = le16_to_cpu(dev->hs_config->wTotalLength);
|
||||||
|
- if (!is_valid_config (dev->hs_config) || total >= length)
|
||||||
|
+ if (!is_valid_config(dev->hs_config, total) ||
|
||||||
|
+ total > length - USB_DT_DEVICE_SIZE)
|
||||||
|
goto fail;
|
||||||
|
kbuf += total;
|
||||||
|
length -= total;
|
71
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0010.patch
Normal file
71
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0010.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From add333a81a16abbd4f106266a2553677a165725f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Fri, 9 Dec 2016 15:18:43 -0500
|
||||||
|
Subject: [PATCH] USB: gadgetfs: fix use-after-free bug
|
||||||
|
|
||||||
|
Andrey Konovalov reports that fuzz testing with syzkaller causes a
|
||||||
|
KASAN use-after-free bug report in gadgetfs:
|
||||||
|
|
||||||
|
BUG: KASAN: use-after-free in gadgetfs_setup+0x208a/0x20e0 at addr ffff88003dfe5bf2
|
||||||
|
Read of size 2 by task syz-executor0/22994
|
||||||
|
CPU: 3 PID: 22994 Comm: syz-executor0 Not tainted 4.9.0-rc7+ #16
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
ffff88006df06a18 ffffffff81f96aba ffffffffe0528500 1ffff1000dbe0cd6
|
||||||
|
ffffed000dbe0cce ffff88006df068f0 0000000041b58ab3 ffffffff8598b4c8
|
||||||
|
ffffffff81f96828 1ffff1000dbe0ccd ffff88006df06708 ffff88006df06748
|
||||||
|
Call Trace:
|
||||||
|
<IRQ> [ 201.343209] [< inline >] __dump_stack lib/dump_stack.c:15
|
||||||
|
<IRQ> [ 201.343209] [<ffffffff81f96aba>] dump_stack+0x292/0x398 lib/dump_stack.c:51
|
||||||
|
[<ffffffff817e4dec>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159
|
||||||
|
[< inline >] print_address_description mm/kasan/report.c:197
|
||||||
|
[<ffffffff817e5080>] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286
|
||||||
|
[< inline >] kasan_report mm/kasan/report.c:306
|
||||||
|
[<ffffffff817e562a>] __asan_report_load_n_noabort+0x3a/0x40 mm/kasan/report.c:337
|
||||||
|
[< inline >] config_buf drivers/usb/gadget/legacy/inode.c:1298
|
||||||
|
[<ffffffff8322c8fa>] gadgetfs_setup+0x208a/0x20e0 drivers/usb/gadget/legacy/inode.c:1368
|
||||||
|
[<ffffffff830fdcd0>] dummy_timer+0x11f0/0x36d0 drivers/usb/gadget/udc/dummy_hcd.c:1858
|
||||||
|
[<ffffffff814807c1>] call_timer_fn+0x241/0x800 kernel/time/timer.c:1308
|
||||||
|
[< inline >] expire_timers kernel/time/timer.c:1348
|
||||||
|
[<ffffffff81482de6>] __run_timers+0xa06/0xec0 kernel/time/timer.c:1641
|
||||||
|
[<ffffffff814832c1>] run_timer_softirq+0x21/0x80 kernel/time/timer.c:1654
|
||||||
|
[<ffffffff84f4af8b>] __do_softirq+0x2fb/0xb63 kernel/softirq.c:284
|
||||||
|
|
||||||
|
The cause of the bug is subtle. The dev_config() routine gets called
|
||||||
|
twice by the fuzzer. The first time, the user data contains both a
|
||||||
|
full-speed configuration descriptor and a high-speed config
|
||||||
|
descriptor, causing dev->hs_config to be set. But it also contains an
|
||||||
|
invalid device descriptor, so the buffer containing the descriptors is
|
||||||
|
deallocated and dev_config() returns an error.
|
||||||
|
|
||||||
|
The second time dev_config() is called, the user data contains only a
|
||||||
|
full-speed config descriptor. But dev->hs_config still has the stale
|
||||||
|
pointer remaining from the first call, causing the routine to think
|
||||||
|
that there is a valid high-speed config. Later on, when the driver
|
||||||
|
dereferences the stale pointer to copy that descriptor, we get a
|
||||||
|
use-after-free access.
|
||||||
|
|
||||||
|
The fix is simple: Clear dev->hs_config if the passed-in data does not
|
||||||
|
contain a high-speed config descriptor.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index 01ed3bc0c3c8e..f1ca339426073 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -1800,6 +1800,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
goto fail;
|
||||||
|
kbuf += total;
|
||||||
|
length -= total;
|
||||||
|
+ } else {
|
||||||
|
+ dev->hs_config = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* could support multiple configs, using another encoding! */
|
129
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0011.patch
Normal file
129
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0011.patch
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
From 7b01738112608ce47083178ae2b9ebadf02d32cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Felix=20H=C3=A4dicke?= <felixhaedicke@web.de>
|
||||||
|
Date: Thu, 29 Dec 2016 23:02:11 +0100
|
||||||
|
Subject: [PATCH] usb: gadget: udc: core: fix return code of
|
||||||
|
usb_gadget_probe_driver()
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This fixes a regression which was introduced by commit f1bddbb, by
|
||||||
|
reverting a small fragment of commit 855ed04.
|
||||||
|
|
||||||
|
If the following conditions were met, usb_gadget_probe_driver() returned
|
||||||
|
0, although the call was unsuccessful:
|
||||||
|
1. A particular UDC was specified by thge gadget driver (using member
|
||||||
|
"udc_name" of struct usb_gadget_driver).
|
||||||
|
2. The UDC with this name is available.
|
||||||
|
3. Another gadget driver is already bound to this gadget.
|
||||||
|
4. The gadget driver has the "match_existing_only" flag set.
|
||||||
|
In this case, the return code variable "ret" is set to 0, the return
|
||||||
|
code of a strcmp() call (to check for the second condition).
|
||||||
|
|
||||||
|
This also fixes an oops which could occur in the following scenario:
|
||||||
|
1. Two usb gadget instances were configured using configfs.
|
||||||
|
2. The first gadget configuration was bound to a UDC (using the configfs
|
||||||
|
attribute "UDC").
|
||||||
|
3. It was tried to bind the second gadget configuration to the same UDC
|
||||||
|
in the same way. This operation was then wrongly reported as being
|
||||||
|
successful.
|
||||||
|
4. The second gadget configuration's "UDC" attribute is cleared, to
|
||||||
|
unbind the (not really bound) second gadget configuration from the UDC.
|
||||||
|
|
||||||
|
<BUG: unable to handle kernel NULL pointer dereference
|
||||||
|
at (null)
|
||||||
|
IP: [<ffffffff94f5e5e9>] __list_del_entry+0x29/0xc0
|
||||||
|
PGD 41b4c5067
|
||||||
|
PUD 41a598067
|
||||||
|
PMD 0
|
||||||
|
|
||||||
|
Oops: 0000 [#1] SMP
|
||||||
|
Modules linked in: cdc_acm usb_f_fs usb_f_serial
|
||||||
|
usb_f_acm u_serial libcomposite configfs dummy_hcd bnep intel_rapl
|
||||||
|
x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm
|
||||||
|
snd_hda_codec_hdmi irqbypass crct10dif_pclmul crc32_pclmul
|
||||||
|
ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper
|
||||||
|
ablk_helper cryptd snd_hda_codec_realtek snd_hda_codec_generic serio_raw
|
||||||
|
uvcvideo videobuf2_vmalloc btusb snd_usb_audio snd_hda_intel
|
||||||
|
videobuf2_memops btrtl snd_hda_codec snd_hda_core snd_usbmidi_lib btbcm
|
||||||
|
videobuf2_v4l2 btintel snd_hwdep videobuf2_core snd_seq_midi bluetooth
|
||||||
|
snd_seq_midi_event videodev xpad efi_pstore snd_pcm_oss rfkill joydev
|
||||||
|
media crc16 ff_memless snd_mixer_oss snd_rawmidi nls_ascii snd_pcm
|
||||||
|
snd_seq snd_seq_device nls_cp437 mei_me snd_timer vfat sg udc_core
|
||||||
|
lpc_ich fat
|
||||||
|
efivars mfd_core mei snd soundcore battery nuvoton_cir rc_core evdev
|
||||||
|
intel_smartconnect ie31200_edac edac_core shpchp tpm_tis tpm_tis_core
|
||||||
|
tpm parport_pc ppdev lp parport efivarfs autofs4 btrfs xor raid6_pq
|
||||||
|
hid_logitech_hidpp hid_logitech_dj hid_generic usbhid hid uas
|
||||||
|
usb_storage sr_mod cdrom sd_mod ahci libahci nouveau i915 crc32c_intel
|
||||||
|
i2c_algo_bit psmouse ttm xhci_pci libata scsi_mod ehci_pci
|
||||||
|
drm_kms_helper xhci_hcd ehci_hcd r8169 mii usbcore drm nvme nvme_core
|
||||||
|
fjes button [last unloaded: net2280]
|
||||||
|
CPU: 5 PID: 829 Comm: bash Not tainted 4.9.0-rc7 #1
|
||||||
|
Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./Z77
|
||||||
|
Extreme3, BIOS P1.50 07/11/2013
|
||||||
|
task: ffff880419ce4040 task.stack: ffffc90002ed4000
|
||||||
|
RIP: 0010:[<ffffffff94f5e5e9>] [<ffffffff94f5e5e9>]
|
||||||
|
__list_del_entry+0x29/0xc0
|
||||||
|
RSP: 0018:ffffc90002ed7d68 EFLAGS: 00010207
|
||||||
|
RAX: 0000000000000000 RBX: ffff88041787ec30 RCX: dead000000000200
|
||||||
|
RDX: 0000000000000000 RSI: ffff880417482002 RDI: ffff88041787ec30
|
||||||
|
RBP: ffffc90002ed7d68 R08: 0000000000000000 R09: 0000000000000010
|
||||||
|
R10: 0000000000000000 R11: ffff880419ce4040 R12: ffff88041787eb68
|
||||||
|
R13: ffff88041787eaa8 R14: ffff88041560a2c0 R15: 0000000000000001
|
||||||
|
FS: 00007fe4e49b8700(0000) GS:ffff88042f340000(0000)
|
||||||
|
knlGS:0000000000000000
|
||||||
|
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
CR2: 0000000000000000 CR3: 000000041b4c4000 CR4: 00000000001406e0
|
||||||
|
Stack:
|
||||||
|
ffffc90002ed7d80 ffffffff94f5e68d ffffffffc0ae5ef0 ffffc90002ed7da0
|
||||||
|
ffffffffc0ae22aa ffff88041787e800 ffff88041787e800 ffffc90002ed7dc0
|
||||||
|
ffffffffc0d7a727 ffffffff952273fa ffff88041aba5760 ffffc90002ed7df8
|
||||||
|
Call Trace:
|
||||||
|
[<ffffffff94f5e68d>] list_del+0xd/0x30
|
||||||
|
[<ffffffffc0ae22aa>] usb_gadget_unregister_driver+0xaa/0xc0 [udc_core]
|
||||||
|
[<ffffffffc0d7a727>] unregister_gadget+0x27/0x60 [libcomposite]
|
||||||
|
[<ffffffff952273fa>] ? mutex_lock+0x1a/0x30
|
||||||
|
[<ffffffffc0d7a9b8>] gadget_dev_desc_UDC_store+0x88/0xe0 [libcomposite]
|
||||||
|
[<ffffffffc0af8aa0>] configfs_write_file+0xa0/0x100 [configfs]
|
||||||
|
[<ffffffff94e10d27>] __vfs_write+0x37/0x160
|
||||||
|
[<ffffffff94e31430>] ? __fd_install+0x30/0xd0
|
||||||
|
[<ffffffff95229dae>] ? _raw_spin_unlock+0xe/0x10
|
||||||
|
[<ffffffff94e11458>] vfs_write+0xb8/0x1b0
|
||||||
|
[<ffffffff94e128f8>] SyS_write+0x58/0xc0
|
||||||
|
[<ffffffff94e31594>] ? __close_fd+0x94/0xc0
|
||||||
|
[<ffffffff9522a0fb>] entry_SYSCALL_64_fastpath+0x1e/0xad
|
||||||
|
Code: 66 90 55 48 8b 07 48 b9 00 01 00 00 00 00 ad de 48 8b 57 08 48 89
|
||||||
|
e5 48 39 c8 74 29 48 b9 00 02 00 00 00 00 ad de 48 39 ca 74 3a <4c> 8b
|
||||||
|
02 4c 39 c7 75 52 4c 8b 40 08 4c 39 c7 75 66 48 89 50 08
|
||||||
|
RIP [<ffffffff94f5e5e9>] __list_del_entry+0x29/0xc0
|
||||||
|
RSP <ffffc90002ed7d68>
|
||||||
|
CR2: 0000000000000000
|
||||||
|
---[ end trace 99fc090ab3ff6cbc ]---
|
||||||
|
|
||||||
|
Fixes: f1bddbb ("usb: gadget: Fix binding to UDC via configfs
|
||||||
|
interface")
|
||||||
|
Signed-off-by: Felix Hädicke <felixhaedicke@web.de>
|
||||||
|
Tested-by: Krzysztof Opasiak <k.opasiak@samsung.com>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/udc/core.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
|
||||||
|
index 9483489080f66..0402177f93cdd 100644
|
||||||
|
--- a/drivers/usb/gadget/udc/core.c
|
||||||
|
+++ b/drivers/usb/gadget/udc/core.c
|
||||||
|
@@ -1317,7 +1317,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
|
||||||
|
if (!ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- if (!ret && !udc->driver)
|
||||||
|
+ if (ret)
|
||||||
|
+ ret = -ENODEV;
|
||||||
|
+ else if (udc->driver)
|
||||||
|
+ ret = -EBUSY;
|
||||||
|
+ else
|
||||||
|
goto found;
|
||||||
|
} else {
|
||||||
|
list_for_each_entry(udc, &udc_list, list) {
|
35
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0012.patch
Normal file
35
Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0012.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 0994b0a257557e18ee8f0b7c5f0f73fe2b54eec1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Date: Tue, 6 Dec 2016 08:36:29 +0100
|
||||||
|
Subject: [PATCH] usb: gadgetfs: restrict upper bound on device configuration
|
||||||
|
size
|
||||||
|
|
||||||
|
Andrey Konovalov reported that we were not properly checking the upper
|
||||||
|
limit before of a device configuration size before calling
|
||||||
|
memdup_user(), which could cause some problems.
|
||||||
|
|
||||||
|
So set the upper limit to PAGE_SIZE * 4, which should be good enough for
|
||||||
|
all devices.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: stable <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/gadget/legacy/inode.c | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
index e8f4102d19df5..48f1409b438ad 100644
|
||||||
|
--- a/drivers/usb/gadget/legacy/inode.c
|
||||||
|
+++ b/drivers/usb/gadget/legacy/inode.c
|
||||||
|
@@ -1762,7 +1762,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|
||||||
|
}
|
||||||
|
spin_unlock_irq(&dev->lock);
|
||||||
|
|
||||||
|
- if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4))
|
||||||
|
+ if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) ||
|
||||||
|
+ (len > PAGE_SIZE * 4))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* we might need to change message format someday */
|
33
Patches/Linux_CVEs/CVE-2017-16525/ANY/0001.patch
Normal file
33
Patches/Linux_CVEs/CVE-2017-16525/ANY/0001.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From bd998c2e0df0469707503023d50d46cf0b10c787 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Johan Hovold <johan@kernel.org>
|
||||||
|
Date: Wed, 4 Oct 2017 11:01:12 +0200
|
||||||
|
Subject: [PATCH] USB: serial: console: fix use-after-free on disconnect
|
||||||
|
|
||||||
|
A clean-up patch removing two redundant NULL-checks from the console
|
||||||
|
disconnect handler inadvertently also removed a third check. This could
|
||||||
|
lead to the struct usb_serial being prematurely freed by the console
|
||||||
|
code when a driver accepts but does not register any ports for an
|
||||||
|
interface which also lacks endpoint descriptors.
|
||||||
|
|
||||||
|
Fixes: 0e517c93dc02 ("USB: serial: console: clean up sanity checks")
|
||||||
|
Cc: stable <stable@vger.kernel.org> # 4.11
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/usb/serial/console.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
|
||||||
|
index fdf89800ebc3f..ed8ba3ef5c794 100644
|
||||||
|
--- a/drivers/usb/serial/console.c
|
||||||
|
+++ b/drivers/usb/serial/console.c
|
||||||
|
@@ -265,7 +265,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);
|
||||||
|
}
|
29
Patches/Linux_CVEs/CVE-2017-16525/ANY/0002.patch
Normal file
29
Patches/Linux_CVEs/CVE-2017-16525/ANY/0002.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From 299d7572e46f98534033a9e65973f13ad1ce9047 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Johan Hovold <johan@kernel.org>
|
||||||
|
Date: Wed, 4 Oct 2017 11:01:13 +0200
|
||||||
|
Subject: [PATCH] USB: serial: console: fix use-after-free after failed setup
|
||||||
|
|
||||||
|
Make sure to reset the USB-console port pointer when console setup fails
|
||||||
|
in order to avoid having the struct usb_serial be prematurely freed by
|
||||||
|
the console code when the device is later disconnected.
|
||||||
|
|
||||||
|
Fixes: 73e487fdb75f ("[PATCH] USB console: fix disconnection issues")
|
||||||
|
Cc: stable <stable@vger.kernel.org> # 2.6.18
|
||||||
|
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/usb/serial/console.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
|
||||||
|
index ed8ba3ef5c794..43a862a90a775 100644
|
||||||
|
--- a/drivers/usb/serial/console.c
|
||||||
|
+++ b/drivers/usb/serial/console.c
|
||||||
|
@@ -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);
|
51
Patches/Linux_CVEs/CVE-2017-16526/ANY/0001.patch
Normal file
51
Patches/Linux_CVEs/CVE-2017-16526/ANY/0001.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From bbf26183b7a6236ba602f4d6a2f7cade35bba043 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Date: Thu, 14 Sep 2017 14:30:55 +0200
|
||||||
|
Subject: [PATCH] uwb: properly check kthread_run return value
|
||||||
|
|
||||||
|
uwbd_start() calls kthread_run() and checks that the return value is
|
||||||
|
not NULL. But the return value is not NULL in case kthread_run() fails,
|
||||||
|
it takes the form of ERR_PTR(-EINTR).
|
||||||
|
|
||||||
|
Use IS_ERR() instead.
|
||||||
|
|
||||||
|
Also add a check to uwbd_stop().
|
||||||
|
|
||||||
|
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: stable <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/uwb/uwbd.c | 12 ++++++++----
|
||||||
|
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
|
||||||
|
index 01c20a260a8b3..39dd4ef53c779 100644
|
||||||
|
--- a/drivers/uwb/uwbd.c
|
||||||
|
+++ b/drivers/uwb/uwbd.c
|
||||||
|
@@ -302,18 +302,22 @@ static int uwbd(void *param)
|
||||||
|
/** Start the UWB daemon */
|
||||||
|
void uwbd_start(struct uwb_rc *rc)
|
||||||
|
{
|
||||||
|
- rc->uwbd.task = kthread_run(uwbd, rc, "uwbd");
|
||||||
|
- if (rc->uwbd.task == NULL)
|
||||||
|
+ struct task_struct *task = kthread_run(uwbd, rc, "uwbd");
|
||||||
|
+ if (IS_ERR(task)) {
|
||||||
|
+ rc->uwbd.task = NULL;
|
||||||
|
printk(KERN_ERR "UWB: Cannot start management daemon; "
|
||||||
|
"UWB won't work\n");
|
||||||
|
- else
|
||||||
|
+ } else {
|
||||||
|
+ rc->uwbd.task = task;
|
||||||
|
rc->uwbd.pid = rc->uwbd.task->pid;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop the UWB daemon and free any unprocessed events */
|
||||||
|
void uwbd_stop(struct uwb_rc *rc)
|
||||||
|
{
|
||||||
|
- kthread_stop(rc->uwbd.task);
|
||||||
|
+ if (rc->uwbd.task)
|
||||||
|
+ kthread_stop(rc->uwbd.task);
|
||||||
|
uwbd_flush(rc);
|
||||||
|
}
|
||||||
|
|
116
Patches/Linux_CVEs/CVE-2017-16527/ANY/0001.patch
Normal file
116
Patches/Linux_CVEs/CVE-2017-16527/ANY/0001.patch
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
From 124751d5e63c823092060074bd0abaae61aaa9c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takashi Iwai <tiwai@suse.de>
|
||||||
|
Date: Tue, 10 Oct 2017 14:10:32 +0200
|
||||||
|
Subject: [PATCH] ALSA: usb-audio: Kill stray URB at exiting
|
||||||
|
|
||||||
|
USB-audio driver may leave a stray URB for the mixer interrupt when it
|
||||||
|
exits by some error during probe. This leads to a use-after-free
|
||||||
|
error as spotted by syzkaller like:
|
||||||
|
==================================================================
|
||||||
|
BUG: KASAN: use-after-free in snd_usb_mixer_interrupt+0x604/0x6f0
|
||||||
|
Call Trace:
|
||||||
|
<IRQ>
|
||||||
|
__dump_stack lib/dump_stack.c:16
|
||||||
|
dump_stack+0x292/0x395 lib/dump_stack.c:52
|
||||||
|
print_address_description+0x78/0x280 mm/kasan/report.c:252
|
||||||
|
kasan_report_error mm/kasan/report.c:351
|
||||||
|
kasan_report+0x23d/0x350 mm/kasan/report.c:409
|
||||||
|
__asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:430
|
||||||
|
snd_usb_mixer_interrupt+0x604/0x6f0 sound/usb/mixer.c:2490
|
||||||
|
__usb_hcd_giveback_urb+0x2e0/0x650 drivers/usb/core/hcd.c:1779
|
||||||
|
....
|
||||||
|
|
||||||
|
Allocated by task 1484:
|
||||||
|
save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
|
||||||
|
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
|
||||||
|
set_track mm/kasan/kasan.c:459
|
||||||
|
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
|
||||||
|
kmem_cache_alloc_trace+0x11e/0x2d0 mm/slub.c:2772
|
||||||
|
kmalloc ./include/linux/slab.h:493
|
||||||
|
kzalloc ./include/linux/slab.h:666
|
||||||
|
snd_usb_create_mixer+0x145/0x1010 sound/usb/mixer.c:2540
|
||||||
|
create_standard_mixer_quirk+0x58/0x80 sound/usb/quirks.c:516
|
||||||
|
snd_usb_create_quirk+0x92/0x100 sound/usb/quirks.c:560
|
||||||
|
create_composite_quirk+0x1c4/0x3e0 sound/usb/quirks.c:59
|
||||||
|
snd_usb_create_quirk+0x92/0x100 sound/usb/quirks.c:560
|
||||||
|
usb_audio_probe+0x1040/0x2c10 sound/usb/card.c:618
|
||||||
|
....
|
||||||
|
|
||||||
|
Freed by task 1484:
|
||||||
|
save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
|
||||||
|
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
|
||||||
|
set_track mm/kasan/kasan.c:459
|
||||||
|
kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524
|
||||||
|
slab_free_hook mm/slub.c:1390
|
||||||
|
slab_free_freelist_hook mm/slub.c:1412
|
||||||
|
slab_free mm/slub.c:2988
|
||||||
|
kfree+0xf6/0x2f0 mm/slub.c:3919
|
||||||
|
snd_usb_mixer_free+0x11a/0x160 sound/usb/mixer.c:2244
|
||||||
|
snd_usb_mixer_dev_free+0x36/0x50 sound/usb/mixer.c:2250
|
||||||
|
__snd_device_free+0x1ff/0x380 sound/core/device.c:91
|
||||||
|
snd_device_free_all+0x8f/0xe0 sound/core/device.c:244
|
||||||
|
snd_card_do_free sound/core/init.c:461
|
||||||
|
release_card_device+0x47/0x170 sound/core/init.c:181
|
||||||
|
device_release+0x13f/0x210 drivers/base/core.c:814
|
||||||
|
....
|
||||||
|
|
||||||
|
Actually such a URB is killed properly at disconnection when the
|
||||||
|
device gets probed successfully, and what we need is to apply it for
|
||||||
|
the error-path, too.
|
||||||
|
|
||||||
|
In this patch, we apply snd_usb_mixer_disconnect() at releasing.
|
||||||
|
Also introduce a new flag, disconnected, to struct usb_mixer_interface
|
||||||
|
for not performing the disconnection procedure twice.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||||
|
---
|
||||||
|
sound/usb/mixer.c | 12 ++++++++++--
|
||||||
|
sound/usb/mixer.h | 2 ++
|
||||||
|
2 files changed, 12 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
|
||||||
|
index 9732edf77f860..91bc8f18791e4 100644
|
||||||
|
--- a/sound/usb/mixer.c
|
||||||
|
+++ b/sound/usb/mixer.c
|
||||||
|
@@ -2234,6 +2234,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
|
||||||
|
|
||||||
|
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
|
||||||
|
{
|
||||||
|
+ /* kill pending URBs */
|
||||||
|
+ snd_usb_mixer_disconnect(mixer);
|
||||||
|
+
|
||||||
|
kfree(mixer->id_elems);
|
||||||
|
if (mixer->urb) {
|
||||||
|
kfree(mixer->urb->transfer_buffer);
|
||||||
|
@@ -2584,8 +2587,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
|
||||||
|
|
||||||
|
void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer)
|
||||||
|
{
|
||||||
|
- usb_kill_urb(mixer->urb);
|
||||||
|
- usb_kill_urb(mixer->rc_urb);
|
||||||
|
+ if (mixer->disconnected)
|
||||||
|
+ return;
|
||||||
|
+ if (mixer->urb)
|
||||||
|
+ usb_kill_urb(mixer->urb);
|
||||||
|
+ if (mixer->rc_urb)
|
||||||
|
+ usb_kill_urb(mixer->rc_urb);
|
||||||
|
+ mixer->disconnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
|
||||||
|
index 2b4b067646ab0..545d99b09706b 100644
|
||||||
|
--- a/sound/usb/mixer.h
|
||||||
|
+++ b/sound/usb/mixer.h
|
||||||
|
@@ -22,6 +22,8 @@ struct usb_mixer_interface {
|
||||||
|
struct urb *rc_urb;
|
||||||
|
struct usb_ctrlrequest *rc_setup_packet;
|
||||||
|
u8 rc_buffer[6];
|
||||||
|
+
|
||||||
|
+ bool disconnected;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_CHANNELS 16 /* max logical channels */
|
76
Patches/Linux_CVEs/CVE-2017-16528/ANY/0001.patch
Normal file
76
Patches/Linux_CVEs/CVE-2017-16528/ANY/0001.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From fc27fe7e8deef2f37cba3f2be2d52b6ca5eb9d57 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takashi Iwai <tiwai@suse.de>
|
||||||
|
Date: Tue, 12 Sep 2017 12:41:20 +0200
|
||||||
|
Subject: [PATCH] ALSA: seq: Cancel pending autoload work at unbinding device
|
||||||
|
|
||||||
|
ALSA sequencer core has a mechanism to load the enumerated devices
|
||||||
|
automatically, and it's performed in an off-load work. This seems
|
||||||
|
causing some race when a sequencer is removed while the pending
|
||||||
|
autoload work is running. As syzkaller spotted, it may lead to some
|
||||||
|
use-after-free:
|
||||||
|
BUG: KASAN: use-after-free in snd_rawmidi_dev_seq_free+0x69/0x70
|
||||||
|
sound/core/rawmidi.c:1617
|
||||||
|
Write of size 8 at addr ffff88006c611d90 by task kworker/2:1/567
|
||||||
|
|
||||||
|
CPU: 2 PID: 567 Comm: kworker/2:1 Not tainted 4.13.0+ #29
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
Workqueue: events autoload_drivers
|
||||||
|
Call Trace:
|
||||||
|
__dump_stack lib/dump_stack.c:16 [inline]
|
||||||
|
dump_stack+0x192/0x22c lib/dump_stack.c:52
|
||||||
|
print_address_description+0x78/0x280 mm/kasan/report.c:252
|
||||||
|
kasan_report_error mm/kasan/report.c:351 [inline]
|
||||||
|
kasan_report+0x230/0x340 mm/kasan/report.c:409
|
||||||
|
__asan_report_store8_noabort+0x1c/0x20 mm/kasan/report.c:435
|
||||||
|
snd_rawmidi_dev_seq_free+0x69/0x70 sound/core/rawmidi.c:1617
|
||||||
|
snd_seq_dev_release+0x4f/0x70 sound/core/seq_device.c:192
|
||||||
|
device_release+0x13f/0x210 drivers/base/core.c:814
|
||||||
|
kobject_cleanup lib/kobject.c:648 [inline]
|
||||||
|
kobject_release lib/kobject.c:677 [inline]
|
||||||
|
kref_put include/linux/kref.h:70 [inline]
|
||||||
|
kobject_put+0x145/0x240 lib/kobject.c:694
|
||||||
|
put_device+0x25/0x30 drivers/base/core.c:1799
|
||||||
|
klist_devices_put+0x36/0x40 drivers/base/bus.c:827
|
||||||
|
klist_next+0x264/0x4a0 lib/klist.c:403
|
||||||
|
next_device drivers/base/bus.c:270 [inline]
|
||||||
|
bus_for_each_dev+0x17e/0x210 drivers/base/bus.c:312
|
||||||
|
autoload_drivers+0x3b/0x50 sound/core/seq_device.c:117
|
||||||
|
process_one_work+0x9fb/0x1570 kernel/workqueue.c:2097
|
||||||
|
worker_thread+0x1e4/0x1350 kernel/workqueue.c:2231
|
||||||
|
kthread+0x324/0x3f0 kernel/kthread.c:231
|
||||||
|
ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:425
|
||||||
|
|
||||||
|
The fix is simply to assure canceling the autoload work at removing
|
||||||
|
the device.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||||
|
---
|
||||||
|
sound/core/seq_device.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/sound/core/seq_device.c b/sound/core/seq_device.c
|
||||||
|
index c4acf17e9f5e5..e40a2cba5002a 100644
|
||||||
|
--- a/sound/core/seq_device.c
|
||||||
|
+++ b/sound/core/seq_device.c
|
||||||
|
@@ -148,8 +148,10 @@ void snd_seq_device_load_drivers(void)
|
||||||
|
flush_work(&autoload_work);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_seq_device_load_drivers);
|
||||||
|
+#define cancel_autoload_drivers() cancel_work_sync(&autoload_work)
|
||||||
|
#else
|
||||||
|
#define queue_autoload_drivers() /* NOP */
|
||||||
|
+#define cancel_autoload_drivers() /* NOP */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -159,6 +161,7 @@ static int snd_seq_device_dev_free(struct snd_device *device)
|
||||||
|
{
|
||||||
|
struct snd_seq_device *dev = device->device_data;
|
||||||
|
|
||||||
|
+ cancel_autoload_drivers();
|
||||||
|
put_device(&dev->dev);
|
||||||
|
return 0;
|
||||||
|
}
|
115
Patches/Linux_CVEs/CVE-2017-16529/ANY/0001.patch
Normal file
115
Patches/Linux_CVEs/CVE-2017-16529/ANY/0001.patch
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
From bfc81a8bc18e3c4ba0cbaa7666ff76be2f998991 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takashi Iwai <tiwai@suse.de>
|
||||||
|
Date: Fri, 22 Sep 2017 16:18:53 +0200
|
||||||
|
Subject: [PATCH] ALSA: usb-audio: Check out-of-bounds access by corrupted
|
||||||
|
buffer descriptor
|
||||||
|
|
||||||
|
When a USB-audio device receives a maliciously adjusted or corrupted
|
||||||
|
buffer descriptor, the USB-audio driver may access an out-of-bounce
|
||||||
|
value at its parser. This was detected by syzkaller, something like:
|
||||||
|
|
||||||
|
BUG: KASAN: slab-out-of-bounds in usb_audio_probe+0x27b2/0x2ab0
|
||||||
|
Read of size 1 at addr ffff88006b83a9e8 by task kworker/0:1/24
|
||||||
|
CPU: 0 PID: 24 Comm: kworker/0:1 Not tainted 4.14.0-rc1-42251-gebb2c2437d80 #224
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
Workqueue: usb_hub_wq hub_event
|
||||||
|
Call Trace:
|
||||||
|
__dump_stack lib/dump_stack.c:16
|
||||||
|
dump_stack+0x292/0x395 lib/dump_stack.c:52
|
||||||
|
print_address_description+0x78/0x280 mm/kasan/report.c:252
|
||||||
|
kasan_report_error mm/kasan/report.c:351
|
||||||
|
kasan_report+0x22f/0x340 mm/kasan/report.c:409
|
||||||
|
__asan_report_load1_noabort+0x19/0x20 mm/kasan/report.c:427
|
||||||
|
snd_usb_create_streams sound/usb/card.c:248
|
||||||
|
usb_audio_probe+0x27b2/0x2ab0 sound/usb/card.c:605
|
||||||
|
usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
|
||||||
|
really_probe drivers/base/dd.c:413
|
||||||
|
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
|
||||||
|
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
|
||||||
|
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
|
||||||
|
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
|
||||||
|
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
|
||||||
|
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
|
||||||
|
device_add+0xd0b/0x1660 drivers/base/core.c:1835
|
||||||
|
usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
|
||||||
|
generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
|
||||||
|
usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
|
||||||
|
really_probe drivers/base/dd.c:413
|
||||||
|
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
|
||||||
|
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
|
||||||
|
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
|
||||||
|
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
|
||||||
|
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
|
||||||
|
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
|
||||||
|
device_add+0xd0b/0x1660 drivers/base/core.c:1835
|
||||||
|
usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
|
||||||
|
hub_port_connect drivers/usb/core/hub.c:4903
|
||||||
|
hub_port_connect_change drivers/usb/core/hub.c:5009
|
||||||
|
port_event drivers/usb/core/hub.c:5115
|
||||||
|
hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
|
||||||
|
process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
|
||||||
|
worker_thread+0x221/0x1850 kernel/workqueue.c:2253
|
||||||
|
kthread+0x3a1/0x470 kernel/kthread.c:231
|
||||||
|
ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
|
||||||
|
|
||||||
|
This patch adds the checks of out-of-bounce accesses at appropriate
|
||||||
|
places and bails out when it goes out of the given buffer.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||||
|
---
|
||||||
|
sound/usb/card.c | 20 ++++++++++++++++++++
|
||||||
|
1 file changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/sound/usb/card.c b/sound/usb/card.c
|
||||||
|
index 3dc36d9135502..23d1d23aefec3 100644
|
||||||
|
--- a/sound/usb/card.c
|
||||||
|
+++ b/sound/usb/card.c
|
||||||
|
@@ -221,6 +221,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
|
||||||
|
struct usb_interface_descriptor *altsd;
|
||||||
|
void *control_header;
|
||||||
|
int i, protocol;
|
||||||
|
+ int rest_bytes;
|
||||||
|
|
||||||
|
/* find audiocontrol interface */
|
||||||
|
host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
|
||||||
|
@@ -235,6 +236,15 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
|
||||||
|
+ control_header;
|
||||||
|
+
|
||||||
|
+ /* just to be sure -- this shouldn't hit at all */
|
||||||
|
+ if (rest_bytes <= 0) {
|
||||||
|
+ dev_err(&dev->dev, "invalid control header\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
switch (protocol) {
|
||||||
|
default:
|
||||||
|
dev_warn(&dev->dev,
|
||||||
|
@@ -245,11 +255,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
|
||||||
|
case UAC_VERSION_1: {
|
||||||
|
struct uac1_ac_header_descriptor *h1 = control_header;
|
||||||
|
|
||||||
|
+ if (rest_bytes < sizeof(*h1)) {
|
||||||
|
+ dev_err(&dev->dev, "too short v1 buffer descriptor\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!h1->bInCollection) {
|
||||||
|
dev_info(&dev->dev, "skipping empty audio interface (v1)\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (rest_bytes < h1->bLength) {
|
||||||
|
+ dev_err(&dev->dev, "invalid buffer length (v1)\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
|
||||||
|
dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n");
|
||||||
|
return -EINVAL;
|
102
Patches/Linux_CVEs/CVE-2017-16530/ANY/0001.patch
Normal file
102
Patches/Linux_CVEs/CVE-2017-16530/ANY/0001.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From 786de92b3cb26012d3d0f00ee37adf14527f35c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Fri, 22 Sep 2017 11:56:49 -0400
|
||||||
|
Subject: [PATCH] USB: uas: fix bug in handling of alternate settings
|
||||||
|
|
||||||
|
The uas driver has a subtle bug in the way it handles alternate
|
||||||
|
settings. The uas_find_uas_alt_setting() routine returns an
|
||||||
|
altsetting value (the bAlternateSetting number in the descriptor), but
|
||||||
|
uas_use_uas_driver() then treats that value as an index to the
|
||||||
|
intf->altsetting array, which it isn't.
|
||||||
|
|
||||||
|
Normally this doesn't cause any problems because the various
|
||||||
|
alternate settings have bAlternateSetting values 0, 1, 2, ..., so the
|
||||||
|
value is equal to the index in the array. But this is not guaranteed,
|
||||||
|
and Andrey Konovalov used the syzkaller fuzzer with KASAN to get a
|
||||||
|
slab-out-of-bounds error by violating this assumption.
|
||||||
|
|
||||||
|
This patch fixes the bug by making uas_find_uas_alt_setting() return a
|
||||||
|
pointer to the altsetting entry rather than either the value or the
|
||||||
|
index. Pointers are less subject to misinterpretation.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: Oliver Neukum <oneukum@suse.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/storage/uas-detect.h | 15 ++++++++-------
|
||||||
|
drivers/usb/storage/uas.c | 10 +++++-----
|
||||||
|
2 files changed, 13 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h
|
||||||
|
index f58caa9e6a27e..a155cd02bce24 100644
|
||||||
|
--- a/drivers/usb/storage/uas-detect.h
|
||||||
|
+++ b/drivers/usb/storage/uas-detect.h
|
||||||
|
@@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_host_interface *intf)
|
||||||
|
intf->desc.bInterfaceProtocol == USB_PR_UAS);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int uas_find_uas_alt_setting(struct usb_interface *intf)
|
||||||
|
+static struct usb_host_interface *uas_find_uas_alt_setting(
|
||||||
|
+ struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(struct usb_interface *intf)
|
||||||
|
struct usb_host_interface *alt = &intf->altsetting[i];
|
||||||
|
|
||||||
|
if (uas_is_interface(alt))
|
||||||
|
- return alt->desc.bAlternateSetting;
|
||||||
|
+ return alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return -ENODEV;
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uas_find_endpoints(struct usb_host_interface *alt,
|
||||||
|
@@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb_interface *intf,
|
||||||
|
struct usb_device *udev = interface_to_usbdev(intf);
|
||||||
|
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
|
||||||
|
unsigned long flags = id->driver_info;
|
||||||
|
- int r, alt;
|
||||||
|
-
|
||||||
|
+ struct usb_host_interface *alt;
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
alt = uas_find_uas_alt_setting(intf);
|
||||||
|
- if (alt < 0)
|
||||||
|
+ if (!alt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- r = uas_find_endpoints(&intf->altsetting[alt], eps);
|
||||||
|
+ r = uas_find_endpoints(alt, eps);
|
||||||
|
if (r < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
|
||||||
|
index cfb1e3bbd4347..63cf981ed81cf 100644
|
||||||
|
--- a/drivers/usb/storage/uas.c
|
||||||
|
+++ b/drivers/usb/storage/uas.c
|
||||||
|
@@ -873,14 +873,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids);
|
||||||
|
static int uas_switch_interface(struct usb_device *udev,
|
||||||
|
struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
- int alt;
|
||||||
|
+ struct usb_host_interface *alt;
|
||||||
|
|
||||||
|
alt = uas_find_uas_alt_setting(intf);
|
||||||
|
- if (alt < 0)
|
||||||
|
- return alt;
|
||||||
|
+ if (!alt)
|
||||||
|
+ return -ENODEV;
|
||||||
|
|
||||||
|
- return usb_set_interface(udev,
|
||||||
|
- intf->altsetting[0].desc.bInterfaceNumber, alt);
|
||||||
|
+ return usb_set_interface(udev, alt->desc.bInterfaceNumber,
|
||||||
|
+ alt->desc.bAlternateSetting);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uas_configure_endpoints(struct uas_dev_info *devinfo)
|
67
Patches/Linux_CVEs/CVE-2017-16531/ANY/0001.patch
Normal file
67
Patches/Linux_CVEs/CVE-2017-16531/ANY/0001.patch
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
From bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Date: Tue, 19 Sep 2017 15:07:17 +0200
|
||||||
|
Subject: [PATCH] USB: fix out-of-bounds in usb_set_configuration
|
||||||
|
|
||||||
|
Andrey Konovalov reported a possible out-of-bounds problem for a USB interface
|
||||||
|
association descriptor. He writes:
|
||||||
|
It seems there's no proper size check of a USB_DT_INTERFACE_ASSOCIATION
|
||||||
|
descriptor. It's only checked that the size is >= 2 in
|
||||||
|
usb_parse_configuration(), so find_iad() might do out-of-bounds access
|
||||||
|
to intf_assoc->bInterfaceCount.
|
||||||
|
|
||||||
|
And he's right, we don't check for crazy descriptors of this type very well, so
|
||||||
|
resolve this problem. Yet another issue found by syzkaller...
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: stable <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/core/config.c | 14 +++++++++++---
|
||||||
|
include/uapi/linux/usb/ch9.h | 1 +
|
||||||
|
2 files changed, 12 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
|
||||||
|
index 854c8d66cfbef..68b54bd88d1eb 100644
|
||||||
|
--- a/drivers/usb/core/config.c
|
||||||
|
+++ b/drivers/usb/core/config.c
|
||||||
|
@@ -643,15 +643,23 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
|
||||||
|
|
||||||
|
} else if (header->bDescriptorType ==
|
||||||
|
USB_DT_INTERFACE_ASSOCIATION) {
|
||||||
|
+ struct usb_interface_assoc_descriptor *d;
|
||||||
|
+
|
||||||
|
+ d = (struct usb_interface_assoc_descriptor *)header;
|
||||||
|
+ if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) {
|
||||||
|
+ dev_warn(ddev,
|
||||||
|
+ "config %d has an invalid interface association descriptor of length %d, skipping\n",
|
||||||
|
+ cfgno, d->bLength);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (iad_num == USB_MAXIADS) {
|
||||||
|
dev_warn(ddev, "found more Interface "
|
||||||
|
"Association Descriptors "
|
||||||
|
"than allocated for in "
|
||||||
|
"configuration %d\n", cfgno);
|
||||||
|
} else {
|
||||||
|
- config->intf_assoc[iad_num] =
|
||||||
|
- (struct usb_interface_assoc_descriptor
|
||||||
|
- *)header;
|
||||||
|
+ config->intf_assoc[iad_num] = d;
|
||||||
|
iad_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
|
||||||
|
index ce1169af39d72..2a5d63040a0b0 100644
|
||||||
|
--- a/include/uapi/linux/usb/ch9.h
|
||||||
|
+++ b/include/uapi/linux/usb/ch9.h
|
||||||
|
@@ -780,6 +780,7 @@ struct usb_interface_assoc_descriptor {
|
||||||
|
__u8 iFunction;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
38
Patches/Linux_CVEs/CVE-2017-16532/ANY/0001.patch
Normal file
38
Patches/Linux_CVEs/CVE-2017-16532/ANY/0001.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 7c80f9e4a588f1925b07134bb2e3689335f6c6d8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Fri, 29 Sep 2017 10:54:24 -0400
|
||||||
|
Subject: [PATCH] usb: usbtest: fix NULL pointer dereference
|
||||||
|
|
||||||
|
If the usbtest driver encounters a device with an IN bulk endpoint but
|
||||||
|
no OUT bulk endpoint, it will try to dereference a NULL pointer
|
||||||
|
(out->desc.bEndpointAddress). The problem can be solved by adding a
|
||||||
|
missing test.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||||
|
---
|
||||||
|
drivers/usb/misc/usbtest.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
|
||||||
|
index 113e38bfe0ef9..b3fc602b2e247 100644
|
||||||
|
--- a/drivers/usb/misc/usbtest.c
|
||||||
|
+++ b/drivers/usb/misc/usbtest.c
|
||||||
|
@@ -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,
|
105
Patches/Linux_CVEs/CVE-2017-16533/ANY/0001.patch
Normal file
105
Patches/Linux_CVEs/CVE-2017-16533/ANY/0001.patch
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
From f043bfc98c193c284e2cd768fefabe18ac2fed9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jaejoong Kim <climbbb.kim@gmail.com>
|
||||||
|
Date: Thu, 28 Sep 2017 19:16:30 +0900
|
||||||
|
Subject: [PATCH] HID: usbhid: fix out-of-bounds bug
|
||||||
|
|
||||||
|
The hid descriptor identifies the length and type of subordinate
|
||||||
|
descriptors for a device. If the received hid descriptor is smaller than
|
||||||
|
the size of the struct hid_descriptor, it is possible to cause
|
||||||
|
out-of-bounds.
|
||||||
|
|
||||||
|
In addition, if bNumDescriptors of the hid descriptor have an incorrect
|
||||||
|
value, this can also cause out-of-bounds while approaching hdesc->desc[n].
|
||||||
|
|
||||||
|
So check the size of hid descriptor and bNumDescriptors.
|
||||||
|
|
||||||
|
BUG: KASAN: slab-out-of-bounds in usbhid_parse+0x9b1/0xa20
|
||||||
|
Read of size 1 at addr ffff88006c5f8edf by task kworker/1:2/1261
|
||||||
|
|
||||||
|
CPU: 1 PID: 1261 Comm: kworker/1:2 Not tainted
|
||||||
|
4.14.0-rc1-42251-gebb2c2437d80 #169
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
Workqueue: usb_hub_wq hub_event
|
||||||
|
Call Trace:
|
||||||
|
__dump_stack lib/dump_stack.c:16
|
||||||
|
dump_stack+0x292/0x395 lib/dump_stack.c:52
|
||||||
|
print_address_description+0x78/0x280 mm/kasan/report.c:252
|
||||||
|
kasan_report_error mm/kasan/report.c:351
|
||||||
|
kasan_report+0x22f/0x340 mm/kasan/report.c:409
|
||||||
|
__asan_report_load1_noabort+0x19/0x20 mm/kasan/report.c:427
|
||||||
|
usbhid_parse+0x9b1/0xa20 drivers/hid/usbhid/hid-core.c:1004
|
||||||
|
hid_add_device+0x16b/0xb30 drivers/hid/hid-core.c:2944
|
||||||
|
usbhid_probe+0xc28/0x1100 drivers/hid/usbhid/hid-core.c:1369
|
||||||
|
usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
|
||||||
|
really_probe drivers/base/dd.c:413
|
||||||
|
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
|
||||||
|
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
|
||||||
|
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
|
||||||
|
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
|
||||||
|
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
|
||||||
|
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
|
||||||
|
device_add+0xd0b/0x1660 drivers/base/core.c:1835
|
||||||
|
usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
|
||||||
|
generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
|
||||||
|
usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
|
||||||
|
really_probe drivers/base/dd.c:413
|
||||||
|
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
|
||||||
|
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
|
||||||
|
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
|
||||||
|
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
|
||||||
|
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
|
||||||
|
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
|
||||||
|
device_add+0xd0b/0x1660 drivers/base/core.c:1835
|
||||||
|
usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
|
||||||
|
hub_port_connect drivers/usb/core/hub.c:4903
|
||||||
|
hub_port_connect_change drivers/usb/core/hub.c:5009
|
||||||
|
port_event drivers/usb/core/hub.c:5115
|
||||||
|
hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
|
||||||
|
process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
|
||||||
|
worker_thread+0x221/0x1850 kernel/workqueue.c:2253
|
||||||
|
kthread+0x3a1/0x470 kernel/kthread.c:231
|
||||||
|
ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
|
||||||
|
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||||
|
---
|
||||||
|
drivers/hid/usbhid/hid-core.c | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
|
||||||
|
index 089bad8a9a21d..045b5da9b9928 100644
|
||||||
|
--- a/drivers/hid/usbhid/hid-core.c
|
||||||
|
+++ b/drivers/hid/usbhid/hid-core.c
|
||||||
|
@@ -975,6 +975,8 @@ static int usbhid_parse(struct hid_device *hid)
|
||||||
|
unsigned int rsize = 0;
|
||||||
|
char *rdesc;
|
||||||
|
int ret, n;
|
||||||
|
+ int num_descriptors;
|
||||||
|
+ size_t offset = offsetof(struct hid_descriptor, desc);
|
||||||
|
|
||||||
|
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
|
||||||
|
le16_to_cpu(dev->descriptor.idProduct));
|
||||||
|
@@ -997,10 +999,18 @@ static int usbhid_parse(struct hid_device *hid)
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (hdesc->bLength < sizeof(struct hid_descriptor)) {
|
||||||
|
+ dbg_hid("hid descriptor is too short\n");
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
hid->version = le16_to_cpu(hdesc->bcdHID);
|
||||||
|
hid->country = hdesc->bCountryCode;
|
||||||
|
|
||||||
|
- for (n = 0; n < hdesc->bNumDescriptors; n++)
|
||||||
|
+ num_descriptors = min_t(int, hdesc->bNumDescriptors,
|
||||||
|
+ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
|
||||||
|
+
|
||||||
|
+ for (n = 0; n < num_descriptors; n++)
|
||||||
|
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
|
||||||
|
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
|
||||||
|
|
37
Patches/Linux_CVEs/CVE-2017-16534/ANY/0001.patch
Normal file
37
Patches/Linux_CVEs/CVE-2017-16534/ANY/0001.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
From 2e1c42391ff2556387b3cb6308b24f6f65619feb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
Date: Thu, 21 Sep 2017 16:58:48 +0200
|
||||||
|
Subject: [PATCH] USB: core: harden cdc_parse_cdc_header
|
||||||
|
|
||||||
|
Andrey Konovalov reported a possible out-of-bounds problem for the
|
||||||
|
cdc_parse_cdc_header function. He writes:
|
||||||
|
It looks like cdc_parse_cdc_header() doesn't validate buflen
|
||||||
|
before accessing buffer[1], buffer[2] and so on. The only check
|
||||||
|
present is while (buflen > 0).
|
||||||
|
|
||||||
|
So fix this issue up by properly validating the buffer length matches
|
||||||
|
what the descriptor says it is.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: stable <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/core/message.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
|
||||||
|
index 4c38ea41ae969..371a07d874a37 100644
|
||||||
|
--- a/drivers/usb/core/message.c
|
||||||
|
+++ b/drivers/usb/core/message.c
|
||||||
|
@@ -2069,6 +2069,10 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr,
|
||||||
|
elength = 1;
|
||||||
|
goto next_desc;
|
||||||
|
}
|
||||||
|
+ if ((buflen < elength) || (elength < 3)) {
|
||||||
|
+ dev_err(&intf->dev, "invalid descriptor buffer length\n");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
if (buffer[1] != USB_DT_CS_INTERFACE) {
|
||||||
|
dev_err(&intf->dev, "skipping garbage\n");
|
||||||
|
goto next_desc;
|
43
Patches/Linux_CVEs/CVE-2017-16535/ANY/0001.patch
Normal file
43
Patches/Linux_CVEs/CVE-2017-16535/ANY/0001.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 1c0edc3633b56000e18d82fc241e3995ca18a69e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Wed, 18 Oct 2017 12:49:38 -0400
|
||||||
|
Subject: [PATCH] USB: core: fix out-of-bounds access bug in
|
||||||
|
usb_get_bos_descriptor()
|
||||||
|
|
||||||
|
Andrey used the syzkaller fuzzer to find an out-of-bounds memory
|
||||||
|
access in usb_get_bos_descriptor(). The code wasn't checking that the
|
||||||
|
next usb_dev_cap_header structure could fit into the remaining buffer
|
||||||
|
space.
|
||||||
|
|
||||||
|
This patch fixes the error and also reduces the bNumDeviceCaps field
|
||||||
|
in the header to match the actual number of capabilities found, in
|
||||||
|
cases where there are fewer than expected.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/core/config.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
|
||||||
|
index 68b54bd88d1eb..883549ee946cb 100644
|
||||||
|
--- a/drivers/usb/core/config.c
|
||||||
|
+++ b/drivers/usb/core/config.c
|
||||||
|
@@ -960,10 +960,12 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
buffer += length;
|
||||||
|
cap = (struct usb_dev_cap_header *)buffer;
|
||||||
|
- length = cap->bLength;
|
||||||
|
|
||||||
|
- if (total_len < length)
|
||||||
|
+ if (total_len < sizeof(*cap) || total_len < cap->bLength) {
|
||||||
|
+ dev->bos->desc->bNumDeviceCaps = i;
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
+ length = cap->bLength;
|
||||||
|
total_len -= length;
|
||||||
|
|
||||||
|
if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
|
61
Patches/Linux_CVEs/CVE-2017-16538/ANY/0001.patch
Normal file
61
Patches/Linux_CVEs/CVE-2017-16538/ANY/0001.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
|
||||||
|
index 5e320fa4a795..992f2011a6ba 100644
|
||||||
|
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
|
||||||
|
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
|
||||||
|
@@ -494,18 +494,23 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
|
||||||
|
|
||||||
|
static int lme2510_return_status(struct dvb_usb_device *d)
|
||||||
|
{
|
||||||
|
- int ret = 0;
|
||||||
|
+ int ret;
|
||||||
|
u8 *data;
|
||||||
|
|
||||||
|
- data = kzalloc(10, GFP_KERNEL);
|
||||||
|
+ data = kzalloc(6, GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
|
||||||
|
- 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
|
||||||
|
- info("Firmware Status: %x (%x)", ret , data[2]);
|
||||||
|
+ ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
|
||||||
|
+ 0x06, 0x80, 0x0302, 0x00,
|
||||||
|
+ data, 0x6, 200);
|
||||||
|
+ if (ret != 6)
|
||||||
|
+ ret = -EINVAL;
|
||||||
|
+ else
|
||||||
|
+ ret = data[2];
|
||||||
|
+
|
||||||
|
+ info("Firmware Status: %6ph", data);
|
||||||
|
|
||||||
|
- ret = (ret < 0) ? -ENODEV : data[2];
|
||||||
|
kfree(data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -1189,6 +1194,7 @@ static int lme2510_get_adapter_count(struct dvb_usb_device *d)
|
||||||
|
static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
|
||||||
|
{
|
||||||
|
struct lme2510_state *st = d->priv;
|
||||||
|
+ int status;
|
||||||
|
|
||||||
|
usb_reset_configuration(d->udev);
|
||||||
|
|
||||||
|
@@ -1197,12 +1203,16 @@ static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
|
||||||
|
|
||||||
|
st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
|
||||||
|
|
||||||
|
- if (lme2510_return_status(d) == 0x44) {
|
||||||
|
+ status = lme2510_return_status(d);
|
||||||
|
+ if (status == 0x44) {
|
||||||
|
*name = lme_firmware_switch(d, 0);
|
||||||
|
return COLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+ if (status != 0x47)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return WARM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
|
37
Patches/Linux_CVEs/CVE-2017-16538/ANY/0002.patch
Normal file
37
Patches/Linux_CVEs/CVE-2017-16538/ANY/0002.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
|
||||||
|
index 992f2011a6ba..be26c029546b 100644
|
||||||
|
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
|
||||||
|
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
|
||||||
|
@@ -1076,8 +1076,6 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
|
||||||
|
if (adap->fe[0]) {
|
||||||
|
info("FE Found M88RS2000");
|
||||||
|
- dvb_attach(ts2020_attach, adap->fe[0], &ts2020_config,
|
||||||
|
- &d->i2c_adap);
|
||||||
|
st->i2c_tuner_gate_w = 5;
|
||||||
|
st->i2c_tuner_gate_r = 5;
|
||||||
|
st->i2c_tuner_addr = 0x60;
|
||||||
|
@@ -1143,17 +1141,18 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
|
||||||
|
ret = st->tuner_config;
|
||||||
|
break;
|
||||||
|
case TUNER_RS2000:
|
||||||
|
- ret = st->tuner_config;
|
||||||
|
+ if (dvb_attach(ts2020_attach, adap->fe[0],
|
||||||
|
+ &ts2020_config, &d->i2c_adap))
|
||||||
|
+ ret = st->tuner_config;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (ret)
|
||||||
|
+ if (ret) {
|
||||||
|
info("TUN Found %s tuner", tun_msg[ret]);
|
||||||
|
- else {
|
||||||
|
- info("TUN No tuner found --- resetting device");
|
||||||
|
- lme_coldreset(d);
|
||||||
|
+ } else {
|
||||||
|
+ info("TUN No tuner found");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
54
Patches/Linux_CVEs/CVE-2017-16643/ANY/0001.patch
Normal file
54
Patches/Linux_CVEs/CVE-2017-16643/ANY/0001.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From a50829479f58416a013a4ccca791336af3c584c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||||
|
Date: Mon, 23 Oct 2017 16:46:00 -0700
|
||||||
|
Subject: [PATCH] Input: gtco - fix potential out-of-bound access
|
||||||
|
|
||||||
|
parse_hid_report_descriptor() has a while (i < length) loop, which
|
||||||
|
only guarantees that there's at least 1 byte in the buffer, but the
|
||||||
|
loop body can read multiple bytes which causes out-of-bounds access.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Reviewed-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/input/tablet/gtco.c | 17 ++++++++++-------
|
||||||
|
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
|
||||||
|
index b796e891e2eed..4b8b9d7aa75e2 100644
|
||||||
|
--- a/drivers/input/tablet/gtco.c
|
||||||
|
+++ b/drivers/input/tablet/gtco.c
|
||||||
|
@@ -230,13 +230,17 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
||||||
|
|
||||||
|
/* Walk this report and pull out the info we need */
|
||||||
|
while (i < length) {
|
||||||
|
- prefix = report[i];
|
||||||
|
-
|
||||||
|
- /* Skip over prefix */
|
||||||
|
- i++;
|
||||||
|
+ prefix = report[i++];
|
||||||
|
|
||||||
|
/* Determine data size and save the data in the proper variable */
|
||||||
|
- size = PREF_SIZE(prefix);
|
||||||
|
+ size = (1U << PREF_SIZE(prefix)) >> 1;
|
||||||
|
+ if (i + size > length) {
|
||||||
|
+ dev_err(ddev,
|
||||||
|
+ "Not enough data (need %d, have %d)\n",
|
||||||
|
+ i + size, length);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
data = report[i];
|
||||||
|
@@ -244,8 +248,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
||||||
|
case 2:
|
||||||
|
data16 = get_unaligned_le16(&report[i]);
|
||||||
|
break;
|
||||||
|
- case 3:
|
||||||
|
- size = 4;
|
||||||
|
+ case 4:
|
||||||
|
data32 = get_unaligned_le32(&report[i]);
|
||||||
|
break;
|
||||||
|
}
|
47
Patches/Linux_CVEs/CVE-2017-16645/ANY/0001.patch
Normal file
47
Patches/Linux_CVEs/CVE-2017-16645/ANY/0001.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From ea04efee7635c9120d015dcdeeeb6988130cb67a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||||
|
Date: Sat, 7 Oct 2017 11:07:47 -0700
|
||||||
|
Subject: [PATCH] Input: ims-psu - check if CDC union descriptor is sane
|
||||||
|
|
||||||
|
Before trying to use CDC union descriptor, try to validate whether that it
|
||||||
|
is sane by checking that intf->altsetting->extra is big enough and that
|
||||||
|
descriptor bLength is not too big and not too small.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/input/misc/ims-pcu.c | 16 ++++++++++++++--
|
||||||
|
1 file changed, 14 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
|
||||||
|
index 6bf82ea8c918a..ae473123583bb 100644
|
||||||
|
--- a/drivers/input/misc/ims-pcu.c
|
||||||
|
+++ b/drivers/input/misc/ims-pcu.c
|
||||||
|
@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- while (buflen > 0) {
|
||||||
|
+ while (buflen >= sizeof(*union_desc)) {
|
||||||
|
union_desc = (struct usb_cdc_union_desc *)buf;
|
||||||
|
|
||||||
|
+ if (union_desc->bLength > buflen) {
|
||||||
|
+ dev_err(&intf->dev, "Too large descriptor\n");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
|
||||||
|
union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
|
||||||
|
dev_dbg(&intf->dev, "Found union header\n");
|
||||||
|
- return union_desc;
|
||||||
|
+
|
||||||
|
+ if (union_desc->bLength >= sizeof(*union_desc))
|
||||||
|
+ return union_desc;
|
||||||
|
+
|
||||||
|
+ dev_err(&intf->dev,
|
||||||
|
+ "Union descriptor to short (%d vs %zd\n)",
|
||||||
|
+ union_desc->bLength, sizeof(*union_desc));
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buflen -= union_desc->bLength;
|
112
Patches/Linux_CVEs/CVE-2017-16646/ANY/0001.patch
Normal file
112
Patches/Linux_CVEs/CVE-2017-16646/ANY/0001.patch
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
|
||||||
|
index 6020170fe99a..92098c1b78e5 100644
|
||||||
|
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
|
||||||
|
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
|
||||||
|
@@ -291,7 +291,7 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
stk7700d_dib7000p_mt2266_config)
|
||||||
|
!= 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -325,7 +325,7 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
stk7700d_dib7000p_mt2266_config)
|
||||||
|
!= 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -478,7 +478,7 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
&stk7700ph_dib7700_xc3028_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
||||||
|
__func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1010,7 +1010,7 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
&dib7070p_dib7000p_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
||||||
|
__func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1068,7 +1068,7 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
&dib7770p_dib7000p_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
||||||
|
__func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3056,7 +3056,7 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
|
||||||
|
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
|
||||||
|
@@ -3109,7 +3109,7 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
|
||||||
|
/* initialize IC 0 */
|
||||||
|
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3139,7 +3139,7 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
|
||||||
|
i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
|
||||||
|
if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3214,7 +3214,7 @@ static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
1, 0x10, &tfe7790p_dib7000p_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
||||||
|
__func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
|
||||||
|
@@ -3309,7 +3309,7 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
|
||||||
|
stk7070pd_dib7000p_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
||||||
|
__func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3384,7 +3384,7 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
stk7070pd_dib7000p_config) != 0) {
|
||||||
|
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
|
||||||
|
__func__);
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3620,7 +3620,7 @@ static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
|
||||||
|
if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
|
||||||
|
/* Demodulator not found for some reason? */
|
||||||
|
- dvb_detach(&state->dib7000p_ops);
|
||||||
|
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
22
Patches/Linux_CVEs/CVE-2017-16647/ANY/0001.patch
Normal file
22
Patches/Linux_CVEs/CVE-2017-16647/ANY/0001.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
|
||||||
|
index b2ff88e69a81..3d4f7959dabb 100644
|
||||||
|
--- a/drivers/net/usb/asix_devices.c
|
||||||
|
+++ b/drivers/net/usb/asix_devices.c
|
||||||
|
@@ -626,7 +626,7 @@ static int asix_suspend(struct usb_interface *intf, pm_message_t message)
|
||||||
|
struct usbnet *dev = usb_get_intfdata(intf);
|
||||||
|
struct asix_common_private *priv = dev->driver_priv;
|
||||||
|
|
||||||
|
- if (priv->suspend)
|
||||||
|
+ if (priv && priv->suspend)
|
||||||
|
priv->suspend(dev);
|
||||||
|
|
||||||
|
return usbnet_suspend(intf, message);
|
||||||
|
@@ -678,7 +678,7 @@ static int asix_resume(struct usb_interface *intf)
|
||||||
|
struct usbnet *dev = usb_get_intfdata(intf);
|
||||||
|
struct asix_common_private *priv = dev->driver_priv;
|
||||||
|
|
||||||
|
- if (priv->resume)
|
||||||
|
+ if (priv && priv->resume)
|
||||||
|
priv->resume(dev);
|
||||||
|
|
||||||
|
return usbnet_resume(intf);
|
13
Patches/Linux_CVEs/CVE-2017-16649/ANY/0001.patch
Normal file
13
Patches/Linux_CVEs/CVE-2017-16649/ANY/0001.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
|
||||||
|
index 3e7a3ac3a362..05dca3e5c93d 100644
|
||||||
|
--- a/drivers/net/usb/cdc_ether.c
|
||||||
|
+++ b/drivers/net/usb/cdc_ether.c
|
||||||
|
@@ -230,7 +230,7 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
|
goto bad_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (header.usb_cdc_ether_desc) {
|
||||||
|
+ if (header.usb_cdc_ether_desc && info->ether->wMaxSegmentSize) {
|
||||||
|
dev->hard_mtu = le16_to_cpu(info->ether->wMaxSegmentSize);
|
||||||
|
/* because of Zaurus, we may be ignoring the host
|
||||||
|
* side link address we were given.
|
13
Patches/Linux_CVEs/CVE-2017-16650/ANY/0001.patch
Normal file
13
Patches/Linux_CVEs/CVE-2017-16650/ANY/0001.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
||||||
|
index 8c3733608271..a4f229edcceb 100644
|
||||||
|
--- a/drivers/net/usb/qmi_wwan.c
|
||||||
|
+++ b/drivers/net/usb/qmi_wwan.c
|
||||||
|
@@ -681,7 +681,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* errors aren't fatal - we can live with the dynamic address */
|
||||||
|
- if (cdc_ether) {
|
||||||
|
+ if (cdc_ether && cdc_ether->wMaxSegmentSize) {
|
||||||
|
dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
|
||||||
|
usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
|
||||||
|
}
|
56
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0001.patch
Normal file
56
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0001.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
From 7682e399485fe19622b6fd82510b1f4551e48a25 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takashi Iwai <tiwai@suse.de>
|
||||||
|
Date: Mon, 2 Oct 2017 14:06:43 +0200
|
||||||
|
Subject: [PATCH] ALSA: usx2y: Suppress kernel warning at page allocation
|
||||||
|
failures
|
||||||
|
|
||||||
|
The usx2y driver allocates the stream read/write buffers in continuous
|
||||||
|
pages depending on the stream setup, and this may spew the kernel
|
||||||
|
warning messages with a stack trace like:
|
||||||
|
WARNING: CPU: 1 PID: 1846 at mm/page_alloc.c:3883
|
||||||
|
__alloc_pages_slowpath+0x1ef2/0x2d70
|
||||||
|
Modules linked in:
|
||||||
|
CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
|
||||||
|
....
|
||||||
|
|
||||||
|
It may confuse user as if it were any serious error, although this is
|
||||||
|
no fatal error and the driver handles the error case gracefully.
|
||||||
|
Since the driver has already some sanity check of the given size (128
|
||||||
|
and 256 pages), it can't pass any crazy value. So it's merely page
|
||||||
|
fragmentation.
|
||||||
|
|
||||||
|
This patch adds __GFP_NOWARN to each caller for suppressing such
|
||||||
|
kernel warnings. The original issue was spotted by syzkaller.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||||
|
---
|
||||||
|
sound/usb/usx2y/usb_stream.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
|
||||||
|
index 4dab490807009..e229abd216526 100644
|
||||||
|
--- a/sound/usb/usx2y/usb_stream.c
|
||||||
|
+++ b/sound/usb/usx2y/usb_stream.c
|
||||||
|
@@ -191,7 +191,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
|
||||||
|
}
|
||||||
|
|
||||||
|
pg = get_order(read_size);
|
||||||
|
- sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
|
||||||
|
+ sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO|
|
||||||
|
+ __GFP_NOWARN, pg);
|
||||||
|
if (!sk->s) {
|
||||||
|
snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
|
||||||
|
goto out;
|
||||||
|
@@ -211,7 +212,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
|
||||||
|
pg = get_order(write_size);
|
||||||
|
|
||||||
|
sk->write_page =
|
||||||
|
- (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
|
||||||
|
+ (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO|
|
||||||
|
+ __GFP_NOWARN, pg);
|
||||||
|
if (!sk->write_page) {
|
||||||
|
snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
|
||||||
|
usb_stream_free(sk);
|
89
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0003.patch
Normal file
89
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0003.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From 70e743e4cec3733dc13559f6184b35d358b9ef3f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Date: Thu, 14 Sep 2017 16:52:59 +0200
|
||||||
|
Subject: [PATCH] uwb: ensure that endpoint is interrupt
|
||||||
|
|
||||||
|
hwarc_neep_init() assumes that endpoint 0 is interrupt, but there's no
|
||||||
|
check for that, which results in a WARNING in USB core code, when a bad
|
||||||
|
USB descriptor is provided from a device:
|
||||||
|
|
||||||
|
usb 1-1: BOGUS urb xfer, pipe 1 != type 3
|
||||||
|
------------[ cut here ]------------
|
||||||
|
WARNING: CPU: 0 PID: 3 at drivers/usb/core/urb.c:449 usb_submit_urb+0xf8a/0x11d0
|
||||||
|
Modules linked in:
|
||||||
|
CPU: 0 PID: 3 Comm: kworker/0:0 Not tainted 4.13.0+ #111
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
Workqueue: usb_hub_wq hub_event
|
||||||
|
task: ffff88006bdc1a00 task.stack: ffff88006bde8000
|
||||||
|
RIP: 0010:usb_submit_urb+0xf8a/0x11d0 drivers/usb/core/urb.c:448
|
||||||
|
RSP: 0018:ffff88006bdee3c0 EFLAGS: 00010282
|
||||||
|
RAX: 0000000000000029 RBX: ffff8800672a7200 RCX: 0000000000000000
|
||||||
|
RDX: 0000000000000029 RSI: ffff88006c815c78 RDI: ffffed000d7bdc6a
|
||||||
|
RBP: ffff88006bdee4c0 R08: fffffbfff0fe00ff R09: fffffbfff0fe00ff
|
||||||
|
R10: 0000000000000018 R11: fffffbfff0fe00fe R12: 1ffff1000d7bdc7f
|
||||||
|
R13: 0000000000000003 R14: 0000000000000001 R15: ffff88006b02cc90
|
||||||
|
FS: 0000000000000000(0000) GS:ffff88006c800000(0000) knlGS:0000000000000000
|
||||||
|
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
CR2: 00007fe4daddf000 CR3: 000000006add6000 CR4: 00000000000006f0
|
||||||
|
Call Trace:
|
||||||
|
hwarc_neep_init+0x4ce/0x9c0 drivers/uwb/hwa-rc.c:710
|
||||||
|
uwb_rc_add+0x2fb/0x730 drivers/uwb/lc-rc.c:361
|
||||||
|
hwarc_probe+0x34e/0x9b0 drivers/uwb/hwa-rc.c:858
|
||||||
|
usb_probe_interface+0x351/0x8d0 drivers/usb/core/driver.c:361
|
||||||
|
really_probe drivers/base/dd.c:385
|
||||||
|
driver_probe_device+0x610/0xa00 drivers/base/dd.c:529
|
||||||
|
__device_attach_driver+0x230/0x290 drivers/base/dd.c:625
|
||||||
|
bus_for_each_drv+0x15e/0x210 drivers/base/bus.c:463
|
||||||
|
__device_attach+0x269/0x3c0 drivers/base/dd.c:682
|
||||||
|
device_initial_probe+0x1f/0x30 drivers/base/dd.c:729
|
||||||
|
bus_probe_device+0x1da/0x280 drivers/base/bus.c:523
|
||||||
|
device_add+0xcf9/0x1640 drivers/base/core.c:1703
|
||||||
|
usb_set_configuration+0x1064/0x1890 drivers/usb/core/message.c:1932
|
||||||
|
generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
|
||||||
|
usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
|
||||||
|
really_probe drivers/base/dd.c:385
|
||||||
|
driver_probe_device+0x610/0xa00 drivers/base/dd.c:529
|
||||||
|
__device_attach_driver+0x230/0x290 drivers/base/dd.c:625
|
||||||
|
bus_for_each_drv+0x15e/0x210 drivers/base/bus.c:463
|
||||||
|
__device_attach+0x269/0x3c0 drivers/base/dd.c:682
|
||||||
|
device_initial_probe+0x1f/0x30 drivers/base/dd.c:729
|
||||||
|
bus_probe_device+0x1da/0x280 drivers/base/bus.c:523
|
||||||
|
device_add+0xcf9/0x1640 drivers/base/core.c:1703
|
||||||
|
usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
|
||||||
|
hub_port_connect drivers/usb/core/hub.c:4890
|
||||||
|
hub_port_connect_change drivers/usb/core/hub.c:4996
|
||||||
|
port_event drivers/usb/core/hub.c:5102
|
||||||
|
hub_event+0x23c8/0x37c0 drivers/usb/core/hub.c:5182
|
||||||
|
process_one_work+0x9fb/0x1570 kernel/workqueue.c:2097
|
||||||
|
worker_thread+0x1e4/0x1350 kernel/workqueue.c:2231
|
||||||
|
kthread+0x324/0x3f0 kernel/kthread.c:231
|
||||||
|
ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:425
|
||||||
|
Code: 48 8b 85 30 ff ff ff 48 8d b8 98 00 00 00 e8 8e 93 07 ff 45 89
|
||||||
|
e8 44 89 f1 4c 89 fa 48 89 c6 48 c7 c7 a0 e5 55 86 e8 20 08 8f fd <0f>
|
||||||
|
ff e9 9b f7 ff ff e8 4a 04 d6 fd e9 80 f7 ff ff e8 60 11 a6
|
||||||
|
---[ end trace 55d741234124cfc3 ]---
|
||||||
|
|
||||||
|
Check that endpoint is interrupt.
|
||||||
|
|
||||||
|
Found by syzkaller.
|
||||||
|
|
||||||
|
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: stable <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/uwb/hwa-rc.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
|
||||||
|
index 35a1e777b4497..9a53912bdfe9f 100644
|
||||||
|
--- a/drivers/uwb/hwa-rc.c
|
||||||
|
+++ b/drivers/uwb/hwa-rc.c
|
||||||
|
@@ -825,6 +825,8 @@ static int hwarc_probe(struct usb_interface *iface,
|
||||||
|
|
||||||
|
if (iface->cur_altsetting->desc.bNumEndpoints < 1)
|
||||||
|
return -ENODEV;
|
||||||
|
+ if (!usb_endpoint_xfer_int(&iface->cur_altsetting->endpoint[0].desc))
|
||||||
|
+ return -ENODEV;
|
||||||
|
|
||||||
|
result = -ENOMEM;
|
||||||
|
uwb_rc = uwb_rc_alloc();
|
39
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0004.patch
Normal file
39
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0004.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 122d6a347329818419b032c5a1776e6b3866d9b9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Cameron Gutman <aicommander@gmail.com>
|
||||||
|
Date: Tue, 12 Sep 2017 11:27:44 -0700
|
||||||
|
Subject: [PATCH] Input: xpad - validate USB endpoint type during probe
|
||||||
|
|
||||||
|
We should only see devices with interrupt endpoints. Ignore any other
|
||||||
|
endpoints that we find, so we don't send try to send them interrupt URBs
|
||||||
|
and trigger a WARN down in the USB stack.
|
||||||
|
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Cc: <stable@vger.kernel.org> # c01b5e7464f0 Input: xpad - don't depend on endpoint order
|
||||||
|
Signed-off-by: Cameron Gutman <aicommander@gmail.com>
|
||||||
|
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/input/joystick/xpad.c | 10 ++++++----
|
||||||
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
|
||||||
|
index 2578a76770404..f670dcb401c05 100644
|
||||||
|
--- a/drivers/input/joystick/xpad.c
|
||||||
|
+++ b/drivers/input/joystick/xpad.c
|
||||||
|
@@ -1750,10 +1750,12 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||||
|
struct usb_endpoint_descriptor *ep =
|
||||||
|
&intf->cur_altsetting->endpoint[i].desc;
|
||||||
|
|
||||||
|
- if (usb_endpoint_dir_in(ep))
|
||||||
|
- ep_irq_in = ep;
|
||||||
|
- else
|
||||||
|
- ep_irq_out = ep;
|
||||||
|
+ if (usb_endpoint_xfer_int(ep)) {
|
||||||
|
+ if (usb_endpoint_dir_in(ep))
|
||||||
|
+ ep_irq_in = ep;
|
||||||
|
+ else
|
||||||
|
+ ep_irq_out = ep;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ep_irq_in || !ep_irq_out) {
|
74
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0005.patch
Normal file
74
Patches/Linux_CVEs/CVE-2017-16USB/ANY/0005.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
From 0a8fd1346254974c3a852338508e4a4cddbb35f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Date: Mon, 19 Dec 2016 12:03:41 -0500
|
||||||
|
Subject: [PATCH] USB: fix problems with duplicate endpoint addresses
|
||||||
|
|
||||||
|
When checking a new device's descriptors, the USB core does not check
|
||||||
|
for duplicate endpoint addresses. This can cause a problem when the
|
||||||
|
sysfs files for those endpoints are created; trying to create multiple
|
||||||
|
files with the same name will provoke a WARNING:
|
||||||
|
|
||||||
|
WARNING: CPU: 2 PID: 865 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x8a/0xa0
|
||||||
|
sysfs: cannot create duplicate filename
|
||||||
|
'/devices/platform/dummy_hcd.0/usb2/2-1/2-1:64.0/ep_05'
|
||||||
|
Kernel panic - not syncing: panic_on_warn set ...
|
||||||
|
|
||||||
|
CPU: 2 PID: 865 Comm: kworker/2:1 Not tainted 4.9.0-rc7+ #34
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
|
||||||
|
Workqueue: usb_hub_wq hub_event
|
||||||
|
ffff88006bee64c8 ffffffff81f96b8a ffffffff00000001 1ffff1000d7dcc2c
|
||||||
|
ffffed000d7dcc24 0000000000000001 0000000041b58ab3 ffffffff8598b510
|
||||||
|
ffffffff81f968f8 ffffffff850fee20 ffffffff85cff020 dffffc0000000000
|
||||||
|
Call Trace:
|
||||||
|
[< inline >] __dump_stack lib/dump_stack.c:15
|
||||||
|
[<ffffffff81f96b8a>] dump_stack+0x292/0x398 lib/dump_stack.c:51
|
||||||
|
[<ffffffff8168c88e>] panic+0x1cb/0x3a9 kernel/panic.c:179
|
||||||
|
[<ffffffff812b80b4>] __warn+0x1c4/0x1e0 kernel/panic.c:542
|
||||||
|
[<ffffffff812b8195>] warn_slowpath_fmt+0xc5/0x110 kernel/panic.c:565
|
||||||
|
[<ffffffff819e70ca>] sysfs_warn_dup+0x8a/0xa0 fs/sysfs/dir.c:30
|
||||||
|
[<ffffffff819e7308>] sysfs_create_dir_ns+0x178/0x1d0 fs/sysfs/dir.c:59
|
||||||
|
[< inline >] create_dir lib/kobject.c:71
|
||||||
|
[<ffffffff81fa1b07>] kobject_add_internal+0x227/0xa60 lib/kobject.c:229
|
||||||
|
[< inline >] kobject_add_varg lib/kobject.c:366
|
||||||
|
[<ffffffff81fa2479>] kobject_add+0x139/0x220 lib/kobject.c:411
|
||||||
|
[<ffffffff82737a63>] device_add+0x353/0x1660 drivers/base/core.c:1088
|
||||||
|
[<ffffffff82738d8d>] device_register+0x1d/0x20 drivers/base/core.c:1206
|
||||||
|
[<ffffffff82cb77d3>] usb_create_ep_devs+0x163/0x260 drivers/usb/core/endpoint.c:195
|
||||||
|
[<ffffffff82c9f27b>] create_intf_ep_devs+0x13b/0x200 drivers/usb/core/message.c:1030
|
||||||
|
[<ffffffff82ca39d3>] usb_set_configuration+0x1083/0x18d0 drivers/usb/core/message.c:1937
|
||||||
|
[<ffffffff82cc9e2e>] generic_probe+0x6e/0xe0 drivers/usb/core/generic.c:172
|
||||||
|
[<ffffffff82caa7fa>] usb_probe_device+0xaa/0xe0 drivers/usb/core/driver.c:263
|
||||||
|
|
||||||
|
This patch prevents the problem by checking for duplicate endpoint
|
||||||
|
addresses during enumeration and skipping any duplicates.
|
||||||
|
|
||||||
|
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||||
|
Reported-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
Tested-by: Andrey Konovalov <andreyknvl@google.com>
|
||||||
|
CC: <stable@vger.kernel.org>
|
||||||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
|
---
|
||||||
|
drivers/usb/core/config.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
|
||||||
|
index 0aa9e7d697a5d..25dbd8c7aec73 100644
|
||||||
|
--- a/drivers/usb/core/config.c
|
||||||
|
+++ b/drivers/usb/core/config.c
|
||||||
|
@@ -239,6 +239,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
||||||
|
if (ifp->desc.bNumEndpoints >= num_ep)
|
||||||
|
goto skip_to_next_endpoint_or_interface_descriptor;
|
||||||
|
|
||||||
|
+ /* Check for duplicate endpoint addresses */
|
||||||
|
+ for (i = 0; i < ifp->desc.bNumEndpoints; ++i) {
|
||||||
|
+ if (ifp->endpoint[i].desc.bEndpointAddress ==
|
||||||
|
+ d->bEndpointAddress) {
|
||||||
|
+ dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
|
||||||
|
+ cfgno, inum, asnum, d->bEndpointAddress);
|
||||||
|
+ goto skip_to_next_endpoint_or_interface_descriptor;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
|
||||||
|
++ifp->desc.bNumEndpoints;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user