All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net: sctp: fix memory leak in sctp_chunk_destroy()
@ 2024-02-05 17:01 Dmitry Antipov
  2024-02-05 23:29 ` Xin Long
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Antipov @ 2024-02-05 17:01 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: Xin Long, linux-sctp, netdev, lvc-project, Dmitry Antipov,
	syzbot+8bb053b5d63595ab47db

In case of GSO, per-chunk 'skb' pointer may point to an entry from
fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
random fraglist entry (and so undefined behavior and/or memory
leak), consume 'head_skb' (i.e. beginning of a fraglist) instead.

Reported-by: syzbot+8bb053b5d63595ab47db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?id=0d8351bbe54fd04a492c2daab0164138db008042
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
 net/sctp/sm_make_chunk.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f80208edd6a5..30fe34743009 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1500,7 +1500,10 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
 	BUG_ON(!list_empty(&chunk->list));
 	list_del_init(&chunk->transmitted_list);
 
-	consume_skb(chunk->skb);
+	/* In case of GSO, 'skb' may be a pointer to fraglist entry.
+	 * Consume the read head if so.
+	 */
+	consume_skb(chunk->head_skb ? chunk->head_skb : chunk->skb);
 	consume_skb(chunk->auth_chunk);
 
 	SCTP_DBG_OBJCNT_DEC(chunk);
-- 
2.43.0


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

* Re: [PATCH] net: sctp: fix memory leak in sctp_chunk_destroy()
  2024-02-05 17:01 [PATCH] net: sctp: fix memory leak in sctp_chunk_destroy() Dmitry Antipov
@ 2024-02-05 23:29 ` Xin Long
  2024-02-06  5:15   ` [lvc-project] " Antipov, Dmitriy
  2024-02-06  9:26   ` [PATCH] net: sctp: fix skb leak in sctp_inq_free() Dmitry Antipov
  0 siblings, 2 replies; 8+ messages in thread
From: Xin Long @ 2024-02-05 23:29 UTC (permalink / raw)
  To: Dmitry Antipov
  Cc: Marcelo Ricardo Leitner, linux-sctp, netdev, lvc-project,
	syzbot+8bb053b5d63595ab47db

On Mon, Feb 5, 2024 at 12:02 PM Dmitry Antipov <dmantipov@yandex.ru> wrote:
>
> In case of GSO, per-chunk 'skb' pointer may point to an entry from
> fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
> random fraglist entry (and so undefined behavior and/or memory
> leak), consume 'head_skb' (i.e. beginning of a fraglist) instead.
Right, chunk->skb is supposed to be set to chunk->head_skb
before calling sctp_chunk_free () in sctp_inq_pop():

                        if (chunk->head_skb)
                                chunk->skb = chunk->head_skb;
                        sctp_chunk_free(chunk);
                        chunk = queue->in_progress = NULL;

However, somehow the loop in sctp_assoc_bh_rcv() breaks without
dequeuing all skbs, and I guess it's because of "asoc->base.dead".

In this case, sctp_inq_free() should take care of its release,
so can you try to fix it there? like:

diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 7182c5a450fb..dda5e1ad9cac 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -52,8 +52,11 @@ void sctp_inq_free(struct sctp_inq *queue)
        /* If there is a packet which is currently being worked on,
         * free it as well.
         */
-       if (queue->in_progress) {
-               sctp_chunk_free(queue->in_progress);
+       chunk = queue->in_progress;
+       if (chunk) {
+               if (chunk->head_skb)
+                       chunk->skb = chunk->head_skb;
+               sctp_chunk_free(chunk);
                queue->in_progress = NULL;
        }
 }

this would avoid doing chunk->head_skb check for all chunks destroying.

Thanks.
>
> Reported-by: syzbot+8bb053b5d63595ab47db@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?id=0d8351bbe54fd04a492c2daab0164138db008042
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
> ---
>  net/sctp/sm_make_chunk.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index f80208edd6a5..30fe34743009 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -1500,7 +1500,10 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
>         BUG_ON(!list_empty(&chunk->list));
>         list_del_init(&chunk->transmitted_list);
>
> -       consume_skb(chunk->skb);
> +       /* In case of GSO, 'skb' may be a pointer to fraglist entry.
> +        * Consume the read head if so.
> +        */
> +       consume_skb(chunk->head_skb ? chunk->head_skb : chunk->skb);
>         consume_skb(chunk->auth_chunk);
>
>         SCTP_DBG_OBJCNT_DEC(chunk);
> --
> 2.43.0
>

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

