]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Dec 2017 10:24:10 +0000 (11:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Dec 2017 10:24:10 +0000 (11:24 +0100)
added patches:
crypto-hmac-require-that-the-underlying-hash-algorithm-is-unkeyed.patch
crypto-rsa-fix-buffer-overread-when-stripping-leading-zeroes.patch
crypto-salsa20-fix-blkcipher_walk-api-usage.patch

queue-4.9/crypto-hmac-require-that-the-underlying-hash-algorithm-is-unkeyed.patch [new file with mode: 0644]
queue-4.9/crypto-rsa-fix-buffer-overread-when-stripping-leading-zeroes.patch [new file with mode: 0644]
queue-4.9/crypto-salsa20-fix-blkcipher_walk-api-usage.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/crypto-hmac-require-that-the-underlying-hash-algorithm-is-unkeyed.patch b/queue-4.9/crypto-hmac-require-that-the-underlying-hash-algorithm-is-unkeyed.patch
new file mode 100644 (file)
index 0000000..c59bcb1
--- /dev/null
@@ -0,0 +1,146 @@
+From af3ff8045bbf3e32f1a448542e73abb4c8ceb6f1 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 28 Nov 2017 18:01:38 -0800
+Subject: crypto: hmac - require that the underlying hash algorithm is unkeyed
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit af3ff8045bbf3e32f1a448542e73abb4c8ceb6f1 upstream.
+
+Because the HMAC template didn't check that its underlying hash
+algorithm is unkeyed, trying to use "hmac(hmac(sha3-512-generic))"
+through AF_ALG or through KEYCTL_DH_COMPUTE resulted in the inner HMAC
+being used without having been keyed, resulting in sha3_update() being
+called without sha3_init(), causing a stack buffer overflow.
+
+This is a very old bug, but it seems to have only started causing real
+problems when SHA-3 support was added (requires CONFIG_CRYPTO_SHA3)
+because the innermost hash's state is ->import()ed from a zeroed buffer,
+and it just so happens that other hash algorithms are fine with that,
+but SHA-3 is not.  However, there could be arch or hardware-dependent
+hash algorithms also affected; I couldn't test everything.
+
+Fix the bug by introducing a function crypto_shash_alg_has_setkey()
+which tests whether a shash algorithm is keyed.  Then update the HMAC
+template to require that its underlying hash algorithm is unkeyed.
+
+Here is a reproducer:
+
+    #include <linux/if_alg.h>
+    #include <sys/socket.h>
+
+    int main()
+    {
+        int algfd;
+        struct sockaddr_alg addr = {
+            .salg_type = "hash",
+            .salg_name = "hmac(hmac(sha3-512-generic))",
+        };
+        char key[4096] = { 0 };
+
+        algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
+        bind(algfd, (const struct sockaddr *)&addr, sizeof(addr));
+        setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key));
+    }
+
+Here was the KASAN report from syzbot:
+
+    BUG: KASAN: stack-out-of-bounds in memcpy include/linux/string.h:341  [inline]
+    BUG: KASAN: stack-out-of-bounds in sha3_update+0xdf/0x2e0  crypto/sha3_generic.c:161
+    Write of size 4096 at addr ffff8801cca07c40 by task syzkaller076574/3044
+
+    CPU: 1 PID: 3044 Comm: syzkaller076574 Not tainted 4.14.0-mm1+ #25
+    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  Google 01/01/2011
+    Call Trace:
+      __dump_stack lib/dump_stack.c:17 [inline]
+      dump_stack+0x194/0x257 lib/dump_stack.c:53
+      print_address_description+0x73/0x250 mm/kasan/report.c:252
+      kasan_report_error mm/kasan/report.c:351 [inline]
+      kasan_report+0x25b/0x340 mm/kasan/report.c:409
+      check_memory_region_inline mm/kasan/kasan.c:260 [inline]
+      check_memory_region+0x137/0x190 mm/kasan/kasan.c:267
+      memcpy+0x37/0x50 mm/kasan/kasan.c:303
+      memcpy include/linux/string.h:341 [inline]
+      sha3_update+0xdf/0x2e0 crypto/sha3_generic.c:161
+      crypto_shash_update+0xcb/0x220 crypto/shash.c:109
+      shash_finup_unaligned+0x2a/0x60 crypto/shash.c:151
+      crypto_shash_finup+0xc4/0x120 crypto/shash.c:165
+      hmac_finup+0x182/0x330 crypto/hmac.c:152
+      crypto_shash_finup+0xc4/0x120 crypto/shash.c:165
+      shash_digest_unaligned+0x9e/0xd0 crypto/shash.c:172
+      crypto_shash_digest+0xc4/0x120 crypto/shash.c:186
+      hmac_setkey+0x36a/0x690 crypto/hmac.c:66
+      crypto_shash_setkey+0xad/0x190 crypto/shash.c:64
+      shash_async_setkey+0x47/0x60 crypto/shash.c:207
+      crypto_ahash_setkey+0xaf/0x180 crypto/ahash.c:200
+      hash_setkey+0x40/0x90 crypto/algif_hash.c:446
+      alg_setkey crypto/af_alg.c:221 [inline]
+      alg_setsockopt+0x2a1/0x350 crypto/af_alg.c:254
+      SYSC_setsockopt net/socket.c:1851 [inline]
+      SyS_setsockopt+0x189/0x360 net/socket.c:1830
+      entry_SYSCALL_64_fastpath+0x1f/0x96
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/hmac.c                  |    6 +++++-
+ crypto/shash.c                 |    5 +++--
+ include/crypto/internal/hash.h |    8 ++++++++
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+--- a/crypto/hmac.c
++++ b/crypto/hmac.c
+@@ -194,11 +194,15 @@ static int hmac_create(struct crypto_tem
+       salg = shash_attr_alg(tb[1], 0, 0);
+       if (IS_ERR(salg))
+               return PTR_ERR(salg);
++      alg = &salg->base;
++      /* The underlying hash algorithm must be unkeyed */
+       err = -EINVAL;
++      if (crypto_shash_alg_has_setkey(salg))
++              goto out_put_alg;
++
+       ds = salg->digestsize;
+       ss = salg->statesize;
+-      alg = &salg->base;
+       if (ds > alg->cra_blocksize ||
+           ss < alg->cra_blocksize)
+               goto out_put_alg;
+--- a/crypto/shash.c
++++ b/crypto/shash.c
+@@ -24,11 +24,12 @@
+ static const struct crypto_type crypto_shash_type;
+-static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
+-                         unsigned int keylen)
++int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
++                  unsigned int keylen)
+ {
+       return -ENOSYS;
+ }
++EXPORT_SYMBOL_GPL(shash_no_setkey);
+ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
+                                 unsigned int keylen)
+--- a/include/crypto/internal/hash.h
++++ b/include/crypto/internal/hash.h
+@@ -80,6 +80,14 @@ int ahash_register_instance(struct crypt
+                           struct ahash_instance *inst);
+ void ahash_free_instance(struct crypto_instance *inst);
++int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
++                  unsigned int keylen);
++
++static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
++{
++      return alg->setkey != shash_no_setkey;
++}
++
+ int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn,
+                           struct hash_alg_common *alg,
+                           struct crypto_instance *inst);
diff --git a/queue-4.9/crypto-rsa-fix-buffer-overread-when-stripping-leading-zeroes.patch b/queue-4.9/crypto-rsa-fix-buffer-overread-when-stripping-leading-zeroes.patch
new file mode 100644 (file)
index 0000000..40c4ff8
--- /dev/null
@@ -0,0 +1,76 @@
+From d2890c3778b164fde587bc16583f3a1c87233ec5 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Sun, 26 Nov 2017 23:16:49 -0800
+Subject: crypto: rsa - fix buffer overread when stripping leading zeroes
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit d2890c3778b164fde587bc16583f3a1c87233ec5 upstream.
+
+In rsa_get_n(), if the buffer contained all 0's and "FIPS mode" is
+enabled, we would read one byte past the end of the buffer while
+scanning the leading zeroes.  Fix it by checking 'n_sz' before '!*ptr'.
+
+This bug was reachable by adding a specially crafted key of type
+"asymmetric" (requires CONFIG_RSA and CONFIG_X509_CERTIFICATE_PARSER).
+
+KASAN report:
+
+    BUG: KASAN: slab-out-of-bounds in rsa_get_n+0x19e/0x1d0 crypto/rsa_helper.c:33
+    Read of size 1 at addr ffff88003501a708 by task keyctl/196
+
+    CPU: 1 PID: 196 Comm: keyctl Not tainted 4.14.0-09238-g1d3b78bbc6e9 #26
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014
+    Call Trace:
+     rsa_get_n+0x19e/0x1d0 crypto/rsa_helper.c:33
+     asn1_ber_decoder+0x82a/0x1fd0 lib/asn1_decoder.c:328
+     rsa_set_pub_key+0xd3/0x320 crypto/rsa.c:278
+     crypto_akcipher_set_pub_key ./include/crypto/akcipher.h:364 [inline]
+     pkcs1pad_set_pub_key+0xae/0x200 crypto/rsa-pkcs1pad.c:117
+     crypto_akcipher_set_pub_key ./include/crypto/akcipher.h:364 [inline]
+     public_key_verify_signature+0x270/0x9d0 crypto/asymmetric_keys/public_key.c:106
+     x509_check_for_self_signed+0x2ea/0x480 crypto/asymmetric_keys/x509_public_key.c:141
+     x509_cert_parse+0x46a/0x620 crypto/asymmetric_keys/x509_cert_parser.c:129
+     x509_key_preparse+0x61/0x750 crypto/asymmetric_keys/x509_public_key.c:174
+     asymmetric_key_preparse+0xa4/0x150 crypto/asymmetric_keys/asymmetric_type.c:388
+     key_create_or_update+0x4d4/0x10a0 security/keys/key.c:850
+     SYSC_add_key security/keys/keyctl.c:122 [inline]
+     SyS_add_key+0xe8/0x290 security/keys/keyctl.c:62
+     entry_SYSCALL_64_fastpath+0x1f/0x96
+
+    Allocated by task 196:
+     __do_kmalloc mm/slab.c:3711 [inline]
+     __kmalloc_track_caller+0x118/0x2e0 mm/slab.c:3726
+     kmemdup+0x17/0x40 mm/util.c:118
+     kmemdup ./include/linux/string.h:414 [inline]
+     x509_cert_parse+0x2cb/0x620 crypto/asymmetric_keys/x509_cert_parser.c:106
+     x509_key_preparse+0x61/0x750 crypto/asymmetric_keys/x509_public_key.c:174
+     asymmetric_key_preparse+0xa4/0x150 crypto/asymmetric_keys/asymmetric_type.c:388
+     key_create_or_update+0x4d4/0x10a0 security/keys/key.c:850
+     SYSC_add_key security/keys/keyctl.c:122 [inline]
+     SyS_add_key+0xe8/0x290 security/keys/keyctl.c:62
+     entry_SYSCALL_64_fastpath+0x1f/0x96
+
+Fixes: 5a7de97309f5 ("crypto: rsa - return raw integers for the ASN.1 parser")
+Cc: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+Reviewed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/rsa_helper.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/crypto/rsa_helper.c
++++ b/crypto/rsa_helper.c
+@@ -30,7 +30,7 @@ int rsa_get_n(void *context, size_t hdrl
+               return -EINVAL;
+       if (fips_enabled) {
+-              while (!*ptr && n_sz) {
++              while (n_sz && !*ptr) {
+                       ptr++;
+                       n_sz--;
+               }
diff --git a/queue-4.9/crypto-salsa20-fix-blkcipher_walk-api-usage.patch b/queue-4.9/crypto-salsa20-fix-blkcipher_walk-api-usage.patch
new file mode 100644 (file)
index 0000000..514067f
--- /dev/null
@@ -0,0 +1,88 @@
+From ecaaab5649781c5a0effdaf298a925063020500e Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 28 Nov 2017 20:56:59 -0800
+Subject: crypto: salsa20 - fix blkcipher_walk API usage
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit ecaaab5649781c5a0effdaf298a925063020500e upstream.
+
+When asked to encrypt or decrypt 0 bytes, both the generic and x86
+implementations of Salsa20 crash in blkcipher_walk_done(), either when
+doing 'kfree(walk->buffer)' or 'free_page((unsigned long)walk->page)',
+because walk->buffer and walk->page have not been initialized.
+
+The bug is that Salsa20 is calling blkcipher_walk_done() even when
+nothing is in 'walk.nbytes'.  But blkcipher_walk_done() is only meant to
+be called when a nonzero number of bytes have been provided.
+
+The broken code is part of an optimization that tries to make only one
+call to salsa20_encrypt_bytes() to process inputs that are not evenly
+divisible by 64 bytes.  To fix the bug, just remove this "optimization"
+and use the blkcipher_walk API the same way all the other users do.
+
+Reproducer:
+
+    #include <linux/if_alg.h>
+    #include <sys/socket.h>
+    #include <unistd.h>
+
+    int main()
+    {
+            int algfd, reqfd;
+            struct sockaddr_alg addr = {
+                    .salg_type = "skcipher",
+                    .salg_name = "salsa20",
+            };
+            char key[16] = { 0 };
+
+            algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
+            bind(algfd, (void *)&addr, sizeof(addr));
+            reqfd = accept(algfd, 0, 0);
+            setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, sizeof(key));
+            read(reqfd, key, sizeof(key));
+    }
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Fixes: eb6f13eb9f81 ("[CRYPTO] salsa20_generic: Fix multi-page processing")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/crypto/salsa20_glue.c |    7 -------
+ crypto/salsa20_generic.c       |    7 -------
+ 2 files changed, 14 deletions(-)
+
+--- a/arch/x86/crypto/salsa20_glue.c
++++ b/arch/x86/crypto/salsa20_glue.c
+@@ -59,13 +59,6 @@ static int encrypt(struct blkcipher_desc
+       salsa20_ivsetup(ctx, walk.iv);
+-      if (likely(walk.nbytes == nbytes))
+-      {
+-              salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
+-                                    walk.dst.virt.addr, nbytes);
+-              return blkcipher_walk_done(desc, &walk, 0);
+-      }
+-
+       while (walk.nbytes >= 64) {
+               salsa20_encrypt_bytes(ctx, walk.src.virt.addr,
+                                     walk.dst.virt.addr,
+--- a/crypto/salsa20_generic.c
++++ b/crypto/salsa20_generic.c
+@@ -188,13 +188,6 @@ static int encrypt(struct blkcipher_desc
+       salsa20_ivsetup(ctx, walk.iv);
+-      if (likely(walk.nbytes == nbytes))
+-      {
+-              salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
+-                                    walk.src.virt.addr, nbytes);
+-              return blkcipher_walk_done(desc, &walk, 0);
+-      }
+-
+       while (walk.nbytes >= 64) {
+               salsa20_encrypt_bytes(ctx, walk.dst.virt.addr,
+                                     walk.src.virt.addr,
index 5b37801ccae7890d544cc273d7387157b774ea90..fd9bd8ec5b5210d61e48d401dce905f41761f1c5 100644 (file)
@@ -1 +1,4 @@
 mfd-fsl-imx25-clean-up-irq-settings-during-removal.patch
+crypto-rsa-fix-buffer-overread-when-stripping-leading-zeroes.patch
+crypto-hmac-require-that-the-underlying-hash-algorithm-is-unkeyed.patch
+crypto-salsa20-fix-blkcipher_walk-api-usage.patch