summaryrefslogtreecommitdiffstats
path: root/crypto/xts.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2017-04-07 22:02:46 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-04-10 07:09:17 -0400
commitaa4a829bdaced81e70c215a84ef6595ce8bd4308 (patch)
treebd43c4cb8887df86b71b5be81bcdd4d555188ea1 /crypto/xts.c
parent40c98cb57cdbc377456116ad4582c89e329721b0 (diff)
crypto: xts - Fix use-after-free on EINPROGRESS
When we get an EINPROGRESS completion in xts, we will end up marking the request as done and freeing it. This then blows up when the request is really completed as we've already freed the memory. Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher") Cc: <stable@vger.kernel.org> Reported-by: Nathan Royce <nroycea+kernel@gmail.com> Reported-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
Diffstat (limited to 'crypto/xts.c')
-rw-r--r--crypto/xts.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/crypto/xts.c b/crypto/xts.c
index c976bfac29da..89ace5ebc2da 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -286,6 +286,13 @@ static void encrypt_done(struct crypto_async_request *areq, int err)
286 struct rctx *rctx; 286 struct rctx *rctx;
287 287
288 rctx = skcipher_request_ctx(req); 288 rctx = skcipher_request_ctx(req);
289
290 if (err == -EINPROGRESS) {
291 if (rctx->left != req->cryptlen)
292 return;
293 goto out;
294 }
295
289 subreq = &rctx->subreq; 296 subreq = &rctx->subreq;
290 subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; 297 subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
291 298
@@ -293,6 +300,7 @@ static void encrypt_done(struct crypto_async_request *areq, int err)
293 if (rctx->left) 300 if (rctx->left)
294 return; 301 return;
295 302
303out:
296 skcipher_request_complete(req, err); 304 skcipher_request_complete(req, err);
297} 305}
298 306
@@ -330,6 +338,13 @@ static void decrypt_done(struct crypto_async_request *areq, int err)
330 struct rctx *rctx; 338 struct rctx *rctx;
331 339
332 rctx = skcipher_request_ctx(req); 340 rctx = skcipher_request_ctx(req);
341
342 if (err == -EINPROGRESS) {
343 if (rctx->left != req->cryptlen)
344 return;
345 goto out;
346 }
347
333 subreq = &rctx->subreq; 348 subreq = &rctx->subreq;
334 subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; 349 subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
335 350
@@ -337,6 +352,7 @@ static void decrypt_done(struct crypto_async_request *areq, int err)
337 if (rctx->left) 352 if (rctx->left)
338 return; 353 return;
339 354
355out:
340 skcipher_request_complete(req, err); 356 skcipher_request_complete(req, err);
341} 357}
342 358