diff options
Diffstat (limited to 'patches/cve')
-rw-r--r-- | patches/cve/4.1.x.scc | 1 | ||||
-rw-r--r-- | patches/cve/CVE-2017-17806-crypto-hmac-require-that-the-underlying-hash-algorit.patch | 158 |
2 files changed, 159 insertions, 0 deletions
diff --git a/patches/cve/4.1.x.scc b/patches/cve/4.1.x.scc index 97f8d60..7901020 100644 --- a/patches/cve/4.1.x.scc +++ b/patches/cve/4.1.x.scc | |||
@@ -27,4 +27,5 @@ patch CVE-2018-10675-mm-mempolicy-fix-use-after-free-when-calling-get_mem.patch | |||
27 | 27 | ||
28 | #fixed in 4.1.49 | 28 | #fixed in 4.1.49 |
29 | patch CVE-2017-17805-crypto-salsa20-fix-blkcipher_walk-API-usage.patch | 29 | patch CVE-2017-17805-crypto-salsa20-fix-blkcipher_walk-API-usage.patch |
30 | patch CVE-2017-17806-crypto-hmac-require-that-the-underlying-hash-algorit.patch | ||
30 | 31 | ||
diff --git a/patches/cve/CVE-2017-17806-crypto-hmac-require-that-the-underlying-hash-algorit.patch b/patches/cve/CVE-2017-17806-crypto-hmac-require-that-the-underlying-hash-algorit.patch new file mode 100644 index 0000000..4b21af2 --- /dev/null +++ b/patches/cve/CVE-2017-17806-crypto-hmac-require-that-the-underlying-hash-algorit.patch | |||
@@ -0,0 +1,158 @@ | |||
1 | From bd7f57da8fff9b75204d6dd2b3ac6a30a6430a5c Mon Sep 17 00:00:00 2001 | ||
2 | From: Eric Biggers <ebiggers@google.com> | ||
3 | Date: Tue, 28 Nov 2017 18:01:38 -0800 | ||
4 | Subject: [PATCH] crypto: hmac - require that the underlying hash algorithm is | ||
5 | unkeyed | ||
6 | |||
7 | [ Upstream commit af3ff8045bbf3e32f1a448542e73abb4c8ceb6f1 ] | ||
8 | |||
9 | Because the HMAC template didn't check that its underlying hash | ||
10 | algorithm is unkeyed, trying to use "hmac(hmac(sha3-512-generic))" | ||
11 | through AF_ALG or through KEYCTL_DH_COMPUTE resulted in the inner HMAC | ||
12 | being used without having been keyed, resulting in sha3_update() being | ||
13 | called without sha3_init(), causing a stack buffer overflow. | ||
14 | |||
15 | This is a very old bug, but it seems to have only started causing real | ||
16 | problems when SHA-3 support was added (requires CONFIG_CRYPTO_SHA3) | ||
17 | because the innermost hash's state is ->import()ed from a zeroed buffer, | ||
18 | and it just so happens that other hash algorithms are fine with that, | ||
19 | but SHA-3 is not. However, there could be arch or hardware-dependent | ||
20 | hash algorithms also affected; I couldn't test everything. | ||
21 | |||
22 | Fix the bug by introducing a function crypto_shash_alg_has_setkey() | ||
23 | which tests whether a shash algorithm is keyed. Then update the HMAC | ||
24 | template to require that its underlying hash algorithm is unkeyed. | ||
25 | |||
26 | Here is a reproducer: | ||
27 | |||
28 | #include <linux/if_alg.h> | ||
29 | #include <sys/socket.h> | ||
30 | |||
31 | int main() | ||
32 | { | ||
33 | int algfd; | ||
34 | struct sockaddr_alg addr = { | ||
35 | .salg_type = "hash", | ||
36 | .salg_name = "hmac(hmac(sha3-512-generic))", | ||
37 | }; | ||
38 | char key[4096] = { 0 }; | ||
39 | |||
40 | algfd = socket(AF_ALG, SOCK_SEQPACKET, 0); | ||
41 | bind(algfd, (const struct sockaddr *)&addr, sizeof(addr)); | ||
42 | setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key)); | ||
43 | } | ||
44 | |||
45 | Here was the KASAN report from syzbot: | ||
46 | |||
47 | BUG: KASAN: stack-out-of-bounds in memcpy include/linux/string.h:341 [inline] | ||
48 | BUG: KASAN: stack-out-of-bounds in sha3_update+0xdf/0x2e0 crypto/sha3_generic.c:161 | ||
49 | Write of size 4096 at addr ffff8801cca07c40 by task syzkaller076574/3044 | ||
50 | |||
51 | CPU: 1 PID: 3044 Comm: syzkaller076574 Not tainted 4.14.0-mm1+ #25 | ||
52 | Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 | ||
53 | Call Trace: | ||
54 | __dump_stack lib/dump_stack.c:17 [inline] | ||
55 | dump_stack+0x194/0x257 lib/dump_stack.c:53 | ||
56 | print_address_description+0x73/0x250 mm/kasan/report.c:252 | ||
57 | kasan_report_error mm/kasan/report.c:351 [inline] | ||
58 | kasan_report+0x25b/0x340 mm/kasan/report.c:409 | ||
59 | check_memory_region_inline mm/kasan/kasan.c:260 [inline] | ||
60 | check_memory_region+0x137/0x190 mm/kasan/kasan.c:267 | ||
61 | memcpy+0x37/0x50 mm/kasan/kasan.c:303 | ||
62 | memcpy include/linux/string.h:341 [inline] | ||
63 | sha3_update+0xdf/0x2e0 crypto/sha3_generic.c:161 | ||
64 | crypto_shash_update+0xcb/0x220 crypto/shash.c:109 | ||
65 | shash_finup_unaligned+0x2a/0x60 crypto/shash.c:151 | ||
66 | crypto_shash_finup+0xc4/0x120 crypto/shash.c:165 | ||
67 | hmac_finup+0x182/0x330 crypto/hmac.c:152 | ||
68 | crypto_shash_finup+0xc4/0x120 crypto/shash.c:165 | ||
69 | shash_digest_unaligned+0x9e/0xd0 crypto/shash.c:172 | ||
70 | crypto_shash_digest+0xc4/0x120 crypto/shash.c:186 | ||
71 | hmac_setkey+0x36a/0x690 crypto/hmac.c:66 | ||
72 | crypto_shash_setkey+0xad/0x190 crypto/shash.c:64 | ||
73 | shash_async_setkey+0x47/0x60 crypto/shash.c:207 | ||
74 | crypto_ahash_setkey+0xaf/0x180 crypto/ahash.c:200 | ||
75 | hash_setkey+0x40/0x90 crypto/algif_hash.c:446 | ||
76 | alg_setkey crypto/af_alg.c:221 [inline] | ||
77 | alg_setsockopt+0x2a1/0x350 crypto/af_alg.c:254 | ||
78 | SYSC_setsockopt net/socket.c:1851 [inline] | ||
79 | SyS_setsockopt+0x189/0x360 net/socket.c:1830 | ||
80 | entry_SYSCALL_64_fastpath+0x1f/0x96 | ||
81 | |||
82 | CVE: CVE-2017-17806 | ||
83 | Upstream-Status: Backport | ||
84 | |||
85 | Reported-by: syzbot <syzkaller@googlegroups.com> | ||
86 | Cc: <stable@vger.kernel.org> | ||
87 | Signed-off-by: Eric Biggers <ebiggers@google.com> | ||
88 | Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> | ||
89 | Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> | ||
90 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
91 | --- | ||
92 | crypto/hmac.c | 6 +++++- | ||
93 | crypto/shash.c | 5 +++-- | ||
94 | include/crypto/internal/hash.h | 8 ++++++++ | ||
95 | 3 files changed, 16 insertions(+), 3 deletions(-) | ||
96 | |||
97 | diff --git a/crypto/hmac.c b/crypto/hmac.c | ||
98 | index 72e38c0..ba07fb6 100644 | ||
99 | --- a/crypto/hmac.c | ||
100 | +++ b/crypto/hmac.c | ||
101 | @@ -194,11 +194,15 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) | ||
102 | salg = shash_attr_alg(tb[1], 0, 0); | ||
103 | if (IS_ERR(salg)) | ||
104 | return PTR_ERR(salg); | ||
105 | + alg = &salg->base; | ||
106 | |||
107 | + /* The underlying hash algorithm must be unkeyed */ | ||
108 | err = -EINVAL; | ||
109 | + if (crypto_shash_alg_has_setkey(salg)) | ||
110 | + goto out_put_alg; | ||
111 | + | ||
112 | ds = salg->digestsize; | ||
113 | ss = salg->statesize; | ||
114 | - alg = &salg->base; | ||
115 | if (ds > alg->cra_blocksize || | ||
116 | ss < alg->cra_blocksize) | ||
117 | goto out_put_alg; | ||
118 | diff --git a/crypto/shash.c b/crypto/shash.c | ||
119 | index 17510ea..73c0653 100644 | ||
120 | --- a/crypto/shash.c | ||
121 | +++ b/crypto/shash.c | ||
122 | @@ -24,11 +24,12 @@ | ||
123 | |||
124 | static const struct crypto_type crypto_shash_type; | ||
125 | |||
126 | -static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, | ||
127 | - unsigned int keylen) | ||
128 | +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, | ||
129 | + unsigned int keylen) | ||
130 | { | ||
131 | return -ENOSYS; | ||
132 | } | ||
133 | +EXPORT_SYMBOL_GPL(shash_no_setkey); | ||
134 | |||
135 | static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, | ||
136 | unsigned int keylen) | ||
137 | diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h | ||
138 | index a25414c..9779c35 100644 | ||
139 | --- a/include/crypto/internal/hash.h | ||
140 | +++ b/include/crypto/internal/hash.h | ||
141 | @@ -83,6 +83,14 @@ int ahash_register_instance(struct crypto_template *tmpl, | ||
142 | struct ahash_instance *inst); | ||
143 | void ahash_free_instance(struct crypto_instance *inst); | ||
144 | |||
145 | +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, | ||
146 | + unsigned int keylen); | ||
147 | + | ||
148 | +static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg) | ||
149 | +{ | ||
150 | + return alg->setkey != shash_no_setkey; | ||
151 | +} | ||
152 | + | ||
153 | int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn, | ||
154 | struct hash_alg_common *alg, | ||
155 | struct crypto_instance *inst); | ||
156 | -- | ||
157 | 2.7.4 | ||
158 | |||