Skip to contentSkip to conversation

gtp: parse extension headers before reading inner protocol

PATCH Superseded Zhixing Chen 2 participants 4 messages Jul 3 – Jul 8

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 gtp: parse extension headers before reading inner protocol

GTPv1-U packets may carry a chain of extension headers before the inner IP packet. The receive path already parses and skips these extension headers, but it currently reads the inner protocol before doing so.

As a result, the first extension header byte is interpreted as the inner IP version. Packets with extension headers are then dropped before PDP lookup.

Parse the extension header chain before calling gtp_inner_proto(), so the inner protocol is read from the actual inner IP header.

Fixes c75fc0b9e5be ("gtp: identify tunnel via GTP device + GTP version + TEID + family")

---

Changes in v2:
- Add missing Fixes tag.

v1: https://lore.kernel.org/netdev/[email protected]/T/

---
 drivers/net/gtp.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/gtp.c +4 -4
index a60ef32b35b8..4a8b00548673 100644
@@ -826,6 +826,10 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
 	if (!pskb_may_pull(skb, hdrlen))
 		return -1;
 
+	if (gtp1->flags & GTP1_F_EXTHDR &&
+	    gtp_parse_exthdrs(skb, &hdrlen) < 0)
+		return -1;
+
 	if (gtp_inner_proto(skb, hdrlen, &inner_proto) < 0) {
 		netdev_dbg(gtp->dev, "GTP packet does not encapsulate an IP packet\n");
 		return -1;
@@ -840,10 +844,6 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb)
 		return 1;
 	}
 
-	if (gtp1->flags & GTP1_F_EXTHDR &&
-	    gtp_parse_exthdrs(skb, &hdrlen) < 0)
-		return -1;
-
 	return gtp_rx(pctx, skb, hdrlen, gtp->role, inner_proto);
 }
 
Signature · 1 line
2.34.1
maintainer Reviewed-by on v2 1/1
#1 lore raw
Quoted 8 lines · Zhixing Chen

GTPv1-U packets may carry a chain of extension headers before the inner IP packet. The receive path already parses and skips these extension headers, but it currently reads the inner protocol before doing so.

As a result, the first extension header byte is interpreted as the inner IP version. Packets with extension headers are then dropped before PDP lookup.

Quoted 5 lines

Parse the extension header chain before calling gtp_inner_proto(), so the inner protocol is read from the actual inner IP header.

Fixes c75fc0b9e5be ("gtp: identify tunnel via GTP device + GTP version + TEID + family")
#2 lore raw
Quoted 9 lines · Pablo Neira Ayuso
Quoted 8 lines · Zhixing Chen

GTPv1-U packets may carry a chain of extension headers before the inner IP packet. The receive path already parses and skips these extension headers, but it currently reads the inner protocol before doing so.

As a result, the first extension header byte is interpreted as the inner IP version. Packets with extension headers are then dropped before PDP lookup.

Quoted 7 lines
Quoted 5 lines

Parse the extension header chain before calling gtp_inner_proto(), so the inner protocol is read from the actual inner IP header.

Fixes c75fc0b9e5be ("gtp: identify tunnel via GTP device + GTP version + TEID + family")

Patch is not good, it needs to refetch gtp header after pskb_may_pull().

#3 lore raw
Quoted 2 lines

Patch is not good, it needs to refetch gtp header after pskb_may_pull().

Thanks for the catch. I’ve sent v3; it refetches gtp header after pskb_may_pull().