summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2017-12-08 11:50:37 +0100
committerHerbert Xu <herbert@gondor.apana.org.au>2017-12-11 22:29:55 +1100
commitbecd0fb2474ef9c1dc09bee93fb13d68681f7f47 (patch)
treef2ca2605039a0201f79188e6ff0943e90fcce924
parente06e082d388cddfd401be58927846add9f3a1666 (diff)
downloadlinux-crypto-becd0fb2474ef9c1dc09bee93fb13d68681f7f47.tar.gz
linux-crypto-becd0fb2474ef9c1dc09bee93fb13d68681f7f47.zip
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: 8a15a4bf1947 ("crypto: algif_skcipher - overhaul memory management") Fixes: 0c2a2d0aa6e4 ("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>
-rw-r--r--crypto/algif_aead.c10
-rw-r--r--crypto/algif_skcipher.c10
2 files changed, 10 insertions, 10 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index c8a32bef..b73db2b2 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -291,6 +291,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
/* AIO operation */
sock_hold(sk);
areq->iocb = msg->msg_iocb;
+
+ /* Remember output size that will be generated. */
+ areq->outlen = outlen;
+
aead_request_set_callback(&areq->cra_u.aead_req,
CRYPTO_TFM_REQ_MAY_BACKLOG,
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);
/* AIO operation in progress */
- if (err == -EINPROGRESS || err == -EBUSY) {
- /* Remember output size that will be generated. */
- areq->outlen = outlen;
-
+ if (err == -EINPROGRESS || err == -EBUSY)
return -EIOCBQUEUED;
- }
sock_put(sk);
} else {
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 6fb595cd..baef9bfc 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -125,6 +125,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
/* AIO operation */
sock_hold(sk);
areq->iocb = msg->msg_iocb;
+
+ /* Remember output size that will be generated. */
+ areq->outlen = len;
+
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
CRYPTO_TFM_REQ_MAY_SLEEP,
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);
/* AIO operation in progress */
- if (err == -EINPROGRESS || err == -EBUSY) {
- /* Remember output size that will be generated. */
- areq->outlen = len;
-
+ if (err == -EINPROGRESS || err == -EBUSY)
return -EIOCBQUEUED;
- }
sock_put(sk);
} else {