summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Wellving <andreas.wellving@enea.com>2018-10-17 14:41:24 +0200
committerAdrian Mangeac <Adrian.Mangeac@enea.com>2018-10-24 12:43:41 +0200
commitf22f4f9800c32ecad2ca00f2ea780fd6f7719490 (patch)
tree00bc34b7d53c3f9569701a169a3c7daced04cb0f
parentfe077124469b84dcd884cef5d0cfec5414351b06 (diff)
downloadenea-kernel-cache-f22f4f9800c32ecad2ca00f2ea780fd6f7719490.tar.gz
timerfd: CVE-2017-10661
timerfd: Protect the might cancel mechanism proper References: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.1.y&id=db14464180fa453a8ba82bce8107884571d7db6d Change-Id: I7fb7967e6740ed96d7d7351e2e204d5d4f8816a2 Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
-rw-r--r--patches/cve/4.1.x.scc3
-rw-r--r--patches/cve/CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch100
2 files changed, 103 insertions, 0 deletions
diff --git a/patches/cve/4.1.x.scc b/patches/cve/4.1.x.scc
index 4741fca..27a4241 100644
--- a/patches/cve/4.1.x.scc
+++ b/patches/cve/4.1.x.scc
@@ -7,3 +7,6 @@ patch CVE-2016-8655-packet-fix-race-condition-in-packet_set_ring.patch
7patch CVE-2016-10229-udp-properly-support-MSG_PEEK-with-truncated-buffers.patch 7patch CVE-2016-10229-udp-properly-support-MSG_PEEK-with-truncated-buffers.patch
8patch CVE-2017-7618-crypto-ahash-Fix-EINPROGRESS-notification-callback.patch 8patch CVE-2017-7618-crypto-ahash-Fix-EINPROGRESS-notification-callback.patch
9patch CVE-2017-7895-nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch 9patch CVE-2017-7895-nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch
10
11#fixed in 4.1.41
12patch CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch
diff --git a/patches/cve/CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch b/patches/cve/CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch
new file mode 100644
index 0000000..f715831
--- /dev/null
+++ b/patches/cve/CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch
@@ -0,0 +1,100 @@
1From db14464180fa453a8ba82bce8107884571d7db6d Mon Sep 17 00:00:00 2001
2From: Thomas Gleixner <tglx@linutronix.de>
3Date: Tue, 31 Jan 2017 15:24:03 +0100
4Subject: [PATCH] timerfd: Protect the might cancel mechanism proper
5
6[ Upstream commit 1e38da300e1e395a15048b0af1e5305bd91402f6 ]
7
8The handling of the might_cancel queueing is not properly protected, so
9parallel operations on the file descriptor can race with each other and
10lead to list corruptions or use after free.
11
12Protect the context for these operations with a seperate lock.
13
14The wait queue lock cannot be reused for this because that would create a
15lock inversion scenario vs. the cancel lock. Replacing might_cancel with an
16atomic (atomic_t or atomic bit) does not help either because it still can
17race vs. the actual list operation.
18
19CVE: CVE-2017-10661
20Upstream-Status: Backport
21
22Reported-by: Dmitry Vyukov <dvyukov@google.com>
23Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
24Cc: "linux-fsdevel@vger.kernel.org"
25Cc: syzkaller <syzkaller@googlegroups.com>
26Cc: Al Viro <viro@zeniv.linux.org.uk>
27Cc: linux-fsdevel@vger.kernel.org
28Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1701311521430.3457@nanos
29Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
30Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
31Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
32---
33 fs/timerfd.c | 17 ++++++++++++++---
34 1 file changed, 14 insertions(+), 3 deletions(-)
35
36diff --git a/fs/timerfd.c b/fs/timerfd.c
37index b94fa6c..1635686 100644
38--- a/fs/timerfd.c
39+++ b/fs/timerfd.c
40@@ -40,6 +40,7 @@ struct timerfd_ctx {
41 short unsigned settime_flags; /* to show in fdinfo */
42 struct rcu_head rcu;
43 struct list_head clist;
44+ spinlock_t cancel_lock;
45 bool might_cancel;
46 };
47
48@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void)
49 rcu_read_unlock();
50 }
51
52-static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
53+static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
54 {
55 if (ctx->might_cancel) {
56 ctx->might_cancel = false;
57@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
58 }
59 }
60
61+static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
62+{
63+ spin_lock(&ctx->cancel_lock);
64+ __timerfd_remove_cancel(ctx);
65+ spin_unlock(&ctx->cancel_lock);
66+}
67+
68 static bool timerfd_canceled(struct timerfd_ctx *ctx)
69 {
70 if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX)
71@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx)
72
73 static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
74 {
75+ spin_lock(&ctx->cancel_lock);
76 if ((ctx->clockid == CLOCK_REALTIME ||
77 ctx->clockid == CLOCK_REALTIME_ALARM) &&
78 (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
79@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
80 list_add_rcu(&ctx->clist, &cancel_list);
81 spin_unlock(&cancel_lock);
82 }
83- } else if (ctx->might_cancel) {
84- timerfd_remove_cancel(ctx);
85+ } else {
86+ __timerfd_remove_cancel(ctx);
87 }
88+ spin_unlock(&ctx->cancel_lock);
89 }
90
91 static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
92@@ -395,6 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
93 return -ENOMEM;
94
95 init_waitqueue_head(&ctx->wqh);
96+ spin_lock_init(&ctx->cancel_lock);
97 ctx->clockid = clockid;
98
99 if (isalarm(ctx))
100--