kraxel / rpms / kernel

Forked from rpms/kernel 2 years ago
Clone
81649bd
From 9a5467bf7b6e9e02ec9c3da4e23747c05faeaac6 Mon Sep 17 00:00:00 2001
81649bd
From: Mathias Krause <minipli@googlemail.com>
81649bd
Date: Tue, 5 Feb 2013 18:19:13 +0100
81649bd
Subject: [PATCH] crypto: user - fix info leaks in report API
81649bd
81649bd
Three errors resulting in kernel memory disclosure:
81649bd
81649bd
1/ The structures used for the netlink based crypto algorithm report API
81649bd
are located on the stack. As snprintf() does not fill the remainder of
81649bd
the buffer with null bytes, those stack bytes will be disclosed to users
81649bd
of the API. Switch to strncpy() to fix this.
81649bd
81649bd
2/ crypto_report_one() does not initialize all field of struct
81649bd
crypto_user_alg. Fix this to fix the heap info leak.
81649bd
81649bd
3/ For the module name we should copy only as many bytes as
81649bd
module_name() returns -- not as much as the destination buffer could
81649bd
hold. But the current code does not and therefore copies random data
81649bd
from behind the end of the module name, as the module name is always
81649bd
shorter than CRYPTO_MAX_ALG_NAME.
81649bd
81649bd
Also switch to use strncpy() to copy the algorithm's name and
81649bd
driver_name. They are strings, after all.
81649bd
81649bd
Signed-off-by: Mathias Krause <minipli@googlemail.com>
81649bd
Cc: Steffen Klassert <steffen.klassert@secunet.com>
81649bd
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
81649bd
---
81649bd
 crypto/ablkcipher.c  | 12 ++++++------
81649bd
 crypto/aead.c        |  9 ++++-----
81649bd
 crypto/ahash.c       |  2 +-
81649bd
 crypto/blkcipher.c   |  6 +++---
81649bd
 crypto/crypto_user.c | 22 +++++++++++-----------
81649bd
 crypto/pcompress.c   |  3 +--
81649bd
 crypto/rng.c         |  2 +-
81649bd
 crypto/shash.c       |  3 ++-
81649bd
 8 files changed, 29 insertions(+), 30 deletions(-)
81649bd
81649bd
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
81649bd
index 533de95..7d4a8d2 100644
81649bd
--- a/crypto/ablkcipher.c
81649bd
+++ b/crypto/ablkcipher.c
81649bd
@@ -388,9 +388,9 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_blkcipher rblkcipher;
81649bd
 
81649bd
-	snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher");
81649bd
-	snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
81649bd
-		 alg->cra_ablkcipher.geniv ?: "<default>");
81649bd
+	strncpy(rblkcipher.type, "ablkcipher", sizeof(rblkcipher.type));
81649bd
+	strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<default>",
81649bd
+		sizeof(rblkcipher.geniv));
81649bd
 
81649bd
 	rblkcipher.blocksize = alg->cra_blocksize;
81649bd
 	rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
81649bd
@@ -469,9 +469,9 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_blkcipher rblkcipher;
81649bd
 
81649bd
-	snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher");
81649bd
-	snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
81649bd
-		 alg->cra_ablkcipher.geniv ?: "<built-in>");
81649bd
+	strncpy(rblkcipher.type, "givcipher", sizeof(rblkcipher.type));
81649bd
+	strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<built-in>",
81649bd
+		sizeof(rblkcipher.geniv));
81649bd
 
81649bd
 	rblkcipher.blocksize = alg->cra_blocksize;
81649bd
 	rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
81649bd
diff --git a/crypto/aead.c b/crypto/aead.c
81649bd
index 4d04e12..547491e 100644
81649bd
--- a/crypto/aead.c
81649bd
+++ b/crypto/aead.c
81649bd
@@ -117,9 +117,8 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 	struct crypto_report_aead raead;
81649bd
 	struct aead_alg *aead = &alg->cra_aead;
81649bd
 
81649bd
-	snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead");
81649bd
-	snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s",
81649bd
-		 aead->geniv ?: "<built-in>");
81649bd
+	strncpy(raead.type, "aead", sizeof(raead.type));
81649bd
+	strncpy(raead.geniv, aead->geniv ?: "<built-in>", sizeof(raead.geniv));
81649bd
 
81649bd
 	raead.blocksize = alg->cra_blocksize;
81649bd
 	raead.maxauthsize = aead->maxauthsize;
81649bd
@@ -203,8 +202,8 @@ static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 	struct crypto_report_aead raead;
81649bd
 	struct aead_alg *aead = &alg->cra_aead;
81649bd
 
81649bd
-	snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead");
81649bd
-	snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv);
81649bd
+	strncpy(raead.type, "nivaead", sizeof(raead.type));
81649bd
+	strncpy(raead.geniv, aead->geniv, sizeof(raead.geniv));
81649bd
 
81649bd
 	raead.blocksize = alg->cra_blocksize;
81649bd
 	raead.maxauthsize = aead->maxauthsize;
81649bd
diff --git a/crypto/ahash.c b/crypto/ahash.c
81649bd
index 3887856..793a27f 100644
81649bd
--- a/crypto/ahash.c
81649bd
+++ b/crypto/ahash.c
81649bd
@@ -404,7 +404,7 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_hash rhash;
81649bd
 
81649bd
-	snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash");
81649bd
+	strncpy(rhash.type, "ahash", sizeof(rhash.type));
81649bd
 
