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

Shihuang Liu <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
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;
+
 	if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL)
 		return -ENOMEM;
 
-- 
2.43.0
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.