* Re: [lvc-project] [PATCH] net: sctp: fix memory leak in sctp_chunk_destroy()
  2024-02-05 23:29 ` Xin Long
@ 2024-02-06  5:15   ` Antipov, Dmitriy
  2024-02-06  9:26   ` [PATCH] net: sctp: fix skb leak in sctp_inq_free() Dmitry Antipov
  1 sibling, 0 replies; 8+ messages in thread
From: Antipov, Dmitriy @ 2024-02-06  5:15 UTC (permalink / raw)
  To: lucien.xin, dmantipov
  Cc: lvc-project, linux-sctp, netdev, syzbot+8bb053b5d63595ab47db,
	marcelo.leitner

On Mon, 2024-02-05 at 18:29 -0500, Xin Long wrote:


> In this case, sctp_inq_free() should take care of its release,
> so can you try to fix it there? like:

Yes, this seems fixes the leak(s) as well. Won't
insist on my version assuming that you know better.

Dmitry

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

* [PATCH] net: sctp: fix skb leak in sctp_inq_free()
  2024-02-05 23:29 ` Xin Long
  2024-02-06  5:15   ` [lvc-project] " Antipov, Dmitriy
@ 2024-02-06  9:26   ` Dmitry Antipov
  2024-02-09 21:47     ` Jakub Kicinski
  1 sibling, 1 reply; 8+ messages in thread
From: Dmitry Antipov @ 2024-02-06  9:26 UTC (permalink / raw)
  To: Xin Long
  Cc: Marcelo Ricardo Leitner, linux-sctp, netdev, lvc-project,
	Dmitry Antipov, syzbot+8bb053b5d63595ab47db

In case of GSO, 'chunk->skb' pointer may point to an entry from
fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
random fraglist entry (and so undefined behavior and/or memory
leak), ensure that 'chunk->skb' is set to 'chunk->head_skb'
(i.e. fraglist head) before calling 'sctp_chunk_free()'.

Reported-by: syzbot+8bb053b5d63595ab47db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?id=0d8351bbe54fd04a492c2daab0164138db008042
Fixes: 90017accff61 ("sctp: Add GSO support")
Suggested-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
 net/sctp/inqueue.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 7182c5a450fb..dda5e1ad9cac 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -52,8 +52,11 @@ void sctp_inq_free(struct sctp_inq *queue)
 	/* If there is a packet which is currently being worked on,
 	 * free it as well.
 	 */
-	if (queue->in_progress) {
-		sctp_chunk_free(queue->in_progress);
+	chunk = queue->in_progress;
+	if (chunk) {
+		if (chunk->head_skb)
+			chunk->skb = chunk->head_skb;
+		sctp_chunk_free(chunk);
 		queue->in_progress = NULL;
 	}
 }
-- 
2.43.0


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

* Re: [PATCH] net: sctp: fix skb leak in sctp_inq_free()
  2024-02-06  9:26   ` [PATCH] net: sctp: fix skb leak in sctp_inq_free() Dmitry Antipov
@ 2024-02-09 21:47     ` Jakub Kicinski
  2024-02-12  8:22       ` [PATCH] [v2] " Dmitry Antipov
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2024-02-09 21:47 UTC (permalink / raw)
  To: Dmitry Antipov
  Cc: Xin Long, Marcelo Ricardo Leitner, linux-sctp, netdev,
	lvc-project, syzbot+8bb053b5d63595ab47db

On Tue,  6 Feb 2024 12:26:17 +0300 Dmitry Antipov wrote:
> In case of GSO, 'chunk->skb' pointer may point to an entry from
> fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
> random fraglist entry (and so undefined behavior and/or memory
> leak), ensure that 'chunk->skb' is set to 'chunk->head_skb'
> (i.e. fraglist head) before calling 'sctp_chunk_free()'.

The code already exists in another place in this file, let's factor it
out to a helper function.
-- 
pw-bot: cr

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

