Commit 32e2524a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto fixes from Herbert Xu:
 "This fixes the following issues:

   - Potential memory overwrite in simd

   - Kernel info leaks in crypto_user

   - NULL dereference and use-after-free in hisilicon"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: user - Zeroize whole structure given to user space
  crypto: user - fix leaking uninitialized memory to userspace
  crypto: simd - correctly take reqsize of wrapped skcipher into account
  crypto: hisilicon - Fix reference after free of memories on error path
  crypto: hisilicon - Fix NULL dereference for same dst and src
parents 4efd3460 9f4debe3
...@@ -84,7 +84,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -84,7 +84,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
{ {
struct crypto_report_cipher rcipher; 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.blocksize = alg->cra_blocksize;
rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; 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) ...@@ -103,7 +103,7 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
{ {
struct crypto_report_comp rcomp; 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, if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
sizeof(struct crypto_report_comp), &rcomp)) sizeof(struct crypto_report_comp), &rcomp))
goto nla_put_failure; goto nla_put_failure;
...@@ -117,7 +117,7 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -117,7 +117,7 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg)
{ {
struct crypto_report_acomp racomp; 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, if (nla_put(skb, CRYPTOCFGA_REPORT_ACOMP,
sizeof(struct crypto_report_acomp), &racomp)) sizeof(struct crypto_report_acomp), &racomp))
...@@ -132,7 +132,7 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -132,7 +132,7 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
{ {
struct crypto_report_akcipher rakcipher; 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, if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
sizeof(struct crypto_report_akcipher), &rakcipher)) sizeof(struct crypto_report_akcipher), &rakcipher))
...@@ -147,7 +147,7 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -147,7 +147,7 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
{ {
struct crypto_report_kpp rkpp; 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, if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
sizeof(struct crypto_report_kpp), &rkpp)) sizeof(struct crypto_report_kpp), &rkpp))
...@@ -161,10 +161,10 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -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, static int crypto_report_one(struct crypto_alg *alg,
struct crypto_user_alg *ualg, struct sk_buff *skb) struct crypto_user_alg *ualg, struct sk_buff *skb)
{ {
strlcpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name)); strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
strlcpy(ualg->cru_driver_name, alg->cra_driver_name, strncpy(ualg->cru_driver_name, alg->cra_driver_name,
sizeof(ualg->cru_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)); sizeof(ualg->cru_module_name));
ualg->cru_type = 0; ualg->cru_type = 0;
...@@ -177,7 +177,7 @@ static int crypto_report_one(struct crypto_alg *alg, ...@@ -177,7 +177,7 @@ static int crypto_report_one(struct crypto_alg *alg,
if (alg->cra_flags & CRYPTO_ALG_LARVAL) { if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
struct crypto_report_larval rl; 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, if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
sizeof(struct crypto_report_larval), &rl)) sizeof(struct crypto_report_larval), &rl))
goto nla_put_failure; goto nla_put_failure;
......
...@@ -37,6 +37,8 @@ static int crypto_report_aead(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -37,6 +37,8 @@ static int crypto_report_aead(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&raead, 0, sizeof(raead));
strncpy(raead.type, "aead", sizeof(raead.type)); strncpy(raead.type, "aead", sizeof(raead.type));
v32 = atomic_read(&alg->encrypt_cnt); v32 = atomic_read(&alg->encrypt_cnt);
...@@ -65,6 +67,8 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -65,6 +67,8 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&rcipher, 0, sizeof(rcipher));
strlcpy(rcipher.type, "cipher", sizeof(rcipher.type)); strlcpy(rcipher.type, "cipher", sizeof(rcipher.type));
v32 = atomic_read(&alg->encrypt_cnt); v32 = atomic_read(&alg->encrypt_cnt);
...@@ -93,6 +97,8 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -93,6 +97,8 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&rcomp, 0, sizeof(rcomp));
strlcpy(rcomp.type, "compression", sizeof(rcomp.type)); strlcpy(rcomp.type, "compression", sizeof(rcomp.type));
v32 = atomic_read(&alg->compress_cnt); v32 = atomic_read(&alg->compress_cnt);
rcomp.stat_compress_cnt = v32; rcomp.stat_compress_cnt = v32;
...@@ -120,6 +126,8 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -120,6 +126,8 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&racomp, 0, sizeof(racomp));
strlcpy(racomp.type, "acomp", sizeof(racomp.type)); strlcpy(racomp.type, "acomp", sizeof(racomp.type));
v32 = atomic_read(&alg->compress_cnt); v32 = atomic_read(&alg->compress_cnt);
racomp.stat_compress_cnt = v32; racomp.stat_compress_cnt = v32;
...@@ -147,6 +155,8 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -147,6 +155,8 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&rakcipher, 0, sizeof(rakcipher));
strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type)); strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
v32 = atomic_read(&alg->encrypt_cnt); v32 = atomic_read(&alg->encrypt_cnt);
rakcipher.stat_encrypt_cnt = v32; rakcipher.stat_encrypt_cnt = v32;
...@@ -177,6 +187,8 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -177,6 +187,8 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
struct crypto_stat rkpp; struct crypto_stat rkpp;
u32 v; u32 v;
memset(&rkpp, 0, sizeof(rkpp));
strlcpy(rkpp.type, "kpp", sizeof(rkpp.type)); strlcpy(rkpp.type, "kpp", sizeof(rkpp.type));
v = atomic_read(&alg->setsecret_cnt); v = atomic_read(&alg->setsecret_cnt);
...@@ -203,6 +215,8 @@ static int crypto_report_ahash(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -203,6 +215,8 @@ static int crypto_report_ahash(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&rhash, 0, sizeof(rhash));
strncpy(rhash.type, "ahash", sizeof(rhash.type)); strncpy(rhash.type, "ahash", sizeof(rhash.type));
v32 = atomic_read(&alg->hash_cnt); v32 = atomic_read(&alg->hash_cnt);
...@@ -227,6 +241,8 @@ static int crypto_report_shash(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -227,6 +241,8 @@ static int crypto_report_shash(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&rhash, 0, sizeof(rhash));
strncpy(rhash.type, "shash", sizeof(rhash.type)); strncpy(rhash.type, "shash", sizeof(rhash.type));
v32 = atomic_read(&alg->hash_cnt); v32 = atomic_read(&alg->hash_cnt);
...@@ -251,6 +267,8 @@ static int crypto_report_rng(struct sk_buff *skb, struct crypto_alg *alg) ...@@ -251,6 +267,8 @@ static int crypto_report_rng(struct sk_buff *skb, struct crypto_alg *alg)
u64 v64; u64 v64;
u32 v32; u32 v32;
memset(&rrng, 0, sizeof(rrng));
strncpy(rrng.type, "rng", sizeof(rrng.type)); strncpy(rrng.type, "rng", sizeof(rrng.type));
v32 = atomic_read(&alg->generate_cnt); v32 = atomic_read(&alg->generate_cnt);
...@@ -275,6 +293,8 @@ static int crypto_reportstat_one(struct crypto_alg *alg, ...@@ -275,6 +293,8 @@ static int crypto_reportstat_one(struct crypto_alg *alg,
struct crypto_user_alg *ualg, struct crypto_user_alg *ualg,
struct sk_buff *skb) struct sk_buff *skb)
{ {
memset(ualg, 0, sizeof(*ualg));
strlcpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name)); strlcpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
strlcpy(ualg->cru_driver_name, alg->cra_driver_name, strlcpy(ualg->cru_driver_name, alg->cra_driver_name,
sizeof(ualg->cru_driver_name)); sizeof(ualg->cru_driver_name));
...@@ -291,6 +311,7 @@ static int crypto_reportstat_one(struct crypto_alg *alg, ...@@ -291,6 +311,7 @@ static int crypto_reportstat_one(struct crypto_alg *alg,
if (alg->cra_flags & CRYPTO_ALG_LARVAL) { if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
struct crypto_stat rl; struct crypto_stat rl;
memset(&rl, 0, sizeof(rl));
strlcpy(rl.type, "larval", sizeof(rl.type)); strlcpy(rl.type, "larval", sizeof(rl.type));
if (nla_put(skb, CRYPTOCFGA_STAT_LARVAL, if (nla_put(skb, CRYPTOCFGA_STAT_LARVAL,
sizeof(struct crypto_stat), &rl)) sizeof(struct crypto_stat), &rl))
......
...@@ -124,8 +124,9 @@ static int simd_skcipher_init(struct crypto_skcipher *tfm) ...@@ -124,8 +124,9 @@ static int simd_skcipher_init(struct crypto_skcipher *tfm)
ctx->cryptd_tfm = cryptd_tfm; ctx->cryptd_tfm = cryptd_tfm;
reqsize = sizeof(struct skcipher_request); reqsize = crypto_skcipher_reqsize(cryptd_skcipher_child(cryptd_tfm));
reqsize += crypto_skcipher_reqsize(&cryptd_tfm->base); reqsize = max(reqsize, crypto_skcipher_reqsize(&cryptd_tfm->base));
reqsize += sizeof(struct skcipher_request);
crypto_skcipher_set_reqsize(tfm, reqsize); crypto_skcipher_set_reqsize(tfm, reqsize);
......
...@@ -732,6 +732,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -732,6 +732,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
int *splits_in_nents; int *splits_in_nents;
int *splits_out_nents = NULL; int *splits_out_nents = NULL;
struct sec_request_el *el, *temp; struct sec_request_el *el, *temp;
bool split = skreq->src != skreq->dst;
mutex_init(&sec_req->lock); mutex_init(&sec_req->lock);
sec_req->req_base = &skreq->base; sec_req->req_base = &skreq->base;
...@@ -750,7 +751,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -750,7 +751,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
if (ret) if (ret)
goto err_free_split_sizes; goto err_free_split_sizes;
if (skreq->src != skreq->dst) { if (split) {
sec_req->len_out = sg_nents(skreq->dst); sec_req->len_out = sg_nents(skreq->dst);
ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps, ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps,
&splits_out, &splits_out_nents, &splits_out, &splits_out_nents,
...@@ -785,8 +786,9 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -785,8 +786,9 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
split_sizes[i], split_sizes[i],
skreq->src != skreq->dst, skreq->src != skreq->dst,
splits_in[i], splits_in_nents[i], splits_in[i], splits_in_nents[i],
splits_out[i], split ? splits_out[i] : NULL,
splits_out_nents[i], info); split ? splits_out_nents[i] : 0,
info);
if (IS_ERR(el)) { if (IS_ERR(el)) {
ret = PTR_ERR(el); ret = PTR_ERR(el);
goto err_free_elements; goto err_free_elements;
...@@ -806,13 +808,6 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -806,13 +808,6 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
* more refined but this is unlikely to happen so no need. * more refined but this is unlikely to happen so no need.
*/ */
/* Cleanup - all elements in pointer arrays have been coppied */
kfree(splits_in_nents);
kfree(splits_in);
kfree(splits_out_nents);
kfree(splits_out);
kfree(split_sizes);
/* Grab a big lock for a long time to avoid concurrency issues */ /* Grab a big lock for a long time to avoid concurrency issues */
mutex_lock(&queue->queuelock); mutex_lock(&queue->queuelock);
...@@ -827,13 +822,13 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -827,13 +822,13 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
(!queue->havesoftqueue || (!queue->havesoftqueue ||
kfifo_avail(&queue->softqueue) > steps)) || kfifo_avail(&queue->softqueue) > steps)) ||
!list_empty(&ctx->backlog)) { !list_empty(&ctx->backlog)) {
ret = -EBUSY;
if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
list_add_tail(&sec_req->backlog_head, &ctx->backlog); list_add_tail(&sec_req->backlog_head, &ctx->backlog);
mutex_unlock(&queue->queuelock); mutex_unlock(&queue->queuelock);
return -EBUSY; goto out;
} }
ret = -EBUSY;
mutex_unlock(&queue->queuelock); mutex_unlock(&queue->queuelock);
goto err_free_elements; goto err_free_elements;
} }
...@@ -842,7 +837,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -842,7 +837,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
if (ret) if (ret)
goto err_free_elements; goto err_free_elements;
return -EINPROGRESS; ret = -EINPROGRESS;
out:
/* Cleanup - all elements in pointer arrays have been copied */
kfree(splits_in_nents);
kfree(splits_in);
kfree(splits_out_nents);
kfree(splits_out);
kfree(split_sizes);
return ret;
err_free_elements: err_free_elements:
list_for_each_entry_safe(el, temp, &sec_req->elements, head) { list_for_each_entry_safe(el, temp, &sec_req->elements, head) {
...@@ -854,7 +857,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, ...@@ -854,7 +857,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
crypto_skcipher_ivsize(atfm), crypto_skcipher_ivsize(atfm),
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
err_unmap_out_sg: err_unmap_out_sg:
if (skreq->src != skreq->dst) if (split)
sec_unmap_sg_on_err(skreq->dst, steps, splits_out, sec_unmap_sg_on_err(skreq->dst, steps, splits_out,
splits_out_nents, sec_req->len_out, splits_out_nents, sec_req->len_out,
info->dev); info->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment