diff options
author | Andreas Wellving <andreas.wellving@enea.com> | 2018-10-17 14:41:24 +0200 |
---|---|---|
committer | Adrian Mangeac <Adrian.Mangeac@enea.com> | 2018-10-24 12:43:41 +0200 |
commit | f22f4f9800c32ecad2ca00f2ea780fd6f7719490 (patch) | |
tree | 00bc34b7d53c3f9569701a169a3c7daced04cb0f | |
parent | fe077124469b84dcd884cef5d0cfec5414351b06 (diff) | |
download | enea-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.scc | 3 | ||||
-rw-r--r-- | patches/cve/CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch | 100 |
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 | |||
7 | patch CVE-2016-10229-udp-properly-support-MSG_PEEK-with-truncated-buffers.patch | 7 | patch CVE-2016-10229-udp-properly-support-MSG_PEEK-with-truncated-buffers.patch |
8 | patch CVE-2017-7618-crypto-ahash-Fix-EINPROGRESS-notification-callback.patch | 8 | patch CVE-2017-7618-crypto-ahash-Fix-EINPROGRESS-notification-callback.patch |
9 | patch CVE-2017-7895-nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch | 9 | patch CVE-2017-7895-nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch |
10 | |||
11 | #fixed in 4.1.41 | ||
12 | patch 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 @@ | |||
1 | From db14464180fa453a8ba82bce8107884571d7db6d Mon Sep 17 00:00:00 2001 | ||
2 | From: Thomas Gleixner <tglx@linutronix.de> | ||
3 | Date: Tue, 31 Jan 2017 15:24:03 +0100 | ||
4 | Subject: [PATCH] timerfd: Protect the might cancel mechanism proper | ||
5 | |||
6 | [ Upstream commit 1e38da300e1e395a15048b0af1e5305bd91402f6 ] | ||
7 | |||
8 | The handling of the might_cancel queueing is not properly protected, so | ||
9 | parallel operations on the file descriptor can race with each other and | ||
10 | lead to list corruptions or use after free. | ||
11 | |||
12 | Protect the context for these operations with a seperate lock. | ||
13 | |||
14 | The wait queue lock cannot be reused for this because that would create a | ||
15 | lock inversion scenario vs. the cancel lock. Replacing might_cancel with an | ||
16 | atomic (atomic_t or atomic bit) does not help either because it still can | ||
17 | race vs. the actual list operation. | ||
18 | |||
19 | CVE: CVE-2017-10661 | ||
20 | Upstream-Status: Backport | ||
21 | |||
22 | Reported-by: Dmitry Vyukov <dvyukov@google.com> | ||
23 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | ||
24 | Cc: "linux-fsdevel@vger.kernel.org" | ||
25 | Cc: syzkaller <syzkaller@googlegroups.com> | ||
26 | Cc: Al Viro <viro@zeniv.linux.org.uk> | ||
27 | Cc: linux-fsdevel@vger.kernel.org | ||
28 | Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1701311521430.3457@nanos | ||
29 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | ||
30 | Signed-off-by: Sasha Levin <alexander.levin@verizon.com> | ||
31 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
32 | --- | ||
33 | fs/timerfd.c | 17 ++++++++++++++--- | ||
34 | 1 file changed, 14 insertions(+), 3 deletions(-) | ||
35 | |||
36 | diff --git a/fs/timerfd.c b/fs/timerfd.c | ||
37 | index 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 | -- | ||