diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2025-03-21 16:43:32 +0800 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2025-03-22 07:25:19 +0800 |
commit | 39fc22a8e53e96392f9b2c840e386272affbe6ba (patch) | |
tree | 123620fcad948fb30bf36fbed57b264a617cafe6 /crypto | |
parent | 8b54e6a8f4156ed43627f40300b0711dc977fbc1 (diff) |
crypto: acomp - Fix synchronous acomp chaining fallback
The synchronous acomp fallback code path is broken because the
completion code path assumes that the state object is always set
but this is only done for asynchronous algorithms.
First of all remove the assumption on the completion code path
by passing in req0 instead of the state. However, also remove
the conditional setting of the state since it's always in the
request object anyway.
Fixes: b67a02600372 ("crypto: acomp - Add request chaining and virtual addresses")
Reported-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/acompress.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/crypto/acompress.c b/crypto/acompress.c index 6ef335f5bf27..f7a3fbe5447e 100644 --- a/crypto/acompress.c +++ b/crypto/acompress.c @@ -155,12 +155,8 @@ EXPORT_SYMBOL_GPL(crypto_alloc_acomp_node); static void acomp_save_req(struct acomp_req *req, crypto_completion_t cplt) { - struct crypto_acomp *tfm = crypto_acomp_reqtfm(req); struct acomp_req_chain *state = &req->chain; - if (!acomp_is_async(tfm)) - return; - state->compl = req->base.complete; state->data = req->base.data; req->base.complete = cplt; @@ -168,14 +164,9 @@ static void acomp_save_req(struct acomp_req *req, crypto_completion_t cplt) state->req0 = req; } -static void acomp_restore_req(struct acomp_req_chain *state) +static void acomp_restore_req(struct acomp_req *req) { - struct acomp_req *req = state->req0; - struct crypto_acomp *tfm; - - tfm = crypto_acomp_reqtfm(req); - if (!acomp_is_async(tfm)) - return; + struct acomp_req_chain *state = req->base.data; req->base.complete = state->compl; req->base.data = state->data; @@ -289,10 +280,9 @@ static int acomp_do_one_req(struct acomp_req_chain *state, return state->op(req); } -static int acomp_reqchain_finish(struct acomp_req_chain *state, - int err, u32 mask) +static int acomp_reqchain_finish(struct acomp_req *req0, int err, u32 mask) { - struct acomp_req *req0 = state->req0; + struct acomp_req_chain *state = req0->base.data; struct acomp_req *req = state->cur; struct acomp_req *n; @@ -323,7 +313,7 @@ static int acomp_reqchain_finish(struct acomp_req_chain *state, list_add_tail(&req->base.list, &req0->base.list); } - acomp_restore_req(state); + acomp_restore_req(req0); out: return err; @@ -342,7 +332,8 @@ static void acomp_reqchain_done(void *data, int err) goto notify; } - err = acomp_reqchain_finish(state, err, CRYPTO_TFM_REQ_MAY_BACKLOG); + err = acomp_reqchain_finish(state->req0, err, + CRYPTO_TFM_REQ_MAY_BACKLOG); if (err == -EBUSY) return; @@ -354,17 +345,15 @@ static int acomp_do_req_chain(struct acomp_req *req, int (*op)(struct acomp_req *req)) { struct crypto_acomp *tfm = crypto_acomp_reqtfm(req); - struct acomp_req_chain *state = &req->chain; + struct acomp_req_chain *state; int err; if (crypto_acomp_req_chain(tfm) || (!acomp_request_chained(req) && acomp_request_issg(req))) return op(req); - if (acomp_is_async(tfm)) { - acomp_save_req(req, acomp_reqchain_done); - state = req->base.data; - } + acomp_save_req(req, acomp_reqchain_done); + state = req->base.data; state->op = op; state->src = NULL; @@ -375,7 +364,7 @@ static int acomp_do_req_chain(struct acomp_req *req, if (err == -EBUSY || err == -EINPROGRESS) return -EBUSY; - return acomp_reqchain_finish(state, err, ~0); + return acomp_reqchain_finish(req, err, ~0); } int crypto_acomp_compress(struct acomp_req *req) |