diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0001.patch new file mode 100644 index 00000000..b6cd2b4b --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0001.patch @@ -0,0 +1,76 @@ +From 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: +Signed-off-by: Felipe Balbi +--- + 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; diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0002.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0002.patch new file mode 100644 index 00000000..dc975650 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0002.patch @@ -0,0 +1,186 @@ +From 520b72fc64debf8a86c3853b8e486aa5982188f0 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include +- ++#include + #include + #include + +@@ -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); diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0003.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0003.patch new file mode 100644 index 00000000..d6963da2 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0003.patch @@ -0,0 +1,40 @@ +From 6e76c01e71551cb221c1f3deacb9dcd9a7346784 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-by: Andrey Konovalov +CC: +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + 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 */ + } diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0004.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0004.patch new file mode 100644 index 00000000..5d159efe --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0004.patch @@ -0,0 +1,264 @@ +From f16443a034c7aa359ddf6f0f9bc40d01ca31faea Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-and-tested-by: Andrey Konovalov +CC: +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } + } diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0005.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0005.patch new file mode 100644 index 00000000..066bb3a0 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0005.patch @@ -0,0 +1,89 @@ +From f50b878fed33e360d01dcdc31a8eeb1815d033d5 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-and-tested-by: Andrey Konovalov +CC: +Signed-off-by: Felipe Balbi +--- + 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. diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0006.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0006.patch new file mode 100644 index 00000000..674ca7fa --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0006.patch @@ -0,0 +1,75 @@ +From bb1107f7c6052c863692a41f78c000db792334bf Mon Sep 17 00:00:00 2001 +From: Michal Hocko +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 +Reported-by: Andrey Konovalov +Acked-by: Christoph Lameter +Cc: Alexei Starovoitov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +--- + 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 diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0007.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0007.patch new file mode 100644 index 00000000..e704bf63 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0007.patch @@ -0,0 +1,64 @@ +From faab50984fe6636e616c7cc3d30308ba391d36fd Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 + [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159 + [< inline >] print_address_description mm/kasan/report.c:197 + [] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286 + [] kasan_report+0x35/0x40 mm/kasan/report.c:306 + [< inline >] check_memory_region_inline mm/kasan/kasan.c:308 + [] check_memory_region+0x139/0x190 mm/kasan/kasan.c:315 + [] 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 + [] dev_config+0x86f/0x1190 drivers/usb/gadget/legacy/inode.c:1759 + [] __vfs_write+0x5d5/0x760 fs/read_write.c:510 + [] vfs_write+0x170/0x4e0 fs/read_write.c:560 + [< inline >] SYSC_write fs/read_write.c:607 + [] SyS_write+0xfb/0x230 fs/read_write.c:599 + [] 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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: +Signed-off-by: Felipe Balbi +--- + 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) { diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0008.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0008.patch new file mode 100644 index 00000000..09a35d55 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0008.patch @@ -0,0 +1,64 @@ +From bcdbeb844773333d2d1c08004f3b3e25921040e5 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 + [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] __warn+0x19f/0x1e0 kernel/panic.c:550 + [] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585 + [] dummy_free_request+0x153/0x170 drivers/usb/gadget/udc/dummy_hcd.c:672 + [] usb_ep_free_request+0xc0/0x420 drivers/usb/gadget/udc/core.c:195 + [] gadgetfs_unbind+0x131/0x190 drivers/usb/gadget/legacy/inode.c:1612 + [] usb_gadget_remove_driver+0x10f/0x2b0 drivers/usb/gadget/udc/core.c:1228 + [] 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 +Reported-by: Andrey Konovalov +CC: +Signed-off-by: Felipe Balbi +--- + 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 */ + } diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0009.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0009.patch new file mode 100644 index 00000000..e4477260 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0009.patch @@ -0,0 +1,65 @@ +From 1c069b057dcf64fada952eaa868d35f02bb0cfc2 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +CC: Andrey Konovalov +CC: +Signed-off-by: Felipe Balbi +--- + 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; diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0010.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0010.patch new file mode 100644 index 00000000..f3962a88 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0010.patch @@ -0,0 +1,71 @@ +From add333a81a16abbd4f106266a2553677a165725f Mon Sep 17 00:00:00 2001 +From: Alan Stern +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: + [ 201.343209] [< inline >] __dump_stack lib/dump_stack.c:15 + [ 201.343209] [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159 + [< inline >] print_address_description mm/kasan/report.c:197 + [] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286 + [< inline >] kasan_report mm/kasan/report.c:306 + [] __asan_report_load_n_noabort+0x3a/0x40 mm/kasan/report.c:337 + [< inline >] config_buf drivers/usb/gadget/legacy/inode.c:1298 + [] gadgetfs_setup+0x208a/0x20e0 drivers/usb/gadget/legacy/inode.c:1368 + [] dummy_timer+0x11f0/0x36d0 drivers/usb/gadget/udc/dummy_hcd.c:1858 + [] call_timer_fn+0x241/0x800 kernel/time/timer.c:1308 + [< inline >] expire_timers kernel/time/timer.c:1348 + [] __run_timers+0xa06/0xec0 kernel/time/timer.c:1641 + [] run_timer_softirq+0x21/0x80 kernel/time/timer.c:1654 + [] __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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: +Signed-off-by: Felipe Balbi +--- + 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! */ diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0011.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0011.patch new file mode 100644 index 00000000..3bc2aaa8 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0011.patch @@ -0,0 +1,129 @@ +From 7b01738112608ce47083178ae2b9ebadf02d32cc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Felix=20H=C3=A4dicke?= +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. + +] __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:[] [] +__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: +[] list_del+0xd/0x30 +[] usb_gadget_unregister_driver+0xaa/0xc0 [udc_core] +[] unregister_gadget+0x27/0x60 [libcomposite] +[] ? mutex_lock+0x1a/0x30 +[] gadget_dev_desc_UDC_store+0x88/0xe0 [libcomposite] +[] configfs_write_file+0xa0/0x100 [configfs] +[] __vfs_write+0x37/0x160 +[] ? __fd_install+0x30/0xd0 +[] ? _raw_spin_unlock+0xe/0x10 +[] vfs_write+0xb8/0x1b0 +[] SyS_write+0x58/0xc0 +[] ? __close_fd+0x94/0xc0 +[] 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 [] __list_del_entry+0x29/0xc0 +RSP +CR2: 0000000000000000 +---[ end trace 99fc090ab3ff6cbc ]--- + +Fixes: f1bddbb ("usb: gadget: Fix binding to UDC via configfs +interface") +Signed-off-by: Felix Hädicke +Tested-by: Krzysztof Opasiak +Signed-off-by: Felipe Balbi +--- + 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) { diff --git a/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0012.patch b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0012.patch new file mode 100644 index 00000000..ae0f884b --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2016-GadgetFS/ANY/0012.patch @@ -0,0 +1,35 @@ +From 0994b0a257557e18ee8f0b7c5f0f73fe2b54eec1 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +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 +Cc: stable +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Felipe Balbi +--- + 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 */ diff --git a/Patches/Linux_CVEs/CVE-2017-16525/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16525/ANY/0001.patch new file mode 100644 index 00000000..032674db --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16525/ANY/0001.patch @@ -0,0 +1,33 @@ +From bd998c2e0df0469707503023d50d46cf0b10c787 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +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 # 4.11 +Reported-by: Andrey Konovalov +Acked-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +--- + 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); + } diff --git a/Patches/Linux_CVEs/CVE-2017-16525/ANY/0002.patch b/Patches/Linux_CVEs/CVE-2017-16525/ANY/0002.patch new file mode 100644 index 00000000..6fb2a047 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16525/ANY/0002.patch @@ -0,0 +1,29 @@ +From 299d7572e46f98534033a9e65973f13ad1ce9047 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +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 # 2.6.18 +Acked-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +--- + 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); diff --git a/Patches/Linux_CVEs/CVE-2017-16526/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16526/ANY/0001.patch new file mode 100644 index 00000000..4ba88198 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16526/ANY/0001.patch @@ -0,0 +1,51 @@ +From bbf26183b7a6236ba602f4d6a2f7cade35bba043 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov +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 +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + diff --git a/Patches/Linux_CVEs/CVE-2017-16527/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16527/ANY/0001.patch new file mode 100644 index 00000000..6a748276 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16527/ANY/0001.patch @@ -0,0 +1,116 @@ +From 124751d5e63c823092060074bd0abaae61aaa9c4 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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: + + __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 +Tested-by: Andrey Konovalov +Cc: +Signed-off-by: Takashi Iwai +--- + 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 */ diff --git a/Patches/Linux_CVEs/CVE-2017-16528/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16528/ANY/0001.patch new file mode 100644 index 00000000..b4e444be --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16528/ANY/0001.patch @@ -0,0 +1,76 @@ +From fc27fe7e8deef2f37cba3f2be2d52b6ca5eb9d57 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +Tested-by: Andrey Konovalov +Cc: +Signed-off-by: Takashi Iwai +--- + 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; + } diff --git a/Patches/Linux_CVEs/CVE-2017-16529/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16529/ANY/0001.patch new file mode 100644 index 00000000..3f690299 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16529/ANY/0001.patch @@ -0,0 +1,115 @@ +From bfc81a8bc18e3c4ba0cbaa7666ff76be2f998991 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +Tested-by: Andrey Konovalov +Cc: +Signed-off-by: Takashi Iwai +--- + 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; diff --git a/Patches/Linux_CVEs/CVE-2017-16530/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16530/ANY/0001.patch new file mode 100644 index 00000000..fb683e22 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16530/ANY/0001.patch @@ -0,0 +1,102 @@ +From 786de92b3cb26012d3d0f00ee37adf14527f35c4 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: Oliver Neukum +CC: +Signed-off-by: Greg Kroah-Hartman +--- + 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) diff --git a/Patches/Linux_CVEs/CVE-2017-16531/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16531/ANY/0001.patch new file mode 100644 index 00000000..8f6fc288 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16531/ANY/0001.patch @@ -0,0 +1,67 @@ +From bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +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 +Tested-by: Andrey Konovalov +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + 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 + + /*-------------------------------------------------------------------------*/ + diff --git a/Patches/Linux_CVEs/CVE-2017-16532/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16532/ANY/0001.patch new file mode 100644 index 00000000..f7439659 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16532/ANY/0001.patch @@ -0,0 +1,38 @@ +From 7c80f9e4a588f1925b07134bb2e3689335f6c6d8 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +Signed-off-by: Felipe Balbi +--- + 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, diff --git a/Patches/Linux_CVEs/CVE-2017-16533/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16533/ANY/0001.patch new file mode 100644 index 00000000..d44e3e43 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16533/ANY/0001.patch @@ -0,0 +1,105 @@ +From f043bfc98c193c284e2cd768fefabe18ac2fed9b Mon Sep 17 00:00:00 2001 +From: Jaejoong Kim +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 +Signed-off-by: Jaejoong Kim +Tested-by: Andrey Konovalov +Acked-by: Alan Stern +Signed-off-by: Jiri Kosina +--- + 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); + diff --git a/Patches/Linux_CVEs/CVE-2017-16534/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16534/ANY/0001.patch new file mode 100644 index 00000000..6056f314 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16534/ANY/0001.patch @@ -0,0 +1,37 @@ +From 2e1c42391ff2556387b3cb6308b24f6f65619feb Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +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 +Tested-by: Andrey Konovalov +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/Patches/Linux_CVEs/CVE-2017-16535/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16535/ANY/0001.patch new file mode 100644 index 00000000..310c58c9 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16535/ANY/0001.patch @@ -0,0 +1,43 @@ +From 1c0edc3633b56000e18d82fc241e3995ca18a69e Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 +Signed-off-by: Alan Stern +Tested-by: Andrey Konovalov +CC: +Signed-off-by: Greg Kroah-Hartman +--- + 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) { diff --git a/Patches/Linux_CVEs/CVE-2017-16538/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16538/ANY/0001.patch new file mode 100644 index 00000000..1407917e --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16538/ANY/0001.patch @@ -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, diff --git a/Patches/Linux_CVEs/CVE-2017-16538/ANY/0002.patch b/Patches/Linux_CVEs/CVE-2017-16538/ANY/0002.patch new file mode 100644 index 00000000..e5ecf350 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16538/ANY/0002.patch @@ -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; + } + diff --git a/Patches/Linux_CVEs/CVE-2017-16643/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16643/ANY/0001.patch new file mode 100644 index 00000000..992c8b96 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16643/ANY/0001.patch @@ -0,0 +1,54 @@ +From a50829479f58416a013a4ccca791336af3c584c7 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +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 +Reviewed-by: Andrey Konovalov +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +--- + 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; + } diff --git a/Patches/Linux_CVEs/CVE-2017-16645/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16645/ANY/0001.patch new file mode 100644 index 00000000..273c3310 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16645/ANY/0001.patch @@ -0,0 +1,47 @@ +From ea04efee7635c9120d015dcdeeeb6988130cb67a Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +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 +Signed-off-by: Dmitry Torokhov +--- + 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; diff --git a/Patches/Linux_CVEs/CVE-2017-16646/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16646/ANY/0001.patch new file mode 100644 index 00000000..335e94e7 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16646/ANY/0001.patch @@ -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; + } + diff --git a/Patches/Linux_CVEs/CVE-2017-16647/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16647/ANY/0001.patch new file mode 100644 index 00000000..b7dd63f4 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16647/ANY/0001.patch @@ -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); diff --git a/Patches/Linux_CVEs/CVE-2017-16649/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16649/ANY/0001.patch new file mode 100644 index 00000000..9e18d383 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16649/ANY/0001.patch @@ -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. diff --git a/Patches/Linux_CVEs/CVE-2017-16650/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16650/ANY/0001.patch new file mode 100644 index 00000000..01ec5a56 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16650/ANY/0001.patch @@ -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); + } diff --git a/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0001.patch b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0001.patch new file mode 100644 index 00000000..dfcbd42f --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0001.patch @@ -0,0 +1,56 @@ +From 7682e399485fe19622b6fd82510b1f4551e48a25 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +Tested-by: Andrey Konovalov +Cc: +Signed-off-by: Takashi Iwai +--- + 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); diff --git a/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0003.patch b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0003.patch new file mode 100644 index 00000000..e7e332f1 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0003.patch @@ -0,0 +1,89 @@ +From 70e743e4cec3733dc13559f6184b35d358b9ef3f Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov +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 +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + 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(); diff --git a/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0004.patch b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0004.patch new file mode 100644 index 00000000..d635e950 --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0004.patch @@ -0,0 +1,39 @@ +From 122d6a347329818419b032c5a1776e6b3866d9b9 Mon Sep 17 00:00:00 2001 +From: Cameron Gutman +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 +Tested-by: Andrey Konovalov +Cc: # c01b5e7464f0 Input: xpad - don't depend on endpoint order +Signed-off-by: Cameron Gutman +Signed-off-by: Dmitry Torokhov +--- + 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) { diff --git a/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0005.patch b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0005.patch new file mode 100644 index 00000000..f28a1e6b --- /dev/null +++ b/Patches/Linux_CVEs/CVE-2017-16USB/ANY/0005.patch @@ -0,0 +1,74 @@ +From 0a8fd1346254974c3a852338508e4a4cddbb35f1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +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 + [] dump_stack+0x292/0x398 lib/dump_stack.c:51 + [] panic+0x1cb/0x3a9 kernel/panic.c:179 + [] __warn+0x1c4/0x1e0 kernel/panic.c:542 + [] warn_slowpath_fmt+0xc5/0x110 kernel/panic.c:565 + [] sysfs_warn_dup+0x8a/0xa0 fs/sysfs/dir.c:30 + [] sysfs_create_dir_ns+0x178/0x1d0 fs/sysfs/dir.c:59 + [< inline >] create_dir lib/kobject.c:71 + [] kobject_add_internal+0x227/0xa60 lib/kobject.c:229 + [< inline >] kobject_add_varg lib/kobject.c:366 + [] kobject_add+0x139/0x220 lib/kobject.c:411 + [] device_add+0x353/0x1660 drivers/base/core.c:1088 + [] device_register+0x1d/0x20 drivers/base/core.c:1206 + [] usb_create_ep_devs+0x163/0x260 drivers/usb/core/endpoint.c:195 + [] create_intf_ep_devs+0x13b/0x200 drivers/usb/core/message.c:1030 + [] usb_set_configuration+0x1083/0x18d0 drivers/usb/core/message.c:1937 + [] generic_probe+0x6e/0xe0 drivers/usb/core/generic.c:172 + [] 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 +Reported-by: Andrey Konovalov +Tested-by: Andrey Konovalov +CC: +Signed-off-by: Greg Kroah-Hartman +--- + 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; +