summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Stratulat <adrian.stratulat@enea.com>2019-10-30 12:15:27 +0100
committerAdrian Stratulat <adrian.stratulat@enea.com>2019-10-30 12:20:47 +0100
commitcb5564e4b430ed587f73aae357ef4f3b15f4b2dc (patch)
tree4b74782b2c1034ae495bd3b82ae22cab5c0d391b
parentaf13b16401b4c2a033bd0f74162530b2d4587f5a (diff)
downloadenea-kernel-cache-cb5564e4b430ed587f73aae357ef4f3b15f4b2dc.tar.gz
keys: CVE-2017-15299
KEYS: don't let add_key() update an uninstantiated key References: https://nvd.nist.gov/vuln/detail/CVE-2017-15299 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=60ff5b2f547af3828aebafd54daded44cfb0807a https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.9.y&id=da0c7503c0b886784bf8bcb279c7d71c1e50c438 Change-Id: Ia6933016fae4fa49769ef37c340978ccb9caa422 Signed-off-by: Adrian Stratulat <adrian.stratulat@enea.com>
-rw-r--r--patches/cve/CVE-2017-15299.patch126
1 files changed, 126 insertions, 0 deletions
diff --git a/patches/cve/CVE-2017-15299.patch b/patches/cve/CVE-2017-15299.patch
new file mode 100644
index 0000000..8f60e35
--- /dev/null
+++ b/patches/cve/CVE-2017-15299.patch
@@ -0,0 +1,126 @@
1From da0c7503c0b886784bf8bcb279c7d71c1e50c438 Mon Sep 17 00:00:00 2001
2From: David Howells <dhowells@redhat.com>
3Date: Thu, 12 Oct 2017 16:00:41 +0100
4Subject: KEYS: don't let add_key() update an uninstantiated key
5
6commit 60ff5b2f547af3828aebafd54daded44cfb0807a upstream.
7
8Currently, when passed a key that already exists, add_key() will call the
9key's ->update() method if such exists. But this is heavily broken in the
10case where the key is uninstantiated because it doesn't call
11__key_instantiate_and_link(). Consequently, it doesn't do most of the
12things that are supposed to happen when the key is instantiated, such as
13setting the instantiation state, clearing KEY_FLAG_USER_CONSTRUCT and
14awakening tasks waiting on it, and incrementing key->user->nikeys.
15
16It also never takes key_construction_mutex, which means that
17->instantiate() can run concurrently with ->update() on the same key. In
18the case of the "user" and "logon" key types this causes a memory leak, at
19best. Maybe even worse, the ->update() methods of the "encrypted" and
20"trusted" key types actually just dereference a NULL pointer when passed an
21uninstantiated key.
22
23Change key_create_or_update() to wait interruptibly for the key to finish
24construction before continuing.
25
26This patch only affects *uninstantiated* keys. For now we still allow a
27negatively instantiated key to be updated (thereby positively
28instantiating it), although that's broken too (the next patch fixes it)
29and I'm not sure that anyone actually uses that functionality either.
30
31Here is a simple reproducer for the bug using the "encrypted" key type
32(requires CONFIG_ENCRYPTED_KEYS=y), though as noted above the bug
33pertained to more than just the "encrypted" key type:
34
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <keyutils.h>
38
39 int main(void)
40 {
41 int ringid = keyctl_join_session_keyring(NULL);
42
43 if (fork()) {
44 for (;;) {
45 const char payload[] = "update user:foo 32";
46
47 usleep(rand() % 10000);
48 add_key("encrypted", "desc", payload, sizeof(payload), ringid);
49 keyctl_clear(ringid);
50 }
51 } else {
52 for (;;)
53 request_key("encrypted", "desc", "callout_info", ringid);
54 }
55 }
56
57It causes:
58
59 BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
60 IP: encrypted_update+0xb0/0x170
61 PGD 7a178067 P4D 7a178067 PUD 77269067 PMD 0
62 PREEMPT SMP
63 CPU: 0 PID: 340 Comm: reproduce Tainted: G D 4.14.0-rc1-00025-g428490e38b2e #796
64 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
65 task: ffff8a467a39a340 task.stack: ffffb15c40770000
66 RIP: 0010:encrypted_update+0xb0/0x170
67 RSP: 0018:ffffb15c40773de8 EFLAGS: 00010246
68 RAX: 0000000000000000 RBX: ffff8a467a275b00 RCX: 0000000000000000
69 RDX: 0000000000000005 RSI: ffff8a467a275b14 RDI: ffffffffb742f303
70 RBP: ffffb15c40773e20 R08: 0000000000000000 R09: ffff8a467a275b17
71 R10: 0000000000000020 R11: 0000000000000000 R12: 0000000000000000
72 R13: 0000000000000000 R14: ffff8a4677057180 R15: ffff8a467a275b0f
73 FS: 00007f5d7fb08700(0000) GS:ffff8a467f200000(0000) knlGS:0000000000000000
74 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
75 CR2: 0000000000000018 CR3: 0000000077262005 CR4: 00000000001606f0
76 Call Trace:
77 key_create_or_update+0x2bc/0x460
78 SyS_add_key+0x10c/0x1d0
79 entry_SYSCALL_64_fastpath+0x1f/0xbe
80 RIP: 0033:0x7f5d7f211259
81 RSP: 002b:00007ffed03904c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000f8
82 RAX: ffffffffffffffda RBX: 000000003b2a7955 RCX: 00007f5d7f211259
83 RDX: 00000000004009e4 RSI: 00000000004009ff RDI: 0000000000400a04
84 RBP: 0000000068db8bad R08: 000000003b2a7955 R09: 0000000000000004
85 R10: 000000000000001a R11: 0000000000000246 R12: 0000000000400868
86 R13: 00007ffed03905d0 R14: 0000000000000000 R15: 0000000000000000
87 Code: 77 28 e8 64 34 1f 00 45 31 c0 31 c9 48 8d 55 c8 48 89 df 48 8d 75 d0 e8 ff f9 ff ff 85 c0 41 89 c4 0f 88 84 00 00 00 4c 8b 7d c8 <49> 8b 75 18 4c 89 ff e8 24 f8 ff ff 85 c0 41 89 c4 78 6d 49 8b
88 RIP: encrypted_update+0xb0/0x170 RSP: ffffb15c40773de8
89 CR2: 0000000000000018
90
91Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.9.y&id=da0c7503c0b886784bf8bcb279c7d71c1e50c438]
92CVE: CVE-2017-15299
93
94Reported-by: Eric Biggers <ebiggers@google.com>
95Signed-off-by: David Howells <dhowells@redhat.com>
96cc: Eric Biggers <ebiggers@google.com>
97Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
98Signed-off-by: Adrian Stratulat <adrian.stratulat@enea.com>
99---
100 security/keys/key.c | 10 ++++++++++
101 1 file changed, 10 insertions(+)
102
103diff --git a/security/keys/key.c b/security/keys/key.c
104index 135e1eb7e468..dd6dcee02492 100644
105--- a/security/keys/key.c
106+++ b/security/keys/key.c
107@@ -905,6 +905,16 @@ error:
108 */
109 __key_link_end(keyring, &index_key, edit);
110
111+ key = key_ref_to_ptr(key_ref);
112+ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) {
113+ ret = wait_for_key_construction(key, true);
114+ if (ret < 0) {
115+ key_ref_put(key_ref);
116+ key_ref = ERR_PTR(ret);
117+ goto error_free_prep;
118+ }
119+ }
120+
121 key_ref = __key_update(key_ref, &prep);
122 goto error_free_prep;
123 }
124--
125cgit 1.2-0.3.lf.el7
126