Skip to content

Commit db7f107

Browse files
holtmanngregkh
authored andcommitted
Bluetooth: Fix regression with minimum encryption key size alignment
commit 693cd8c upstream. When trying to align the minimum encryption key size requirement for Bluetooth connections, it turns out doing this in a central location in the HCI connection handling code is not possible. Original Bluetooth version up to 2.0 used a security model where the L2CAP service would enforce authentication and encryption. Starting with Bluetooth 2.1 and Secure Simple Pairing that model has changed into that the connection initiator is responsible for providing an encrypted ACL link before any L2CAP communication can happen. Now connecting Bluetooth 2.1 or later devices with Bluetooth 2.0 and before devices are causing a regression. The encryption key size check needs to be moved out of the HCI connection handling into the L2CAP channel setup. To achieve this, the current check inside hci_conn_security() has been moved into l2cap_check_enc_key_size() helper function and then called from four decisions point inside L2CAP to cover all combinations of Secure Simple Pairing enabled devices and device using legacy pairing and legacy service security model. Fixes: d5bb334 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203643 Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5e9a6c6 commit db7f107

2 files changed

Lines changed: 37 additions & 14 deletions

File tree

net/bluetooth/hci_conn.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,14 +1276,6 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
12761276
!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
12771277
return 0;
12781278

1279-
/* The minimum encryption key size needs to be enforced by the
1280-
* host stack before establishing any L2CAP connections. The
1281-
* specification in theory allows a minimum of 1, but to align
1282-
* BR/EDR and LE transports, a minimum of 7 is chosen.
1283-
*/
1284-
if (conn->enc_key_size < HCI_MIN_ENC_KEY_SIZE)
1285-
return 0;
1286-
12871279
return 1;
12881280
}
12891281

@@ -1400,8 +1392,16 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
14001392
return 0;
14011393

14021394
encrypt:
1403-
if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
1395+
if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) {
1396+
/* Ensure that the encryption key size has been read,
1397+
* otherwise stall the upper layer responses.
1398+
*/
1399+
if (!conn->enc_key_size)
1400+
return 0;
1401+
1402+
/* Nothing else needed, all requirements are met */
14041403
return 1;
1404+
}
14051405

14061406
hci_conn_encrypt(conn);
14071407
return 0;

net/bluetooth/l2cap_core.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,21 @@ static void l2cap_request_info(struct l2cap_conn *conn)
13401340
sizeof(req), &req);
13411341
}
13421342

1343+
static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
1344+
{
1345+
/* The minimum encryption key size needs to be enforced by the
1346+
* host stack before establishing any L2CAP connections. The
1347+
* specification in theory allows a minimum of 1, but to align
1348+
* BR/EDR and LE transports, a minimum of 7 is chosen.
1349+
*
1350+
* This check might also be called for unencrypted connections
1351+
* that have no key size requirements. Ensure that the link is
1352+
* actually encrypted before enforcing a key size.
1353+
*/
1354+
return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
1355+
hcon->enc_key_size > HCI_MIN_ENC_KEY_SIZE);
1356+
}
1357+
13431358
static void l2cap_do_start(struct l2cap_chan *chan)
13441359
{
13451360
struct l2cap_conn *conn = chan->conn;
@@ -1357,9 +1372,14 @@ static void l2cap_do_start(struct l2cap_chan *chan)
13571372
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
13581373
return;
13591374

1360-
if (l2cap_chan_check_security(chan, true) &&
1361-
__l2cap_no_conn_pending(chan))
1375+
if (!l2cap_chan_check_security(chan, true) ||
1376+
!__l2cap_no_conn_pending(chan))
1377+
return;
1378+
1379+
if (l2cap_check_enc_key_size(conn->hcon))
13621380
l2cap_start_connection(chan);
1381+
else
1382+
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
13631383
}
13641384

13651385
static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
@@ -1438,7 +1458,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
14381458
continue;
14391459
}
14401460

1441-
l2cap_start_connection(chan);
1461+
if (l2cap_check_enc_key_size(conn->hcon))
1462+
l2cap_start_connection(chan);
1463+
else
1464+
l2cap_chan_close(chan, ECONNREFUSED);
14421465

14431466
} else if (chan->state == BT_CONNECT2) {
14441467
struct l2cap_conn_rsp rsp;
@@ -7455,7 +7478,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
74557478
}
74567479

74577480
if (chan->state == BT_CONNECT) {
7458-
if (!status)
7481+
if (!status && l2cap_check_enc_key_size(hcon))
74597482
l2cap_start_connection(chan);
74607483
else
74617484
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
@@ -7464,7 +7487,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
74647487
struct l2cap_conn_rsp rsp;
74657488
__u16 res, stat;
74667489

7467-
if (!status) {
7490+
if (!status && l2cap_check_enc_key_size(hcon)) {
74687491
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
74697492
res = L2CAP_CR_PEND;
74707493
stat = L2CAP_CS_AUTHOR_PEND;

0 commit comments

Comments
 (0)