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

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Wed Dec 28 20:44:02 UTC 2016


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

benh pushed a commit to branch wheezy-security
in repository linux.

commit 31069ba3b42613ea9df3d07c62eab4603f2b5a1d
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Dec 28 16:21:16 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 1fde1c3..8e37247 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -103,6 +103,7 @@ linux (3.2.84-1) UNRELEASED; urgency=medium
   * net: cleanups in sock_setsockopt() (CVE-2012-6704)
   * net: avoid signed overflows for SO_{SND|RCV}BUFFORCE (CVE-2016-9793)
   * sg: Fix double-free when drives detach during SG_IO (CVE-2015-8962)
+  * perf: Fix race in swevent hash (CVE-2015-8963)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 28 Nov 2016 18:43:52 +0000
 
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..a48ac54
--- /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
+@@ -4958,9 +4958,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);
+@@ -5203,14 +5200,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);
+ 
+@@ -5282,7 +5273,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;
+ 
+@@ -7149,7 +7139,6 @@ static void __cpuinit perf_event_init_cp
+ 	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;
+ 
+@@ -7202,14 +7191,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 ba81022..464db1b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1108,6 +1108,7 @@ bugfix/all/ecryptfs-fix-handling-of-directory-opening.patch
 bugfix/all/net-cleanups-in-sock_setsockopt.patch
 bugfix/all/net-avoid-signed-overflows-for-so_-snd-rcv-bufforce.patch
 bugfix/all/sg-fix-double-free-when-drives-detach-during-sg_io.patch
+bugfix/all/perf-fix-race-in-swevent-hash.patch
 
 # ABI maintenance
 debian/perf-hide-abi-change-in-3.2.30.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