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: 83094e5e9e
("crypto: af_alg - add async support to...")
Cc: <stable@vger.kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Родитель
ef0579b64e
Коммит
e6534aebb2
|
@ -40,6 +40,7 @@ struct aead_async_req {
|
||||||
struct aead_async_rsgl first_rsgl;
|
struct aead_async_rsgl first_rsgl;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct kiocb *iocb;
|
struct kiocb *iocb;
|
||||||
|
struct sock *sk;
|
||||||
unsigned int tsgls;
|
unsigned int tsgls;
|
||||||
char iv[];
|
char iv[];
|
||||||
};
|
};
|
||||||
|
@ -379,12 +380,10 @@ unlock:
|
||||||
|
|
||||||
static void aead_async_cb(struct crypto_async_request *_req, int err)
|
static void aead_async_cb(struct crypto_async_request *_req, int err)
|
||||||
{
|
{
|
||||||
struct sock *sk = _req->data;
|
struct aead_request *req = _req->data;
|
||||||
struct alg_sock *ask = alg_sk(sk);
|
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
||||||
struct aead_ctx *ctx = ask->private;
|
|
||||||
struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req);
|
|
||||||
struct aead_request *req = aead_request_cast(_req);
|
|
||||||
struct aead_async_req *areq = GET_ASYM_REQ(req, tfm);
|
struct aead_async_req *areq = GET_ASYM_REQ(req, tfm);
|
||||||
|
struct sock *sk = areq->sk;
|
||||||
struct scatterlist *sg = areq->tsgl;
|
struct scatterlist *sg = areq->tsgl;
|
||||||
struct aead_async_rsgl *rsgl;
|
struct aead_async_rsgl *rsgl;
|
||||||
struct kiocb *iocb = areq->iocb;
|
struct kiocb *iocb = areq->iocb;
|
||||||
|
@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
|
||||||
memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl));
|
memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl));
|
||||||
INIT_LIST_HEAD(&areq->list);
|
INIT_LIST_HEAD(&areq->list);
|
||||||
areq->iocb = msg->msg_iocb;
|
areq->iocb = msg->msg_iocb;
|
||||||
|
areq->sk = sk;
|
||||||
memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm));
|
memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm));
|
||||||
aead_request_set_tfm(req, tfm);
|
aead_request_set_tfm(req, tfm);
|
||||||
aead_request_set_ad(req, ctx->aead_assoclen);
|
aead_request_set_ad(req, ctx->aead_assoclen);
|
||||||
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||||
aead_async_cb, sk);
|
aead_async_cb, req);
|
||||||
used -= ctx->aead_assoclen;
|
used -= ctx->aead_assoclen;
|
||||||
|
|
||||||
/* take over all tx sgls from ctx */
|
/* take over all tx sgls from ctx */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче