forked from Minki/linux
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
This commit is contained in:
commit
32e2524a52
@ -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 @@ nla_put_failure:
|
||||
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;
|
||||
|
@ -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))
|
||||
|
@ -124,8 +124,9 @@ static int simd_skcipher_init(struct crypto_skcipher *tfm)
|
||||
|
||||
ctx->cryptd_tfm = cryptd_tfm;
|
||||
|
||||
reqsize = sizeof(struct skcipher_request);
|
||||
reqsize += crypto_skcipher_reqsize(&cryptd_tfm->base);
|
||||
reqsize = crypto_skcipher_reqsize(cryptd_skcipher_child(cryptd_tfm));
|
||||
reqsize = max(reqsize, crypto_skcipher_reqsize(&cryptd_tfm->base));
|
||||
reqsize += sizeof(struct skcipher_request);
|
||||
|
||||
crypto_skcipher_set_reqsize(tfm, reqsize);
|
||||
|
||||
|
@ -732,6 +732,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
|
||||
int *splits_in_nents;
|
||||
int *splits_out_nents = NULL;
|
||||
struct sec_request_el *el, *temp;
|
||||
bool split = skreq->src != skreq->dst;
|
||||
|
||||
mutex_init(&sec_req->lock);
|
||||
sec_req->req_base = &skreq->base;
|
||||
@ -750,7 +751,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
|
||||
if (ret)
|
||||
goto err_free_split_sizes;
|
||||
|
||||
if (skreq->src != skreq->dst) {
|
||||
if (split) {
|
||||
sec_req->len_out = sg_nents(skreq->dst);
|
||||
ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps,
|
||||
&splits_out, &splits_out_nents,
|
||||
@ -785,8 +786,9 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
|
||||
split_sizes[i],
|
||||
skreq->src != skreq->dst,
|
||||
splits_in[i], splits_in_nents[i],
|
||||
splits_out[i],
|
||||
splits_out_nents[i], info);
|
||||
split ? splits_out[i] : NULL,
|
||||
split ? splits_out_nents[i] : 0,
|
||||
info);
|
||||
if (IS_ERR(el)) {
|
||||
ret = PTR_ERR(el);
|
||||
goto err_free_elements;
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
mutex_lock(&queue->queuelock);
|
||||
|
||||
@ -827,13 +822,13 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
|
||||
(!queue->havesoftqueue ||
|
||||
kfifo_avail(&queue->softqueue) > steps)) ||
|
||||
!list_empty(&ctx->backlog)) {
|
||||
ret = -EBUSY;
|
||||
if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
|
||||
list_add_tail(&sec_req->backlog_head, &ctx->backlog);
|
||||
mutex_unlock(&queue->queuelock);
|
||||
return -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EBUSY;
|
||||
mutex_unlock(&queue->queuelock);
|
||||
goto err_free_elements;
|
||||
}
|
||||
@ -842,7 +837,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
|
||||
if (ret)
|
||||
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:
|
||||
list_for_each_entry_safe(el, temp, &sec_req->elements, head) {
|
||||
@ -854,7 +857,7 @@ err_free_elements:
|
||||
crypto_skcipher_ivsize(atfm),
|
||||
DMA_BIDIRECTIONAL);
|
||||
err_unmap_out_sg:
|
||||
if (skreq->src != skreq->dst)
|
||||
if (split)
|
||||
sec_unmap_sg_on_err(skreq->dst, steps, splits_out,
|
||||
splits_out_nents, sec_req->len_out,
|
||||
info->dev);
|
||||
|
Loading…
Reference in New Issue
Block a user