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>

authored by Stephan Mueller and committed by Herbert Xu d53c5135 9abffc6f

+10 -10
+5 -5
crypto/algif_aead.c
··· 291 291 /* AIO operation */ 292 292 sock_hold(sk); 293 293 areq->iocb = msg->msg_iocb; 294 + 295 + /* Remember output size that will be generated. */ 296 + areq->outlen = outlen; 297 + 294 298 aead_request_set_callback(&areq->cra_u.aead_req, 295 299 CRYPTO_TFM_REQ_MAY_BACKLOG, 296 300 af_alg_async_cb, areq); ··· 302 298 crypto_aead_decrypt(&areq->cra_u.aead_req); 303 299 304 300 /* AIO operation in progress */ 305 - if (err == -EINPROGRESS || err == -EBUSY) { 306 - /* Remember output size that will be generated. */ 307 - areq->outlen = outlen; 308 - 301 + if (err == -EINPROGRESS || err == -EBUSY) 309 302 return -EIOCBQUEUED; 310 - } 311 303 312 304 sock_put(sk); 313 305 } else {
+5 -5
crypto/algif_skcipher.c
··· 125 125 /* AIO operation */ 126 126 sock_hold(sk); 127 127 areq->iocb = msg->msg_iocb; 128 + 129 + /* Remember output size that will be generated. */ 130 + areq->outlen = len; 131 + 128 132 skcipher_request_set_callback(&areq->cra_u.skcipher_req, 129 133 CRYPTO_TFM_REQ_MAY_SLEEP, 130 134 af_alg_async_cb, areq); ··· 137 133 crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); 138 134 139 135 /* AIO operation in progress */ 140 - if (err == -EINPROGRESS || err == -EBUSY) { 141 - /* Remember output size that will be generated. */ 142 - areq->outlen = len; 143 - 136 + if (err == -EINPROGRESS || err == -EBUSY) 144 137 return -EIOCBQUEUED; 145 - } 146 138 147 139 sock_put(sk); 148 140 } else {