[PATCH] net: gue: reject invalid REMCSUM offsets

Jérémy Jean <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The REMCSUM option carries an absolute checksum start and checksum field
offset. gue_remcsum() passes them to skb_remcsum_process(), whose
partial path stores offset - start in the u16 skb->csum_offset. If
offset is less than start, this underflows (for example, 1/0 becomes
0xffff).

A forwarded packet can retain CHECKSUM_PARTIAL and reach a
NETIF_F_HW_CSUM driver which trusts the metadata, leading
skb_copy_and_csum_dev() to write two bytes about 64 KiB beyond the
destination buffer.

Reject reversed tuples in both normal and GRO receive paths.

Fixes: fe881ef11cf0 ("gue: Use checksum partial with remote checksum offload")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <[email protected]>
---
 net/ipv4/fou_core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c
index ab09dfcdecbd..c4b8b7293994 100644
--- a/net/ipv4/fou_core.c
+++ b/net/ipv4/fou_core.c
@@ -97,6 +97,9 @@ static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
 	size_t plen = sizeof(struct udphdr) + hdrlen +
 	    max_t(size_t, offset + sizeof(u16), start);
 
+	if (unlikely(offset < start))
+		return NULL;
+
 	if (skb->remcsum_offload)
 		return guehdr;
 
@@ -308,6 +311,9 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
 	size_t start = ntohs(pd[0]);
 	size_t offset = ntohs(pd[1]);
 
+	if (unlikely(offset < start))
+		return NULL;
+
 	if (skb->remcsum_offload)
 		return guehdr;
 
-- 
2.47.3
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.