aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2016-02-03 08:39:24 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2016-02-06 02:23:55 -0500
commitec69bbfb9902c32a5c1492f2b1b8ad032a66d724 (patch)
tree19763d06c1961ff7e32af742aaf05a1b14af4402 /crypto
parent63e41ebc6630f39422d87f8a4bade1e793f37a01 (diff)
crypto: algif_skcipher - Do not assume that req is unchanged
The async path in algif_skcipher assumes that the crypto completion function will be called with the original request. This is not necessarily the case. In fact there is no need for this anyway since we already embed information into the request with struct skcipher_async_req. This patch adds a pointer to that struct and then passes it as the data to the callback function. Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Tadeusz Struk <tadeusz.struk@intel.com>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algif_skcipher.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 38c1aa89d3a0..ec07a864b9c5 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -65,18 +65,10 @@ struct skcipher_async_req {
65 struct skcipher_async_rsgl first_sgl; 65 struct skcipher_async_rsgl first_sgl;
66 struct list_head list; 66 struct list_head list;
67 struct scatterlist *tsg; 67 struct scatterlist *tsg;
68 char iv[]; 68 atomic_t *inflight;
69 struct skcipher_request req;
69}; 70};
70 71
71#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
72 crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)))
73
74#define GET_REQ_SIZE(ctx) \
75 crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))
76
77#define GET_IV_SIZE(ctx) \
78 crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req))
79
80#define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \ 72#define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
81 sizeof(struct scatterlist) - 1) 73 sizeof(struct scatterlist) - 1)
82 74
@@ -102,15 +94,12 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq)
102 94
103static void skcipher_async_cb(struct crypto_async_request *req, int err) 95static void skcipher_async_cb(struct crypto_async_request *req, int err)
104{ 96{
105 struct sock *sk = req->data; 97 struct skcipher_async_req *sreq = req->data;
106 struct alg_sock *ask = alg_sk(sk);
107 struct skcipher_ctx *ctx = ask->private;
108 struct skcipher_async_req *sreq = GET_SREQ(req, ctx);
109 struct kiocb *iocb = sreq->iocb; 98 struct kiocb *iocb = sreq->iocb;
110 99
111 atomic_dec(&ctx->inflight); 100 atomic_dec(sreq->inflight);
112 skcipher_free_async_sgls(sreq); 101 skcipher_free_async_sgls(sreq);
113 kfree(req); 102 kzfree(sreq);
114 iocb->ki_complete(iocb, err, err); 103 iocb->ki_complete(iocb, err, err);
115} 104}
116 105
@@ -509,37 +498,42 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
509{ 498{
510 struct sock *sk = sock->sk; 499 struct sock *sk = sock->sk;
511 struct alg_sock *ask = alg_sk(sk); 500 struct alg_sock *ask = alg_sk(sk);
501 struct sock *psk = ask->parent;
502 struct alg_sock *pask = alg_sk(psk);
512 struct skcipher_ctx *ctx = ask->private; 503 struct skcipher_ctx *ctx = ask->private;
504 struct skcipher_tfm *skc = pask->private;
505 struct crypto_skcipher *tfm = skc->skcipher;
513 struct skcipher_sg_list *sgl; 506 struct skcipher_sg_list *sgl;
514 struct scatterlist *sg; 507 struct scatterlist *sg;
515 struct skcipher_async_req *sreq; 508 struct skcipher_async_req *sreq;
516 struct skcipher_request *req; 509 struct skcipher_request *req;
517 struct skcipher_async_rsgl *last_rsgl = NULL; 510 struct skcipher_async_rsgl *last_rsgl = NULL;
518 unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx); 511 unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
519 unsigned int reqlen = sizeof(struct skcipher_async_req) + 512 unsigned int reqsize = crypto_skcipher_reqsize(tfm);
520 GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx); 513 unsigned int ivsize = crypto_skcipher_ivsize(tfm);
521 int err = -ENOMEM; 514 int err = -ENOMEM;
522 bool mark = false; 515 bool mark = false;
516 char *iv;
523 517
524 lock_sock(sk); 518 sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL);
525 req = kmalloc(reqlen, GFP_KERNEL); 519 if (unlikely(!sreq))
526 if (unlikely(!req)) 520 goto out;
527 goto unlock;
528 521
529 sreq = GET_SREQ(req, ctx); 522 req = &sreq->req;
523 iv = (char *)(req + 1) + reqsize;
530 sreq->iocb = msg->msg_iocb; 524 sreq->iocb = msg->msg_iocb;
531 memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl));
532 INIT_LIST_HEAD(&sreq->list); 525 INIT_LIST_HEAD(&sreq->list);
526 sreq->inflight = &ctx->inflight;
527
528 lock_sock(sk);
533 sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); 529 sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
534 if (unlikely(!sreq->tsg)) { 530 if (unlikely(!sreq->tsg))
535 kfree(req);
536 goto unlock; 531 goto unlock;
537 }
538 sg_init_table(sreq->tsg, tx_nents); 532 sg_init_table(sreq->tsg, tx_nents);
539 memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx)); 533 memcpy(iv, ctx->iv, ivsize);
540 skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req)); 534 skcipher_request_set_tfm(req, tfm);
541 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 535 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
542 skcipher_async_cb, sk); 536 skcipher_async_cb, sreq);
543 537
544 while (iov_iter_count(&msg->msg_iter)) { 538 while (iov_iter_count(&msg->msg_iter)) {
545 struct skcipher_async_rsgl *rsgl; 539 struct skcipher_async_rsgl *rsgl;
@@ -615,20 +609,22 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg,
615 sg_mark_end(sreq->tsg + txbufs - 1); 609 sg_mark_end(sreq->tsg + txbufs - 1);
616 610
617 skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg, 611 skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
618 len, sreq->iv); 612 len, iv);
619 err = ctx->enc ? crypto_skcipher_encrypt(req) : 613 err = ctx->enc ? crypto_skcipher_encrypt(req) :
620 crypto_skcipher_decrypt(req); 614 crypto_skcipher_decrypt(req);
621 if (err == -EINPROGRESS) { 615 if (err == -EINPROGRESS) {
622 atomic_inc(&ctx->inflight); 616 atomic_inc(&ctx->inflight);
623 err = -EIOCBQUEUED; 617 err = -EIOCBQUEUED;
618 sreq = NULL;
624 goto unlock; 619 goto unlock;
625 } 620 }
626free: 621free:
627 skcipher_free_async_sgls(sreq); 622 skcipher_free_async_sgls(sreq);
628 kfree(req);
629unlock: 623unlock:
630 skcipher_wmem_wakeup(sk); 624 skcipher_wmem_wakeup(sk);
631 release_sock(sk); 625 release_sock(sk);
626 kzfree(sreq);
627out:
632 return err; 628 return err;
633} 629}
634 630