mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
crypto: af_alg - fix race accessing cipher request
When invoking an asynchronous cipher operation, the invocation of the callback may be performed before the subsequent operations in the initial code path are invoked. The callback deletes the cipher request data structure which implies that after the invocation of the asynchronous cipher operation, this data structure must not be accessed any more. The setting of the return code size with the request data structure must therefore be moved before the invocation of the asynchronous cipher operation. Fixes:e870456d8e
("crypto: algif_skcipher - overhaul memory management") Fixes:d887c52d6a
("crypto: algif_aead - overhaul memory management") Reported-by: syzbot <syzkaller@googlegroups.com> Cc: <stable@vger.kernel.org> # v4.14+ Signed-off-by: Stephan Mueller <smueller@chronox.de> Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
9abffc6f2e
commit
d53c513579
@ -291,6 +291,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
/* AIO operation */
|
/* AIO operation */
|
||||||
sock_hold(sk);
|
sock_hold(sk);
|
||||||
areq->iocb = msg->msg_iocb;
|
areq->iocb = msg->msg_iocb;
|
||||||
|
|
||||||
|
/* Remember output size that will be generated. */
|
||||||
|
areq->outlen = outlen;
|
||||||
|
|
||||||
aead_request_set_callback(&areq->cra_u.aead_req,
|
aead_request_set_callback(&areq->cra_u.aead_req,
|
||||||
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||||
af_alg_async_cb, areq);
|
af_alg_async_cb, areq);
|
||||||
@ -298,12 +302,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
crypto_aead_decrypt(&areq->cra_u.aead_req);
|
crypto_aead_decrypt(&areq->cra_u.aead_req);
|
||||||
|
|
||||||
/* AIO operation in progress */
|
/* AIO operation in progress */
|
||||||
if (err == -EINPROGRESS || err == -EBUSY) {
|
if (err == -EINPROGRESS || err == -EBUSY)
|
||||||
/* Remember output size that will be generated. */
|
|
||||||
areq->outlen = outlen;
|
|
||||||
|
|
||||||
return -EIOCBQUEUED;
|
return -EIOCBQUEUED;
|
||||||
}
|
|
||||||
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,6 +125,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
/* AIO operation */
|
/* AIO operation */
|
||||||
sock_hold(sk);
|
sock_hold(sk);
|
||||||
areq->iocb = msg->msg_iocb;
|
areq->iocb = msg->msg_iocb;
|
||||||
|
|
||||||
|
/* Remember output size that will be generated. */
|
||||||
|
areq->outlen = len;
|
||||||
|
|
||||||
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
|
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
|
||||||
CRYPTO_TFM_REQ_MAY_SLEEP,
|
CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||||
af_alg_async_cb, areq);
|
af_alg_async_cb, areq);
|
||||||
@ -133,12 +137,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||||||
crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
|
crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
|
||||||
|
|
||||||
/* AIO operation in progress */
|
/* AIO operation in progress */
|
||||||
if (err == -EINPROGRESS || err == -EBUSY) {
|
if (err == -EINPROGRESS || err == -EBUSY)
|
||||||
/* Remember output size that will be generated. */
|
|
||||||
areq->outlen = len;
|
|
||||||
|
|
||||||
return -EIOCBQUEUED;
|
return -EIOCBQUEUED;
|
||||||
}
|
|
||||||
|
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user