[linux] 01/03: timerfd: Protect the might cancel mechanism proper (CVE-2017-10661)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Thu Aug 17 23:59:45 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 6ee058dfa725c9ecf77ab0277cf33c912c1e31cc
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Thu Aug 17 23:01:26 2017 +0100

    timerfd: Protect the might cancel mechanism proper (CVE-2017-10661)
---
 debian/changelog                                   |  1 +
 ...protect-the-might-cancel-mechanism-proper.patch | 92 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 94 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 47c5c97..fb79b5e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -94,6 +94,7 @@ linux (3.2.91-1) UNRELEASED; urgency=medium
   [ Ben Hutchings ]
   * ipv6: avoid overflow of offset in ip6_find_1stfragopt (CVE-2017-7542)
   * mqueue: fix a use-after-free in sys_mq_notify() (CVE-2017-11176)
+  * timerfd: Protect the might cancel mechanism proper (CVE-2017-10661)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 03 Jul 2017 17:17:55 +0100
 
diff --git a/debian/patches/bugfix/all/timerfd-protect-the-might-cancel-mechanism-proper.patch b/debian/patches/bugfix/all/timerfd-protect-the-might-cancel-mechanism-proper.patch
new file mode 100644
index 0000000..1ec46f7
--- /dev/null
+++ b/debian/patches/bugfix/all/timerfd-protect-the-might-cancel-mechanism-proper.patch
@@ -0,0 +1,92 @@
+From: Thomas Gleixner <tglx at linutronix.de>
+Date: Tue, 31 Jan 2017 15:24:03 +0100
+Subject: timerfd: Protect the might cancel mechanism proper
+Origin: https://git.kernel.org/linus/1e38da300e1e395a15048b0af1e5305bd91402f6
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-10661
+
+The handling of the might_cancel queueing is not properly protected, so
+parallel operations on the file descriptor can race with each other and
+lead to list corruptions or use after free.
+
+Protect the context for these operations with a seperate lock.
+
+The wait queue lock cannot be reused for this because that would create a
+lock inversion scenario vs. the cancel lock. Replacing might_cancel with an
+atomic (atomic_t or atomic bit) does not help either because it still can
+race vs. the actual list operation.
+
+Reported-by: Dmitry Vyukov <dvyukov at google.com>
+Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
+Cc: "linux-fsdevel at vger.kernel.org"
+Cc: syzkaller <syzkaller at googlegroups.com>
+Cc: Al Viro <viro at zeniv.linux.org.uk>
+Cc: linux-fsdevel at vger.kernel.org
+Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1701311521430.3457@nanos
+Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
+[bwh: Backported to 3.2: adjust context]
+---
+ fs/timerfd.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/fs/timerfd.c
++++ b/fs/timerfd.c
+@@ -34,6 +34,7 @@ struct timerfd_ctx {
+ 	int clockid;
+ 	struct rcu_head rcu;
+ 	struct list_head clist;
++	spinlock_t cancel_lock;
+ 	bool might_cancel;
+ };
+ 
+@@ -86,7 +87,7 @@ void timerfd_clock_was_set(void)
+ 	rcu_read_unlock();
+ }
+ 
+-static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
++static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
+ {
+ 	if (ctx->might_cancel) {
+ 		ctx->might_cancel = false;
+@@ -96,6 +97,13 @@ static void timerfd_remove_cancel(struct
+ 	}
+ }
+ 
++static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
++{
++	spin_lock(&ctx->cancel_lock);
++	__timerfd_remove_cancel(ctx);
++	spin_unlock(&ctx->cancel_lock);
++}
++
+ static bool timerfd_canceled(struct timerfd_ctx *ctx)
+ {
+ 	if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX)
+@@ -106,6 +114,7 @@ static bool timerfd_canceled(struct time
+ 
+ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
+ {
++	spin_lock(&ctx->cancel_lock);
+ 	if (ctx->clockid == CLOCK_REALTIME && (flags & TFD_TIMER_ABSTIME) &&
+ 	    (flags & TFD_TIMER_CANCEL_ON_SET)) {
+ 		if (!ctx->might_cancel) {
+@@ -114,9 +123,10 @@ static void timerfd_setup_cancel(struct
+ 			list_add_rcu(&ctx->clist, &cancel_list);
+ 			spin_unlock(&cancel_lock);
+ 		}
+-	} else if (ctx->might_cancel) {
+-		timerfd_remove_cancel(ctx);
++	} else {
++		__timerfd_remove_cancel(ctx);
+ 	}
++	spin_unlock(&ctx->cancel_lock);
+ }
+ 
+ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
+@@ -268,6 +278,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clo
+ 		return -ENOMEM;
+ 
+ 	init_waitqueue_head(&ctx->wqh);
++	spin_lock_init(&ctx->cancel_lock);
+ 	ctx->clockid = clockid;
+ 	hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
+ 	ctx->moffs = ktime_get_monotonic_offset();
diff --git a/debian/patches/series b/debian/patches/series
index 5d24aad..fa106a3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1113,6 +1113,7 @@ bugfix/all/ipv6-fix-leak-in-ipv6_gso_segment.patch
 bugfix/arm/mm-larger-stack-guard-gap-between-vmas-arm-topdown.patch
 bugfix/all/ipv6-avoid-overflow-of-offset-in-ip6_find_1stfragopt.patch
 bugfix/all/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch
+bugfix/all/timerfd-protect-the-might-cancel-mechanism-proper.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