summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Stratulat <adrian.stratulat@enea.com>2019-10-30 12:12:27 +0100
committerAdrian Stratulat <adrian.stratulat@enea.com>2019-10-30 12:20:47 +0100
commitaf13b16401b4c2a033bd0f74162530b2d4587f5a (patch)
tree3ae3d882f1c1df5e47f18e706f567562d5bb90ae
parent10f6ab5aea81a94af751bbdbebbf49303d83879f (diff)
downloadenea-kernel-cache-af13b16401b4c2a033bd0f74162530b2d4587f5a.tar.gz
tunnels: CVE-2016-8666
tunnels: Don't apply GRO to multiple layers of encapsulation References: https://nvd.nist.gov/vuln/detail/CVE-2016-8666 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fac8e0f579695a3ecbc4d3cac369139d7f819971 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.1.y&id=066b300e5be43cb61697539e2a3a9aac5afb422f Change-Id: I55c79f32e2ce1c06c59f40ab087015e461388795 Signed-off-by: Adrian Stratulat <adrian.stratulat@enea.com>
-rw-r--r--patches/cve/CVE-2016-8666.patch166
1 files changed, 166 insertions, 0 deletions
diff --git a/patches/cve/CVE-2016-8666.patch b/patches/cve/CVE-2016-8666.patch
new file mode 100644
index 0000000..cac0a09
--- /dev/null
+++ b/patches/cve/CVE-2016-8666.patch
@@ -0,0 +1,166 @@
1From 066b300e5be43cb61697539e2a3a9aac5afb422f Mon Sep 17 00:00:00 2001
2From: Jesse Gross <jesse@kernel.org>
3Date: Sat, 19 Mar 2016 09:32:01 -0700
4Subject: tunnels: Don't apply GRO to multiple layers of encapsulation.
5
6[ Upstream commit fac8e0f579695a3ecbc4d3cac369139d7f819971 ]
7
8When drivers express support for TSO of encapsulated packets, they
9only mean that they can do it for one layer of encapsulation.
10Supporting additional levels would mean updating, at a minimum,
11more IP length fields and they are unaware of this.
12
13No encapsulation device expresses support for handling offloaded
14encapsulated packets, so we won't generate these types of frames
15in the transmit path. However, GRO doesn't have a check for
16multiple levels of encapsulation and will attempt to build them.
17
18UDP tunnel GRO actually does prevent this situation but it only
19handles multiple UDP tunnels stacked on top of each other. This
20generalizes that solution to prevent any kind of tunnel stacking
21that would cause problems.
22
23Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.1.y&id=066b300e5be43cb61697539e2a3a9aac5afb422f]
24CVE: CVE-2016-8666
25
26Fixes: bf5a755f ("net-gre-gro: Add GRE support to the GRO stack")
27Signed-off-by: Jesse Gross <jesse@kernel.org>
28Signed-off-by: David S. Miller <davem@davemloft.net>
29Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
30Signed-off-by: Adrian Stratulat <adrian.stratulat@enea.com>
31---
32 include/linux/netdevice.h | 4 ++--
33 net/core/dev.c | 2 +-
34 net/ipv4/af_inet.c | 15 ++++++++++++++-
35 net/ipv4/gre_offload.c | 5 +++++
36 net/ipv4/udp_offload.c | 6 +++---
37 net/ipv6/ip6_offload.c | 13 +++++++++++++
38 6 files changed, 38 insertions(+), 7 deletions(-)
39
40diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
41index ddd47c3a757d..c11f9d1963c3 100644
42--- a/include/linux/netdevice.h
43+++ b/include/linux/netdevice.h
44@@ -1949,8 +1949,8 @@ struct napi_gro_cb {
45 /* This is non-zero if the packet may be of the same flow. */
46 u8 same_flow:1;
47
48- /* Used in udp_gro_receive */
49- u8 udp_mark:1;
50+ /* Used in tunnel GRO receive */
51+ u8 encap_mark:1;
52
53 /* GRO checksum is valid */
54 u8 csum_valid:1;
55diff --git a/net/core/dev.c b/net/core/dev.c
56index 56d820fc2707..0f9289ff0f2a 100644
57--- a/net/core/dev.c
58+++ b/net/core/dev.c
59@@ -4158,8 +4158,8 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
60 NAPI_GRO_CB(skb)->same_flow = 0;
61 NAPI_GRO_CB(skb)->flush = 0;
62 NAPI_GRO_CB(skb)->free = 0;
63- NAPI_GRO_CB(skb)->udp_mark = 0;
64 NAPI_GRO_CB(skb)->recursion_counter = 0;
65+ NAPI_GRO_CB(skb)->encap_mark = 0;
66 NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
67
68 /* Setup for GRO checksum validation */
69diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
70index f952caa5cfe1..84e46837610b 100644
71--- a/net/ipv4/af_inet.c
72+++ b/net/ipv4/af_inet.c
73@@ -1388,6 +1388,19 @@ out:
74 return pp;
75 }
76
77+static struct sk_buff **ipip_gro_receive(struct sk_buff **head,
78+ struct sk_buff *skb)
79+{
80+ if (NAPI_GRO_CB(skb)->encap_mark) {
81+ NAPI_GRO_CB(skb)->flush = 1;
82+ return NULL;
83+ }
84+
85+ NAPI_GRO_CB(skb)->encap_mark = 1;
86+
87+ return inet_gro_receive(head, skb);
88+}
89+
90 int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
91 {
92 if (sk->sk_family == AF_INET)
93@@ -1646,7 +1659,7 @@ static struct packet_offload ip_packet_offload __read_mostly = {
94 static const struct net_offload ipip_offload = {
95 .callbacks = {
96 .gso_segment = inet_gso_segment,
97- .gro_receive = inet_gro_receive,
98+ .gro_receive = ipip_gro_receive,
99 .gro_complete = inet_gro_complete,
100 },
101 };
102diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
103index 53300b88d569..79ae0d7becbf 100644
104--- a/net/ipv4/gre_offload.c
105+++ b/net/ipv4/gre_offload.c
106@@ -128,6 +128,11 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
107 struct packet_offload *ptype;
108 __be16 type;
109
110+ if (NAPI_GRO_CB(skb)->encap_mark)
111+ goto out;
112+
113+ NAPI_GRO_CB(skb)->encap_mark = 1;
114+
115 off = skb_gro_offset(skb);
116 hlen = off + sizeof(*greh);
117 greh = skb_gro_header_fast(skb, off);
118diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
119index 2af7b7e1a0f6..dfcab88c3e74 100644
120--- a/net/ipv4/udp_offload.c
121+++ b/net/ipv4/udp_offload.c
122@@ -299,14 +299,14 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb,
123 unsigned int off = skb_gro_offset(skb);
124 int flush = 1;
125
126- if (NAPI_GRO_CB(skb)->udp_mark ||
127+ if (NAPI_GRO_CB(skb)->encap_mark ||
128 (skb->ip_summed != CHECKSUM_PARTIAL &&
129 NAPI_GRO_CB(skb)->csum_cnt == 0 &&
130 !NAPI_GRO_CB(skb)->csum_valid))
131 goto out;
132
133- /* mark that this skb passed once through the udp gro layer */
134- NAPI_GRO_CB(skb)->udp_mark = 1;
135+ /* mark that this skb passed once through the tunnel gro layer */
136+ NAPI_GRO_CB(skb)->encap_mark = 1;
137
138 rcu_read_lock();
139 uo_priv = rcu_dereference(udp_offload_base);
140diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
141index db0b8428d248..9b01da54d475 100644
142--- a/net/ipv6/ip6_offload.c
143+++ b/net/ipv6/ip6_offload.c
144@@ -260,6 +260,19 @@ out:
145 return pp;
146 }
147
148+static struct sk_buff **sit_gro_receive(struct sk_buff **head,
149+ struct sk_buff *skb)
150+{
151+ if (NAPI_GRO_CB(skb)->encap_mark) {
152+ NAPI_GRO_CB(skb)->flush = 1;
153+ return NULL;
154+ }
155+
156+ NAPI_GRO_CB(skb)->encap_mark = 1;
157+
158+ return ipv6_gro_receive(head, skb);
159+}
160+
161 static int ipv6_gro_complete(struct sk_buff *skb, int nhoff)
162 {
163 const struct net_offload *ops;
164--
165cgit 1.2-0.3.lf.el7
166