Commit 51c08251 authored by Herbert Xu's avatar Herbert Xu

crypto: xts - Handle EBUSY correctly

As it is xts only handles the special return value of EINPROGRESS,
which means that in all other cases it will free data related to the
request.

However, as the caller of xts may specify MAY_BACKLOG, we also need
to expect EBUSY and treat it in the same way.  Otherwise backlogged
requests will trigger a use-after-free.

Fixes: 8083b1bf ("crypto: xts - add support for ciphertext stealing")
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Acked-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 4bc713a4
...@@ -203,12 +203,12 @@ static void xts_encrypt_done(struct crypto_async_request *areq, int err) ...@@ -203,12 +203,12 @@ static void xts_encrypt_done(struct crypto_async_request *areq, int err)
if (!err) { if (!err) {
struct xts_request_ctx *rctx = skcipher_request_ctx(req); struct xts_request_ctx *rctx = skcipher_request_ctx(req);
rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
err = xts_xor_tweak_post(req, true); err = xts_xor_tweak_post(req, true);
if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) { if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
err = xts_cts_final(req, crypto_skcipher_encrypt); err = xts_cts_final(req, crypto_skcipher_encrypt);
if (err == -EINPROGRESS) if (err == -EINPROGRESS || err == -EBUSY)
return; return;
} }
} }
...@@ -223,12 +223,12 @@ static void xts_decrypt_done(struct crypto_async_request *areq, int err) ...@@ -223,12 +223,12 @@ static void xts_decrypt_done(struct crypto_async_request *areq, int err)
if (!err) { if (!err) {
struct xts_request_ctx *rctx = skcipher_request_ctx(req); struct xts_request_ctx *rctx = skcipher_request_ctx(req);
rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG;
err = xts_xor_tweak_post(req, false); err = xts_xor_tweak_post(req, false);
if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) { if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
err = xts_cts_final(req, crypto_skcipher_decrypt); err = xts_cts_final(req, crypto_skcipher_decrypt);
if (err == -EINPROGRESS) if (err == -EINPROGRESS || err == -EBUSY)
return; return;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment