* [PATCH net] net: fix frag_list leak in skb_segment_list() error path
@ 2026-10-21 16:18 Eric Dumazet
2026-10-21 16:54 ` Willem de Bruijn
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Eric Dumazet @ 2026-10-21 16:18 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Willem de Bruijn, Simon Horman, netdev, Eric Dumazet,
Simon Polack
skb_segment_list() detaches the frag_list from the head skb and moves
its members one by one to the skb->next chain. On error, err_linearize
frees that chain with kfree_skb_list(skb->next), relying on the members
not yet processed to still be linked after the current one.
This does not hold when the current member was shared: it is replaced
by skb_clone(), and __skb_clone() clears ->next. If __skb_linearize()
then fails on that clone, the remaining members are no longer reachable
from skb->next nor from skb_shinfo(skb)->frag_list, and they leak.
The skb_shared() error branch already relinks nskb->next to list_skb
before jumping to err_linearize. Do it unconditionally right after nskb
is added to the chain, so every error exit sees the remaining members.
On the last member list_skb is NULL, which still terminates the chain.
Fixes: 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Cc: Simon Polack <spolack+git@mailbox.org>
---
Bug discovered while reviewing at Simon Polack upcoming patch in
skb_segment_list()
net/core/skbuff.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ab178af02a2262d65175daff7f093c85eaa09c92..beddbf6812b9f387672c7ab5f0a1c07ab9bd0806 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4734,10 +4734,13 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
else
tail->next = nskb;
- if (unlikely(err)) {
- nskb->next = list_skb;
+ /* nskb may be a clone with a NULL ->next: keep the remaining
+ * members linked so that err_linearize frees them.
+ */
+ nskb->next = list_skb;
+
+ if (unlikely(err))
goto err_linearize;
- }
tail = nskb;
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: fix frag_list leak in skb_segment_list() error path
2026-10-21 16:18 [PATCH net] net: fix frag_list leak in skb_segment_list() error path Eric Dumazet
@ 2026-10-21 16:54 ` Willem de Bruijn
2026-10-22 4:35 ` Wang Zhan
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Willem de Bruijn @ 2026-10-21 16:54 UTC (permalink / raw)
To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Willem de Bruijn, Simon Horman, netdev, Eric Dumazet,
Simon Polack
Eric Dumazet wrote:
> skb_segment_list() detaches the frag_list from the head skb and moves
> its members one by one to the skb->next chain. On error, err_linearize
> frees that chain with kfree_skb_list(skb->next), relying on the members
> not yet processed to still be linked after the current one.
>
> This does not hold when the current member was shared: it is replaced
> by skb_clone(), and __skb_clone() clears ->next. If __skb_linearize()
> then fails on that clone, the remaining members are no longer reachable
> from skb->next nor from skb_shinfo(skb)->frag_list, and they leak.
>
> The skb_shared() error branch already relinks nskb->next to list_skb
> before jumping to err_linearize. Do it unconditionally right after nskb
> is added to the chain, so every error exit sees the remaining members.
> On the last member list_skb is NULL, which still terminates the chain.
>
> Fixes: 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist")
> Signed-off-by: Eric Dumazet <edumazet@kernel.org>
> Cc: Simon Polack <spolack+git@mailbox.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: fix frag_list leak in skb_segment_list() error path
2026-10-21 16:18 [PATCH net] net: fix frag_list leak in skb_segment_list() error path Eric Dumazet
2026-10-21 16:54 ` Willem de Bruijn
@ 2026-10-22 4:35 ` Wang Zhan
2026-10-22 8:47 ` Jiayuan Chen
2026-10-23 21:30 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Wang Zhan @ 2026-10-22 4:35 UTC (permalink / raw)
To: netdev, Eric Dumazet
Cc: Wang Zhan, David S . Miller, Jakub Kicinski, Paolo Abeni,
Willem de Bruijn, Simon Horman, Simon Polack
On Wed, 21 Oct 2026 18:18:58 +0200 Eric Dumazet wrote:
> skb_segment_list() detaches the frag_list from the head skb and moves
> its members one by one to the skb->next chain. On error, err_linearize
> frees that chain with kfree_skb_list(skb->next), relying on the members
> not yet processed to still be linked after the current one.
>
> This does not hold when the current member was shared: it is replaced
> by skb_clone(), and __skb_clone() clears ->next. If __skb_linearize()
> then fails on that clone, the remaining members are no longer reachable
> from skb->next nor from skb_shinfo(skb)->frag_list, and they leak.
>
> The skb_shared() error branch already relinks nskb->next to list_skb
> before jumping to err_linearize. Do it unconditionally right after nskb
> is added to the chain, so every error exit sees the remaining members.
> On the last member list_skb is NULL, which still terminates the chain.
>
> Fixes: 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist")
> Signed-off-by: Eric Dumazet <edumazet@kernel.org>
> Cc: Simon Polack <spolack+git@mailbox.org>
Reviewed-by: Wang Zhan <wang.zhan@smartx.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: fix frag_list leak in skb_segment_list() error path
2026-10-21 16:18 [PATCH net] net: fix frag_list leak in skb_segment_list() error path Eric Dumazet
2026-10-21 16:54 ` Willem de Bruijn
2026-10-22 4:35 ` Wang Zhan
@ 2026-10-22 8:47 ` Jiayuan Chen
2026-10-23 21:30 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: Jiayuan Chen @ 2026-10-22 8:47 UTC (permalink / raw)
To: netdev
On 10/22/26 12:18 AM, Eric Dumazet wrote:
> skb_segment_list() detaches the frag_list from the head skb and moves
> its members one by one to the skb->next chain. On error, err_linearize
> frees that chain with kfree_skb_list(skb->next), relying on the members
> not yet processed to still be linked after the current one.
>
> This does not hold when the current member was shared: it is replaced
> by skb_clone(), and __skb_clone() clears ->next. If __skb_linearize()
> then fails on that clone, the remaining members are no longer reachable
> from skb->next nor from skb_shinfo(skb)->frag_list, and they leak.
>
> The skb_shared() error branch already relinks nskb->next to list_skb
> before jumping to err_linearize. Do it unconditionally right after nskb
> is added to the chain, so every error exit sees the remaining members.
> On the last member list_skb is NULL, which still terminates the chain.
>
> Fixes: 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist")
> Signed-off-by: Eric Dumazet <edumazet@kernel.org>
> Cc: Simon Polack <spolack+git@mailbox.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
> ---
> Bug discovered while reviewing at Simon Polack upcoming patch in
> skb_segment_list()
>
> net/core/skbuff.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index ab178af02a2262d65175daff7f093c85eaa09c92..beddbf6812b9f387672c7ab5f0a1c07ab9bd0806 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -4734,10 +4734,13 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
> else
> tail->next = nskb;
>
> - if (unlikely(err)) {
> - nskb->next = list_skb;
> + /* nskb may be a clone with a NULL ->next: keep the remaining
> + * members linked so that err_linearize frees them.
> + */
> + nskb->next = list_skb;
> +
> + if (unlikely(err))
> goto err_linearize;
> - }
>
> tail = nskb;
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: fix frag_list leak in skb_segment_list() error path
2026-10-21 16:18 [PATCH net] net: fix frag_list leak in skb_segment_list() error path Eric Dumazet
` (2 preceding siblings ...)
2026-10-22 8:47 ` Jiayuan Chen
@ 2026-10-23 21:30 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-10-23 21:30 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, kuba, pabeni, willemb, horms, netdev, spolack+git
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 21 Oct 2026 18:18:58 +0200 you wrote:
> skb_segment_list() detaches the frag_list from the head skb and moves
> its members one by one to the skb->next chain. On error, err_linearize
> frees that chain with kfree_skb_list(skb->next), relying on the members
> not yet processed to still be linked after the current one.
>
> This does not hold when the current member was shared: it is replaced
> by skb_clone(), and __skb_clone() clears ->next. If __skb_linearize()
> then fails on that clone, the remaining members are no longer reachable
> from skb->next nor from skb_shinfo(skb)->frag_list, and they leak.
>
> [...]
Here is the summary with links:
- [net] net: fix frag_list leak in skb_segment_list() error path
https://git.kernel.org/netdev/net/c/546daf344420
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-23 21:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-21 16:18 [PATCH net] net: fix frag_list leak in skb_segment_list() error path Eric Dumazet
2026-10-21 16:54 ` Willem de Bruijn
2026-10-22 4:35 ` Wang Zhan
2026-10-22 8:47 ` Jiayuan Chen
2026-10-23 21:30 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox