diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2020-05-29 17:23:49 +0300 |
---|---|---|
committer | Sasha Levin <sashal@kernel.org> | 2024-03-27 01:22:34 +0300 |
commit | de564b59755dfb080ef237dd4fbd02cb0c3e58a1 (patch) | |
tree | fc489c1ba24c8b9baee17e1ab89d555813c759a0 /crypto | |
parent | 0ca02d4beebb7b47ea0cbdceac891465cbb966c6 (diff) | |
download | linux-de564b59755dfb080ef237dd4fbd02cb0c3e58a1.tar.xz |
crypto: algif_aead - Only wake up when ctx->more is zero
[ Upstream commit f3c802a1f30013f8f723b62d7fa49eb9e991da23 ]
AEAD does not support partial requests so we must not wake up
while ctx->more is set. In order to distinguish between the
case of no data sent yet and a zero-length request, a new init
flag has been added to ctx.
SKCIPHER has also been modified to ensure that at least a block
of data is available if there is more data to come.
Fixes: 2d97591ef43d ("crypto: af_alg - consolidation of...")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/af_alg.c | 11 | ||||
-rw-r--r-- | crypto/algif_aead.c | 4 | ||||
-rw-r--r-- | crypto/algif_skcipher.c | 4 |
3 files changed, 12 insertions, 7 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index ed62632a1c35..78f041754f04 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -648,6 +648,7 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, if (!ctx->used) ctx->merge = 0; + ctx->init = ctx->more; } EXPORT_SYMBOL_GPL(af_alg_pull_tsgl); @@ -747,9 +748,10 @@ EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup); * * @sk socket of connection to user space * @flags If MSG_DONTWAIT is set, then only report if function would sleep + * @min Set to minimum request size if partial requests are allowed. * @return 0 when writable memory is available, < 0 upon error */ -int af_alg_wait_for_data(struct sock *sk, unsigned flags) +int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min) { DEFINE_WAIT_FUNC(wait, woken_wake_function); struct alg_sock *ask = alg_sk(sk); @@ -767,7 +769,9 @@ int af_alg_wait_for_data(struct sock *sk, unsigned flags) if (signal_pending(current)) break; timeout = MAX_SCHEDULE_TIMEOUT; - if (sk_wait_event(sk, &timeout, (ctx->used || !ctx->more), + if (sk_wait_event(sk, &timeout, + ctx->init && (!ctx->more || + (min && ctx->used >= min)), &wait)) { err = 0; break; @@ -856,7 +860,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, } lock_sock(sk); - if (!ctx->more && ctx->used) { + if (ctx->init && (init || !ctx->more)) { err = -EINVAL; goto unlock; } @@ -867,6 +871,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, memcpy(ctx->iv, con.iv->iv, ivsize); ctx->aead_assoclen = con.aead_assoclen; + ctx->init = true; } while (size) { diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index 4cb2b1217549..63ba443b2315 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -110,8 +110,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, size_t usedpages = 0; /* [in] RX bufs to be used from user */ size_t processed = 0; /* [in] TX bufs to be consumed */ - if (!ctx->used) { - err = af_alg_wait_for_data(sk, flags); + if (!ctx->init || ctx->more) { + err = af_alg_wait_for_data(sk, flags, 0); if (err) return err; } diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index af08fc18a492..6cfdbe71a2ce 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -65,8 +65,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, int err = 0; size_t len = 0; - if (!ctx->used) { - err = af_alg_wait_for_data(sk, flags); + if (!ctx->init || (ctx->more && ctx->used < bs)) { + err = af_alg_wait_for_data(sk, flags, bs); if (err) return err; } |