All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Stephan Müller" <smueller@chronox.de>
To: syzbot
	<bot+b6e703f648ebbbf57a4528d4314e0c2a5c893dc2@syzkaller.appspotmail.com>
Cc: davem@davemloft.net, herbert@gondor.apana.org.au,
	linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
	syzkaller-bugs@googlegroups.com
Subject: [PATCH] crypto: AF_ALG - limit mask and type
Date: Tue, 12 Dec 2017 07:09:08 +0100	[thread overview]
Message-ID: <4450500.tGvsruIfR8@positron.chronox.de> (raw)
In-Reply-To: <001a1141c43ad30ccf055efb76ed@google.com>

Hi Herbert,

you see the reported problem by simply using

sa.salg_mask = 0xffffffff;

Note, I am not fully sure about whether CRYPTO_AF_ALG_ALLOWED_MASK and
CRYPTO_AF_ALG_ALLOWED_TYPE have the correct value. But I think that all
that user space should reach is potentially the ASYNC flag and the
cipher types flags.

---8<---

The user space interface allows specifying the type and the mask field
used to allocate the cipher. Only a subset of the type and mask is
considered relevant to be set by user space if needed at all.

This fixes a bug where user space is able to cause one cipher to be
registered multiple times potentially exhausting kernel memory.

Reported-by: syzbot <syzkaller@googlegroups.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/af_alg.c         | 7 +++++++
 crypto/algif_aead.c     | 2 ++
 crypto/algif_hash.c     | 2 ++
 crypto/algif_rng.c      | 2 ++
 crypto/algif_skcipher.c | 2 ++
 include/crypto/if_alg.h | 1 +
 include/linux/crypto.h  | 3 +++
 7 files changed, 19 insertions(+)

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 1e5353f62067..16cfbde64048 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -1172,6 +1172,13 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
 }
 EXPORT_SYMBOL_GPL(af_alg_get_rsgl);
 
+void af_alg_restrict_type_mask(u32 *type, u32 *mask)
+{
+	*type &= CRYPTO_AF_ALG_ALLOWED_TYPE;
+	*mask &= CRYPTO_AF_ALG_ALLOWED_MASK;
+}
+EXPORT_SYMBOL_GPL(af_alg_restrict_type_mask);
+
 static int __init af_alg_init(void)
 {
 	int err = proto_register(&alg_proto, 0);
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 9d73be28cf01..5d21db83bdfd 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -463,6 +463,8 @@ static void *aead_bind(const char *name, u32 type, u32 mask)
 	if (!tfm)
 		return ERR_PTR(-ENOMEM);
 
+	af_alg_restrict_type_mask(&type, &mask);
+
 	aead = crypto_alloc_aead(name, type, mask);
 	if (IS_ERR(aead)) {
 		kfree(tfm);
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 76d2e716c792..f7660e80cd05 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -419,6 +419,8 @@ static void *hash_bind(const char *name, u32 type, u32 mask)
 	if (!tfm)
 		return ERR_PTR(-ENOMEM);
 
+	af_alg_restrict_type_mask(&type, &mask);
+
 	hash = crypto_alloc_ahash(name, type, mask);
 	if (IS_ERR(hash)) {
 		kfree(tfm);
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
index 150c2b6480ed..33a7064996f2 100644
--- a/crypto/algif_rng.c
+++ b/crypto/algif_rng.c
@@ -116,6 +116,8 @@ static struct proto_ops algif_rng_ops = {
 
 static void *rng_bind(const char *name, u32 type, u32 mask)
 {
+	af_alg_restrict_type_mask(&type, &mask);
+
 	return crypto_alloc_rng(name, type, mask);
 }
 
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 9954b078f0b9..0a4987aa9d5c 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -314,6 +314,8 @@ static void *skcipher_bind(const char *name, u32 type, u32 mask)
 	if (!tfm)
 		return ERR_PTR(-ENOMEM);
 
+	af_alg_restrict_type_mask(&type, &mask);
+
 	skcipher = crypto_alloc_skcipher(name, type, mask);
 	if (IS_ERR(skcipher)) {
 		kfree(tfm);
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 6abf0a3604dc..8ade69d46025 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -250,5 +250,6 @@ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk,
 int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
 		    struct af_alg_async_req *areq, size_t maxsize,
 		    size_t *outlen);
+void af_alg_restrict_type_mask(u32 *type, u32 *mask);
 
 #endif	/* _CRYPTO_IF_ALG_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 78508ca4b108..0d7694673fff 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -70,6 +70,9 @@
 #define CRYPTO_ALG_DYING		0x00000040
 #define CRYPTO_ALG_ASYNC		0x00000080
 
+#define CRYPTO_AF_ALG_ALLOWED_MASK	0x000000ff
+#define CRYPTO_AF_ALG_ALLOWED_TYPE	0x000000ff
+
 /*
  * Set this bit if and only if the algorithm requires another algorithm of
  * the same type to handle corner cases.
-- 
2.14.3

  parent reply	other threads:[~2017-12-12  6:09 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-27 18:56 general protection fault in crypto_remove_spawns syzbot
2017-11-27 18:56 ` syzbot
2017-11-28 22:06 ` Stephan Müller
2017-11-28 22:06   ` Stephan Müller
2017-12-12  6:09 ` Stephan Müller [this message]
2017-12-12  6:09   ` [PATCH] crypto: AF_ALG - limit mask and type Stephan Müller
2017-12-12  8:57   ` Eric Biggers
2017-12-12  8:57     ` Eric Biggers
2017-12-12  9:22     ` Stephan Mueller
2017-12-12  9:22       ` Stephan Mueller
2017-12-19  6:25   ` [PATCH v2] " Stephan Müller
2017-12-19  6:25     ` Stephan Müller
2017-12-22  7:36     ` Herbert Xu
2017-12-22  7:36       ` Herbert Xu
2017-12-22  7:41       ` Stephan Mueller
2017-12-22  7:41         ` Stephan Mueller
2017-12-22  7:58         ` Herbert Xu
2017-12-22  7:58           ` Herbert Xu
2018-01-02  7:53           ` [PATCH v3] crypto: AF_ALG - whitelist " Stephan Müller
2018-01-02  7:53             ` Stephan Müller
2018-01-02  7:55             ` [PATCH v4] " Stephan Müller
2018-01-02  7:55               ` Stephan Müller
2018-01-12 12:23               ` Herbert Xu
2018-01-12 12:23                 ` Herbert Xu
2017-12-29 20:30 ` [PATCH] crypto: algapi - fix NULL dereference in crypto_remove_spawns() Eric Biggers
2018-01-05 11:18   ` Herbert Xu
2018-01-17  6:34 ` general protection fault in crypto_remove_spawns Eric Biggers
2018-01-17  6:34   ` Eric Biggers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4450500.tGvsruIfR8@positron.chronox.de \
    --to=smueller@chronox.de \
    --cc=bot+b6e703f648ebbbf57a4528d4314e0c2a5c893dc2@syzkaller.appspotmail.com \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzkaller-bugs@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.