* [PATCH] [v2] net: sctp: fix skb leak in sctp_inq_free()
  2024-02-09 21:47     ` Jakub Kicinski
@ 2024-02-12  8:22       ` Dmitry Antipov
  2024-02-13  0:25         ` Jakub Kicinski
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Antipov @ 2024-02-12  8:22 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Xin Long, Marcelo Ricardo Leitner, linux-sctp, netdev,
	lvc-project, Dmitry Antipov, syzbot+8bb053b5d63595ab47db

In case of GSO, 'chunk->skb' pointer may point to an entry from
fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
random fraglist entry (and so undefined behavior and/or memory
leak), introduce 'sctp_chunk_release()' helper to ensure that
'chunk->skb' is set to 'chunk->head_skb' (i.e. fraglist head)
before calling 'sctp_chunk_free()', and use the aforementioned
helper in 'sctp_inq_pop()' as well.

Reported-by: syzbot+8bb053b5d63595ab47db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?id=0d8351bbe54fd04a492c2daab0164138db008042
Fixes: 90017accff61 ("sctp: Add GSO support")
Suggested-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
v2: factor the fix out to helper function (Jakub Kicinski)
---
 net/sctp/inqueue.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 7182c5a450fb..9ec172405ff4 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -38,6 +38,14 @@ void sctp_inq_init(struct sctp_inq *queue)
 	INIT_WORK(&queue->immediate, NULL);
 }
 
+/* Properly release the chunk which is being worked on. */
+static inline void sctp_chunk_release(struct sctp_chunk *chunk)
+{
+	if (chunk->head_skb)
+		chunk->skb = chunk->head_skb;
+	sctp_chunk_free(chunk);
+}
+
 /* Release the memory associated with an SCTP inqueue.  */
 void sctp_inq_free(struct sctp_inq *queue)
 {
@@ -53,7 +61,7 @@ void sctp_inq_free(struct sctp_inq *queue)
 	 * free it as well.
 	 */
 	if (queue->in_progress) {
-		sctp_chunk_free(queue->in_progress);
+		sctp_chunk_release(queue->in_progress);
 		queue->in_progress = NULL;
 	}
 }
@@ -130,9 +138,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
 				goto new_skb;
 			}
 
-			if (chunk->head_skb)
-				chunk->skb = chunk->head_skb;
-			sctp_chunk_free(chunk);
+			sctp_chunk_release(chunk);
 			chunk = queue->in_progress = NULL;
 		} else {
 			/* Nothing to do. Next chunk in the packet, please. */
-- 
2.43.0


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

* Re: [PATCH] [v2] net: sctp: fix skb leak in sctp_inq_free()
  2024-02-12  8:22       ` [PATCH] [v2] " Dmitry Antipov
@ 2024-02-13  0:25         ` Jakub Kicinski
  2024-02-13 15:21           ` Xin Long
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2024-02-13  0:25 UTC (permalink / raw)
  To: Dmitry Antipov
  Cc: Xin Long, Marcelo Ricardo Leitner, linux-sctp, netdev,
	lvc-project, syzbot+8bb053b5d63595ab47db

On Mon, 12 Feb 2024 11:22:02 +0300 Dmitry Antipov wrote:
> In case of GSO, 'chunk->skb' pointer may point to an entry from
> fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
> random fraglist entry (and so undefined behavior and/or memory
> leak), introduce 'sctp_chunk_release()' helper to ensure that
> 'chunk->skb' is set to 'chunk->head_skb' (i.e. fraglist head)
> before calling 'sctp_chunk_free()', and use the aforementioned
> helper in 'sctp_inq_pop()' as well.

Please repost this as a separate thread, per:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#resending-after-review
Xin Long is probably out for New Year celebrations, anyway.
-- 
pw-bot: cr

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

* Re: [PATCH] [v2] net: sctp: fix skb leak in sctp_inq_free()
  2024-02-13  0:25         ` Jakub Kicinski
@ 2024-02-13 15:21           ` Xin Long
  0 siblings, 0 replies; 8+ messages in thread
From: Xin Long @ 2024-02-13 15:21 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Dmitry Antipov, Marcelo Ricardo Leitner, linux-sctp, netdev,
	lvc-project, syzbot+8bb053b5d63595ab47db

On Mon, Feb 12, 2024 at 7:25 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Mon, 12 Feb 2024 11:22:02 +0300 Dmitry Antipov wrote:
> > In case of GSO, 'chunk->skb' pointer may point to an entry from
> > fraglist created in 'sctp_packet_gso_append()'. To avoid freeing
> > random fraglist entry (and so undefined behavior and/or memory
> > leak), introduce 'sctp_chunk_release()' helper to ensure that
> > 'chunk->skb' is set to 'chunk->head_skb' (i.e. fraglist head)
> > before calling 'sctp_chunk_free()', and use the aforementioned
> > helper in 'sctp_inq_pop()' as well.
>
> Please repost this as a separate thread, per:
> https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#resending-after-review
and instead of sctp_chunk_release(), please use a better name like
"sctp_inq_chunk_free()" when you repost.

Thanks.

> Xin Long is probably out for New Year celebrations, anyway.
> --
> pw-bot: cr

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

end of thread, other threads:[~2024-02-13 15:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-05 17:01 [PATCH] net: sctp: fix memory leak in sctp_chunk_destroy() Dmitry Antipov
2024-02-05 23:29 ` Xin Long
2024-02-06  5:15   ` [lvc-project] " Antipov, Dmitriy
2024-02-06  9:26   ` [PATCH] net: sctp: fix skb leak in sctp_inq_free() Dmitry Antipov
2024-02-09 21:47     ` Jakub Kicinski
2024-02-12  8:22       ` [PATCH] [v2] " Dmitry Antipov
2024-02-13  0:25         ` Jakub Kicinski
2024-02-13 15:21           ` Xin Long

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.