<!DOCTYPE html>
<!-- BaNnErBlUrFlE-BoDy-start -->
<!-- Preheader Text : BEGIN -->
<div style="display:none !important;display:none;visibility:hidden;mso-hide:all;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;opacity:0;overflow:hidden;">
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</div>
<!-- Preheader Text : END -->

<!-- Email Banner : BEGIN -->
<div style="display:none !important;display:none;visibility:hidden;mso-hide:all;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;opacity:0;overflow:hidden;"></div>
<!-- Email Banner : END -->

<!-- BaNnErBlUrFlE-BoDy-end -->
<html>
<head><!-- BaNnErBlUrFlE-HeAdEr-start -->
<style>
  #pfptBannerzpfm39e { all: revert !important; display: block !important;
    visibility: visible !important; opacity: 1 !important;
    background-color: #c2d4d4 !important;
    max-width: none !important; max-height: none !important }
  .pfptPrimaryButtonzpfm39e:hover, .pfptPrimaryButtonzpfm39e:focus {
    background-color: #a2b1b1 !important; }
  .pfptPrimaryButtonzpfm39e:active {
    background-color: #828e8e !important; }
  html:root, html:root>body { all: revert !important; display: block !important;
    visibility: visible !important; opacity: 1 !important; }
</style>

<!-- BaNnErBlUrFlE-HeAdEr-end -->
</head><body><pre style="font-family: sans-serif; font-size: 100%; white-space: pre-wrap; word-wrap: break-word">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,
</pre></body></html>