aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2017-04-10 05:59:07 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-04-10 07:09:19 -0400
commite6534aebb26e32fbab14df9c713c65e8507d17e4 (patch)
tree952b4316749252a82a6a148a5d857bbddb8ad45d
parentef0579b64e93188710d48667cb5e014926af9f1b (diff)
crypto: algif_aead - Fix bogus request dereference in completion function
The algif_aead completion function tries to deduce the aead_request from the crypto_async_request argument. This is broken because the API does not guarantee that the same request will be pased to the completion function. Only the value of req->data can be used in the completion function. This patch fixes it by storing a pointer to sk in areq and using that instead of passing in sk through req->data. Fixes: 83094e5e9e49 ("crypto: af_alg - add async support to...") Cc: <stable@vger.kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/algif_aead.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 5a8053758657..ef59d9926ee9 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -40,6 +40,7 @@ struct aead_async_req {
40 struct aead_async_rsgl first_rsgl; 40 struct aead_async_rsgl first_rsgl;
41 struct list_head list; 41 struct list_head list;
42 struct kiocb *iocb; 42 struct kiocb *iocb;
43 struct sock *sk;
43 unsigned int tsgls; 44 unsigned int tsgls;
44 char iv[]; 45 char iv[];
45}; 46};
@@ -379,12 +380,10 @@ unlock:
379 380
380static void aead_async_cb(struct crypto_async_request *_req, int err) 381static void aead_async_cb(struct crypto_async_request *_req, int err)
381{ 382{
382 struct sock *sk = _req->data; 383 struct aead_request *req = _req->data;
383 struct alg_sock *ask = alg_sk(sk); 384 struct crypto_aead *tfm = crypto_aead_reqtfm(req);
384 struct aead_ctx *ctx = ask->private;
385 struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req);
386 struct aead_request *req = aead_request_cast(_req);
387 struct aead_async_req *areq = GET_ASYM_REQ(req, tfm); 385 struct aead_async_req *areq = GET_ASYM_REQ(req, tfm);
386 struct sock *sk = areq->sk;
388 struct scatterlist *sg = areq->tsgl; 387 struct scatterlist *sg = areq->tsgl;
389 struct aead_async_rsgl *rsgl; 388 struct aead_async_rsgl *rsgl;
390 struct kiocb *iocb = areq->iocb; 389 struct kiocb *iocb = areq->iocb;
@@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
447 memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl)); 446 memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl));
448 INIT_LIST_HEAD(&areq->list); 447 INIT_LIST_HEAD(&areq->list);
449 areq->iocb = msg->msg_iocb; 448 areq->iocb = msg->msg_iocb;
449 areq->sk = sk;
450 memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm)); 450 memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm));
451 aead_request_set_tfm(req, tfm); 451 aead_request_set_tfm(req, tfm);
452 aead_request_set_ad(req, ctx->aead_assoclen); 452 aead_request_set_ad(req, ctx->aead_assoclen);
453 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 453 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
454 aead_async_cb, sk); 454 aead_async_cb, req);
455 used -= ctx->aead_assoclen; 455 used -= ctx->aead_assoclen;
456 456
457 /* take over all tx sgls from ctx */ 457 /* take over all tx sgls from ctx */