This patchset backports commit f3c802a1f300 ("crypto: algif_aead - Only wake up when ctx->more is zero") and following bugfixes. commit 21dfbcd1f5cb ("crypto: algif_aead - fix uninitialized ctx->init") is merged beforehand.
Herbert Xu (3): crypto: algif_aead - Only wake up when ctx->more is zero crypto: af_alg - Fix regression on empty requests crypto: af_alg - Work around empty control messages without MSG_MORE
crypto/af_alg.c | 22 +++++++++++++++++----- crypto/algif_aead.c | 4 ++-- crypto/algif_skcipher.c | 4 ++-- include/crypto/if_alg.h | 4 +++- 4 files changed, 24 insertions(+), 10 deletions(-)
From: Herbert Xu herbert@gondor.apana.org.au
mainline inclusion from mainline-v5.9-rc1 commit f3c802a1f30013f8f723b62d7fa49eb9e991da23 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I992IL CVE: NA
Reference: https://github.com/torvalds/linux/commit/f3c802a1f30013f8f723b62d7fa49eb9e99...
--------------------------------
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 Conflicts: include/crypto/if_alg.h Signed-off-by: GUO Zihua guozihua@huawei.com --- crypto/af_alg.c | 11 ++++++++--- crypto/algif_aead.c | 4 ++-- crypto/algif_skcipher.c | 4 ++-- include/crypto/if_alg.h | 4 +++- 4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 2b8f690130c5..4a116f8ca842 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);
@@ -749,9 +750,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); @@ -769,7 +771,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; @@ -860,7 +864,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; } @@ -871,6 +875,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 3f20d3e4acfb..43a861a79209 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 94aeb8b946b0..c5813e14e905 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; } diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index ba9828506aab..9ff2826cdd48 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -140,6 +140,7 @@ struct af_alg_async_req { * SG? * @enc: Cryptographic operation to be performed when * recvmsg is invoked. + * @init: True if metadata has been sent. * @len: Length of memory allocated for this data structure. * @inflight: Non-zero when AIO requests are in flight. */ @@ -157,6 +158,7 @@ struct af_alg_ctx { bool more; bool merge; bool enc; + bool init;
unsigned int len;
@@ -240,7 +242,7 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, void af_alg_free_areq_sgls(struct af_alg_async_req *areq); int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags); void af_alg_wmem_wakeup(struct sock *sk); -int af_alg_wait_for_data(struct sock *sk, unsigned flags); +int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min); void af_alg_data_wakeup(struct sock *sk); int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, unsigned int ivsize);
From: Herbert Xu herbert@gondor.apana.org.au
mainline inclusion from mainline-v5.9-rc1 commit 662bb52f50bca16a74fe92b487a14d7dccb85e1a category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I991GQ CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Some user-space programs rely on crypto requests that have no control metadata. This broke when a check was added to require the presence of control metadata with the ctx->init flag.
This patch fixes the regression by setting ctx->init as long as one sendmsg(2) has been made, with or without a control message.
Reported-by: Sachin Sant sachinp@linux.vnet.ibm.com Reported-by: Naresh Kamboju naresh.kamboju@linaro.org Fixes: f3c802a1f300 ("crypto: algif_aead - Only wake up when...") Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: GUO Zihua guozihua@huawei.com --- crypto/af_alg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 4a116f8ca842..4486db4c869a 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -868,6 +868,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, err = -EINVAL; goto unlock; } + ctx->init = true;
if (init) { ctx->enc = enc; @@ -875,7 +876,6 @@ 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) {
From: Herbert Xu herbert@gondor.apana.org.au
mainline inclusion from mainline-v5.9-rc3 commit c195d66a8a75c60515819b101975f38b7ec6577f category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I991GQ CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
The iwd daemon uses libell which sets up the skcipher operation with two separate control messages. As the first control message is sent without MSG_MORE, it is interpreted as an empty request.
While libell should be fixed to use MSG_MORE where appropriate, this patch works around the bug in the kernel so that existing binaries continue to work.
We will print a warning however.
A separate issue is that the new kernel code no longer allows the control message to be sent twice within the same request. This restriction is obviously incompatible with what iwd was doing (first setting an IV and then sending the real control message). This patch changes the kernel so that this is explicitly allowed.
Reported-by: Caleb Jorden caljorden@hotmail.com Fixes: f3c802a1f300 ("crypto: algif_aead - Only wake up when...") Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: GUO Zihua guozihua@huawei.com --- crypto/af_alg.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 4486db4c869a..fdccf8c9c4ff 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -21,6 +21,7 @@ #include <linux/module.h> #include <linux/net.h> #include <linux/rwsem.h> +#include <linux/sched.h> #include <linux/sched/signal.h> #include <linux/security.h>
@@ -864,9 +865,15 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, }
lock_sock(sk); - if (ctx->init && (init || !ctx->more)) { - err = -EINVAL; - goto unlock; + if (ctx->init && !ctx->more) { + if (ctx->used) { + err = -EINVAL; + goto unlock; + } + + pr_info_once( + "%s sent an empty control message without MSG_MORE.\n", + current->comm); } ctx->init = true;
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/5290 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/K...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/5290 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/K...