1 From 251e28b0a1b1a4e2c3d373610d2becd1a55a9480 Mon Sep 17 00:00:00 2001
2 From: Sabrina Dubroca <sd@queasysnail.net>
3 Date: Mon, 25 Mar 2019 14:30:00 +0100
4 Subject: esp4: add length check for UDP encapsulation
6 [ Upstream commit 8dfb4eba4100e7cdd161a8baef2d8d61b7a7e62e ]
8 esp_output_udp_encap can produce a length that doesn't fit in the 16
9 bits of a UDP header's length field. In that case, we'll send a
10 fragmented packet whose length is larger than IP_MAX_MTU (resulting in
11 "Oversized IP packet" warnings on receive) and with a bogus UDP
14 To prevent this, add a length check to esp_output_udp_encap and return
17 This seems to be older than git history.
19 Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
20 Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
21 Signed-off-by: Sasha Levin <sashal@kernel.org>
23 net/ipv4/esp4.c | 20 +++++++++++++++-----
24 1 file changed, 15 insertions(+), 5 deletions(-)
26 diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
27 index 12a43a5369a54..114f9def1ec54 100644
30 @@ -223,7 +223,7 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
31 tail[plen - 1] = proto;
34 -static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
35 +static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
39 @@ -231,6 +231,7 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
41 struct xfrm_encap_tmpl *encap = x->encap;
42 struct ip_esp_hdr *esph = esp->esph;
45 spin_lock_bh(&x->lock);
46 sport = encap->encap_sport;
47 @@ -238,11 +239,14 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
48 encap_type = encap->encap_type;
49 spin_unlock_bh(&x->lock);
51 + len = skb->len + esp->tailen - skb_transport_offset(skb);
52 + if (len + sizeof(struct iphdr) >= IP_MAX_MTU)
55 uh = (struct udphdr *)esph;
58 - uh->len = htons(skb->len + esp->tailen
59 - - skb_transport_offset(skb));
60 + uh->len = htons(len);
64 @@ -259,6 +263,8 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru
66 *skb_mac_header(skb) = IPPROTO_UDP;
72 int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
73 @@ -272,8 +278,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
74 int tailen = esp->tailen;
76 /* this is non-NULL only with UDP Encapsulation */
78 - esp_output_udp_encap(x, skb, esp);
80 + int err = esp_output_udp_encap(x, skb, esp);
86 if (!skb_cloned(skb)) {
87 if (tailen <= skb_tailroom(skb)) {