]>
Commit | Line | Data |
---|---|---|
41da1dd5 FG |
1 | From edd3cde476d196ebdc771a8fa789d2f4de52ae72 Mon Sep 17 00:00:00 2001 |
2 | From: Dan Carpenter <dan.carpenter@oracle.com> | |
3 | Date: Wed, 13 Jul 2016 11:43:47 +0100 | |
4 | Subject: [PATCH] KEYS: potential uninitialized variable | |
5 | ||
6 | If __key_link_begin() failed then "edit" would be uninitialized. I've | |
7 | added a check to fix that. | |
8 | ||
9 | This allows a random user to crash the kernel, though it's quite | |
10 | difficult to achieve. There are three ways it can be done as the user | |
11 | would have to cause an error to occur in __key_link(): | |
12 | ||
13 | (1) Cause the kernel to run out of memory. In practice, this is difficult | |
14 | to achieve without ENOMEM cropping up elsewhere and aborting the | |
15 | attempt. | |
16 | ||
17 | (2) Revoke the destination keyring between the keyring ID being looked up | |
18 | and it being tested for revocation. In practice, this is difficult to | |
19 | time correctly because the KEYCTL_REJECT function can only be used | |
20 | from the request-key upcall process. Further, users can only make use | |
21 | of what's in /sbin/request-key.conf, though this does including a | |
22 | rejection debugging test - which means that the destination keyring | |
23 | has to be the caller's session keyring in practice. | |
24 | ||
25 | (3) Have just enough key quota available to create a key, a new session | |
26 | keyring for the upcall and a link in the session keyring, but not then | |
27 | sufficient quota to create a link in the nominated destination keyring | |
28 | so that it fails with EDQUOT. | |
29 | ||
30 | The bug can be triggered using option (3) above using something like the | |
31 | following: | |
32 | ||
33 | echo 80 >/proc/sys/kernel/keys/root_maxbytes | |
34 | keyctl request2 user debug:fred negate @t | |
35 | ||
36 | The above sets the quota to something much lower (80) to make the bug | |
37 | easier to trigger, but this is dependent on the system. Note also that | |
38 | the name of the keyring created contains a random number that may be | |
39 | between 1 and 10 characters in size, so may throw the test off by | |
40 | changing the amount of quota used. | |
41 | ||
42 | Assuming the failure occurs, something like the following will be seen: | |
43 | ||
44 | kfree_debugcheck: out of range ptr 6b6b6b6b6b6b6b68h | |
45 | ------------[ cut here ]------------ | |
46 | kernel BUG at ../mm/slab.c:2821! | |
47 | ... | |
48 | RIP: 0010:[<ffffffff811600f9>] kfree_debugcheck+0x20/0x25 | |
49 | RSP: 0018:ffff8804014a7de8 EFLAGS: 00010092 | |
50 | RAX: 0000000000000034 RBX: 6b6b6b6b6b6b6b68 RCX: 0000000000000000 | |
51 | RDX: 0000000000040001 RSI: 00000000000000f6 RDI: 0000000000000300 | |
52 | RBP: ffff8804014a7df0 R08: 0000000000000001 R09: 0000000000000000 | |
53 | R10: ffff8804014a7e68 R11: 0000000000000054 R12: 0000000000000202 | |
54 | R13: ffffffff81318a66 R14: 0000000000000000 R15: 0000000000000001 | |
55 | ... | |
56 | Call Trace: | |
57 | kfree+0xde/0x1bc | |
58 | assoc_array_cancel_edit+0x1f/0x36 | |
59 | __key_link_end+0x55/0x63 | |
60 | key_reject_and_link+0x124/0x155 | |
61 | keyctl_reject_key+0xb6/0xe0 | |
62 | keyctl_negate_key+0x10/0x12 | |
63 | SyS_keyctl+0x9f/0xe7 | |
64 | do_syscall_64+0x63/0x13a | |
65 | entry_SYSCALL64_slow_path+0x25/0x25 | |
66 | ||
67 | Fixes: f70e2e06196a ('KEYS: Do preallocation for __key_link()') | |
68 | Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> | |
69 | Signed-off-by: David Howells <dhowells@redhat.com> | |
70 | cc: stable@vger.kernel.org | |
71 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
72 | (cherry picked from commit 38327424b40bcebe2de92d07312c89360ac9229a) | |
73 | CVE-2016-4470 | |
74 | Signed-off-by: Luis Henriques <luis.henriques@canonical.com> | |
75 | --- | |
76 | security/keys/key.c | 2 +- | |
77 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
78 | ||
79 | diff --git a/security/keys/key.c b/security/keys/key.c | |
80 | index 2779d13..1d2d3a9 100644 | |
81 | --- a/security/keys/key.c | |
82 | +++ b/security/keys/key.c | |
83 | @@ -580,7 +580,7 @@ int key_reject_and_link(struct key *key, | |
84 | ||
85 | mutex_unlock(&key_construction_mutex); | |
86 | ||
87 | - if (keyring) | |
88 | + if (keyring && link_ret == 0) | |
89 | __key_link_end(keyring, &key->index_key, edit); | |
90 | ||
91 | /* wake up anyone waiting for a key to be constructed */ | |
92 | -- | |
93 | 2.1.4 | |
94 |