Skip to content

Commit 9a5467b

Browse files
minipliherbertx
authored andcommitted
crypto: user - fix info leaks in report API
Three errors resulting in kernel memory disclosure: 1/ The structures used for the netlink based crypto algorithm report API are located on the stack. As snprintf() does not fill the remainder of the buffer with null bytes, those stack bytes will be disclosed to users of the API. Switch to strncpy() to fix this. 2/ crypto_report_one() does not initialize all field of struct crypto_user_alg. Fix this to fix the heap info leak. 3/ For the module name we should copy only as many bytes as module_name() returns -- not as much as the destination buffer could hold. But the current code does not and therefore copies random data from behind the end of the module name, as the module name is always shorter than CRYPTO_MAX_ALG_NAME. Also switch to use strncpy() to copy the algorithm's name and driver_name. They are strings, after all. Signed-off-by: Mathias Krause <minipli@googlemail.com> Cc: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 7eb9c5d commit 9a5467b

File tree

8 files changed

+29
-30
lines changed

8 files changed

+29
-30
lines changed

Diff for: crypto/ablkcipher.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,9 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
388388
{
389389
struct crypto_report_blkcipher rblkcipher;
390390

391-
snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher");
392-
snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
393-
alg->cra_ablkcipher.geniv ?: "<default>");
391+
strncpy(rblkcipher.type, "ablkcipher", sizeof(rblkcipher.type));
392+
strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<default>",
393+
sizeof(rblkcipher.geniv));
394394

395395
rblkcipher.blocksize = alg->cra_blocksize;
396396
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
@@ -469,9 +469,9 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
469469
{
470470
struct crypto_report_blkcipher rblkcipher;
471471

472-
snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher");
473-
snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
474-
alg->cra_ablkcipher.geniv ?: "<built-in>");
472+
strncpy(rblkcipher.type, "givcipher", sizeof(rblkcipher.type));
473+
strncpy(rblkcipher.geniv, alg->cra_ablkcipher.geniv ?: "<built-in>",
474+
sizeof(rblkcipher.geniv));
475475

476476
rblkcipher.blocksize = alg->cra_blocksize;
477477
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;

Diff for: crypto/aead.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,8 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
117117
struct crypto_report_aead raead;
118118
struct aead_alg *aead = &alg->cra_aead;
119119

120-
snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead");
121-
snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s",
122-
aead->geniv ?: "<built-in>");
120+
strncpy(raead.type, "aead", sizeof(raead.type));
121+
strncpy(raead.geniv, aead->geniv ?: "<built-in>", sizeof(raead.geniv));
123122

124123
raead.blocksize = alg->cra_blocksize;
125124
raead.maxauthsize = aead->maxauthsize;
@@ -203,8 +202,8 @@ static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
203202
struct crypto_report_aead raead;
204203
struct aead_alg *aead = &alg->cra_aead;
205204

206-
snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead");
207-
snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv);
205+
strncpy(raead.type, "nivaead", sizeof(raead.type));
206+
strncpy(raead.geniv, aead->geniv, sizeof(raead.geniv));
208207

209208
raead.blocksize = alg->cra_blocksize;
210209
raead.maxauthsize = aead->maxauthsize;

Diff for: crypto/ahash.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
404404
{
405405
struct crypto_report_hash rhash;
406406

407-
snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash");
407+
strncpy(rhash.type, "ahash", sizeof(rhash.type));
408408

409409
rhash.blocksize = alg->cra_blocksize;
410410
rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize;

Diff for: crypto/blkcipher.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,9 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
499499
{
500500
struct crypto_report_blkcipher rblkcipher;
501501

502-
snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher");
503-
snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
504-
alg->cra_blkcipher.geniv ?: "<default>");
502+
strncpy(rblkcipher.type, "blkcipher", sizeof(rblkcipher.type));
503+
strncpy(rblkcipher.geniv, alg->cra_blkcipher.geniv ?: "<default>",
504+
sizeof(rblkcipher.geniv));
505505

506506
rblkcipher.blocksize = alg->cra_blocksize;
507507
rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;

Diff for: crypto/crypto_user.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
7575
{
7676
struct crypto_report_cipher rcipher;
7777

78-
snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher");
78+
strncpy(rcipher.type, "cipher", sizeof(rcipher.type));
7979

8080
rcipher.blocksize = alg->cra_blocksize;
8181
rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
@@ -94,8 +94,7 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
9494
{
9595
struct crypto_report_comp rcomp;
9696

97-
snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression");
98-
97+
strncpy(rcomp.type, "compression", sizeof(rcomp.type));
9998
if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
10099
sizeof(struct crypto_report_comp), &rcomp))
101100
goto nla_put_failure;
@@ -108,12 +107,14 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
108107
static int crypto_report_one(struct crypto_alg *alg,
109108
struct crypto_user_alg *ualg, struct sk_buff *skb)
110109
{
111-
memcpy(&ualg->cru_name, &alg->cra_name, sizeof(ualg->cru_name));
112-
memcpy(&ualg->cru_driver_name, &alg->cra_driver_name,
113-
sizeof(ualg->cru_driver_name));
114-
memcpy(&ualg->cru_module_name, module_name(alg->cra_module),
115-
CRYPTO_MAX_ALG_NAME);
116-
110+
strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
111+
strncpy(ualg->cru_driver_name, alg->cra_driver_name,
112+
sizeof(ualg->cru_driver_name));
113+
strncpy(ualg->cru_module_name, module_name(alg->cra_module),
114+
sizeof(ualg->cru_module_name));
115+
116+
ualg->cru_type = 0;
117+
ualg->cru_mask = 0;
117118
ualg->cru_flags = alg->cra_flags;
118119
ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
119120

@@ -122,8 +123,7 @@ static int crypto_report_one(struct crypto_alg *alg,
122123
if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
123124
struct crypto_report_larval rl;
124125

125-
snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval");
126-
126+
strncpy(rl.type, "larval", sizeof(rl.type));
127127
if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
128128
sizeof(struct crypto_report_larval), &rl))
129129
goto nla_put_failure;

Diff for: crypto/pcompress.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
5353
{
5454
struct crypto_report_comp rpcomp;
5555

56-
snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp");
57-
56+
strncpy(rpcomp.type, "pcomp", sizeof(rpcomp.type));
5857
if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
5958
sizeof(struct crypto_report_comp), &rpcomp))
6059
goto nla_put_failure;

Diff for: crypto/rng.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
6565
{
6666
struct crypto_report_rng rrng;
6767

68-
snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng");
68+
strncpy(rrng.type, "rng", sizeof(rrng.type));
6969

7070
rrng.seedsize = alg->cra_rng.seedsize;
7171

Diff for: crypto/shash.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
530530
struct crypto_report_hash rhash;
531531
struct shash_alg *salg = __crypto_shash_alg(alg);
532532

533-
snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash");
533+
strncpy(rhash.type, "shash", sizeof(rhash.type));
534+
534535
rhash.blocksize = alg->cra_blocksize;
535536
rhash.digestsize = salg->digestsize;
536537

0 commit comments

Comments
 (0)