aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2017-12-08 05:50:37 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2017-12-11 06:29:55 -0500
commitd53c5135792319e095bb126bc43b2ee98586f7fe (patch)
treec7ee7f22e25143a15f5ebeef77430dae79efd14a
parent9abffc6f2efe46c3564c04312e52e07622d40e51 (diff)
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: e870456d8e7c ("crypto: algif_skcipher - overhaul memory management") Fixes: d887c52d6ae4 ("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 c8a32bef208a..b73db2b27656 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,
291 /* AIO operation */ 291 /* AIO operation */
292 sock_hold(sk); 292 sock_hold(sk);
293 areq->iocb = msg->msg_iocb; 293 areq->iocb = msg->msg_iocb;
294
295 /* Remember output size that will be generated. */
296 areq->outlen = outlen;
297
294 aead_request_set_callback(&areq->cra_u.aead_req, 298 aead_request_set_callback(&areq->cra_u.aead_req,
295 CRYPTO_TFM_REQ_MAY_BACKLOG, 299 CRYPTO_TFM_REQ_MAY_BACKLOG,
296 af_alg_async_cb, areq); 300 af_alg_async_cb, areq);
@@ -298,12 +302,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
298 crypto_aead_decrypt(&areq->cra_u.aead_req); 302 crypto_aead_decrypt(&areq->cra_u.aead_req);
299 303
300 /* AIO operation in progress */ 304 /* AIO operation in progress */
301 if (err == -EINPROGRESS || err == -EBUSY) { 305 if (err == -EINPROGRESS || err == -EBUSY)
302 /* Remember output size that will be generated. */
303 areq->outlen = outlen;
304
305 return -EIOCBQUEUED; 306 return -EIOCBQUEUED;
306 }
307 307
308 sock_put(sk); 308 sock_put(sk);
309 } else { 309 } else {
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 6fb595cd63ac..baef9bfccdda 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,
125 /* AIO operation */ 125 /* AIO operation */
126 sock_hold(sk); 126 sock_hold(sk);
127 areq->iocb = msg->msg_iocb; 127 areq->iocb = msg->msg_iocb;
128
129 /* Remember output size that will be generated. */
130 areq->outlen = len;
131
128 skcipher_request_set_callback(&areq->cra_u.skcipher_req, 132 skcipher_request_set_callback(&areq->cra_u.skcipher_req,
129 CRYPTO_TFM_REQ_MAY_SLEEP, 133 CRYPTO_TFM_REQ_MAY_SLEEP,
130 af_alg_async_cb, areq); 134 af_alg_async_cb, areq);
@@ -133,12 +137,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
133 crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); 137 crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
134 138
135 /* AIO operation in progress */ 139 /* AIO operation in progress */
136 if (err == -EINPROGRESS || err == -EBUSY) { 140 if (err == -EINPROGRESS || err == -EBUSY)
137 /* Remember output size that will be generated. */
138 areq->outlen = len;
139
140 return -EIOCBQUEUED; 141 return -EIOCBQUEUED;
141 }
142 142
143 sock_put(sk); 143 sock_put(sk);
144 } else { 144 } else {