From: Herbert Xu Date: Mon, 10 Apr 2017 09:15:48 +0000 (+0800) Subject: crypto: lrw - Fix use-after-free on EINPROGRESS X-Git-Tag: v4.10.12~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa7ca04fb26cd374e4b9739b9fc070025ea8c490;p=thirdparty%2Fkernel%2Fstable.git crypto: lrw - Fix use-after-free on EINPROGRESS commit 4702bbeefb490e315189636a5588628c1151223d upstream. When we get an EINPROGRESS completion in lrw, 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: 700cb3f5fe75 ("crypto: lrw - Convert to skcipher") Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- diff --git a/crypto/lrw.c b/crypto/lrw.c index 3ea095adafd9a..a8bfae4451bfc 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -345,6 +345,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; @@ -352,6 +359,7 @@ static void encrypt_done(struct crypto_async_request *areq, int err) if (rctx->left) return; +out: skcipher_request_complete(req, err); } @@ -389,6 +397,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; @@ -396,6 +411,7 @@ static void decrypt_done(struct crypto_async_request *areq, int err) if (rctx->left) return; +out: skcipher_request_complete(req, err); }