Gentoo Archives: gentoo-commits

From: Mike Pagano <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/linux-patches:4.12 commit in: /
Date: Wed, 13 Sep 2017 12:23:28
Message-Id: 1505305395.54b1ba4af883c5b5915f7ef50d6504bae1d1a664.mpagano@gentoo
1 commit: 54b1ba4af883c5b5915f7ef50d6504bae1d1a664
2 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
3 AuthorDate: Wed Sep 13 12:23:15 2017 +0000
4 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
5 CommitDate: Wed Sep 13 12:23:15 2017 +0000
6 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=54b1ba4a
7
8 Validate the output buffer length for L2CAP config reqs and resps to avoid stack buffer overflowing. CVE-2017-1000251. See bug #630840
9
10 0000_README | 4 +
11 2400_BT-check-L2CAP-buffer-length.patch | 357 ++++++++++++++++++++++++++++++++
12 2 files changed, 361 insertions(+)
13
14 diff --git a/0000_README b/0000_README
15 index c3ac518..bd9f666 100644
16 --- a/0000_README
17 +++ b/0000_README
18 @@ -107,6 +107,10 @@ Patch: 2300_enable-poweroff-on-Mac-Pro-11.patch
19 From: http://kernel.ubuntu.com/git/ubuntu/ubuntu-xenial.git/patch/drivers/pci/quirks.c?id=5080ff61a438f3dd80b88b423e1a20791d8a774c
20 Desc: Workaround to enable poweroff on Mac Pro 11. See bug #601964.
21
22 +Patch: 2400_BT-check-L2CAP-buffer-length.patch
23 +From: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e860d2c904d1a9f38a24eb44c9f34b8f915a6ea3
24 +Desc: Validate the output buffer length for L2CAP config reqs and resps to avoid stack buffer overflowing. CVE-2017-1000251. See bug #630840
25 +
26 Patch: 2600_enable-key-swapping-for-apple-mac.patch
27 From: https://github.com/free5lot/hid-apple-patched
28 Desc: This hid-apple patch enables swapping of the FN and left Control keys and some additional on some apple keyboards. See bug #622902
29
30 diff --git a/2400_BT-check-L2CAP-buffer-length.patch b/2400_BT-check-L2CAP-buffer-length.patch
31 new file mode 100644
32 index 0000000..c6bfdf7
33 --- /dev/null
34 +++ b/2400_BT-check-L2CAP-buffer-length.patch
35 @@ -0,0 +1,357 @@
36 +From e860d2c904d1a9f38a24eb44c9f34b8f915a6ea3 Mon Sep 17 00:00:00 2001
37 +From: Ben Seri <ben@×××××.com>
38 +Date: Sat, 9 Sep 2017 23:15:59 +0200
39 +Subject: Bluetooth: Properly check L2CAP config option output buffer length
40 +
41 +Validate the output buffer length for L2CAP config requests and responses
42 +to avoid overflowing the stack buffer used for building the option blocks.
43 +
44 +Cc: stable@×××××××××××.org
45 +Signed-off-by: Ben Seri <ben@×××××.com>
46 +Signed-off-by: Marcel Holtmann <marcel@××××××××.org>
47 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
48 +---
49 + net/bluetooth/l2cap_core.c | 80 +++++++++++++++++++++++++---------------------
50 + 1 file changed, 43 insertions(+), 37 deletions(-)
51 +
52 +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
53 +index 303c779..43ba91c 100644
54 +--- a/net/bluetooth/l2cap_core.c
55 ++++ b/net/bluetooth/l2cap_core.c
56 +@@ -58,7 +58,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
57 + u8 code, u8 ident, u16 dlen, void *data);
58 + static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
59 + void *data);
60 +-static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
61 ++static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size);
62 + static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
63 +
64 + static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
65 +@@ -1473,7 +1473,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
66 +
67 + set_bit(CONF_REQ_SENT, &chan->conf_state);
68 + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
69 +- l2cap_build_conf_req(chan, buf), buf);
70 ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
71 + chan->num_conf_req++;
72 + }
73 +
74 +@@ -2987,12 +2987,15 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
75 + return len;
76 + }
77 +
78 +-static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
79 ++static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size)
80 + {
81 + struct l2cap_conf_opt *opt = *ptr;
82 +
83 + BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
84 +
85 ++ if (size < L2CAP_CONF_OPT_SIZE + len)
86 ++ return;
87 ++
88 + opt->type = type;
89 + opt->len = len;
90 +
91 +@@ -3017,7 +3020,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
92 + *ptr += L2CAP_CONF_OPT_SIZE + len;
93 + }
94 +
95 +-static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
96 ++static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size)
97 + {
98 + struct l2cap_conf_efs efs;
99 +
100 +@@ -3045,7 +3048,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
101 + }
102 +
103 + l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
104 +- (unsigned long) &efs);
105 ++ (unsigned long) &efs, size);
106 + }
107 +
108 + static void l2cap_ack_timeout(struct work_struct *work)
109 +@@ -3191,11 +3194,12 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
110 + chan->ack_win = chan->tx_win;
111 + }
112 +
113 +-static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
114 ++static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
115 + {
116 + struct l2cap_conf_req *req = data;
117 + struct l2cap_conf_rfc rfc = { .mode = chan->mode };
118 + void *ptr = req->data;
119 ++ void *endptr = data + data_size;
120 + u16 size;
121 +
122 + BT_DBG("chan %p", chan);
123 +@@ -3220,7 +3224,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
124 +
125 + done:
126 + if (chan->imtu != L2CAP_DEFAULT_MTU)
127 +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
128 ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
129 +
130 + switch (chan->mode) {
131 + case L2CAP_MODE_BASIC:
132 +@@ -3239,7 +3243,7 @@ done:
133 + rfc.max_pdu_size = 0;
134 +
135 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
136 +- (unsigned long) &rfc);
137 ++ (unsigned long) &rfc, endptr - ptr);
138 + break;
139 +
140 + case L2CAP_MODE_ERTM:
141 +@@ -3259,21 +3263,21 @@ done:
142 + L2CAP_DEFAULT_TX_WINDOW);
143 +
144 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
145 +- (unsigned long) &rfc);
146 ++ (unsigned long) &rfc, endptr - ptr);
147 +
148 + if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
149 +- l2cap_add_opt_efs(&ptr, chan);
150 ++ l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
151 +
152 + if (test_bit(FLAG_EXT_CTRL, &chan->flags))
153 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
154 +- chan->tx_win);
155 ++ chan->tx_win, endptr - ptr);
156 +
157 + if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
158 + if (chan->fcs == L2CAP_FCS_NONE ||
159 + test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
160 + chan->fcs = L2CAP_FCS_NONE;
161 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
162 +- chan->fcs);
163 ++ chan->fcs, endptr - ptr);
164 + }
165 + break;
166 +
167 +@@ -3291,17 +3295,17 @@ done:
168 + rfc.max_pdu_size = cpu_to_le16(size);
169 +
170 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
171 +- (unsigned long) &rfc);
172 ++ (unsigned long) &rfc, endptr - ptr);
173 +
174 + if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
175 +- l2cap_add_opt_efs(&ptr, chan);
176 ++ l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
177 +
178 + if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
179 + if (chan->fcs == L2CAP_FCS_NONE ||
180 + test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
181 + chan->fcs = L2CAP_FCS_NONE;
182 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
183 +- chan->fcs);
184 ++ chan->fcs, endptr - ptr);
185 + }
186 + break;
187 + }
188 +@@ -3312,10 +3316,11 @@ done:
189 + return ptr - data;
190 + }
191 +
192 +-static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
193 ++static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
194 + {
195 + struct l2cap_conf_rsp *rsp = data;
196 + void *ptr = rsp->data;
197 ++ void *endptr = data + data_size;
198 + void *req = chan->conf_req;
199 + int len = chan->conf_len;
200 + int type, hint, olen;
201 +@@ -3417,7 +3422,7 @@ done:
202 + return -ECONNREFUSED;
203 +
204 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
205 +- (unsigned long) &rfc);
206 ++ (unsigned long) &rfc, endptr - ptr);
207 + }
208 +
209 + if (result == L2CAP_CONF_SUCCESS) {
210 +@@ -3430,7 +3435,7 @@ done:
211 + chan->omtu = mtu;
212 + set_bit(CONF_MTU_DONE, &chan->conf_state);
213 + }
214 +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
215 ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr);
216 +
217 + if (remote_efs) {
218 + if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
219 +@@ -3444,7 +3449,7 @@ done:
220 +
221 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
222 + sizeof(efs),
223 +- (unsigned long) &efs);
224 ++ (unsigned long) &efs, endptr - ptr);
225 + } else {
226 + /* Send PENDING Conf Rsp */
227 + result = L2CAP_CONF_PENDING;
228 +@@ -3477,7 +3482,7 @@ done:
229 + set_bit(CONF_MODE_DONE, &chan->conf_state);
230 +
231 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
232 +- sizeof(rfc), (unsigned long) &rfc);
233 ++ sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
234 +
235 + if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
236 + chan->remote_id = efs.id;
237 +@@ -3491,7 +3496,7 @@ done:
238 + le32_to_cpu(efs.sdu_itime);
239 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
240 + sizeof(efs),
241 +- (unsigned long) &efs);
242 ++ (unsigned long) &efs, endptr - ptr);
243 + }
244 + break;
245 +
246 +@@ -3505,7 +3510,7 @@ done:
247 + set_bit(CONF_MODE_DONE, &chan->conf_state);
248 +
249 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
250 +- (unsigned long) &rfc);
251 ++ (unsigned long) &rfc, endptr - ptr);
252 +
253 + break;
254 +
255 +@@ -3527,10 +3532,11 @@ done:
256 + }
257 +
258 + static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
259 +- void *data, u16 *result)
260 ++ void *data, size_t size, u16 *result)
261 + {
262 + struct l2cap_conf_req *req = data;
263 + void *ptr = req->data;
264 ++ void *endptr = data + size;
265 + int type, olen;
266 + unsigned long val;
267 + struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
268 +@@ -3548,13 +3554,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
269 + chan->imtu = L2CAP_DEFAULT_MIN_MTU;
270 + } else
271 + chan->imtu = val;
272 +- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
273 ++ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
274 + break;
275 +
276 + case L2CAP_CONF_FLUSH_TO:
277 + chan->flush_to = val;
278 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
279 +- 2, chan->flush_to);
280 ++ 2, chan->flush_to, endptr - ptr);
281 + break;
282 +
283 + case L2CAP_CONF_RFC:
284 +@@ -3568,13 +3574,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
285 + chan->fcs = 0;
286 +
287 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
288 +- sizeof(rfc), (unsigned long) &rfc);
289 ++ sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
290 + break;
291 +
292 + case L2CAP_CONF_EWS:
293 + chan->ack_win = min_t(u16, val, chan->ack_win);
294 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
295 +- chan->tx_win);
296 ++ chan->tx_win, endptr - ptr);
297 + break;
298 +
299 + case L2CAP_CONF_EFS:
300 +@@ -3587,7 +3593,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
301 + return -ECONNREFUSED;
302 +
303 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
304 +- (unsigned long) &efs);
305 ++ (unsigned long) &efs, endptr - ptr);
306 + break;
307 +
308 + case L2CAP_CONF_FCS:
309 +@@ -3692,7 +3698,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
310 + return;
311 +
312 + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
313 +- l2cap_build_conf_req(chan, buf), buf);
314 ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
315 + chan->num_conf_req++;
316 + }
317 +
318 +@@ -3900,7 +3906,7 @@ sendresp:
319 + u8 buf[128];
320 + set_bit(CONF_REQ_SENT, &chan->conf_state);
321 + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
322 +- l2cap_build_conf_req(chan, buf), buf);
323 ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
324 + chan->num_conf_req++;
325 + }
326 +
327 +@@ -3978,7 +3984,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
328 + break;
329 +
330 + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
331 +- l2cap_build_conf_req(chan, req), req);
332 ++ l2cap_build_conf_req(chan, req, sizeof(req)), req);
333 + chan->num_conf_req++;
334 + break;
335 +
336 +@@ -4090,7 +4096,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
337 + }
338 +
339 + /* Complete config. */
340 +- len = l2cap_parse_conf_req(chan, rsp);
341 ++ len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp));
342 + if (len < 0) {
343 + l2cap_send_disconn_req(chan, ECONNRESET);
344 + goto unlock;
345 +@@ -4124,7 +4130,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
346 + if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
347 + u8 buf[64];
348 + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
349 +- l2cap_build_conf_req(chan, buf), buf);
350 ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
351 + chan->num_conf_req++;
352 + }
353 +
354 +@@ -4184,7 +4190,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
355 + char buf[64];
356 +
357 + len = l2cap_parse_conf_rsp(chan, rsp->data, len,
358 +- buf, &result);
359 ++ buf, sizeof(buf), &result);
360 + if (len < 0) {
361 + l2cap_send_disconn_req(chan, ECONNRESET);
362 + goto done;
363 +@@ -4214,7 +4220,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
364 + /* throw out any old stored conf requests */
365 + result = L2CAP_CONF_SUCCESS;
366 + len = l2cap_parse_conf_rsp(chan, rsp->data, len,
367 +- req, &result);
368 ++ req, sizeof(req), &result);
369 + if (len < 0) {
370 + l2cap_send_disconn_req(chan, ECONNRESET);
371 + goto done;
372 +@@ -4791,7 +4797,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
373 + set_bit(CONF_REQ_SENT, &chan->conf_state);
374 + l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
375 + L2CAP_CONF_REQ,
376 +- l2cap_build_conf_req(chan, buf), buf);
377 ++ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
378 + chan->num_conf_req++;
379 + }
380 + }
381 +@@ -7465,7 +7471,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
382 + set_bit(CONF_REQ_SENT, &chan->conf_state);
383 + l2cap_send_cmd(conn, l2cap_get_ident(conn),
384 + L2CAP_CONF_REQ,
385 +- l2cap_build_conf_req(chan, buf),
386 ++ l2cap_build_conf_req(chan, buf, sizeof(buf)),
387 + buf);
388 + chan->num_conf_req++;
389 + }
390 +--
391 +cgit v1.1
392 +