]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.9/bluetooth-fix-regression-with-minimum-encryption-key-size-alignment.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.9 / bluetooth-fix-regression-with-minimum-encryption-key-size-alignment.patch
1 From 693cd8ce3f882524a5d06f7800dd8492411877b3 Mon Sep 17 00:00:00 2001
2 From: Marcel Holtmann <marcel@holtmann.org>
3 Date: Sat, 22 Jun 2019 15:47:01 +0200
4 Subject: Bluetooth: Fix regression with minimum encryption key size alignment
5
6 From: Marcel Holtmann <marcel@holtmann.org>
7
8 commit 693cd8ce3f882524a5d06f7800dd8492411877b3 upstream.
9
10 When trying to align the minimum encryption key size requirement for
11 Bluetooth connections, it turns out doing this in a central location in
12 the HCI connection handling code is not possible.
13
14 Original Bluetooth version up to 2.0 used a security model where the
15 L2CAP service would enforce authentication and encryption. Starting
16 with Bluetooth 2.1 and Secure Simple Pairing that model has changed into
17 that the connection initiator is responsible for providing an encrypted
18 ACL link before any L2CAP communication can happen.
19
20 Now connecting Bluetooth 2.1 or later devices with Bluetooth 2.0 and
21 before devices are causing a regression. The encryption key size check
22 needs to be moved out of the HCI connection handling into the L2CAP
23 channel setup.
24
25 To achieve this, the current check inside hci_conn_security() has been
26 moved into l2cap_check_enc_key_size() helper function and then called
27 from four decisions point inside L2CAP to cover all combinations of
28 Secure Simple Pairing enabled devices and device using legacy pairing
29 and legacy service security model.
30
31 Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections")
32 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203643
33 Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
34 Cc: stable@vger.kernel.org
35 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
36 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
37
38 ---
39 net/bluetooth/hci_conn.c | 18 +++++++++---------
40 net/bluetooth/l2cap_core.c | 33 ++++++++++++++++++++++++++++-----
41 2 files changed, 37 insertions(+), 14 deletions(-)
42
43 --- a/net/bluetooth/hci_conn.c
44 +++ b/net/bluetooth/hci_conn.c
45 @@ -1165,14 +1165,6 @@ int hci_conn_check_link_mode(struct hci_
46 !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
47 return 0;
48
49 - /* The minimum encryption key size needs to be enforced by the
50 - * host stack before establishing any L2CAP connections. The
51 - * specification in theory allows a minimum of 1, but to align
52 - * BR/EDR and LE transports, a minimum of 7 is chosen.
53 - */
54 - if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE)
55 - return 0;
56 -
57 return 1;
58 }
59
60 @@ -1289,8 +1281,16 @@ auth:
61 return 0;
62
63 encrypt:
64 - if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
65 + if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) {
66 + /* Ensure that the encryption key size has been read,
67 + * otherwise stall the upper layer responses.
68 + */
69 + if (!conn->enc_key_size)
70 + return 0;
71 +
72 + /* Nothing else needed, all requirements are met */
73 return 1;
74 + }
75
76 hci_conn_encrypt(conn);
77 return 0;
78 --- a/net/bluetooth/l2cap_core.c
79 +++ b/net/bluetooth/l2cap_core.c
80 @@ -1340,6 +1340,21 @@ static void l2cap_request_info(struct l2
81 sizeof(req), &req);
82 }
83
84 +static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
85 +{
86 + /* The minimum encryption key size needs to be enforced by the
87 + * host stack before establishing any L2CAP connections. The
88 + * specification in theory allows a minimum of 1, but to align
89 + * BR/EDR and LE transports, a minimum of 7 is chosen.
90 + *
91 + * This check might also be called for unencrypted connections
92 + * that have no key size requirements. Ensure that the link is
93 + * actually encrypted before enforcing a key size.
94 + */
95 + return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
96 + hcon->enc_key_size > HCI_MIN_ENC_KEY_SIZE);
97 +}
98 +
99 static void l2cap_do_start(struct l2cap_chan *chan)
100 {
101 struct l2cap_conn *conn = chan->conn;
102 @@ -1357,9 +1372,14 @@ static void l2cap_do_start(struct l2cap_
103 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
104 return;
105
106 - if (l2cap_chan_check_security(chan, true) &&
107 - __l2cap_no_conn_pending(chan))
108 + if (!l2cap_chan_check_security(chan, true) ||
109 + !__l2cap_no_conn_pending(chan))
110 + return;
111 +
112 + if (l2cap_check_enc_key_size(conn->hcon))
113 l2cap_start_connection(chan);
114 + else
115 + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
116 }
117
118 static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
119 @@ -1438,7 +1458,10 @@ static void l2cap_conn_start(struct l2ca
120 continue;
121 }
122
123 - l2cap_start_connection(chan);
124 + if (l2cap_check_enc_key_size(conn->hcon))
125 + l2cap_start_connection(chan);
126 + else
127 + l2cap_chan_close(chan, ECONNREFUSED);
128
129 } else if (chan->state == BT_CONNECT2) {
130 struct l2cap_conn_rsp rsp;
131 @@ -7447,7 +7470,7 @@ static void l2cap_security_cfm(struct hc
132 }
133
134 if (chan->state == BT_CONNECT) {
135 - if (!status)
136 + if (!status && l2cap_check_enc_key_size(hcon))
137 l2cap_start_connection(chan);
138 else
139 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
140 @@ -7456,7 +7479,7 @@ static void l2cap_security_cfm(struct hc
141 struct l2cap_conn_rsp rsp;
142 __u16 res, stat;
143
144 - if (!status) {
145 + if (!status && l2cap_check_enc_key_size(hcon)) {
146 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
147 res = L2CAP_CR_PEND;
148 stat = L2CAP_CS_AUTHOR_PEND;