diff options
-rw-r--r-- | patches/cve/CVE-2017-17805-crypto-salsa20-fix-blkcipher_walk-API-usage.patch | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/patches/cve/CVE-2017-17805-crypto-salsa20-fix-blkcipher_walk-API-usage.patch b/patches/cve/CVE-2017-17805-crypto-salsa20-fix-blkcipher_walk-API-usage.patch new file mode 100644 index 0000000..bd7cc1e --- /dev/null +++ b/patches/cve/CVE-2017-17805-crypto-salsa20-fix-blkcipher_walk-API-usage.patch | |||
@@ -0,0 +1,96 @@ | |||
1 | From c68b31521d5fb7216cb1113130399afe65437c6c Mon Sep 17 00:00:00 2001 | ||
2 | From: Eric Biggers <ebiggers@google.com> | ||
3 | Date: Tue, 28 Nov 2017 20:56:59 -0800 | ||
4 | Subject: [PATCH] crypto: salsa20 - fix blkcipher_walk API usage | ||
5 | |||
6 | commit ecaaab5649781c5a0effdaf298a925063020500e upstream. | ||
7 | |||
8 | When asked to encrypt or decrypt 0 bytes, both the generic and x86 | ||
9 | implementations of Salsa20 crash in blkcipher_walk_done(), either when | ||
10 | doing 'kfree(walk->buffer)' or 'free_page((unsigned long)walk->page)', | ||
11 | because walk->buffer and walk->page have not been initialized. | ||
12 | |||
13 | The bug is that Salsa20 is calling blkcipher_walk_done() even when | ||
14 | nothing is in 'walk.nbytes'. But blkcipher_walk_done() is only meant to | ||
15 | be called when a nonzero number of bytes have been provided. | ||
16 | |||
17 | The broken code is part of an optimization that tries to make only one | ||
18 | call to salsa20_encrypt_bytes() to process inputs that are not evenly | ||
19 | divisible by 64 bytes. To fix the bug, just remove this "optimization" | ||
20 | and use the blkcipher_walk API the same way all the other users do. | ||
21 | |||
22 | Reproducer: | ||
23 | |||
24 | #include <linux/if_alg.h> | ||
25 | #include <sys/socket.h> | ||
26 | #include <unistd.h> | ||
27 | |||
28 | int main() | ||
29 | { | ||
30 | int algfd, reqfd; | ||
31 | struct sockaddr_alg addr = { | ||
32 | .salg_type = "skcipher", | ||
33 | .salg_name = "salsa20", | ||
34 | }; | ||
35 | char key[16] = { 0 }; | ||
36 | |||
37 | algfd = socket(AF_ALG, SOCK_SEQPACKET, 0); | ||
38 | bind(algfd, (void *)&addr, sizeof(addr)); | ||
39 | reqfd = accept(algfd, 0, 0); | ||
40 | setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key)); | ||
41 | read(reqfd, key, sizeof(key)); | ||
42 | } | ||
43 | |||
44 | CVE: CVE-2017-17805 | ||
45 | Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.14.y&id=c68b31521d5fb7216cb1113130399afe65437c6c] | ||
46 | |||
47 | Reported-by: syzbot <syzkaller@googlegroups.com> | ||
48 | Fixes: eb6f13eb9f81 ("[CRYPTO] salsa20_generic: Fix multi-page processing") | ||
49 | Signed-off-by: Eric Biggers <ebiggers@google.com> | ||
50 | Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> | ||
51 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
52 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
53 | --- | ||
54 | arch/x86/crypto/salsa20_glue.c | 7 ------- | ||
55 | crypto/salsa20_generic.c | 7 ------- | ||
56 | 2 files changed, 14 deletions(-) | ||
57 | |||
58 | diff --git a/arch/x86/crypto/salsa20_glue.c b/arch/x86/crypto/salsa20_glue.c | ||
59 | index 399a29d067d6..cb91a64a99e7 100644 | ||
60 | --- a/arch/x86/crypto/salsa20_glue.c | ||
61 | +++ b/arch/x86/crypto/salsa20_glue.c | ||
62 | @@ -59,13 +59,6 @@ static int encrypt(struct blkcipher_desc *desc, | ||
63 | |||
64 | salsa20_ivsetup(ctx, walk.iv); | ||
65 | |||
66 | - if (likely(walk.nbytes == nbytes)) | ||
67 | - { | ||
68 | - salsa20_encrypt_bytes(ctx, walk.src.virt.addr, | ||
69 | - walk.dst.virt.addr, nbytes); | ||
70 | - return blkcipher_walk_done(desc, &walk, 0); | ||
71 | - } | ||
72 | - | ||
73 | while (walk.nbytes >= 64) { | ||
74 | salsa20_encrypt_bytes(ctx, walk.src.virt.addr, | ||
75 | walk.dst.virt.addr, | ||
76 | diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c | ||
77 | index f550b5d94630..d7da0eea5622 100644 | ||
78 | --- a/crypto/salsa20_generic.c | ||
79 | +++ b/crypto/salsa20_generic.c | ||
80 | @@ -188,13 +188,6 @@ static int encrypt(struct blkcipher_desc *desc, | ||
81 | |||
82 | salsa20_ivsetup(ctx, walk.iv); | ||
83 | |||
84 | - if (likely(walk.nbytes == nbytes)) | ||
85 | - { | ||
86 | - salsa20_encrypt_bytes(ctx, walk.dst.virt.addr, | ||
87 | - walk.src.virt.addr, nbytes); | ||
88 | - return blkcipher_walk_done(desc, &walk, 0); | ||
89 | - } | ||
90 | - | ||
91 | while (walk.nbytes >= 64) { | ||
92 | salsa20_encrypt_bytes(ctx, walk.dst.virt.addr, | ||
93 | walk.src.virt.addr, | ||
94 | -- | ||
95 | 2.20.1 | ||
96 | |||