From 4e3dbf27ce3d119bb7267c57f5dfb46c0b9b0da3 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Fri, 1 Apr 2016 13:50:04 +0200 Subject: kernel/usb: CVE-2015-8816 Fixes USB hub invalid memory access in hub_activate(). References: http://www.spinics.net/lists/linux-usb/msg132311.html http://seclists.org/oss-sec/2016/q1/404 https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2015-8816 Reference to upstream patch: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/patch /?id=a7e83b16c8d83a75c58989e845c664ecaa6e0aa6 Signed-off-by: Sona Sarmadi Signed-off-by: Tudor Florea --- .../linux-hierofalcon-4.1/usb-CVE-2015-8816.patch | 88 ++++++++++++++++++++++ recipes-kernel/linux/linux-hierofalcon_4.1.bb | 1 + 2 files changed, 89 insertions(+) create mode 100644 recipes-kernel/linux/linux-hierofalcon-4.1/usb-CVE-2015-8816.patch diff --git a/recipes-kernel/linux/linux-hierofalcon-4.1/usb-CVE-2015-8816.patch b/recipes-kernel/linux/linux-hierofalcon-4.1/usb-CVE-2015-8816.patch new file mode 100644 index 0000000..2949ced --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon-4.1/usb-CVE-2015-8816.patch @@ -0,0 +1,88 @@ +From a7e83b16c8d83a75c58989e845c664ecaa6e0aa6 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 16 Dec 2015 13:32:38 -0500 +Subject: USB: fix invalid memory access in hub_activate() + +commit e50293ef9775c5f1cf3fcc093037dd6a8c5684ea upstream. + +Commit 8520f38099cc ("USB: change hub initialization sleeps to +delayed_work") changed the hub_activate() routine to make part of it +run in a workqueue. However, the commit failed to take a reference to +the usb_hub structure or to lock the hub interface while doing so. As +a result, if a hub is plugged in and quickly unplugged before the work +routine can run, the routine will try to access memory that has been +deallocated. Or, if the hub is unplugged while the routine is +running, the memory may be deallocated while it is in active use. + +This patch fixes the problem by taking a reference to the usb_hub at +the start of hub_activate() and releasing it at the end (when the work +is finished), and by locking the hub interface while the work routine +is running. It also adds a check at the start of the routine to see +if the hub has already been disconnected, in which nothing should be +done. + +Fixes CVE-2015-8816. +Upstream-Status: Backport + +Signed-off-by: Alan Stern +Reported-by: Alexandru Cornea +Tested-by: Alexandru Cornea +Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work") +CC: +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sona Sarmadi +--- + drivers/usb/core/hub.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index d68c4a4..ee11b30 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1034,10 +1034,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) + unsigned delay; + + /* Continue a partial initialization */ +- if (type == HUB_INIT2) +- goto init2; +- if (type == HUB_INIT3) ++ if (type == HUB_INIT2 || type == HUB_INIT3) { ++ device_lock(hub->intfdev); ++ ++ /* Was the hub disconnected while we were waiting? */ ++ if (hub->disconnected) { ++ device_unlock(hub->intfdev); ++ kref_put(&hub->kref, hub_release); ++ return; ++ } ++ if (type == HUB_INIT2) ++ goto init2; + goto init3; ++ } ++ kref_get(&hub->kref); + + /* The superspeed hub except for root hub has to use Hub Depth + * value as an offset into the route string to locate the bits +@@ -1235,6 +1245,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) + queue_delayed_work(system_power_efficient_wq, + &hub->init_work, + msecs_to_jiffies(delay)); ++ device_unlock(hub->intfdev); + return; /* Continues at init3: below */ + } else { + msleep(delay); +@@ -1256,6 +1267,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) + /* Allow autosuspend if it was suppressed */ + if (type <= HUB_INIT3) + usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); ++ ++ if (type == HUB_INIT2 || type == HUB_INIT3) ++ device_unlock(hub->intfdev); ++ ++ kref_put(&hub->kref, hub_release); + } + + /* Implement the continuations for the delays above */ +-- +cgit v0.12 + diff --git a/recipes-kernel/linux/linux-hierofalcon_4.1.bb b/recipes-kernel/linux/linux-hierofalcon_4.1.bb index f0b6207..8112cdd 100644 --- a/recipes-kernel/linux/linux-hierofalcon_4.1.bb +++ b/recipes-kernel/linux/linux-hierofalcon_4.1.bb @@ -33,6 +33,7 @@ SRC_URI = "git://git.yoctoproject.org/linux-yocto-4.1;branch="standard/qemuarm64 file://virtio-net-CVE-2015-5156.patch \ file://ipc-CVE-2015-7613.patch \ file://net-unix-CVE-2013-7446.patch \ + file://usb-CVE-2015-8816.patch \ " S = "${WORKDIR}/git" -- cgit v1.2.3-54-g00ecf