* [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
@ 2026-09-11 11:49 Eric Dumazet
2026-09-11 16:13 ` Ivy Lopez
2026-09-12 6:38 ` luoxuanqiang
0 siblings, 2 replies; 8+ messages in thread
From: Eric Dumazet @ 2026-09-11 11:49 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet,
syzbot+586af68eb819833c2d91, Allison Henderson, rds-devel
pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
the first bytes of a packet and reallocate skb->head.
All the headers that were present before the operation are gone,
but both functions call skb_headers_offset_update(skb, 0), which
is a no-op : skb->mac_header, skb->network_header,
skb->transport_header and skb->csum_start are left with their old
values, now pointing into the freshly allocated (and possibly much
smaller) skb->head.
For pskb_carve_inside_nonlinear() the result is a zombie skb with
an empty linear part (skb->data == skb_tail_pointer(skb),
skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
skb->mac_header pointing far beyond skb_end_pointer(skb).
The only user of pskb_extract() is rds_tcp_data_recv(), and the
carved skb is queued on tinc->ti_skb_list. When the RDS incoming
message is released, rds_tcp_inc_free() calls skb_queue_purge(),
which frees the skbs with SKB_DROP_REASON_QUEUE_PURGE. This is
visible from drop_monitor, which then tries to pull back to the
(bogus) mac header :
skbuff: __skb_pull(len=234)
skb len=6968 data_len=6968 headroom=0 headlen=0 tailroom=0
end-tail=384 mac=(234,14) mac_len=14 net=(248,40) trans=288
shinfo(txflags=0 nr_frags=1 gso(size=1428 type=16 segs=5))
csum(0x100120 start=288 offset=16 ip_summed=3 complete_sw=0 valid=1 level=0)
hash(0x7b446c6c sw=0 l4=1) proto=0x86dd pkttype=0 iif=60
------------[ cut here ]------------
kernel BUG at ./include/linux/skbuff.h:2847!
Add skb_carve_reset_headers() to mark the mac and transport headers
as not set, reset the network header, clear skb->mac_len, and drop
a now meaningless CHECKSUM_PARTIAL (csum_start would point outside
of the new buffer).
Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
Reported-by: syzbot+586af68eb819833c2d91@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6aa3e9d3.f2639fcc.29487d.0028.GAE@google.com/
Cc: Allison Henderson <achender@kernel.org>
Cc: rds-devel@oss.oracle.com
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/skbuff.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index cc3b4b70288b4e3f17984cd4f4e4b7a330353e15..0e6637db6da201fe2640c244e1b0983fca39b918 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6832,6 +6832,23 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
}
EXPORT_SYMBOL(alloc_skb_with_frags);
+/* pskb_carve_inside_header() and pskb_carve_inside_nonlinear()
+ * remove the first bytes of a packet and reallocate skb->head.
+ *
+ * Whatever headers were present before the operation are gone,
+ * we must not leave stale offsets, otherwise users of this skb
+ * (skb_dump(), drop_monitor, taps, ...) would read or pull garbage.
+ */
+static void skb_carve_reset_headers(struct sk_buff *skb)
+{
+ skb_unset_mac_header(skb);
+ skb_unset_transport_header(skb);
+ skb_reset_network_header(skb);
+ skb->mac_len = 0;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ skb->ip_summed = CHECKSUM_NONE;
+}
+
/* carve out the first off bytes from skb when off < headlen */
static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
const int headlen, gfp_t gfp_mask)
@@ -6887,7 +6904,7 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
skb->head_frag = 0;
skb_set_end_offset(skb, size);
skb_set_tail_pointer(skb, skb_headlen(skb));
- skb_headers_offset_update(skb, 0);
+ skb_carve_reset_headers(skb);
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
@@ -7027,7 +7044,7 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
skb->data = data;
skb_set_end_offset(skb, size);
skb_reset_tail_pointer(skb);
- skb_headers_offset_update(skb, 0);
+ skb_carve_reset_headers(skb);
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
--
2.55.0.1007.g17ff1f9808-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-11 11:49 [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve() Eric Dumazet
@ 2026-09-11 16:13 ` Ivy Lopez
2026-09-12 6:38 ` luoxuanqiang
1 sibling, 0 replies; 8+ messages in thread
From: Ivy Lopez @ 2026-09-11 16:13 UTC (permalink / raw)
To: edumazet; +Cc: netdev, davem, kuba, pabeni, horms, achender, rds-devel,
Ivy Lopez
LGTM.
Reviewed-by: Ivy Lopez <skunkolee@gmail.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-11 11:49 [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve() Eric Dumazet
2026-09-11 16:13 ` Ivy Lopez
@ 2026-09-12 6:38 ` luoxuanqiang
2026-09-12 8:57 ` Eric Dumazet
1 sibling, 1 reply; 8+ messages in thread
From: luoxuanqiang @ 2026-09-12 6:38 UTC (permalink / raw)
To: Eric Dumazet
Cc: Simon Horman, netdev, eric.dumazet, syzbot+586af68eb819833c2d91,
Allison Henderson, rds-devel, David S . Miller, Jakub Kicinski,
Paolo Abeni
在 2026/9/11 19:49, Eric Dumazet 写道:
> pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
> the first bytes of a packet and reallocate skb->head.
>
> All the headers that were present before the operation are gone,
> but both functions call skb_headers_offset_update(skb, 0), which
> is a no-op : skb->mac_header, skb->network_header,
> skb->transport_header and skb->csum_start are left with their old
> values, now pointing into the freshly allocated (and possibly much
> smaller) skb->head.
>
> For pskb_carve_inside_nonlinear() the result is a zombie skb with
> an empty linear part (skb->data == skb_tail_pointer(skb),
> skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
> skb->mac_header pointing far beyond skb_end_pointer(skb).
>
Could you please clarify how the MAC pointer ends up beyond
skb_end_pointer() here? The carve helpers allocate based on the old
skb_end_offset(), and kmalloc_reserve() adds room for skb_shared_info,
so the new capacity shouldn't be smaller.
The dump shows mac=234 and end=384. I understand how the stale offset
causes skb_pull() on an empty linear area and triggers the BUG, but I
don't see how it ends up beyond the new end. Am I missing another
condition?
Thanks,
Xuanqiang
> The only user of pskb_extract() is rds_tcp_data_recv(), and the
> carved skb is queued on tinc->ti_skb_list. When the RDS incoming
> message is released, rds_tcp_inc_free() calls skb_queue_purge(),
> which frees the skbs with SKB_DROP_REASON_QUEUE_PURGE. This is
> visible from drop_monitor, which then tries to pull back to the
> (bogus) mac header :
>
> skbuff: __skb_pull(len=234)
> skb len=6968 data_len=6968 headroom=0 headlen=0 tailroom=0
> end-tail=384 mac=(234,14) mac_len=14 net=(248,40) trans=288
> shinfo(txflags=0 nr_frags=1 gso(size=1428 type=16 segs=5))
> csum(0x100120 start=288 offset=16 ip_summed=3 complete_sw=0 valid=1 level=0)
> hash(0x7b446c6c sw=0 l4=1) proto=0x86dd pkttype=0 iif=60
> ------------[ cut here ]------------
> kernel BUG at ./include/linux/skbuff.h:2847!
>
> Add skb_carve_reset_headers() to mark the mac and transport headers
> as not set, reset the network header, clear skb->mac_len, and drop
> a now meaningless CHECKSUM_PARTIAL (csum_start would point outside
> of the new buffer).
>
> Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
> Reported-by: syzbot+586af68eb819833c2d91@syzkaller.appspotmail.com
> Closes: https://lore.kernel.org/netdev/6aa3e9d3.f2639fcc.29487d.0028.GAE@google.com/
> Cc: Allison Henderson <achender@kernel.org>
> Cc: rds-devel@oss.oracle.com
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> net/core/skbuff.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index cc3b4b70288b4e3f17984cd4f4e4b7a330353e15..0e6637db6da201fe2640c244e1b0983fca39b918 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -6832,6 +6832,23 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
> }
> EXPORT_SYMBOL(alloc_skb_with_frags);
>
> +/* pskb_carve_inside_header() and pskb_carve_inside_nonlinear()
> + * remove the first bytes of a packet and reallocate skb->head.
> + *
> + * Whatever headers were present before the operation are gone,
> + * we must not leave stale offsets, otherwise users of this skb
> + * (skb_dump(), drop_monitor, taps, ...) would read or pull garbage.
> + */
> +static void skb_carve_reset_headers(struct sk_buff *skb)
> +{
> + skb_unset_mac_header(skb);
> + skb_unset_transport_header(skb);
> + skb_reset_network_header(skb);
> + skb->mac_len = 0;
> + if (skb->ip_summed == CHECKSUM_PARTIAL)
> + skb->ip_summed = CHECKSUM_NONE;
> +}
> +
> /* carve out the first off bytes from skb when off < headlen */
> static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
> const int headlen, gfp_t gfp_mask)
> @@ -6887,7 +6904,7 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
> skb->head_frag = 0;
> skb_set_end_offset(skb, size);
> skb_set_tail_pointer(skb, skb_headlen(skb));
> - skb_headers_offset_update(skb, 0);
> + skb_carve_reset_headers(skb);
> skb->cloned = 0;
> skb->hdr_len = 0;
> skb->nohdr = 0;
> @@ -7027,7 +7044,7 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
> skb->data = data;
> skb_set_end_offset(skb, size);
> skb_reset_tail_pointer(skb);
> - skb_headers_offset_update(skb, 0);
> + skb_carve_reset_headers(skb);
> skb->cloned = 0;
> skb->hdr_len = 0;
> skb->nohdr = 0;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-12 6:38 ` luoxuanqiang
@ 2026-09-12 8:57 ` Eric Dumazet
2026-09-12 13:39 ` Xuanqiang Luo
0 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2026-09-12 8:57 UTC (permalink / raw)
To: luoxuanqiang
Cc: Simon Horman, netdev, eric.dumazet, syzbot+586af68eb819833c2d91,
Allison Henderson, rds-devel, David S . Miller, Jakub Kicinski,
Paolo Abeni
On Fri, Sep 11, 2026 at 11:38 PM luoxuanqiang <xuanqiang.luo@linux.dev> wrote:
>
> 在 2026/9/11 19:49, Eric Dumazet 写道:
> > pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
> > the first bytes of a packet and reallocate skb->head.
> >
> > All the headers that were present before the operation are gone,
> > but both functions call skb_headers_offset_update(skb, 0), which
> > is a no-op : skb->mac_header, skb->network_header,
> > skb->transport_header and skb->csum_start are left with their old
> > values, now pointing into the freshly allocated (and possibly much
> > smaller) skb->head.
> >
> > For pskb_carve_inside_nonlinear() the result is a zombie skb with
> > an empty linear part (skb->data == skb_tail_pointer(skb),
> > skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
> > skb->mac_header pointing far beyond skb_end_pointer(skb).
> >
> Could you please clarify how the MAC pointer ends up beyond
> skb_end_pointer() here? The carve helpers allocate based on the old
> skb_end_offset(), and kmalloc_reserve() adds room for skb_shared_info,
> so the new capacity shouldn't be smaller.
>
> The dump shows mac=234 and end=384. I understand how the stale offset
> causes skb_pull() on an empty linear area and triggers the BUG, but I
> don't see how it ends up beyond the new end. Am I missing another
> condition?
skb_headers_offset_update(skb, 0) is a no-op, so mac=234, net=248,
trans=288 and csum_start=288 survive and now describe bytes that are not
there anymore. skb_mac_header_was_set() still returns true, so drop_monitor
does skb_pull(skb, 234) on an empty linear part and hits the BUG in
__skb_pull().
pskb_carve_inside_header() has the same issue, the remaining linear data is
shifted by off bytes while the offsets are left untouched.
Thanks,
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-12 8:57 ` Eric Dumazet
@ 2026-09-12 13:39 ` Xuanqiang Luo
2026-09-12 13:44 ` Eric Dumazet
0 siblings, 1 reply; 8+ messages in thread
From: Xuanqiang Luo @ 2026-09-12 13:39 UTC (permalink / raw)
To: Eric Dumazet
Cc: Simon Horman, netdev, eric.dumazet, syzbot+586af68eb819833c2d91,
Allison Henderson, rds-devel, David S . Miller, Jakub Kicinski,
Paolo Abeni
在 2026/9/12 16:57, Eric Dumazet 写道:
> On Fri, Sep 11, 2026 at 11:38 PM luoxuanqiang <xuanqiang.luo@linux.dev> wrote:
>>
>> 在 2026/9/11 19:49, Eric Dumazet 写道:
>>> pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
>>> the first bytes of a packet and reallocate skb->head.
>>>
>>> All the headers that were present before the operation are gone,
>>> but both functions call skb_headers_offset_update(skb, 0), which
>>> is a no-op : skb->mac_header, skb->network_header,
>>> skb->transport_header and skb->csum_start are left with their old
>>> values, now pointing into the freshly allocated (and possibly much
>>> smaller) skb->head.
>>>
>>> For pskb_carve_inside_nonlinear() the result is a zombie skb with
>>> an empty linear part (skb->data == skb_tail_pointer(skb),
>>> skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
>>> skb->mac_header pointing far beyond skb_end_pointer(skb).
>>>
>> Could you please clarify how the MAC pointer ends up beyond
>> skb_end_pointer() here? The carve helpers allocate based on the old
>> skb_end_offset(), and kmalloc_reserve() adds room for skb_shared_info,
>> so the new capacity shouldn't be smaller.
>>
>> The dump shows mac=234 and end=384. I understand how the stale offset
>> causes skb_pull() on an empty linear area and triggers the BUG, but I
>> don't see how it ends up beyond the new end. Am I missing another
>> condition?
>
> skb_headers_offset_update(skb, 0) is a no-op, so mac=234, net=248,
> trans=288 and csum_start=288 survive and now describe bytes that are not
> there anymore. skb_mac_header_was_set() still returns true, so drop_monitor
> does skb_pull(skb, 234) on an empty linear part and hits the BUG in
> __skb_pull().
>
> pskb_carve_inside_header() has the same issue, the remaining linear data is
> shifted by off bytes while the offsets are left untouched.
>
Thanks for the explanation. The fix itself looks correct to me, and I
understand why the stale MAC offset causes the BUG.
Could I check my understanding of "far beyond skb_end_pointer()"?
The dump shows headroom=0 and headlen=0, so head=data=tail. With
end-tail=384 and mac=234, the MAC pointer is head+234, still before
end at head+384. For this nonlinear skb, did you mean beyond
skb_tail_pointer() rather than skb_end_pointer()?
Thanks,
Xuanqiang
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-12 13:39 ` Xuanqiang Luo
@ 2026-09-12 13:44 ` Eric Dumazet
2026-09-12 15:29 ` Xuanqiang Luo
0 siblings, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2026-09-12 13:44 UTC (permalink / raw)
To: Xuanqiang Luo
Cc: Simon Horman, netdev, eric.dumazet, syzbot+586af68eb819833c2d91,
Allison Henderson, rds-devel, David S . Miller, Jakub Kicinski,
Paolo Abeni
On Sat, Sep 12, 2026 at 6:39 AM Xuanqiang Luo <xuanqiang.luo@linux.dev> wrote:
>
> 在 2026/9/12 16:57, Eric Dumazet 写道:
> > On Fri, Sep 11, 2026 at 11:38 PM luoxuanqiang <xuanqiang.luo@linux.dev> wrote:
> >>
> >> 在 2026/9/11 19:49, Eric Dumazet 写道:
> >>> pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
> >>> the first bytes of a packet and reallocate skb->head.
> >>>
> >>> All the headers that were present before the operation are gone,
> >>> but both functions call skb_headers_offset_update(skb, 0), which
> >>> is a no-op : skb->mac_header, skb->network_header,
> >>> skb->transport_header and skb->csum_start are left with their old
> >>> values, now pointing into the freshly allocated (and possibly much
> >>> smaller) skb->head.
> >>>
> >>> For pskb_carve_inside_nonlinear() the result is a zombie skb with
> >>> an empty linear part (skb->data == skb_tail_pointer(skb),
> >>> skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
> >>> skb->mac_header pointing far beyond skb_end_pointer(skb).
> >>>
> >> Could you please clarify how the MAC pointer ends up beyond
> >> skb_end_pointer() here? The carve helpers allocate based on the old
> >> skb_end_offset(), and kmalloc_reserve() adds room for skb_shared_info,
> >> so the new capacity shouldn't be smaller.
> >>
> >> The dump shows mac=234 and end=384. I understand how the stale offset
> >> causes skb_pull() on an empty linear area and triggers the BUG, but I
> >> don't see how it ends up beyond the new end. Am I missing another
> >> condition?
> >
> > skb_headers_offset_update(skb, 0) is a no-op, so mac=234, net=248,
> > trans=288 and csum_start=288 survive and now describe bytes that are not
> > there anymore. skb_mac_header_was_set() still returns true, so drop_monitor
> > does skb_pull(skb, 234) on an empty linear part and hits the BUG in
> > __skb_pull().
> >
> > pskb_carve_inside_header() has the same issue, the remaining linear data is
> > shifted by off bytes while the offsets are left untouched.
> >
> Thanks for the explanation. The fix itself looks correct to me, and I
> understand why the stale MAC offset causes the BUG.
>
> Could I check my understanding of "far beyond skb_end_pointer()"?
> The dump shows headroom=0 and headlen=0, so head=data=tail. With
> end-tail=384 and mac=234, the MAC pointer is head+234, still before
> end at head+384. For this nonlinear skb, did you mean beyond
> skb_tail_pointer() rather than skb_end_pointer()?
Is it an LLM which triggers your replies?
Do you have an issue with the code?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-12 13:44 ` Eric Dumazet
@ 2026-09-12 15:29 ` Xuanqiang Luo
2026-09-12 15:40 ` Eric Dumazet
0 siblings, 1 reply; 8+ messages in thread
From: Xuanqiang Luo @ 2026-09-12 15:29 UTC (permalink / raw)
To: Eric Dumazet
Cc: Simon Horman, netdev, eric.dumazet, syzbot+586af68eb819833c2d91,
Allison Henderson, rds-devel, David S . Miller, Jakub Kicinski,
Paolo Abeni
在 2026/9/12 21:44, Eric Dumazet 写道:
> On Sat, Sep 12, 2026 at 6:39 AM Xuanqiang Luo <xuanqiang.luo@linux.dev> wrote:
>>
>> 在 2026/9/12 16:57, Eric Dumazet 写道:
>>> On Fri, Sep 11, 2026 at 11:38 PM luoxuanqiang <xuanqiang.luo@linux.dev> wrote:
>>>>
>>>> 在 2026/9/11 19:49, Eric Dumazet 写道:
>>>>> pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
>>>>> the first bytes of a packet and reallocate skb->head.
>>>>>
>>>>> All the headers that were present before the operation are gone,
>>>>> but both functions call skb_headers_offset_update(skb, 0), which
>>>>> is a no-op : skb->mac_header, skb->network_header,
>>>>> skb->transport_header and skb->csum_start are left with their old
>>>>> values, now pointing into the freshly allocated (and possibly much
>>>>> smaller) skb->head.
>>>>>
>>>>> For pskb_carve_inside_nonlinear() the result is a zombie skb with
>>>>> an empty linear part (skb->data == skb_tail_pointer(skb),
>>>>> skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
>>>>> skb->mac_header pointing far beyond skb_end_pointer(skb).
>>>>>
>>>> Could you please clarify how the MAC pointer ends up beyond
>>>> skb_end_pointer() here? The carve helpers allocate based on the old
>>>> skb_end_offset(), and kmalloc_reserve() adds room for skb_shared_info,
>>>> so the new capacity shouldn't be smaller.
>>>>
>>>> The dump shows mac=234 and end=384. I understand how the stale offset
>>>> causes skb_pull() on an empty linear area and triggers the BUG, but I
>>>> don't see how it ends up beyond the new end. Am I missing another
>>>> condition?
>>>
>>> skb_headers_offset_update(skb, 0) is a no-op, so mac=234, net=248,
>>> trans=288 and csum_start=288 survive and now describe bytes that are not
>>> there anymore. skb_mac_header_was_set() still returns true, so drop_monitor
>>> does skb_pull(skb, 234) on an empty linear part and hits the BUG in
>>> __skb_pull().
>>>
>>> pskb_carve_inside_header() has the same issue, the remaining linear data is
>>> shifted by off bytes while the offsets are left untouched.
>>>
>> Thanks for the explanation. The fix itself looks correct to me, and I
>> understand why the stale MAC offset causes the BUG.
>>
>> Could I check my understanding of "far beyond skb_end_pointer()"?
>> The dump shows headroom=0 and headlen=0, so head=data=tail. With
>> end-tail=384 and mac=234, the MAC pointer is head+234, still before
>> end at head+384. For this nonlinear skb, did you mean beyond
>> skb_tail_pointer() rather than skb_end_pointer()?
>
> Is it an LLM which triggers your replies?
>
> Do you have an issue with the code?
Yes, I use an LLM to help analyze patches on the mailing list and polish
my replies. I only reply once I understand the relevant code.
I haven't found an issue with the code. My follow-up questions were only
about the commit message wording.
Sorry for repeatedly asking about that point.
Thanks,
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-12 15:29 ` Xuanqiang Luo
@ 2026-09-12 15:40 ` Eric Dumazet
0 siblings, 0 replies; 8+ messages in thread
From: Eric Dumazet @ 2026-09-12 15:40 UTC (permalink / raw)
To: Xuanqiang Luo
Cc: Simon Horman, netdev, eric.dumazet, syzbot+586af68eb819833c2d91,
Allison Henderson, rds-devel, David S . Miller, Jakub Kicinski,
Paolo Abeni
On Sat, Sep 12, 2026 at 8:29 AM Xuanqiang Luo <xuanqiang.luo@linux.dev> wrote:
>
> 在 2026/9/12 21:44, Eric Dumazet 写道:
> > On Sat, Sep 12, 2026 at 6:39 AM Xuanqiang Luo <xuanqiang.luo@linux.dev> wrote:
> >>
> >> 在 2026/9/12 16:57, Eric Dumazet 写道:
> >>> On Fri, Sep 11, 2026 at 11:38 PM luoxuanqiang <xuanqiang.luo@linux.dev> wrote:
> >>>>
> >>>> 在 2026/9/11 19:49, Eric Dumazet 写道:
> >>>>> pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
> >>>>> the first bytes of a packet and reallocate skb->head.
> >>>>>
> >>>>> All the headers that were present before the operation are gone,
> >>>>> but both functions call skb_headers_offset_update(skb, 0), which
> >>>>> is a no-op : skb->mac_header, skb->network_header,
> >>>>> skb->transport_header and skb->csum_start are left with their old
> >>>>> values, now pointing into the freshly allocated (and possibly much
> >>>>> smaller) skb->head.
> >>>>>
> >>>>> For pskb_carve_inside_nonlinear() the result is a zombie skb with
> >>>>> an empty linear part (skb->data == skb_tail_pointer(skb),
> >>>>> skb_headlen(skb) == 0) but skb_mac_header_was_set() still true and
> >>>>> skb->mac_header pointing far beyond skb_end_pointer(skb).
> >>>>>
> >>>> Could you please clarify how the MAC pointer ends up beyond
> >>>> skb_end_pointer() here? The carve helpers allocate based on the old
> >>>> skb_end_offset(), and kmalloc_reserve() adds room for skb_shared_info,
> >>>> so the new capacity shouldn't be smaller.
> >>>>
> >>>> The dump shows mac=234 and end=384. I understand how the stale offset
> >>>> causes skb_pull() on an empty linear area and triggers the BUG, but I
> >>>> don't see how it ends up beyond the new end. Am I missing another
> >>>> condition?
> >>>
> >>> skb_headers_offset_update(skb, 0) is a no-op, so mac=234, net=248,
> >>> trans=288 and csum_start=288 survive and now describe bytes that are not
> >>> there anymore. skb_mac_header_was_set() still returns true, so drop_monitor
> >>> does skb_pull(skb, 234) on an empty linear part and hits the BUG in
> >>> __skb_pull().
> >>>
> >>> pskb_carve_inside_header() has the same issue, the remaining linear data is
> >>> shifted by off bytes while the offsets are left untouched.
> >>>
> >> Thanks for the explanation. The fix itself looks correct to me, and I
> >> understand why the stale MAC offset causes the BUG.
> >>
> >> Could I check my understanding of "far beyond skb_end_pointer()"?
> >> The dump shows headroom=0 and headlen=0, so head=data=tail. With
> >> end-tail=384 and mac=234, the MAC pointer is head+234, still before
> >> end at head+384. For this nonlinear skb, did you mean beyond
> >> skb_tail_pointer() rather than skb_end_pointer()?
> >
> > Is it an LLM which triggers your replies?
> >
> > Do you have an issue with the code?
>
> Yes, I use an LLM to help analyze patches on the mailing list and polish
> my replies. I only reply once I understand the relevant code.
>
> I haven't found an issue with the code. My follow-up questions were only
> about the commit message wording.
>
> Sorry for repeatedly asking about that point.
I gave you a precise explanation in the initial answer, I do not think
I can do more than that,
I have other urgent issues to address.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-12 15:41 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 11:49 [PATCH net] net: skbuff: do not leave stale header offsets after pskb_carve() Eric Dumazet
2026-09-11 16:13 ` Ivy Lopez
2026-09-12 6:38 ` luoxuanqiang
2026-09-12 8:57 ` Eric Dumazet
2026-09-12 13:39 ` Xuanqiang Luo
2026-09-12 13:44 ` Eric Dumazet
2026-09-12 15:29 ` Xuanqiang Luo
2026-09-12 15:40 ` Eric Dumazet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox