Browse code

kernels: fixes for CVE-2016-7039 and CVE-2016-7425

Change-Id: Ie0eedbf3e83df7207c7b7d992fb55666b48e6aec
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/1541
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: suezzelur <anishs@vmware.com>
(cherry picked from commit 67632e8491125f4ea24637b6a6b21788ec4a6d2c)
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/1542
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Tested-by: suezzelur <anishs@vmware.com>

Alexey Makhalov authored on 2016/10/20 09:00:40
Showing 4 changed files
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:       Kernel
3 3
 Name:          linux-esx
4 4
 Version:       4.4.20
5
-Release:       6%{?dist}
5
+Release:       7%{?dist}
6 6
 License:       GPLv2
7 7
 URL:           http://www.kernel.org/
8 8
 Group:         System Environment/Kernel
... ...
@@ -39,6 +39,8 @@ Patch21:       vmci-1.1.5.0-doorbell-create-and-destroy-fixes.patch
39 39
 Patch22:       ipip-properly-mark-ipip-GRO-packets-as-encapsulated.patch
40 40
 #fixes CVE-2016-8666
41 41
 Patch23:       tunnels-dont-apply-GRO-to-multiple-layers-of-encapsulation.patch
42
+#fixes CVE-2016-7039
43
+Patch24:        net-add-recursion-limit-to-GRO.patch
42 44
 BuildRequires: bc
43 45
 BuildRequires: kbd
44 46
 BuildRequires: kmod
... ...
@@ -97,6 +99,7 @@ The Linux package contains the Linux kernel doc files
97 97
 %patch21 -p1
98 98
 %patch22 -p1
99 99
 %patch23 -p1
100
+%patch24 -p1
100 101
 
101 102
 %build
102 103
 # patch vmw_balloon driver
... ...
@@ -168,6 +171,8 @@ ln -sf %{name}-%{version}-%{release}.cfg /boot/photon.cfg
168 168
 /usr/src/%{name}-headers-%{version}-%{release}
169 169
 
170 170
 %changelog
171
+*   Wed Oct 19 2016 Alexey Makhalov <amakhalov@vmware.com> 4.4.20-7
172
+-   net-add-recursion-limit-to-GRO.patch
171 173
 *   Tue Oct 18 2016 Alexey Makhalov <amakhalov@vmware.com> 4.4.20-6
172 174
 -   ipip-properly-mark-ipip-GRO-packets-as-encapsulated.patch
173 175
 -   tunnels-dont-apply-GRO-to-multiple-layers-of-encapsulation.patch
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux
4 4
 Version:    	4.4.20
5
-Release:    	5%{?dist}
5
+Release:    	6%{?dist}
6 6
 License:    	GPLv2
7 7
 URL:        	http://www.kernel.org/
8 8
 Group:        	System Environment/Kernel
... ...
@@ -35,6 +35,10 @@ Patch16:        keys-fix-asn.1-indefinite-length-object-parsing.patch
35 35
 Patch17:        ipip-properly-mark-ipip-GRO-packets-as-encapsulated.patch
36 36
 #fixes CVE-2016-8666
37 37
 Patch18:        tunnels-dont-apply-GRO-to-multiple-layers-of-encapsulation.patch
38
+#fixes CVE-2016-7039
39
+Patch19:        net-add-recursion-limit-to-GRO.patch
40
+#fixes CVE-2016-7425
41
+Patch20:        scsi-arcmsr-buffer-overflow-in-arcmsr_iop_message_xfer.patch
38 42
 BuildRequires:  bc
39 43
 BuildRequires:  kbd
40 44
 BuildRequires:  kmod
... ...
@@ -109,6 +113,8 @@ Kernel driver for oprofile, a statistical profiler for Linux systems
109 109
 %patch16 -p1
110 110
 %patch17 -p1
111 111
 %patch18 -p1
112
+%patch19 -p1
113
+%patch20 -p1
112 114
 
113 115
 %build
114 116
 make mrproper
... ...
@@ -206,6 +212,9 @@ ln -s /usr/lib/debug/lib/modules/%{version}/vmlinux-%{version}-%{release}.debug
206 206
 /lib/modules/%{version}/kernel/arch/x86/oprofile/
207 207
 
208 208
 %changelog
209
+*   Wed Oct 19 2016 Alexey Makhalov <amakhalov@vmware.com> 4.4.20-6
210
+-   net-add-recursion-limit-to-GRO.patch
211
+-   scsi-arcmsr-buffer-overflow-in-arcmsr_iop_message_xfer.patch
209 212
 *   Tue Oct 18 2016 Alexey Makhalov <amakhalov@vmware.com> 4.4.20-5
210 213
 -   ipip-properly-mark-ipip-GRO-packets-as-encapsulated.patch
211 214
 -   tunnels-dont-apply-GRO-to-multiple-layers-of-encapsulation.patch
212 215
new file mode 100644
... ...
@@ -0,0 +1,227 @@
0
+From: Sabrina Dubroca <sd@queasysnail.net>
1
+Date: Thu, 15 Sep 2016 10:49:30 +0200
2
+Subject: net: add recursion limit to GRO
3
+Patch-mainline: Not yet, embargoed (likely v4.9-rc1)
4
+References: CVE-2016-7039 bsc#1001486
5
+
6
+Currently, GRO can do unlimited recursion through the gro_receive
7
+handlers.  This was fixed for tunneling protocols by limiting tunnel GRO
8
+to one level with encap_mark, but both VLAN and TEB still have this
9
+problem.  Thus, the kernel is vulnerable to a stack overflow, if we
10
+receive a packet composed entirely of VLAN headers.
11
+
12
+This patch adds a recursion counter to the GRO layer to prevent stack
13
+overflow.  When a gro_receive function hits the recursion limit, GRO is
14
+aborted for this skb and it is processed normally.
15
+
16
+Fixes: 9b174d88c257 ("net: Add Transparent Ethernet Bridging GRO support.")
17
+Fixes: 66e5133f19e9 ("vlan: Add GRO support for non hardware accelerated vlan")
18
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
19
+Reviewed-by: Jiri Benc <jbenc@redhat.com>
20
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
21
+Acked-by: Michal Kubecek <mkubecek@suse.cz>
22
+---
23
+ drivers/net/geneve.c      |  2 +-
24
+ drivers/net/vxlan.c       |  2 +-
25
+ include/linux/netdevice.h | 24 +++++++++++++++++++++++-
26
+ net/8021q/vlan.c          |  2 +-
27
+ net/core/dev.c            |  1 +
28
+ net/ethernet/eth.c        |  2 +-
29
+ net/ipv4/af_inet.c        |  2 +-
30
+ net/ipv4/fou.c            |  4 ++--
31
+ net/ipv4/gre_offload.c    |  2 +-
32
+ net/ipv4/udp_offload.c    |  8 +++++++-
33
+ net/ipv6/ip6_offload.c    |  2 +-
34
+ 11 files changed, 40 insertions(+), 11 deletions(-)
35
+
36
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
37
+index 3c20e87bb761..16af1ce99233 100644
38
+--- a/drivers/net/geneve.c
39
+@@ -453,7 +453,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk,
40
+ 
41
+ 	skb_gro_pull(skb, gh_len);
42
+ 	skb_gro_postpull_rcsum(skb, gh, gh_len);
43
+-	pp = ptype->callbacks.gro_receive(head, skb);
44
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
45
+ 
46
+ out_unlock:
47
+ 	rcu_read_unlock();
48
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
49
+index 6e65832051d6..5ae664c02528 100644
50
+--- a/drivers/net/vxlan.c
51
+@@ -584,7 +584,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk,
52
+ 		}
53
+ 	}
54
+ 
55
+-	pp = eth_gro_receive(head, skb);
56
++	pp = call_gro_receive(eth_gro_receive, head, skb);
57
+ 
58
+ out:
59
+ 	skb_gro_remcsum_cleanup(skb, &grc);
60
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
61
+index e8d79d4ebcfe..a41b22ce9172 100644
62
+--- a/include/linux/netdevice.h
63
+@@ -2154,7 +2154,10 @@ struct napi_gro_cb {
64
+ 	/* Used in foo-over-udp, set in udp[46]_gro_receive */
65
+ 	u8	is_ipv6:1;
66
+ 
67
+-	/* 7 bit hole */
68
++	/* Number of gro_receive callbacks this packet already went through */
69
++	u8 recursion_counter:4;
70
++
71
++	/* 3 bit hole */
72
+ 
73
+ 	/* used to support CHECKSUM_COMPLETE for tunneling protocols */
74
+ 	__wsum	csum;
75
+@@ -2165,6 +2168,25 @@ struct napi_gro_cb {
76
+ 
77
+ #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
78
+ 
79
++#define GRO_RECURSION_LIMIT 15
80
++static inline int gro_recursion_inc_test(struct sk_buff *skb)
81
++{
82
++	return ++NAPI_GRO_CB(skb)->recursion_counter == GRO_RECURSION_LIMIT;
83
++}
84
++
85
++typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *);
86
++static inline struct sk_buff **call_gro_receive(gro_receive_t cb,
87
++						struct sk_buff **head,
88
++						struct sk_buff *skb)
89
++{
90
++	if (gro_recursion_inc_test(skb)) {
91
++		NAPI_GRO_CB(skb)->flush |= 1;
92
++		return NULL;
93
++	}
94
++
95
++	return cb(head, skb);
96
++}
97
++
98
+ struct packet_type {
99
+ 	__be16			type;	/* This is really htons(ether_type). */
100
+ 	struct net_device	*dev;	/* NULL is wildcarded here	     */
101
+diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
102
+index 8de138d3306b..f2531ad66b68 100644
103
+--- a/net/8021q/vlan.c
104
+@@ -664,7 +664,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head,
105
+ 
106
+ 	skb_gro_pull(skb, sizeof(*vhdr));
107
+ 	skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
108
+-	pp = ptype->callbacks.gro_receive(head, skb);
109
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
110
+ 
111
+ out_unlock:
112
+ 	rcu_read_unlock();
113
+diff --git a/net/core/dev.c b/net/core/dev.c
114
+index ea6312057a71..7f34d2e45218 100644
115
+--- a/net/core/dev.c
116
+@@ -4496,6 +4496,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
117
+ 		NAPI_GRO_CB(skb)->flush = 0;
118
+ 		NAPI_GRO_CB(skb)->free = 0;
119
+ 		NAPI_GRO_CB(skb)->encap_mark = 0;
120
++		NAPI_GRO_CB(skb)->recursion_counter = 0;
121
+ 		NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
122
+ 
123
+ 		/* Setup for GRO checksum validation */
124
+diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
125
+index 66dff5e3d772..02acfff36028 100644
126
+--- a/net/ethernet/eth.c
127
+@@ -439,7 +439,7 @@ struct sk_buff **eth_gro_receive(struct sk_buff **head,
128
+ 
129
+ 	skb_gro_pull(skb, sizeof(*eh));
130
+ 	skb_gro_postpull_rcsum(skb, eh, sizeof(*eh));
131
+-	pp = ptype->callbacks.gro_receive(head, skb);
132
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
133
+ 
134
+ out_unlock:
135
+ 	rcu_read_unlock();
136
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
137
+index 55513e654d79..eebbc0f2baa8 100644
138
+--- a/net/ipv4/af_inet.c
139
+@@ -1388,7 +1388,7 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)
140
+ 	skb_gro_pull(skb, sizeof(*iph));
141
+ 	skb_set_transport_header(skb, skb_gro_offset(skb));
142
+ 
143
+-	pp = ops->callbacks.gro_receive(head, skb);
144
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
145
+ 
146
+ out_unlock:
147
+ 	rcu_read_unlock();
148
+diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
149
+index 321d57f825ce..5351b61ab8d3 100644
150
+--- a/net/ipv4/fou.c
151
+@@ -249,7 +249,7 @@ static struct sk_buff **fou_gro_receive(struct sock *sk,
152
+ 	if (!ops || !ops->callbacks.gro_receive)
153
+ 		goto out_unlock;
154
+ 
155
+-	pp = ops->callbacks.gro_receive(head, skb);
156
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
157
+ 
158
+ out_unlock:
159
+ 	rcu_read_unlock();
160
+@@ -441,7 +441,7 @@ next_proto:
161
+ 	if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive))
162
+ 		goto out_unlock;
163
+ 
164
+-	pp = ops->callbacks.gro_receive(head, skb);
165
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
166
+ 
167
+ out_unlock:
168
+ 	rcu_read_unlock();
169
+diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
170
+index ecd1e09dbbf1..6871f59cd0c0 100644
171
+--- a/net/ipv4/gre_offload.c
172
+@@ -227,7 +227,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
173
+ 	/* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/
174
+ 	skb_gro_postpull_rcsum(skb, greh, grehlen);
175
+ 
176
+-	pp = ptype->callbacks.gro_receive(head, skb);
177
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
178
+ 
179
+ out_unlock:
180
+ 	rcu_read_unlock();
181
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
182
+index 81f253b6ff36..92677d9dded6 100644
183
+--- a/net/ipv4/udp_offload.c
184
+@@ -293,8 +293,14 @@ unflush:
185
+ 	skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
186
+ 	skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
187
+ 	NAPI_GRO_CB(skb)->proto = uo_priv->offload->ipproto;
188
+-	pp = uo_priv->offload->callbacks.gro_receive(head, skb,
189
+-						     uo_priv->offload);
190
++
191
++	if (gro_recursion_inc_test(skb)) {
192
++		flush = 1;
193
++		pp = NULL;
194
++	} else {
195
++		pp = uo_priv->offload->callbacks.gro_receive(head, skb,
196
++							     uo_priv->offload);
197
++	}
198
+ 
199
+ out_unlock:
200
+ 	rcu_read_unlock();
201
+diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
202
+index 22e90e56b5a9..a09418bda1f8 100644
203
+--- a/net/ipv6/ip6_offload.c
204
+@@ -243,7 +243,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
205
+ 
206
+ 	skb_gro_postpull_rcsum(skb, iph, nlen);
207
+ 
208
+-	pp = ops->callbacks.gro_receive(head, skb);
209
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
210
+ 
211
+ out_unlock:
212
+ 	rcu_read_unlock();
213
+-- 
214
+2.10.0
215
+
0 216
new file mode 100644
... ...
@@ -0,0 +1,46 @@
0
+From 7bc2b55a5c030685b399bb65b6baa9ccc3d1f167 Mon Sep 17 00:00:00 2001
1
+From: Dan Carpenter <dan.carpenter@oracle.com>
2
+Date: Thu, 15 Sep 2016 16:44:56 +0300
3
+Subject: scsi: arcmsr: Buffer overflow in arcmsr_iop_message_xfer()
4
+
5
+We need to put an upper bound on "user_len" so the memcpy() doesn't
6
+overflow.
7
+
8
+Cc: <stable@vger.kernel.org>
9
+Reported-by: Marco Grassi <marco.gra@gmail.com>
10
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
11
+Reviewed-by: Tomas Henzl <thenzl@redhat.com>
12
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
13
+---
14
+ drivers/scsi/arcmsr/arcmsr_hba.c | 8 +++++++-
15
+ 1 file changed, 7 insertions(+), 1 deletion(-)
16
+
17
+diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
18
+index 7640498..110eca9 100644
19
+--- a/drivers/scsi/arcmsr/arcmsr_hba.c
20
+@@ -2388,7 +2388,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
21
+ 	}
22
+ 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
23
+ 		unsigned char *ver_addr;
24
+-		int32_t user_len, cnt2end;
25
++		uint32_t user_len;
26
++		int32_t cnt2end;
27
+ 		uint8_t *pQbuffer, *ptmpuserbuffer;
28
+ 		ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC);
29
+ 		if (!ver_addr) {
30
+@@ -2397,6 +2398,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
31
+ 		}
32
+ 		ptmpuserbuffer = ver_addr;
33
+ 		user_len = pcmdmessagefld->cmdmessage.Length;
34
++		if (user_len > ARCMSR_API_DATA_BUFLEN) {
35
++			retvalue = ARCMSR_MESSAGE_FAIL;
36
++			kfree(ver_addr);
37
++			goto message_out;
38
++		}
39
+ 		memcpy(ptmpuserbuffer,
40
+ 			pcmdmessagefld->messagedatabuffer, user_len);
41
+ 		spin_lock_irqsave(&acb->wqbuffer_lock, flags);
42
+-- 
43
+cgit v0.12
44
+