summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Sarmadi <sona.sarmadi@enea.com>2017-09-29 15:05:14 +0200
committerMartin Borg <martin.borg@enea.com>2017-10-02 09:41:27 +0200
commit5374c76b359fa7a773453e7d4232025ddc11e2fb (patch)
tree04da2a8cac6734436ac29d860cc73233b366c156
parentb367b96333d52663a3c2a9274a8ce96226fa4bd6 (diff)
downloadmeta-enea-bsp-arm-5374c76b359fa7a773453e7d4232025ddc11e2fb.tar.gz
linux-cavium: CVE-2017-8062
w2102.c interacts incorrectly with the CONFIG_VMAP_STACK option Reference: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2017-8062 Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> Signed-off-by: Martin Borg <martin.borg@enea.com>
-rw-r--r--recipes-kernel/linux/linux-cavium/CVE-2017-8062.patch440
-rw-r--r--recipes-kernel/linux/linux-cavium_4.9.inc1
2 files changed, 441 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-cavium/CVE-2017-8062.patch b/recipes-kernel/linux/linux-cavium/CVE-2017-8062.patch
new file mode 100644
index 0000000..eab23f2
--- /dev/null
+++ b/recipes-kernel/linux/linux-cavium/CVE-2017-8062.patch
@@ -0,0 +1,440 @@
1From 06996254a605913cd7c1927d0e8a89b5138e110d Mon Sep 17 00:00:00 2001
2From: Jonathan McDowell <noodles@earth.li>
3Date: Wed, 15 Feb 2017 18:29:15 -0200
4Subject: [PATCH] dw2102: don't do DMA on stack
5
6commit 606142af57dad981b78707234cfbd15f9f7b7125 upstream.
7
8On Kernel 4.9, WARNINGs about doing DMA on stack are hit at
9the dw2102 driver: one in su3000_power_ctrl() and the other in tt_s2_4600_frontend_attach().
10
11Both were due to the use of buffers on the stack as parameters to
12dvb_usb_generic_rw() and the resulting attempt to do DMA with them.
13
14The device was non-functional as a result.
15
16So, switch this driver over to use a buffer within the device state
17structure, as has been done with other DVB-USB drivers.
18
19Tested with TechnoTrend TT-connect S2-4600.
20
21CVE: CVE-2017-8062
22Upstream-Status: Backport [from kernel.org longterm 4.9.52]
23
24[mchehab@osg.samsung.com: fixed a warning at su3000_i2c_transfer() that
25 state var were dereferenced before check 'd']
26Signed-off-by: Jonathan McDowell <noodles@earth.li>
27Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
28Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
30---
31 drivers/media/usb/dvb-usb/dw2102.c | 244 ++++++++++++++++++++++---------------
32 1 file changed, 145 insertions(+), 99 deletions(-)
33
34diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
35index 2c720cb..c3e6734 100644
36--- a/drivers/media/usb/dvb-usb/dw2102.c
37+++ b/drivers/media/usb/dvb-usb/dw2102.c
38@@ -68,6 +68,7 @@
39 struct dw2102_state {
40 u8 initialized;
41 u8 last_lock;
42+ u8 data[MAX_XFER_SIZE + 4];
43 struct i2c_client *i2c_client_demod;
44 struct i2c_client *i2c_client_tuner;
45
46@@ -662,62 +663,72 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
47 int num)
48 {
49 struct dvb_usb_device *d = i2c_get_adapdata(adap);
50- u8 obuf[0x40], ibuf[0x40];
51+ struct dw2102_state *state;
52
53 if (!d)
54 return -ENODEV;
55+
56+ state = d->priv;
57+
58 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
59 return -EAGAIN;
60+ if (mutex_lock_interruptible(&d->data_mutex) < 0) {
61+ mutex_unlock(&d->i2c_mutex);
62+ return -EAGAIN;
63+ }
64
65 switch (num) {
66 case 1:
67 switch (msg[0].addr) {
68 case SU3000_STREAM_CTRL:
69- obuf[0] = msg[0].buf[0] + 0x36;
70- obuf[1] = 3;
71- obuf[2] = 0;
72- if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
73+ state->data[0] = msg[0].buf[0] + 0x36;
74+ state->data[1] = 3;
75+ state->data[2] = 0;
76+ if (dvb_usb_generic_rw(d, state->data, 3,
77+ state->data, 0, 0) < 0)
78 err("i2c transfer failed.");
79 break;
80 case DW2102_RC_QUERY:
81- obuf[0] = 0x10;
82- if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
83+ state->data[0] = 0x10;
84+ if (dvb_usb_generic_rw(d, state->data, 1,
85+ state->data, 2, 0) < 0)
86 err("i2c transfer failed.");
87- msg[0].buf[1] = ibuf[0];
88- msg[0].buf[0] = ibuf[1];
89+ msg[0].buf[1] = state->data[0];
90+ msg[0].buf[0] = state->data[1];
91 break;
92 default:
93 /* always i2c write*/
94- obuf[0] = 0x08;
95- obuf[1] = msg[0].addr;
96- obuf[2] = msg[0].len;
97+ state->data[0] = 0x08;
98+ state->data[1] = msg[0].addr;
99+ state->data[2] = msg[0].len;
100
101- memcpy(&obuf[3], msg[0].buf, msg[0].len);
102+ memcpy(&state->data[3], msg[0].buf, msg[0].len);
103
104- if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
105- ibuf, 1, 0) < 0)
106+ if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
107+ state->data, 1, 0) < 0)
108 err("i2c transfer failed.");
109
110 }
111 break;
112 case 2:
113 /* always i2c read */
114- obuf[0] = 0x09;
115- obuf[1] = msg[0].len;
116- obuf[2] = msg[1].len;
117- obuf[3] = msg[0].addr;
118- memcpy(&obuf[4], msg[0].buf, msg[0].len);
119-
120- if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
121- ibuf, msg[1].len + 1, 0) < 0)
122+ state->data[0] = 0x09;
123+ state->data[1] = msg[0].len;
124+ state->data[2] = msg[1].len;
125+ state->data[3] = msg[0].addr;
126+ memcpy(&state->data[4], msg[0].buf, msg[0].len);
127+
128+ if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
129+ state->data, msg[1].len + 1, 0) < 0)
130 err("i2c transfer failed.");
131
132- memcpy(msg[1].buf, &ibuf[1], msg[1].len);
133+ memcpy(msg[1].buf, &state->data[1], msg[1].len);
134 break;
135 default:
136 warn("more than 2 i2c messages at a time is not handled yet.");
137 break;
138 }
139+ mutex_unlock(&d->data_mutex);
140 mutex_unlock(&d->i2c_mutex);
141 return num;
142 }
143@@ -845,17 +856,23 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
144 static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
145 {
146 struct dw2102_state *state = (struct dw2102_state *)d->priv;
147- u8 obuf[] = {0xde, 0};
148+ int ret = 0;
149
150 info("%s: %d, initialized %d", __func__, i, state->initialized);
151
152 if (i && !state->initialized) {
153+ mutex_lock(&d->data_mutex);
154+
155+ state->data[0] = 0xde;
156+ state->data[1] = 0;
157+
158 state->initialized = 1;
159 /* reset board */
160- return dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
161+ ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0);
162+ mutex_unlock(&d->data_mutex);
163 }
164
165- return 0;
166+ return ret;
167 }
168
169 static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
170@@ -1310,49 +1327,57 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
171 return 0;
172 }
173
174-static int su3000_frontend_attach(struct dvb_usb_adapter *d)
175+static int su3000_frontend_attach(struct dvb_usb_adapter *adap)
176 {
177- u8 obuf[3] = { 0xe, 0x80, 0 };
178- u8 ibuf[] = { 0 };
179+ struct dvb_usb_device *d = adap->dev;
180+ struct dw2102_state *state = d->priv;
181+
182+ mutex_lock(&d->data_mutex);
183+
184+ state->data[0] = 0xe;
185+ state->data[1] = 0x80;
186+ state->data[2] = 0;
187
188- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
189+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
190 err("command 0x0e transfer failed.");
191
192- obuf[0] = 0xe;
193- obuf[1] = 0x02;
194- obuf[2] = 1;
195+ state->data[0] = 0xe;
196+ state->data[1] = 0x02;
197+ state->data[2] = 1;
198
199- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
200+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
201 err("command 0x0e transfer failed.");
202 msleep(300);
203
204- obuf[0] = 0xe;
205- obuf[1] = 0x83;
206- obuf[2] = 0;
207+ state->data[0] = 0xe;
208+ state->data[1] = 0x83;
209+ state->data[2] = 0;
210
211- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
212+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
213 err("command 0x0e transfer failed.");
214
215- obuf[0] = 0xe;
216- obuf[1] = 0x83;
217- obuf[2] = 1;
218+ state->data[0] = 0xe;
219+ state->data[1] = 0x83;
220+ state->data[2] = 1;
221
222- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
223+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
224 err("command 0x0e transfer failed.");
225
226- obuf[0] = 0x51;
227+ state->data[0] = 0x51;
228
229- if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
230+ if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
231 err("command 0x51 transfer failed.");
232
233- d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
234- &d->dev->i2c_adap);
235- if (d->fe_adap[0].fe == NULL)
236+ mutex_unlock(&d->data_mutex);
237+
238+ adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
239+ &d->i2c_adap);
240+ if (adap->fe_adap[0].fe == NULL)
241 return -EIO;
242
243- if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
244+ if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
245 &dw2104_ts2020_config,
246- &d->dev->i2c_adap)) {
247+ &d->i2c_adap)) {
248 info("Attached DS3000/TS2020!");
249 return 0;
250 }
251@@ -1361,47 +1386,55 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
252 return -EIO;
253 }
254
255-static int t220_frontend_attach(struct dvb_usb_adapter *d)
256+static int t220_frontend_attach(struct dvb_usb_adapter *adap)
257 {
258- u8 obuf[3] = { 0xe, 0x87, 0 };
259- u8 ibuf[] = { 0 };
260+ struct dvb_usb_device *d = adap->dev;
261+ struct dw2102_state *state = d->priv;
262+
263+ mutex_lock(&d->data_mutex);
264
265- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
266+ state->data[0] = 0xe;
267+ state->data[1] = 0x87;
268+ state->data[2] = 0x0;
269+
270+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
271 err("command 0x0e transfer failed.");
272
273- obuf[0] = 0xe;
274- obuf[1] = 0x86;
275- obuf[2] = 1;
276+ state->data[0] = 0xe;
277+ state->data[1] = 0x86;
278+ state->data[2] = 1;
279
280- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
281+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
282 err("command 0x0e transfer failed.");
283
284- obuf[0] = 0xe;
285- obuf[1] = 0x80;
286- obuf[2] = 0;
287+ state->data[0] = 0xe;
288+ state->data[1] = 0x80;
289+ state->data[2] = 0;
290
291- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
292+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
293 err("command 0x0e transfer failed.");
294
295 msleep(50);
296
297- obuf[0] = 0xe;
298- obuf[1] = 0x80;
299- obuf[2] = 1;
300+ state->data[0] = 0xe;
301+ state->data[1] = 0x80;
302+ state->data[2] = 1;
303
304- if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
305+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
306 err("command 0x0e transfer failed.");
307
308- obuf[0] = 0x51;
309+ state->data[0] = 0x51;
310
311- if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
312+ if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
313 err("command 0x51 transfer failed.");
314
315- d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
316- &d->dev->i2c_adap, NULL);
317- if (d->fe_adap[0].fe != NULL) {
318- if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
319- &d->dev->i2c_adap, &tda18271_config)) {
320+ mutex_unlock(&d->data_mutex);
321+
322+ adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
323+ &d->i2c_adap, NULL);
324+ if (adap->fe_adap[0].fe != NULL) {
325+ if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60,
326+ &d->i2c_adap, &tda18271_config)) {
327 info("Attached TDA18271HD/CXD2820R!");
328 return 0;
329 }
330@@ -1411,23 +1444,30 @@ static int t220_frontend_attach(struct dvb_usb_adapter *d)
331 return -EIO;
332 }
333
334-static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
335+static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap)
336 {
337- u8 obuf[] = { 0x51 };
338- u8 ibuf[] = { 0 };
339+ struct dvb_usb_device *d = adap->dev;
340+ struct dw2102_state *state = d->priv;
341+
342+ mutex_lock(&d->data_mutex);
343
344- if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
345+ state->data[0] = 0x51;
346+
347+ if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
348 err("command 0x51 transfer failed.");
349
350- d->fe_adap[0].fe = dvb_attach(m88rs2000_attach, &s421_m88rs2000_config,
351- &d->dev->i2c_adap);
352+ mutex_unlock(&d->data_mutex);
353
354- if (d->fe_adap[0].fe == NULL)
355+ adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
356+ &s421_m88rs2000_config,
357+ &d->i2c_adap);
358+
359+ if (adap->fe_adap[0].fe == NULL)
360 return -EIO;
361
362- if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
363+ if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
364 &dw2104_ts2020_config,
365- &d->dev->i2c_adap)) {
366+ &d->i2c_adap)) {
367 info("Attached RS2000/TS2020!");
368 return 0;
369 }
370@@ -1440,44 +1480,50 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
371 {
372 struct dvb_usb_device *d = adap->dev;
373 struct dw2102_state *state = d->priv;
374- u8 obuf[3] = { 0xe, 0x80, 0 };
375- u8 ibuf[] = { 0 };
376 struct i2c_adapter *i2c_adapter;
377 struct i2c_client *client;
378 struct i2c_board_info board_info;
379 struct m88ds3103_platform_data m88ds3103_pdata = {};
380 struct ts2020_config ts2020_config = {};
381
382- if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
383+ mutex_lock(&d->data_mutex);
384+
385+ state->data[0] = 0xe;
386+ state->data[1] = 0x80;
387+ state->data[2] = 0x0;
388+
389+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
390 err("command 0x0e transfer failed.");
391
392- obuf[0] = 0xe;
393- obuf[1] = 0x02;
394- obuf[2] = 1;
395+ state->data[0] = 0xe;
396+ state->data[1] = 0x02;
397+ state->data[2] = 1;
398
399- if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
400+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
401 err("command 0x0e transfer failed.");
402 msleep(300);
403
404- obuf[0] = 0xe;
405- obuf[1] = 0x83;
406- obuf[2] = 0;
407+ state->data[0] = 0xe;
408+ state->data[1] = 0x83;
409+ state->data[2] = 0;
410
411- if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
412+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
413 err("command 0x0e transfer failed.");
414
415- obuf[0] = 0xe;
416- obuf[1] = 0x83;
417- obuf[2] = 1;
418+ state->data[0] = 0xe;
419+ state->data[1] = 0x83;
420+ state->data[2] = 1;
421
422- if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
423+ if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
424 err("command 0x0e transfer failed.");
425
426- obuf[0] = 0x51;
427+ state->data[0] = 0x51;
428
429- if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 1, 0) < 0)
430+ if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
431 err("command 0x51 transfer failed.");
432
433+ mutex_unlock(&d->data_mutex);
434+
435 /* attach demod */
436 m88ds3103_pdata.clk = 27000000;
437 m88ds3103_pdata.i2c_wr_max = 33;
438--
4391.9.1
440
diff --git a/recipes-kernel/linux/linux-cavium_4.9.inc b/recipes-kernel/linux/linux-cavium_4.9.inc
index 39ba2e7..6e79f44 100644
--- a/recipes-kernel/linux/linux-cavium_4.9.inc
+++ b/recipes-kernel/linux/linux-cavium_4.9.inc
@@ -29,6 +29,7 @@ SRC_URI = "git://git@git.enea.com/linux/linux-cavium.git;protocol=ssh;name=machi
29 file://CVE-2017-7487.patch \ 29 file://CVE-2017-7487.patch \
30 file://CVE-2017-7618.patch \ 30 file://CVE-2017-7618.patch \
31 file://CVE-2017-7645.patch \ 31 file://CVE-2017-7645.patch \
32 file://CVE-2017-8062.patch \
32 file://CVE-2017-8063.patch \ 33 file://CVE-2017-8063.patch \
33 file://CVE-2017-8064.patch \ 34 file://CVE-2017-8064.patch \
34 file://CVE-2017-8066.patch \ 35 file://CVE-2017-8066.patch \