[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