]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.0.18/crypto-skcipher-don-t-warn-on-unprocessed-data-after-slow-walk-step.patch
Linux 5.0.18
[thirdparty/kernel/stable-queue.git] / releases / 5.0.18 / crypto-skcipher-don-t-warn-on-unprocessed-data-after-slow-walk-step.patch
1 From dcaca01a42cc2c425154a13412b4124293a6e11e Mon Sep 17 00:00:00 2001
2 From: Eric Biggers <ebiggers@google.com>
3 Date: Sun, 31 Mar 2019 13:04:15 -0700
4 Subject: crypto: skcipher - don't WARN on unprocessed data after slow walk step
5
6 From: Eric Biggers <ebiggers@google.com>
7
8 commit dcaca01a42cc2c425154a13412b4124293a6e11e upstream.
9
10 skcipher_walk_done() assumes it's a bug if, after the "slow" path is
11 executed where the next chunk of data is processed via a bounce buffer,
12 the algorithm says it didn't process all bytes. Thus it WARNs on this.
13
14 However, this can happen legitimately when the message needs to be
15 evenly divisible into "blocks" but isn't, and the algorithm has a
16 'walksize' greater than the block size. For example, ecb-aes-neonbs
17 sets 'walksize' to 128 bytes and only supports messages evenly divisible
18 into 16-byte blocks. If, say, 17 message bytes remain but they straddle
19 scatterlist elements, the skcipher_walk code will take the "slow" path
20 and pass the algorithm all 17 bytes in the bounce buffer. But the
21 algorithm will only be able to process 16 bytes, triggering the WARN.
22
23 Fix this by just removing the WARN_ON(). Returning -EINVAL, as the code
24 already does, is the right behavior.
25
26 This bug was detected by my patches that improve testmgr to fuzz
27 algorithms against their generic implementation.
28
29 Fixes: b286d8b1a690 ("crypto: skcipher - Add skcipher walk interface")
30 Cc: <stable@vger.kernel.org> # v4.10+
31 Signed-off-by: Eric Biggers <ebiggers@google.com>
32 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
33 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
34
35 ---
36 crypto/skcipher.c | 9 +++++++--
37 1 file changed, 7 insertions(+), 2 deletions(-)
38
39 --- a/crypto/skcipher.c
40 +++ b/crypto/skcipher.c
41 @@ -131,8 +131,13 @@ unmap_src:
42 memcpy(walk->dst.virt.addr, walk->page, n);
43 skcipher_unmap_dst(walk);
44 } else if (unlikely(walk->flags & SKCIPHER_WALK_SLOW)) {
45 - if (WARN_ON(err)) {
46 - /* unexpected case; didn't process all bytes */
47 + if (err) {
48 + /*
49 + * Didn't process all bytes. Either the algorithm is
50 + * broken, or this was the last step and it turned out
51 + * the message wasn't evenly divisible into blocks but
52 + * the algorithm requires it.
53 + */
54 err = -EINVAL;
55 goto finish;
56 }