[linux] 03/18: perf: Fix race in swevent hash (CVE-2015-8963)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Thu Dec 29 03:44:11 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie
in repository linux.

commit 155aee446c7c2831cf6aa5d0d8e537b6da6dc87a
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Dec 28 22:42:41 2016 +0000

    perf: Fix race in swevent hash (CVE-2015-8963)
---
 debian/changelog                                   |  1 +
 .../bugfix/all/perf-fix-race-in-swevent-hash.patch | 92 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 94 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 0c297d2..56a6550 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -490,6 +490,7 @@ linux (3.16.39-1) UNRELEASED; urgency=medium
   * Fix backport of "fs: Give dentry to inode_change_ok() instead of inode"
     in fuse, xfs
   * sg: Fix double-free when drives detach during SG_IO (CVE-2015-8962)
+  * perf: Fix race in swevent hash (CVE-2015-8963)
 
   [ Julien Cristau ]
   * hwrng: Add chaoskey driver, backported from 4.8 (Closes: #839616)
diff --git a/debian/patches/bugfix/all/perf-fix-race-in-swevent-hash.patch b/debian/patches/bugfix/all/perf-fix-race-in-swevent-hash.patch
new file mode 100644
index 0000000..7df1e1e
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-fix-race-in-swevent-hash.patch
@@ -0,0 +1,92 @@
+From: Peter Zijlstra <peterz at infradead.org>
+Date: Tue, 15 Dec 2015 13:49:05 +0100
+Subject: perf: Fix race in swevent hash
+Origin: https://git.kernel.org/linus/12ca6ad2e3a896256f086497a7c7406a547ee373
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2015-8963
+
+There's a race on CPU unplug where we free the swevent hash array
+while it can still have events on. This will result in a
+use-after-free which is BAD.
+
+Simply do not free the hash array on unplug. This leaves the thing
+around and no use-after-free takes place.
+
+When the last swevent dies, we do a for_each_possible_cpu() iteration
+anyway to clean these up, at which time we'll free it, so no leakage
+will occur.
+
+Reported-by: Sasha Levin <sasha.levin at oracle.com>
+Tested-by: Sasha Levin <sasha.levin at oracle.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz at infradead.org>
+Cc: Arnaldo Carvalho de Melo <acme at redhat.com>
+Cc: Frederic Weisbecker <fweisbec at gmail.com>
+Cc: Jiri Olsa <jolsa at redhat.com>
+Cc: Linus Torvalds <torvalds at linux-foundation.org>
+Cc: Peter Zijlstra <peterz at infradead.org>
+Cc: Stephane Eranian <eranian at google.com>
+Cc: Thomas Gleixner <tglx at linutronix.de>
+Cc: Vince Weaver <vincent.weaver at maine.edu>
+Signed-off-by: Ingo Molnar <mingo at kernel.org>
+---
+ kernel/events/core.c | 20 +-------------------
+ 1 file changed, 1 insertion(+), 19 deletions(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -5595,9 +5595,6 @@ struct swevent_htable {
+ 
+ 	/* Recursion avoidance in each contexts */
+ 	int				recursion[PERF_NR_CONTEXTS];
+-
+-	/* Keeps track of cpu being initialized/exited */
+-	bool				online;
+ };
+ 
+ static DEFINE_PER_CPU(struct swevent_htable, swevent_htable);
+@@ -5844,14 +5841,8 @@ static int perf_swevent_add(struct perf_
+ 	hwc->state = !(flags & PERF_EF_START);
+ 
+ 	head = find_swevent_head(swhash, event);
+-	if (!head) {
+-		/*
+-		 * We can race with cpu hotplug code. Do not
+-		 * WARN if the cpu just got unplugged.
+-		 */
+-		WARN_ON_ONCE(swhash->online);
++	if (WARN_ON_ONCE(!head))
+ 		return -EINVAL;
+-	}
+ 
+ 	hlist_add_head_rcu(&event->hlist_entry, head);
+ 
+@@ -5918,7 +5909,6 @@ static int swevent_hlist_get_cpu(struct
+ 	int err = 0;
+ 
+ 	mutex_lock(&swhash->hlist_mutex);
+-
+ 	if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) {
+ 		struct swevent_hlist *hlist;
+ 
+@@ -8050,7 +8040,6 @@ static void perf_event_init_cpu(int cpu)
+ 	struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
+ 
+ 	mutex_lock(&swhash->hlist_mutex);
+-	swhash->online = true;
+ 	if (swhash->hlist_refcount > 0) {
+ 		struct swevent_hlist *hlist;
+ 
+@@ -8103,14 +8092,7 @@ static void perf_event_exit_cpu_context(
+ 
+ static void perf_event_exit_cpu(int cpu)
+ {
+-	struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
+-
+ 	perf_event_exit_cpu_context(cpu);
+-
+-	mutex_lock(&swhash->hlist_mutex);
+-	swhash->online = false;
+-	swevent_hlist_release(swhash);
+-	mutex_unlock(&swhash->hlist_mutex);
+ }
+ #else
+ static inline void perf_event_exit_cpu(int cpu) { }
diff --git a/debian/patches/series b/debian/patches/series
index 550ca0d..5ba605f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -658,6 +658,7 @@ features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch
 
 # Security fixes
 bugfix/all/sg-fix-double-free-when-drives-detach-during-sg_io.patch
+bugfix/all/perf-fix-race-in-swevent-hash.patch
 
 # Fix ABI changes
 debian/of-fix-abi-changes.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list