diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2023-11-28 16:25:49 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-01-25 15:27:21 -0800 |
commit | d5d4dfc73bed7860f9574255e1ce1b3801ed0881 (patch) | |
tree | 6becd35559093075a5be0935d117adeb088a547c /crypto/af_alg.c | |
parent | f3a11fdd02b32e214e9477c5cd7a710654320641 (diff) |
crypto: af_alg - Disallow multiple in-flight AIO requests
[ Upstream commit 67b164a871af1d736f131fd6fe78a610909f06f3 ]
Having multiple in-flight AIO requests results in unpredictable
output because they all share the same IV. Fix this by only allowing
one request at a time.
Fixes: 83094e5e9e49 ("crypto: af_alg - add async support to algif_aead")
Fixes: a596999b7ddf ("crypto: algif - change algif_skcipher to be asynchronous")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'crypto/af_alg.c')
-rw-r--r-- | crypto/af_alg.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index e893c0f6c879..fef69d2a6b18 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -1045,9 +1045,13 @@ EXPORT_SYMBOL_GPL(af_alg_sendpage); void af_alg_free_resources(struct af_alg_async_req *areq) { struct sock *sk = areq->sk; + struct af_alg_ctx *ctx; af_alg_free_areq_sgls(areq); sock_kfree_s(sk, areq, areq->areqlen); + + ctx = alg_sk(sk)->private; + ctx->inflight = false; } EXPORT_SYMBOL_GPL(af_alg_free_resources); @@ -1117,11 +1121,19 @@ EXPORT_SYMBOL_GPL(af_alg_poll); struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, unsigned int areqlen) { - struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); + struct af_alg_ctx *ctx = alg_sk(sk)->private; + struct af_alg_async_req *areq; + + /* Only one AIO request can be in flight. */ + if (ctx->inflight) + return ERR_PTR(-EBUSY); + areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); if (unlikely(!areq)) return ERR_PTR(-ENOMEM); + ctx->inflight = true; + areq->areqlen = areqlen; areq->sk = sk; areq->last_rsgl = NULL; |