crypto: crypto_user reporting fixes and cleanups
cover crypto: crypto_user reporting fixes and cleanups
This series fixes all the information leaks in crypto_user reporting, removes some redundant reporting functions, and makes some changes to reduce the chance of similar information leaks in the future. Patch 2 is based on a patch already sent by Corentin Labbe, but it was incomplete so I fixed it.
Corentin Labbe (1):
crypto: crypto_user_stat - Zeroize whole structure given to user space
Eric Biggers (3):
crypto: crypto_user - fix leaking uninitialized memory to userspace
crypto: crypto_user - remove redundant reporting functions
crypto: crypto_user - clean up report structure copying
crypto/ablkcipher.c | 32 ++++------ crypto/acompress.c | 10 +--- crypto/aead.c | 14 ++--- crypto/ahash.c | 12 ++-- crypto/akcipher.c | 11 ++-- crypto/blkcipher.c | 16 ++--- crypto/crypto_user_base.c | 95 +++++------------------------ crypto/crypto_user_stat.c | 123 ++++++++++++++------------------------ crypto/kpp.c | 10 +--- crypto/rng.c | 12 ++-- crypto/scompress.c | 11 ++-- crypto/shash.c | 12 ++-- crypto/skcipher.c | 15 ++--- 13 files changed, 116 insertions(+), 257 deletions(-)
Signature · 1 line
2.19.1
PATCH 1/4 crypto: crypto_user - fix leaking uninitialized memory to userspace
From: Eric Biggers <[email protected]>
All bytes of the NETLINK_CRYPTO report structures must be initialized, since they are copied to userspace. The change from strncpy() to strlcpy() broke this. As a minimal fix, change it back.
--- crypto/crypto_user_base.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
crypto/crypto_user_base.c +9 -9
@@ -84,7 +84,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_cipher rcipher; -strlcpy (rcipher.type,"cipher" ,sizeof (rcipher.type)); +strncpy (rcipher.type,"cipher" ,sizeof (rcipher.type)); rcipher.blocksize = alg->cra_blocksize; rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
@@ -103,7 +103,7 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_comp rcomp; -strlcpy (rcomp.type,"compression" ,sizeof (rcomp.type)); +strncpy (rcomp.type,"compression" ,sizeof (rcomp.type));if (nla_put (skb,CRYPTOCFGA_REPORT_COMPRESS ,sizeof (struct crypto_report_comp ), &rcomp)) goto nla_put_failure;
@@ -117,7 +117,7 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_acomp racomp; -strlcpy (racomp.type,"acomp" ,sizeof (racomp.type)); +strncpy (racomp.type,"acomp" ,sizeof (racomp.type));if (nla_put (skb,CRYPTOCFGA_REPORT_ACOMP ,sizeof (struct crypto_report_acomp ), &racomp))
@@ -132,7 +132,7 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_akcipher rakcipher; -strlcpy (rakcipher.type,"akcipher" ,sizeof (rakcipher.type)); +strncpy (rakcipher.type,"akcipher" ,sizeof (rakcipher.type));if (nla_put (skb,CRYPTOCFGA_REPORT_AKCIPHER ,sizeof (struct crypto_report_akcipher ), &rakcipher))
@@ -147,7 +147,7 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_kpp rkpp; -strlcpy (rkpp.type,"kpp" ,sizeof (rkpp.type)); +strncpy (rkpp.type,"kpp" ,sizeof (rkpp.type));if (nla_put (skb,CRYPTOCFGA_REPORT_KPP ,sizeof (struct crypto_report_kpp ), &rkpp))
@@ -161,10 +161,10 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)static int crypto_report_one (struct crypto_alg *alg,struct crypto_user_alg *ualg,struct sk_buff *skb) { -strlcpy (ualg->cru_name, alg->cra_name,sizeof (ualg->cru_name)); -strlcpy (ualg->cru_driver_name, alg->cra_driver_name, +strncpy (ualg->cru_name, alg->cra_name,sizeof (ualg->cru_name)); +strncpy (ualg->cru_driver_name, alg->cra_driver_name,sizeof (ualg->cru_driver_name)); -strlcpy (ualg->cru_module_name,module_name (alg->cra_module), +strncpy (ualg->cru_module_name,module_name (alg->cra_module),sizeof (ualg->cru_module_name)); ualg->cru_type =0 ;
@@ -177,7 +177,7 @@ static int crypto_report_one(struct crypto_alg *alg,if (alg->cra_flags &CRYPTO_ALG_LARVAL ) {struct crypto_report_larval rl; -strlcpy (rl.type,"larval" ,sizeof (rl.type)); +strncpy (rl.type,"larval" ,sizeof (rl.type));if (nla_put (skb,CRYPTOCFGA_REPORT_LARVAL ,sizeof (struct crypto_report_larval ), &rl)) goto nla_put_failure;
Signature · 1 line
2.19.1
PATCH 2/4 crypto: crypto_user_stat - Zeroize whole structure given to user space
In reply to Eric BiggersFrom: Corentin Labbe <[email protected]>
For preventing uninitialized data to be given to user-space (and so leak potential useful data), the crypto_stat structure must be correctly initialized.
--- crypto/crypto_user_stat.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
crypto/crypto_user_stat.c +21 -0
@@ -37,6 +37,8 @@ static int crypto_report_aead(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&raead,0 ,sizeof (raead)); +strncpy (raead.type,"aead" ,sizeof (raead.type)); v32 =atomic_read (&alg->encrypt_cnt);
@@ -65,6 +67,8 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&rcipher,0 ,sizeof (rcipher)); +strlcpy (rcipher.type,"cipher" ,sizeof (rcipher.type)); v32 =atomic_read (&alg->encrypt_cnt);
@@ -93,6 +97,8 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&rcomp,0 ,sizeof (rcomp)); +strlcpy (rcomp.type,"compression" ,sizeof (rcomp.type)); v32 =atomic_read (&alg->compress_cnt); rcomp.stat_compress_cnt = v32;
@@ -120,6 +126,8 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&racomp,0 ,sizeof (racomp)); +strlcpy (racomp.type,"acomp" ,sizeof (racomp.type)); v32 =atomic_read (&alg->compress_cnt); racomp.stat_compress_cnt = v32;
@@ -147,6 +155,8 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&rakcipher,0 ,sizeof (rakcipher)); +strncpy (rakcipher.type,"akcipher" ,sizeof (rakcipher.type)); v32 =atomic_read (&alg->encrypt_cnt); rakcipher.stat_encrypt_cnt = v32;
@@ -177,6 +187,8 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)struct crypto_stat rkpp;u32 v; +memset (&rkpp,0 ,sizeof (rkpp)); +strlcpy (rkpp.type,"kpp" ,sizeof (rkpp.type)); v =atomic_read (&alg->setsecret_cnt);
@@ -203,6 +215,8 @@ static int crypto_report_ahash(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&rhash,0 ,sizeof (rhash)); +strncpy (rhash.type,"ahash" ,sizeof (rhash.type)); v32 =atomic_read (&alg->hash_cnt);
@@ -227,6 +241,8 @@ static int crypto_report_shash(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&rhash,0 ,sizeof (rhash)); +strncpy (rhash.type,"shash" ,sizeof (rhash.type)); v32 =atomic_read (&alg->hash_cnt);
@@ -251,6 +267,8 @@ static int crypto_report_rng(struct sk_buff *skb, struct crypto_alg *alg)u64 v64;u32 v32; +memset (&rrng,0 ,sizeof (rrng)); +strncpy (rrng.type,"rng" ,sizeof (rrng.type)); v32 =atomic_read (&alg->generate_cnt);
@@ -275,6 +293,8 @@ static int crypto_reportstat_one(struct crypto_alg *alg,struct crypto_user_alg *ualg, struct sk_buff *skb) { + memset(ualg, 0, sizeof(*ualg)); +strlcpy (ualg->cru_name, alg->cra_name,sizeof (ualg->cru_name));strlcpy (ualg->cru_driver_name, alg->cra_driver_name,sizeof (ualg->cru_driver_name));
@@ -291,6 +311,7 @@ static int crypto_reportstat_one(struct crypto_alg *alg,if (alg->cra_flags &CRYPTO_ALG_LARVAL ) {struct crypto_stat rl; +memset (&rl,0 ,sizeof (rl));strlcpy (rl.type,"larval" ,sizeof (rl.type));if (nla_put (skb,CRYPTOCFGA_STAT_LARVAL ,sizeof (struct crypto_stat ), &rl))
Signature · 1 line
2.19.1
PATCH 3/4 crypto: crypto_user - remove redundant reporting functions
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
The acomp, akcipher, and kpp algorithm types already have .report methods defined, so there's no need to duplicate this functionality in crypto_user itself; the duplicate functions are actually never executed. Remove the unused code.
--- crypto/crypto_user_base.c | 59 --------------------------------------- 1 file changed, 59 deletions(-)
crypto/crypto_user_base.c +0 -59
@@ -113,51 +113,6 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)return -EMSGSIZE ; } -static int crypto_report_acomp (struct sk_buff *skb,struct crypto_alg *alg) -{ -struct crypto_report_acomp racomp; - -strncpy (racomp.type,"acomp" ,sizeof (racomp.type)); - -if (nla_put (skb,CRYPTOCFGA_REPORT_ACOMP , -sizeof (struct crypto_report_acomp ), &racomp)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; -} - -static int crypto_report_akcipher (struct sk_buff *skb,struct crypto_alg *alg) -{ -struct crypto_report_akcipher rakcipher; - -strncpy (rakcipher.type,"akcipher" ,sizeof (rakcipher.type)); - -if (nla_put (skb,CRYPTOCFGA_REPORT_AKCIPHER , -sizeof (struct crypto_report_akcipher ), &rakcipher)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; -} - -static int crypto_report_kpp (struct sk_buff *skb,struct crypto_alg *alg) -{ -struct crypto_report_kpp rkpp; - -strncpy (rkpp.type,"kpp" ,sizeof (rkpp.type)); - -if (nla_put (skb,CRYPTOCFGA_REPORT_KPP , -sizeof (struct crypto_report_kpp ), &rkpp)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; -} -static int crypto_report_one (struct crypto_alg *alg,struct crypto_user_alg *ualg,struct sk_buff *skb) {
@@ -202,20 +157,6 @@ static int crypto_report_one(struct crypto_alg *alg, goto nla_put_failure;break ; -case CRYPTO_ALG_TYPE_ACOMPRESS : -if (crypto_report_acomp (skb, alg)) - goto nla_put_failure; - -break ; -case CRYPTO_ALG_TYPE_AKCIPHER : -if (crypto_report_akcipher (skb, alg)) - goto nla_put_failure; - -break ; -case CRYPTO_ALG_TYPE_KPP : -if (crypto_report_kpp (skb, alg)) - goto nla_put_failure; -break ; } out:
Signature · 1 line
2.19.1
PATCH 4/4 crypto: crypto_user - clean up report structure copying
In reply to Eric BiggersFrom: Eric Biggers <[email protected]>
There have been a pretty ridiculous number of issues with initializing the report structures that are copied to userspace by NETLINK_CRYPTO. Commit 4473710df1f8 ("crypto: user - Prepare for CRYPTO_MAX_ALG_NAME expansion") replaced some strncpy()s with strlcpy()s, thereby introducing information leaks. Later two other people tried to replace other strncpy()s with strlcpy() too, which would have introduced even more information leaks:
- https://lore.kernel.org/patchwork/patch/954991/
- https://patchwork.kernel.org/patch/10434351/
Commit cac5818c25d0 ("crypto: user - Implement a generic crypto statistics") also uses the buggy strlcpy() approach and therefore leaks uninitialized memory to userspace. A fix was proposed, but it was originally incomplete.
Seeing as how apparently no one can get this right with the current approach, change all the reporting functions to:
- Start by memsetting the report structure to 0. This guarantees it's always initialized, regardless of what happens later.
- Initialize all strings using strscpy(). This is safe after the memset, ensures null termination of long strings, avoids unnecessary work, and avoids the -Wstringop-truncation warnings from gcc.
- Use sizeof(var) instead of sizeof(type). This is more robust against copy+paste errors.
For simplicity, also reuse the -EMSGSIZE return value from nla_put().
--- crypto/ablkcipher.c | 32 +++++------- crypto/acompress.c | 10 ++-- crypto/aead.c | 14 ++---- crypto/ahash.c | 12 ++--- crypto/akcipher.c | 11 ++-- crypto/blkcipher.c | 16 +++--- crypto/crypto_user_base.c | 38 +++++++------- crypto/crypto_user_stat.c | 102 +++++++++----------------------------- crypto/kpp.c | 10 ++-- crypto/rng.c | 12 ++--- crypto/scompress.c | 11 ++-- crypto/shash.c | 12 ++--- crypto/skcipher.c | 15 +++--- 13 files changed, 96 insertions(+), 199 deletions(-)
crypto/ablkcipher.c +12 -20
@@ -365,23 +365,19 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_blkcipher rblkcipher; -strncpy (rblkcipher.type,"ablkcipher" ,sizeof (rblkcipher.type)); -strncpy (rblkcipher.geniv, alg->cra_ablkcipher.geniv ?:"<default>" , +memset (&rblkcipher,0 ,sizeof (rblkcipher)); + +strscpy (rblkcipher.type,"ablkcipher" ,sizeof (rblkcipher.type)); +strscpy (rblkcipher.geniv, alg->cra_ablkcipher.geniv ?:"<default>" ,sizeof (rblkcipher.geniv)); - rblkcipher.geniv[sizeof (rblkcipher.geniv) -1 ] ='\0' ; rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize; rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize; rblkcipher.ivsize = alg->cra_ablkcipher.ivsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , -sizeof (struct crypto_report_blkcipher ), &rblkcipher)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , +sizeof (rblkcipher), &rblkcipher); }#else static int crypto_ablkcipher_report (struct sk_buff *skb,struct crypto_alg *alg)
@@ -440,23 +436,19 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_blkcipher rblkcipher; -strncpy (rblkcipher.type,"givcipher" ,sizeof (rblkcipher.type)); -strncpy (rblkcipher.geniv, alg->cra_ablkcipher.geniv ?:"<built-in>" , +memset (&rblkcipher,0 ,sizeof (rblkcipher)); + +strscpy (rblkcipher.type,"givcipher" ,sizeof (rblkcipher.type)); +strscpy (rblkcipher.geniv, alg->cra_ablkcipher.geniv ?:"<built-in>" ,sizeof (rblkcipher.geniv)); - rblkcipher.geniv[sizeof (rblkcipher.geniv) -1 ] ='\0' ; rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize; rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize; rblkcipher.ivsize = alg->cra_ablkcipher.ivsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , -sizeof (struct crypto_report_blkcipher ), &rblkcipher)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , +sizeof (rblkcipher), &rblkcipher); }#else static int crypto_givcipher_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/acompress.c +3 -7
@@ -33,15 +33,11 @@ static int crypto_acomp_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_acomp racomp; -strncpy (racomp.type,"acomp" ,sizeof (racomp.type)); +memset (&racomp,0 ,sizeof (racomp)); -if (nla_put (skb,CRYPTOCFGA_REPORT_ACOMP , -sizeof (struct crypto_report_acomp ), &racomp)) - goto nla_put_failure; -return 0 ; +strscpy (racomp.type,"acomp" ,sizeof (racomp.type)); -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_ACOMP ,sizeof (racomp), &racomp); }#else static int crypto_acomp_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/aead.c +5 -9
@@ -119,20 +119,16 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)struct crypto_report_aead raead; struct aead_alg *aead = container_of(alg, struct aead_alg, base); -strncpy (raead.type,"aead" ,sizeof (raead.type)); -strncpy (raead.geniv,"<none>" ,sizeof (raead.geniv)); +memset (&raead,0 ,sizeof (raead)); + +strscpy (raead.type,"aead" ,sizeof (raead.type)); +strscpy (raead.geniv,"<none>" ,sizeof (raead.geniv)); raead.blocksize = alg->cra_blocksize; raead.maxauthsize = aead->maxauthsize; raead.ivsize = aead->ivsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_AEAD , -sizeof (struct crypto_report_aead ), &raead)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: - return -EMSGSIZE; + return nla_put(skb, CRYPTOCFGA_REPORT_AEAD, sizeof(raead), &raead); }#else static int crypto_aead_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/ahash.c +4 -8
@@ -498,18 +498,14 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_hash rhash; -strncpy (rhash.type,"ahash" ,sizeof (rhash.type)); +memset (&rhash,0 ,sizeof (rhash)); + +strscpy (rhash.type,"ahash" ,sizeof (rhash.type)); rhash.blocksize = alg->cra_blocksize; rhash.digestsize =__crypto_hash_alg_common (alg)->digestsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_HASH , -sizeof (struct crypto_report_hash ), &rhash)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_HASH ,sizeof (rhash), &rhash); }#else static int crypto_ahash_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/akcipher.c +4 -7
@@ -30,15 +30,12 @@ static int crypto_akcipher_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_akcipher rakcipher; -strncpy (rakcipher.type,"akcipher" ,sizeof (rakcipher.type)); +memset (&rakcipher,0 ,sizeof (rakcipher)); -if (nla_put (skb,CRYPTOCFGA_REPORT_AKCIPHER , -sizeof (struct crypto_report_akcipher ), &rakcipher)) - goto nla_put_failure; -return 0 ; +strscpy (rakcipher.type,"akcipher" ,sizeof (rakcipher.type)); -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_AKCIPHER , +sizeof (rakcipher), &rakcipher); }#else static int crypto_akcipher_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/blkcipher.c +6 -10
@@ -507,23 +507,19 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_blkcipher rblkcipher; -strncpy (rblkcipher.type,"blkcipher" ,sizeof (rblkcipher.type)); -strncpy (rblkcipher.geniv, alg->cra_blkcipher.geniv ?:"<default>" , +memset (&rblkcipher,0 ,sizeof (rblkcipher)); + +strscpy (rblkcipher.type,"blkcipher" ,sizeof (rblkcipher.type)); +strscpy (rblkcipher.geniv, alg->cra_blkcipher.geniv ?:"<default>" ,sizeof (rblkcipher.geniv)); - rblkcipher.geniv[sizeof (rblkcipher.geniv) -1 ] ='\0' ; rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize; rblkcipher.max_keysize = alg->cra_blkcipher.max_keysize; rblkcipher.ivsize = alg->cra_blkcipher.ivsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , -sizeof (struct crypto_report_blkcipher ), &rblkcipher)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , +sizeof (rblkcipher), &rblkcipher); }#else static int crypto_blkcipher_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/crypto_user_base.c +17 -21
@@ -84,42 +84,38 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_cipher rcipher; -strncpy (rcipher.type,"cipher" ,sizeof (rcipher.type)); +memset (&rcipher,0 ,sizeof (rcipher)); + +strscpy (rcipher.type,"cipher" ,sizeof (rcipher.type)); rcipher.blocksize = alg->cra_blocksize; rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; rcipher.max_keysize = alg->cra_cipher.cia_max_keysize; -if (nla_put (skb,CRYPTOCFGA_REPORT_CIPHER , -sizeof (struct crypto_report_cipher ), &rcipher)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_CIPHER , +sizeof (rcipher), &rcipher); }static int crypto_report_comp (struct sk_buff *skb,struct crypto_alg *alg) {struct crypto_report_comp rcomp; -strncpy (rcomp.type,"compression" ,sizeof (rcomp.type)); -if (nla_put (skb,CRYPTOCFGA_REPORT_COMPRESS , -sizeof (struct crypto_report_comp ), &rcomp)) - goto nla_put_failure; -return 0 ; +memset (&rcomp,0 ,sizeof (rcomp)); -nla_put_failure: -return -EMSGSIZE ; +strscpy (rcomp.type,"compression" ,sizeof (rcomp.type)); + +return nla_put (skb,CRYPTOCFGA_REPORT_COMPRESS ,sizeof (rcomp), &rcomp); }static int crypto_report_one (struct crypto_alg *alg,struct crypto_user_alg *ualg,struct sk_buff *skb) { -strncpy (ualg->cru_name, alg->cra_name,sizeof (ualg->cru_name)); -strncpy (ualg->cru_driver_name, alg->cra_driver_name, +memset (ualg,0 ,sizeof (*ualg)); + +strscpy (ualg->cru_name, alg->cra_name,sizeof (ualg->cru_name)); +strscpy (ualg->cru_driver_name, alg->cra_driver_name,sizeof (ualg->cru_driver_name)); -strncpy (ualg->cru_module_name,module_name (alg->cra_module), +strscpy (ualg->cru_module_name,module_name (alg->cra_module),sizeof (ualg->cru_module_name)); ualg->cru_type =0 ;
@@ -132,9 +128,9 @@ static int crypto_report_one(struct crypto_alg *alg,if (alg->cra_flags &CRYPTO_ALG_LARVAL ) {struct crypto_report_larval rl; -strncpy (rl.type,"larval" ,sizeof (rl.type)); -if (nla_put (skb,CRYPTOCFGA_REPORT_LARVAL , -sizeof (struct crypto_report_larval ), &rl)) +memset (&rl,0 ,sizeof (rl)); +strscpy (rl.type,"larval" ,sizeof (rl.type)); +if (nla_put (skb,CRYPTOCFGA_REPORT_LARVAL ,sizeof (rl), &rl)) goto nla_put_failure; goto out; }
crypto/crypto_user_stat.c +24 -78
223 lines not on this page · raw message
crypto/kpp.c +3 -7
@@ -30,15 +30,11 @@ static int crypto_kpp_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_kpp rkpp; -strncpy (rkpp.type,"kpp" ,sizeof (rkpp.type)); +memset (&rkpp,0 ,sizeof (rkpp)); -if (nla_put (skb,CRYPTOCFGA_REPORT_KPP , -sizeof (struct crypto_report_kpp ), &rkpp)) - goto nla_put_failure; -return 0 ; +strscpy (rkpp.type,"kpp" ,sizeof (rkpp.type)); -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_KPP ,sizeof (rkpp), &rkpp); }#else static int crypto_kpp_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/rng.c +4 -8
@@ -74,17 +74,13 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_rng rrng; -strncpy (rrng.type,"rng" ,sizeof (rrng.type)); +memset (&rrng,0 ,sizeof (rrng)); - rrng.seedsize =seedsize (alg); +strscpy (rrng.type,"rng" ,sizeof (rrng.type)); -if (nla_put (skb,CRYPTOCFGA_REPORT_RNG , -sizeof (struct crypto_report_rng ), &rrng)) - goto nla_put_failure; -return 0 ; + rrng.seedsize =seedsize (alg); -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_RNG ,sizeof (rrng), &rrng); }#else static int crypto_rng_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/scompress.c +4 -7
@@ -40,15 +40,12 @@ static int crypto_scomp_report(struct sk_buff *skb, struct crypto_alg *alg) {struct crypto_report_comp rscomp; -strncpy (rscomp.type,"scomp" ,sizeof (rscomp.type)); +memset (&rscomp,0 ,sizeof (rscomp)); -if (nla_put (skb,CRYPTOCFGA_REPORT_COMPRESS , -sizeof (struct crypto_report_comp ), &rscomp)) - goto nla_put_failure; -return 0 ; +strscpy (rscomp.type,"scomp" ,sizeof (rscomp.type)); -nla_put_failure: -return -EMSGSIZE ; +return nla_put (skb,CRYPTOCFGA_REPORT_COMPRESS , +sizeof (rscomp), &rscomp); }#else static int crypto_scomp_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/shash.c +4 -8
@@ -408,18 +408,14 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)struct crypto_report_hash rhash;struct shash_alg *salg =__crypto_shash_alg (alg); -strncpy (rhash.type,"shash" ,sizeof (rhash.type)); +memset (&rhash,0 ,sizeof (rhash)); + +strscpy (rhash.type,"shash" ,sizeof (rhash.type)); rhash.blocksize = alg->cra_blocksize; rhash.digestsize = salg->digestsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_HASH , -sizeof (struct crypto_report_hash ), &rhash)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: - return -EMSGSIZE; + return nla_put(skb, CRYPTOCFGA_REPORT_HASH, sizeof(rhash), &rhash); }#else static int crypto_shash_report (struct sk_buff *skb,struct crypto_alg *alg)
crypto/skcipher.c +6 -9
@@ -897,21 +897,18 @@ static int crypto_skcipher_report(struct sk_buff *skb, struct crypto_alg *alg) struct skcipher_alg *skcipher = container_of(alg, struct skcipher_alg, base); -strncpy (rblkcipher.type,"skcipher" ,sizeof (rblkcipher.type)); -strncpy (rblkcipher.geniv,"<none>" ,sizeof (rblkcipher.geniv)); +memset (&rblkcipher,0 ,sizeof (rblkcipher)); + +strscpy (rblkcipher.type,"skcipher" ,sizeof (rblkcipher.type)); +strscpy (rblkcipher.geniv,"<none>" ,sizeof (rblkcipher.geniv)); rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = skcipher->min_keysize; rblkcipher.max_keysize = skcipher->max_keysize; rblkcipher.ivsize = skcipher->ivsize; -if (nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , -sizeof (struct crypto_report_blkcipher ), &rblkcipher)) - goto nla_put_failure; -return 0 ; - -nla_put_failure: - return -EMSGSIZE; +return nla_put (skb,CRYPTOCFGA_REPORT_BLKCIPHER , + sizeof(rblkcipher), &rblkcipher); }#else static int crypto_skcipher_report (struct sk_buff *skb,struct crypto_alg *alg)
Signature · 1 line
2.19.1
Herbert Xu
maintainerQuoted 14 lines · Eric Biggers
This series fixes all the information leaks in
crypto_userreporting, removes some redundant reporting functions, and makes some changes to reduce the chance of similar information leaks in the future. Patch 2 is based on a patch already sent by Corentin Labbe, but it was incomplete so I fixed it.Corentin Labbe (1):
crypto:crypto_user_stat- Zeroize whole structure given to user spaceEric Biggers (3):
crypto:crypto_user- fix leaking uninitialized memory to userspace
crypto:crypto_user- remove redundant reporting functions
crypto:crypto_user- clean up report structure copying
Quoted 14 lines
crypto/ablkcipher.c | 32 ++++------ crypto/acompress.c | 10 +--- crypto/aead.c | 14 ++--- crypto/ahash.c | 12 ++-- crypto/akcipher.c | 11 ++-- crypto/blkcipher.c | 16 ++--- crypto/crypto_user_base.c | 95 +++++------------------------ crypto/crypto_user_stat.c | 123 ++++++++++++++------------------------ crypto/kpp.c | 10 +--- crypto/rng.c | 12 ++-- crypto/scompress.c | 11 ++-- crypto/shash.c | 12 ++-- crypto/skcipher.c | 15 ++--- 13 files changed, 116 insertions(+), 257 deletions(-)
All applied. Patches 1-2 went into crypto and 3-4 are in cryptodev.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt