[linux] 01/04: 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:32 UTC 2017


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

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

commit f49b53d40564d4d5f8f5245d5a0fafe1f494c349
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Thu Aug 17 22:53:45 2017 +0100

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

diff --git a/debian/changelog b/debian/changelog
index df1d53a..c78ec64 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,7 @@ linux (3.16.43-2+deb8u4) UNRELEASED; urgency=medium
   * ALSA: timer: Fix race between read and ioctl (CVE-2017-1000380)
   * ALSA: timer: Fix missing queue indices reset at SNDRV_TIMER_IOCTL_SELECT
     (CVE-2017-1000380)
+  * timerfd: Protect the might cancel mechanism proper (CVE-2017-10661)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Sun, 06 Aug 2017 22:03:56 +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..e8dea18
--- /dev/null
+++ b/debian/patches/bugfix/all/timerfd-protect-the-might-cancel-mechanism-proper.patch
@@ -0,0 +1,91 @@
+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>
+---
+ fs/timerfd.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/fs/timerfd.c
++++ b/fs/timerfd.c
+@@ -39,6 +39,7 @@ struct timerfd_ctx {
+ 	int clockid;
+ 	struct rcu_head rcu;
+ 	struct list_head clist;
++	spinlock_t cancel_lock;
+ 	bool might_cancel;
+ };
+ 
+@@ -111,7 +112,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;
+@@ -121,6 +122,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)
+@@ -131,6 +139,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 ||
+ 	     ctx->clockid == CLOCK_REALTIME_ALARM) &&
+ 	    (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
+@@ -140,9 +149,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)
+@@ -326,6 +336,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clo
+ 		return -ENOMEM;
+ 
+ 	init_waitqueue_head(&ctx->wqh);
++	spin_lock_init(&ctx->cancel_lock);
+ 	ctx->clockid = clockid;
+ 
+ 	if (isalarm(ctx))
diff --git a/debian/patches/series b/debian/patches/series
index 9e212d2..1ceae98 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -728,6 +728,7 @@ bugfix/all/dentry-name-snapshots.patch
 bugfix/x86/kvm-x86-fix-singlestepping-over-syscall.patch
 bugfix/all/alsa-timer-fix-race-between-read-and-ioctl.patch
 bugfix/all/alsa-timer-fix-missing-queue-indices-reset-at.patch
+bugfix/all/timerfd-protect-the-might-cancel-mechanism-proper.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