Re: [PATCH net] net: skbuff: reject invalid pull bounds
From: Eric Dumazet
Date: Thu Aug 27 2026 - 03:22:30 EST
On Sun, Aug 23, 2026 at 4:51 PM Eric Dumazet <edumazet@xxxxxxxxxx> wrote:
>
> On Sun, Aug 23, 2026 at 4:26 PM Shihuang Liu <shlomojune6@xxxxxxxxx> wrote:
> >
> > skb_maybe_pull_tail() subtracts skb_headlen(skb) from the unsigned max
> > argument and passes the result to __pskb_pull_tail() as a signed int. The
> > function does not ensure that max is at least skb_headlen(skb).
> >
> > This can happen while parsing IPv6 extension headers when an skb already
> > has a linear area larger than MAX_IPV6_HDR_LEN. Once the parser needs data
> > beyond the linear area, max - skb_headlen(skb) wraps and is converted to a
> > negative delta. __pskb_pull_tail() then passes that negative length to
> > skb_copy_bits(), where it can become a very large copy length.
> >
> > Reject this inconsistent bound before doing the subtraction. In this case
> > pulling up to max cannot satisfy len because the initial check established
> > that skb_headlen(skb) is smaller than len.
> >
> > Fixes: 1431fb31ecba ("xen-netback: fix fragment detection in checksum setup")
> > Cc: stable@xxxxxxxxxxxxxxx
> > Assisted-by: LLM
>
> > Signed-off-by: Shihuang Liu <shlomojune6@xxxxxxxxx>
> > ---
> > net/core/skbuff.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> > index c82a147..33022f7 100644
> > --- a/net/core/skbuff.c
> > +++ b/net/core/skbuff.c
> > @@ -5838,6 +5838,9 @@ static int skb_maybe_pull_tail(struct sk_buff *skb, unsigned int len,
> > if (max > skb->len)
> > max = skb->len;
> >
> > + if (max < skb_headlen(skb))
> > + return -EPROTO;
> > +
>
> pw-bot: rejected
>
> Please ask your LLM not to slow down the fast path, and find a better
> fix in skb_checksum_setup_ipv6().
>
> Note how skb_checksum_setup_ip() is fine.
>
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index d4382b68d56e0b3b247868b4d29ab383cfcf7440..f77d7480594ca6a1dcce2fea737e421d5ea2d38d
> 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -5974,7 +5974,8 @@ static int skb_checksum_setup_ipv6(struct
> sk_buff *skb, bool recalculate)
> err = skb_maybe_pull_tail(skb,
> off +
> sizeof(struct ipv6_opt_hdr),
> - MAX_IPV6_HDR_LEN);
> + off +
> + sizeof(struct ipv6_opt_hdr));
> if (err < 0)
> goto out;
>
> @@ -5989,7 +5990,8 @@ static int skb_checksum_setup_ipv6(struct
> sk_buff *skb, bool recalculate)
> err = skb_maybe_pull_tail(skb,
> off +
> sizeof(struct ip_auth_hdr),
> - MAX_IPV6_HDR_LEN);
> + off +
> + sizeof(struct ip_auth_hdr));
> if (err < 0)
> goto out;
>
> @@ -6004,7 +6006,8 @@ static int skb_checksum_setup_ipv6(struct
> sk_buff *skb, bool recalculate)
> err = skb_maybe_pull_tail(skb,
> off +
> sizeof(struct frag_hdr),
> - MAX_IPV6_HDR_LEN);
> + off +
> + sizeof(struct frag_hdr));
> if (err < 0)
> goto out;
Following up on this, are you planning to send a V2?
Thanks.