Re: [PATCH net] net: skbuff: reject invalid pull bounds

Eric Dumazet <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <CANn89i+5o16tSTk9MpLE24nCAn+SkMeZvHv0W=MqxnXGZDBBiQ@mail.gmail.com>
On Sun, Aug 23, 2026 at 4:26 PM Shihuang Liu <[email protected]> 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: [email protected]
> Assisted-by: LLM

> Signed-off-by: Shihuang Liu <[email protected]>
> ---
>  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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.