aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <[email protected]>2017-04-08 10:02:46 +0800
committerHerbert Xu <[email protected]>2017-04-10 19:09:17 +0800
commitaa4a829bdaced81e70c215a84ef6595ce8bd4308 (patch)
treebd43c4cb8887df86b71b5be81bcdd4d555188ea1
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: <[email protected]> Reported-by: Nathan Royce <[email protected]> Reported-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Herbert Xu <[email protected]> Tested-by: Krzysztof Kozlowski <[email protected]>
-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)
struct rctx *rctx;
rctx = skcipher_request_ctx(req);
+
+ if (err == -EINPROGRESS) {
+ if (rctx->left != req->cryptlen)
+ return;
+ goto out;
+ }
+
subreq = &rctx->subreq;
subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
@@ -293,6 +300,7 @@ static void encrypt_done(struct crypto_async_request *areq, int err)
if (rctx->left)
return;
+out:
skcipher_request_complete(req, err);
}
@@ -330,6 +338,13 @@ static void decrypt_done(struct crypto_async_request *areq, int err)
struct rctx *rctx;
rctx = skcipher_request_ctx(req);
+
+ if (err == -EINPROGRESS) {
+ if (rctx->left != req->cryptlen)
+ return;
+ goto out;
+ }
+
subreq = &rctx->subreq;
subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
@@ -337,6 +352,7 @@ static void decrypt_done(struct crypto_async_request *areq, int err)
if (rctx->left)
return;
+out:
skcipher_request_complete(req, err);
}