netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
@ 2023-06-14 23:27 David Howells
  2023-06-15  9:28 ` Herbert Xu
  2023-06-16 10:27 ` Herbert Xu
  0 siblings, 2 replies; 9+ messages in thread
From: David Howells @ 2023-06-14 23:27 UTC (permalink / raw)
  To: netdev
  Cc: dhowells, syzbot+13a08c0bf4d212766c3c,
	syzbot+14234ccf6d0ef629ec1a, syzbot+4e2e47f32607d0f72d43,
	syzbot+472626bb5e7c59fb768f, Herbert Xu, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jens Axboe,
	Matthew Wilcox, linux-crypto, linux-kernel

    
If an AF_ALG socket bound to a hashing algorithm is sent a zero-length
message with MSG_MORE set and then recvmsg() is called without first
sending another message without MSG_MORE set to end the operation, an oops
will occur because the crypto context and result doesn't now get set up in
advance because hash_sendmsg() now defers that as long as possible in the
hope that it can use crypto_ahash_digest() - and then because the message
is zero-length, it the data wrangling loop is skipped.

Fix this by always making a pass of the loop, even in the case that no data
is provided to the sendmsg().

Fix also extract_iter_to_sg() to handle a zero-length iterator by returning
0 immediately.

Whilst we're at it, remove the code to create a kvmalloc'd scatterlist if
we get more than ALG_MAX_PAGES - this shouldn't happen.

Fixes: c662b043cdca ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES")
Reported-by: syzbot+13a08c0bf4d212766c3c@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/000000000000b928f705fdeb873a@google.com/
Reported-by: syzbot+14234ccf6d0ef629ec1a@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/000000000000c047db05fdeb8790@google.com/
Reported-by: syzbot+4e2e47f32607d0f72d43@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/000000000000bcca3205fdeb87fb@google.com/
Reported-by: syzbot+472626bb5e7c59fb768f@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/000000000000b55d8805fdeb8385@google.com/
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: syzbot+13a08c0bf4d212766c3c@syzkaller.appspotmail.com
Tested-by: syzbot+14234ccf6d0ef629ec1a@syzkaller.appspotmail.com
Tested-by: syzbot+4e2e47f32607d0f72d43@syzkaller.appspotmail.com
Tested-by: syzbot+472626bb5e7c59fb768f@syzkaller.appspotmail.com
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Jens Axboe <axboe@kernel.dk>
cc: Matthew Wilcox <willy@infradead.org>
cc: linux-crypto@vger.kernel.org
cc: netdev@vger.kernel.org
---
 crypto/algif_hash.c |   21 +++++----------------
 lib/scatterlist.c   |    2 +-
 2 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index dfb048cefb60..1176533a55c9 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -83,26 +83,14 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
 
 	ctx->more = false;
 
