[PATCH net-next 5/9] net: skbuff: don't BUG() on leftover length in skb_checksum() and friends
From: Josef Bacik
Date: Tue Oct 06 2026 - 13:14:45 EST
skb_checksum(), skb_crc32c() and __skb_to_sgvec() walk the head, frags
and frag_list and BUG() if they run out of skb before they run out of
@len. By then nothing has been read past the end of the skb. The walk
stopped at the end of the data, and the check only tells us the caller
asked for a range the skb doesn't have. commit 06a0afcfe2f5 ("xfrm: do
pskb_pull properly in __xfrm_transport_prep") fixed one such caller that
crashed in __skb_to_sgvec().
Warn once and return what each function already returns when it can't
do the work:
- __skb_to_sgvec() returns -EINVAL. Every skb_to_sgvec() caller has
checked for a negative return since it learned to return -EMSGSIZE.
- skb_checksum() and skb_crc32c() return 0, as they already do for
unreadable frags. The resulting checksum is wrong, so the packet
fails verification on receive or goes out with a bad checksum on
transmit, rather than taking the machine down.
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
net/core/skbuff.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6cd7135e0dce..4070e0c25f63 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3613,7 +3613,8 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, __wsum csum)
}
start = end;
}
- BUG_ON(len);
+ if (WARN_ON_ONCE(len))
+ return 0;
return csum;
}
@@ -3778,7 +3779,8 @@ u32 skb_crc32c(const struct sk_buff *skb, int offset, int len, u32 crc)
}
start = end;
}
- BUG_ON(len);
+ if (WARN_ON_ONCE(len))
+ return 0;
return crc;
}
@@ -5333,7 +5335,8 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len,
}
start = end;
}
- BUG_ON(len);
+ if (WARN_ON_ONCE(len))
+ return -EINVAL;
return elt;
}
--
2.55.0