81649bd
 	rhash.blocksize = alg->cra_blocksize;
81649bd
 	rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize;
81649bd
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
81649bd
index e9e7244..a79e7e9 100644
81649bd
--- a/crypto/blkcipher.c
81649bd
+++ b/crypto/blkcipher.c
81649bd
@@ -499,9 +499,9 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_blkcipher rblkcipher;
81649bd
 
81649bd
-	snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher");
81649bd
-	snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
81649bd
-		 alg->cra_blkcipher.geniv ?: "<default>");
81649bd
+	strncpy(rblkcipher.type, "blkcipher", sizeof(rblkcipher.type));
81649bd
+	strncpy(rblkcipher.geniv, alg->cra_blkcipher.geniv ?: "<default>",
81649bd
+		sizeof(rblkcipher.geniv));
81649bd
 
81649bd
 	rblkcipher.blocksize = alg->cra_blocksize;
81649bd
 	rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
81649bd
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
81649bd
index 35d700a..f6d9baf 100644
81649bd
--- a/crypto/crypto_user.c
81649bd
+++ b/crypto/crypto_user.c
81649bd
@@ -75,7 +75,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_cipher rcipher;
81649bd
 
81649bd
-	snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher");
81649bd
+	strncpy(rcipher.type, "cipher", sizeof(rcipher.type));
81649bd
 
81649bd
 	rcipher.blocksize = alg->cra_blocksize;
81649bd
 	rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
81649bd
@@ -94,8 +94,7 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_comp rcomp;
81649bd
 
81649bd
-	snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression");
81649bd
-
81649bd
+	strncpy(rcomp.type, "compression", sizeof(rcomp.type));
81649bd
 	if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
81649bd
 		    sizeof(struct crypto_report_comp), &rcomp))
81649bd
 		goto nla_put_failure;
81649bd
@@ -108,12 +107,14 @@ nla_put_failure:
81649bd
 static int crypto_report_one(struct crypto_alg *alg,
81649bd
 			     struct crypto_user_alg *ualg, struct sk_buff *skb)
81649bd
 {
81649bd
-	memcpy(&ualg->cru_name, &alg->cra_name, sizeof(ualg->cru_name));
81649bd
-	memcpy(&ualg->cru_driver_name, &alg->cra_driver_name,
81649bd
-	       sizeof(ualg->cru_driver_name));
81649bd
-	memcpy(&ualg->cru_module_name, module_name(alg->cra_module),
81649bd
-	       CRYPTO_MAX_ALG_NAME);
81649bd
-
81649bd
+	strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
81649bd
+	strncpy(ualg->cru_driver_name, alg->cra_driver_name,
81649bd
+		sizeof(ualg->cru_driver_name));
81649bd
+	strncpy(ualg->cru_module_name, module_name(alg->cra_module),
81649bd
+		sizeof(ualg->cru_module_name));
81649bd
+
81649bd
+	ualg->cru_type = 0;
81649bd
+	ualg->cru_mask = 0;
81649bd
 	ualg->cru_flags = alg->cra_flags;
81649bd
 	ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
81649bd
 
81649bd
@@ -122,8 +123,7 @@ static int crypto_report_one(struct crypto_alg *alg,
81649bd
 	if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
81649bd
 		struct crypto_report_larval rl;
81649bd
 
81649bd
-		snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval");
81649bd
-
81649bd
+		strncpy(rl.type, "larval", sizeof(rl.type));
81649bd
 		if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
81649bd
 			    sizeof(struct crypto_report_larval), &rl))
81649bd
 			goto nla_put_failure;
81649bd
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
81649bd
index 04e083f..7140fe7 100644
81649bd
--- a/crypto/pcompress.c
81649bd
+++ b/crypto/pcompress.c
81649bd
@@ -53,8 +53,7 @@ static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_comp rpcomp;
81649bd
 
81649bd
-	snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp");
81649bd
-
81649bd
+	strncpy(rpcomp.type, "pcomp", sizeof(rpcomp.type));
81649bd
 	if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
81649bd
 		    sizeof(struct crypto_report_comp), &rpcomp))
81649bd
 		goto nla_put_failure;
81649bd
diff --git a/crypto/rng.c b/crypto/rng.c
81649bd
index f3b7894..e0a25c2 100644
81649bd
--- a/crypto/rng.c
81649bd
+++ b/crypto/rng.c
81649bd
@@ -65,7 +65,7 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 {
81649bd
 	struct crypto_report_rng rrng;
81649bd
 
81649bd
-	snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng");
81649bd
+	strncpy(rrng.type, "rng", sizeof(rrng.type));
81649bd
 
81649bd
 	rrng.seedsize = alg->cra_rng.seedsize;
81649bd
 
81649bd
diff --git a/crypto/shash.c b/crypto/shash.c
81649bd
index f426330f..929058a 100644
81649bd
--- a/crypto/shash.c
81649bd
+++ b/crypto/shash.c
81649bd
@@ -530,7 +530,8 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
81649bd
 	struct crypto_report_hash rhash;
81649bd
 	struct shash_alg *salg = __crypto_shash_alg(alg);
81649bd
 
81649bd
-	snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash");
81649bd
+	strncpy(rhash.type, "shash", sizeof(rhash.type));
81649bd
+
81649bd
 	rhash.blocksize = alg->cra_blocksize;
81649bd
 	rhash.digestsize = salg->digestsize;
81649bd
 
81649bd
-- 
81649bd
1.8.1.2
81649bd