-	while (msg_data_left(msg)) {
+	do {
 		ctx->sgl.sgt.sgl = ctx->sgl.sgl;
 		ctx->sgl.sgt.nents = 0;
 		ctx->sgl.sgt.orig_nents = 0;
 
 		err = -EIO;
 		npages = iov_iter_npages(&msg->msg_iter, max_pages);
-		if (npages == 0)
-			goto unlock_free;
-
-		if (npages > ARRAY_SIZE(ctx->sgl.sgl)) {
-			err = -ENOMEM;
-			ctx->sgl.sgt.sgl =
-				kvmalloc(array_size(npages,
-						    sizeof(*ctx->sgl.sgt.sgl)),
-					 GFP_KERNEL);
-			if (!ctx->sgl.sgt.sgl)
-				goto unlock_free;
-		}
-		sg_init_table(ctx->sgl.sgl, npages);
+		sg_init_table(ctx->sgl.sgl, max_t(size_t, npages, 1));
 
 		ctx->sgl.need_unpin = iov_iter_extract_will_pin(&msg->msg_iter);
 
@@ -111,7 +99,8 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
 		if (err < 0)
 			goto unlock_free;
 		len = err;
-		sg_mark_end(ctx->sgl.sgt.sgl + ctx->sgl.sgt.nents - 1);
+		if (len > 0)
+			sg_mark_end(ctx->sgl.sgt.sgl + ctx->sgl.sgt.nents - 1);
 
 		if (!msg_data_left(msg)) {
 			err = hash_alloc_result(sk, ctx);
@@ -148,7 +137,7 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
 
 		copied += len;
 		af_alg_free_sg(&ctx->sgl);
-	}
+	} while (msg_data_left(msg));
 
 	ctx->more = msg->msg_flags & MSG_MORE;
 	err = 0;
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index e97d7060329e..77a7b18ee751 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -1340,7 +1340,7 @@ ssize_t extract_iter_to_sg(struct iov_iter *iter, size_t maxsize,
 			   struct sg_table *sgtable, unsigned int sg_max,
 			   iov_iter_extraction_t extraction_flags)
 {
-	if (maxsize == 0)
+	if (!maxsize || !iter->count)
 		return 0;
 
 	switch (iov_iter_type(iter)) {


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-14 23:27 [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE) David Howells
@ 2023-06-15  9:28 ` Herbert Xu
  2023-06-15 11:28   ` David Howells
  2023-06-16 10:27 ` Herbert Xu
  1 sibling, 1 reply; 9+ messages in thread
From: Herbert Xu @ 2023-06-15  9:28 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, syzbot+13a08c0bf4d212766c3c, syzbot+14234ccf6d0ef629ec1a,
	syzbot+4e2e47f32607d0f72d43, syzbot+472626bb5e7c59fb768f,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jens Axboe, Matthew Wilcox, linux-crypto, linux-kernel

On Thu, Jun 15, 2023 at 12:27:53AM +0100, David Howells wrote:
>     
> If an AF_ALG socket bound to a hashing algorithm is sent a zero-length
> message with MSG_MORE set and then recvmsg() is called without first
> sending another message without MSG_MORE set to end the operation, an oops
> will occur because the crypto context and result doesn't now get set up in
> advance because hash_sendmsg() now defers that as long as possible in the
> hope that it can use crypto_ahash_digest() - and then because the message
> is zero-length, it the data wrangling loop is skipped.
> 
> Fix this by always making a pass of the loop, even in the case that no data
> is provided to the sendmsg().
> 
> Fix also extract_iter_to_sg() to handle a zero-length iterator by returning
> 0 immediately.
> 
> Whilst we're at it, remove the code to create a kvmalloc'd scatterlist if
> we get more than ALG_MAX_PAGES - this shouldn't happen.

I don't think this is right.  If it's a zero-length message with
MSG_MORE set, it should be ignored until a recvmsg(2) call is made.

In any case, this patch doesn't fix all the syzbot reports.

We need to think about reverting this change if it can't be fixed
in time.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-15  9:28 ` Herbert Xu
@ 2023-06-15 11:28   ` David Howells
  0 siblings, 0 replies; 9+ messages in thread
From: David Howells @ 2023-06-15 11:28 UTC (permalink / raw)
  To: Herbert Xu
  Cc: dhowells, netdev, syzbot+13a08c0bf4d212766c3c,
	syzbot+14234ccf6d0ef629ec1a, syzbot+4e2e47f32607d0f72d43,
	syzbot+472626bb5e7c59fb768f, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jens Axboe, Matthew Wilcox,
	linux-crypto, linux-kernel

Herbert Xu <herbert@gondor.apana.org.au> wrote:

> In any case, this patch doesn't fix all the syzbot reports.

One of them I can't actually reproduce locally, but I have two more patches
that might fix it.

David


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-14 23:27 [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE) David Howells
  2023-06-15  9:28 ` Herbert Xu
@ 2023-06-16 10:27 ` Herbert Xu
  2023-06-16 10:37   ` David Howells
  1 sibling, 1 reply; 9+ messages in thread
From: Herbert Xu @ 2023-06-16 10:27 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, syzbot+13a08c0bf4d212766c3c, syzbot+14234ccf6d0ef629ec1a,
	syzbot+4e2e47f32607d0f72d43, syzbot+472626bb5e7c59fb768f,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jens Axboe, Matthew Wilcox, linux-crypto, linux-kernel

On Thu, Jun 15, 2023 at 12:27:53AM +0100, David Howells wrote:
>     
> If an AF_ALG socket bound to a hashing algorithm is sent a zero-length
> message with MSG_MORE set and then recvmsg() is called without first
> sending another message without MSG_MORE set to end the operation, an oops
> will occur because the crypto context and result doesn't now get set up in
> advance because hash_sendmsg() now defers that as long as possible in the
> hope that it can use crypto_ahash_digest() - and then because the message
> is zero-length, it the data wrangling loop is skipped.
> 
> Fix this by always making a pass of the loop, even in the case that no data
> is provided to the sendmsg().
> 
> Fix also extract_iter_to_sg() to handle a zero-length iterator by returning
> 0 immediately.
> 
> Whilst we're at it, remove the code to create a kvmalloc'd scatterlist if
> we get more than ALG_MAX_PAGES - this shouldn't happen.
> 
> Fixes: c662b043cdca ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES")
> Reported-by: syzbot+13a08c0bf4d212766c3c@syzkaller.appspotmail.com
> Link: https://lore.kernel.org/r/000000000000b928f705fdeb873a@google.com/
> Reported-by: syzbot+14234ccf6d0ef629ec1a@syzkaller.appspotmail.com
> Link: https://lore.kernel.org/r/000000000000c047db05fdeb8790@google.com/
> Reported-by: syzbot+4e2e47f32607d0f72d43@syzkaller.appspotmail.com
> Link: https://lore.kernel.org/r/000000000000bcca3205fdeb87fb@google.com/
> Reported-by: syzbot+472626bb5e7c59fb768f@syzkaller.appspotmail.com
> Link: https://lore.kernel.org/r/000000000000b55d8805fdeb8385@google.com/
> Signed-off-by: David Howells <dhowells@redhat.com>
> Tested-by: syzbot+13a08c0bf4d212766c3c@syzkaller.appspotmail.com
> Tested-by: syzbot+14234ccf6d0ef629ec1a@syzkaller.appspotmail.com
> Tested-by: syzbot+4e2e47f32607d0f72d43@syzkaller.appspotmail.com
> Tested-by: syzbot+472626bb5e7c59fb768f@syzkaller.appspotmail.com
> cc: Herbert Xu <herbert@gondor.apana.org.au>
> cc: "David S. Miller" <davem@davemloft.net>
> cc: Eric Dumazet <edumazet@google.com>
> cc: Jakub Kicinski <kuba@kernel.org>
> cc: Paolo Abeni <pabeni@redhat.com>
> cc: Jens Axboe <axboe@kernel.dk>
> cc: Matthew Wilcox <willy@infradead.org>
> cc: linux-crypto@vger.kernel.org
> cc: netdev@vger.kernel.org
> ---
>  crypto/algif_hash.c |   21 +++++----------------
>  lib/scatterlist.c   |    2 +-
>  2 files changed, 6 insertions(+), 17 deletions(-)

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-16 10:27 ` Herbert Xu
@ 2023-06-16 10:37   ` David Howells
  2023-06-16 10:43     ` Herbert Xu
  0 siblings, 1 reply; 9+ messages in thread
From: David Howells @ 2023-06-16 10:37 UTC (permalink / raw)
  To: Herbert Xu
  Cc: dhowells, netdev, syzbot+13a08c0bf4d212766c3c,
	syzbot+14234ccf6d0ef629ec1a, syzbot+4e2e47f32607d0f72d43,
	syzbot+472626bb5e7c59fb768f, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jens Axboe, Matthew Wilcox,
	linux-crypto, linux-kernel

Can you have a look at:

	https://lore.kernel.org/r/415439.1686877276@warthog.procyon.org.uk/

I'm proposing that as an alternative to this patch.

David


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-16 10:37   ` David Howells
@ 2023-06-16 10:43     ` Herbert Xu
  2023-06-16 11:11       ` David Howells
  2023-06-19 16:47       ` David Howells
  0 siblings, 2 replies; 9+ messages in thread
From: Herbert Xu @ 2023-06-16 10:43 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, syzbot+13a08c0bf4d212766c3c, syzbot+14234ccf6d0ef629ec1a,
	syzbot+4e2e47f32607d0f72d43, syzbot+472626bb5e7c59fb768f,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jens Axboe, Matthew Wilcox, linux-crypto, linux-kernel

On Fri, Jun 16, 2023 at 11:37:58AM +0100, David Howells wrote:
> Can you have a look at:
> 
> 	https://lore.kernel.org/r/415439.1686877276@warthog.procyon.org.uk/
> 
> I'm proposing that as an alternative to this patch.

It'd be easier to comment on it if you sent it by email.

Anyway, why did you remove the condition on hash_free_result?
We free the result if it's not needed, not to clear the previous
hash.  So by doing it uncondtionally you will simply end up
freeing and reallocating the result for no good reason.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-16 10:43     ` Herbert Xu
@ 2023-06-16 11:11       ` David Howells
  2023-06-19 16:47       ` David Howells
  1 sibling, 0 replies; 9+ messages in thread
From: David Howells @ 2023-06-16 11:11 UTC (permalink / raw)
  To: Herbert Xu
  Cc: dhowells, netdev, syzbot+13a08c0bf4d212766c3c,
	syzbot+14234ccf6d0ef629ec1a, syzbot+4e2e47f32607d0f72d43,
	syzbot+472626bb5e7c59fb768f, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jens Axboe, Matthew Wilcox,
	linux-crypto, linux-kernel

Herbert Xu <herbert@gondor.apana.org.au> wrote:

> It'd be easier to comment on it if you sent it by email.

Done.  Could you repost your comments against that?

Thanks,
David


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-16 10:43     ` Herbert Xu
  2023-06-16 11:11       ` David Howells
@ 2023-06-19 16:47       ` David Howells
  2023-06-20  4:47         ` Herbert Xu
  1 sibling, 1 reply; 9+ messages in thread
From: David Howells @ 2023-06-19 16:47 UTC (permalink / raw)
  To: Herbert Xu
  Cc: dhowells, netdev, syzbot+13a08c0bf4d212766c3c,
	syzbot+14234ccf6d0ef629ec1a, syzbot+4e2e47f32607d0f72d43,
	syzbot+472626bb5e7c59fb768f, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jens Axboe, Matthew Wilcox,
	linux-crypto, linux-kernel

Herbert Xu <herbert@gondor.apana.org.au> wrote:

> Anyway, why did you remove the condition on hash_free_result?
> We free the result if it's not needed, not to clear the previous
> hash.  So by doing it uncondtionally you will simply end up
> freeing and reallocating the result for no good reason.

The free here:

	if (!continuing) {
		if ((msg->msg_flags & MSG_MORE))
			hash_free_result(sk, ctx);

only happens in the following case:

	send(hashfd, "", 0, 0);
	send(hashfd, "", 0, MSG_MORE);  <--- by this

and the patch changes how this case works if no data is given.  In Linus's
tree, it will create a result, init the crypto and finalise it in
hash_sendmsg(); with this patch that case is then handled by hash_recvmsg().
If you consider the following sequence:

	send(hashfd, "", 0, 0);
	send(hashfd, "", 0, 0);
	send(hashfd, "", 0, 0);
	send(hashfd, "", 0, 0);

Upstream, the first one will create a result and then each of them will init
and finalise a hash, whereas with my patch, the first one will release any
outstanding result and then none of them will do any crypto ops.

However, as, with my patch hash_sendmsg() no longer calculated a result, it
has to clear the result pointer because the logic inside hash_recvmsg() relies
on the result pointer to indicate that there is a result.

Instead, hash_recvmsg() concocts the result - something it has to be able to
do anyway in case someone calls recvmsg() without first supplying data.

David


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE)
  2023-06-19 16:47       ` David Howells
@ 2023-06-20  4:47         ` Herbert Xu
  0 siblings, 0 replies; 9+ messages in thread
From: Herbert Xu @ 2023-06-20  4:47 UTC (permalink / raw)
  To: David Howells
  Cc: netdev, syzbot+13a08c0bf4d212766c3c, syzbot+14234ccf6d0ef629ec1a,
	syzbot+4e2e47f32607d0f72d43, syzbot+472626bb5e7c59fb768f,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jens Axboe, Matthew Wilcox, linux-crypto, linux-kernel

On Mon, Jun 19, 2023 at 05:47:26PM +0100, David Howells wrote:
>
> The free here:
> 
> 	if (!continuing) {
> 		if ((msg->msg_flags & MSG_MORE))
> 			hash_free_result(sk, ctx);
> 
> only happens in the following case:
> 
> 	send(hashfd, "", 0, 0);
> 	send(hashfd, "", 0, MSG_MORE);  <--- by this

Yes and that's what I'm complaining about.

> and the patch changes how this case works if no data is given.  In Linus's
> tree, it will create a result, init the crypto and finalise it in
> hash_sendmsg(); with this patch that case is then handled by hash_recvmsg().
> If you consider the following sequence:
> 
> 	send(hashfd, "", 0, 0);
> 	send(hashfd, "", 0, 0);
> 	send(hashfd, "", 0, 0);
> 	send(hashfd, "", 0, 0);
> 
> Upstream, the first one will create a result and then each of them will init
> and finalise a hash, whereas with my patch, the first one will release any
> outstanding result and then none of them will do any crypto ops.

This is correct.  If MSG_MORE is not set, then the hash will be
finalised.  In which case if there is already a result allocated
then we should reuse it and not free it.

If MSG_MORE is set, then we can delay the allocation of the result,
in which case it makes sense to free any previous results since
the next request may not come for a very long time (or perhaps even
never).

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-06-20  4:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-14 23:27 [PATCH net-next] crypto: af_alg/hash: Fix recvmsg() after sendmsg(MSG_MORE) David Howells
2023-06-15  9:28 ` Herbert Xu
2023-06-15 11:28   ` David Howells
2023-06-16 10:27 ` Herbert Xu
2023-06-16 10:37   ` David Howells
2023-06-16 10:43     ` Herbert Xu
2023-06-16 11:11       ` David Howells
2023-06-19 16:47       ` David Howells
2023-06-20  4:47         ` Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).