[linux] 06/07: irda: Fix locking in hashbin_delete() (CVE-2017-6348)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Tue Mar 7 02:36:44 UTC 2017


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

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

commit d1838126f6c39d6591e9967d676cecd682ab0900
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Tue Mar 7 02:20:47 2017 +0000

    irda: Fix locking in hashbin_delete() (CVE-2017-6348)
---
 debian/changelog                                   |  1 +
 ...fix-lockdep-annotations-in-hashbin_delete.patch | 84 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 86 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index cfb96c8..4c2a4ea 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -81,6 +81,7 @@ linux (3.2.86-1) UNRELEASED; urgency=medium
   * sctp: avoid BUG_ON on sctp_wait_for_sndbuf (CVE-2017-5986)
   * net/llc: avoid BUG_ON() in skb_orphan() (CVE-2017-6345)
   * packet: fix races in fanout_add() (CVE-2017-6346)
+  * irda: Fix locking in hashbin_delete() (CVE-2017-6348)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Tue, 07 Mar 2017 01:47:48 +0000
 
diff --git a/debian/patches/bugfix/all/irda-fix-lockdep-annotations-in-hashbin_delete.patch b/debian/patches/bugfix/all/irda-fix-lockdep-annotations-in-hashbin_delete.patch
new file mode 100644
index 0000000..eca2e4a
--- /dev/null
+++ b/debian/patches/bugfix/all/irda-fix-lockdep-annotations-in-hashbin_delete.patch
@@ -0,0 +1,84 @@
+From: "David S. Miller" <davem at davemloft.net>
+Date: Fri, 17 Feb 2017 16:19:39 -0500
+Subject: irda: Fix lockdep annotations in hashbin_delete().
+Origin: https://git.kernel.org/linus/4c03b862b12f980456f9de92db6d508a4999b788
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-6348
+
+A nested lock depth was added to the hasbin_delete() code but it
+doesn't actually work some well and results in tons of lockdep splats.
+
+Fix the code instead to properly drop the lock around the operation
+and just keep peeking the head of the hashbin queue.
+
+Reported-by: Dmitry Vyukov <dvyukov at google.com>
+Tested-by: Dmitry Vyukov <dvyukov at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ net/irda/irqueue.c | 34 ++++++++++++++++------------------
+ 1 file changed, 16 insertions(+), 18 deletions(-)
+
+--- a/net/irda/irqueue.c
++++ b/net/irda/irqueue.c
+@@ -385,9 +385,6 @@ EXPORT_SYMBOL(hashbin_new);
+  *    for deallocating this structure if it's complex. If not the user can
+  *    just supply kfree, which should take care of the job.
+  */
+-#ifdef CONFIG_LOCKDEP
+-static int hashbin_lock_depth = 0;
+-#endif
+ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
+ {
+ 	irda_queue_t* queue;
+@@ -398,22 +395,27 @@ int hashbin_delete( hashbin_t* hashbin,
+ 	IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;);
+ 
+ 	/* Synchronize */
+-	if ( hashbin->hb_type & HB_LOCK ) {
+-		spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags,
+-					 hashbin_lock_depth++);
+-	}
++	if (hashbin->hb_type & HB_LOCK)
++		spin_lock_irqsave(&hashbin->hb_spinlock, flags);
+ 
+ 	/*
+ 	 *  Free the entries in the hashbin, TODO: use hashbin_clear when
+ 	 *  it has been shown to work
+ 	 */
+ 	for (i = 0; i < HASHBIN_SIZE; i ++ ) {
+-		queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
+-		while (queue ) {
+-			if (free_func)
+-				(*free_func)(queue);
+-			queue = dequeue_first(
+-				(irda_queue_t**) &hashbin->hb_queue[i]);
++		while (1) {
++			queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
++
++			if (!queue)
++				break;
++
++			if (free_func) {
++				if (hashbin->hb_type & HB_LOCK)
++					spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
++				free_func(queue);
++				if (hashbin->hb_type & HB_LOCK)
++					spin_lock_irqsave(&hashbin->hb_spinlock, flags);
++			}
+ 		}
+ 	}
+ 
+@@ -422,12 +424,8 @@ int hashbin_delete( hashbin_t* hashbin,
+ 	hashbin->magic = ~HB_MAGIC;
+ 
+ 	/* Release lock */
+-	if ( hashbin->hb_type & HB_LOCK) {
++	if (hashbin->hb_type & HB_LOCK)
+ 		spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
+-#ifdef CONFIG_LOCKDEP
+-		hashbin_lock_depth--;
+-#endif
+-	}
+ 
+ 	/*
+ 	 *  Free the hashbin structure
diff --git a/debian/patches/series b/debian/patches/series
index 3506891..4a9f973 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1110,6 +1110,7 @@ bugfix/all/ipc-shm-fix-shmat-mmap-nil-page-protection.patch
 bugfix/all/sctp-avoid-bug_on-on-sctp_wait_for_sndbuf.patch
 bugfix/all/net-llc-avoid-bug_on-in-skb_orphan.patch
 bugfix/all/packet-fix-races-in-fanout_add.patch
+bugfix/all/irda-fix-lockdep-annotations-in-hashbin_delete.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