Thread (3 messages) 3 messages, 2 authors, 26d ago

Re: [PATCH net 1/1] inet: frags: orphan non-wmem skbs before building frag_list

flat view

From: Eric Dumazet <edumazet@kernel.org>
Date: 2026-10-01 08:50:21

On Thu, Oct 1, 2026 at 9:54 AM Ren Wei [off-list ref] wrote:
quoted hunk ↗ jump to hunk
From: Zixuan Chai <redacted>

When a fragment skb cannot be coalesced, reassembly clears skb->sk
before linking it to frag_list. If the skb still has a non-wmem
destructor, the callback remains installed and may dereference the
cleared socket when the skb is freed, causing a NULL pointer
dereference.

Orphan non-wmem skbs that have a destructor before adding them to
frag_list. Keep the existing skb->sk clearing for skbs without a
destructor and for wmem skbs, preserving TX accounting.

Fixes: d15f5ac8deea ("ipv6: frags: Fix bogus skb->sk in reassembled packets")
Cc: <redacted>
Reported-by: Vega <redacted>
Assisted-by: LLM
Signed-off-by: Zixuan Chai <redacted>
Signed-off-by: Ren Wei <redacted>
---
 net/ipv4/inet_fragment.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index b286ee429da8..cc6718f579fa 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -652,7 +652,10 @@ void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
                        } else {
                                fp->prev = NULL;
                                memset(&fp->rbnode, 0, sizeof(fp->rbnode));
-                               fp->sk = NULL;
+                               if (fp->destructor && !is_skb_wmem(fp))
+                                       skb_orphan(fp);
+                               else
+                                       fp->sk = NULL;
Hmm

The root cause is that 18685451fc4e ("inet: inet_defrag: prevent sk
release while still in use") moved skb_orphan() into ip_frag_queue()
and nf_ct_frag6_queue(), but not into ip6_frag_queue().

Fixing this in inet_frag_reasm_finish() is too late. Sockets assigned
by bpf_sk_assign() are often not refcounted (SOCK_RCU_FREE), so a
queued fragment can hold a stale skb->sk for up to ipfrag_time.
sock_pfree() would then dereference freed memory when the queue
expires, on the coalesce path, or in your new skb_orphan(fp) call.

Please instead add skb_orphan(skb) before 'return -EINPROGRESS' in
ip6_frag_queue(), matching the IPv4 and nf_conntrack paths?

Also, a better tag would be:

Fixes: cf7fbe660f2d ("bpf: Add socket assign support")

pw-bot: cr
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help