Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[Bluetooth] Reject L2CAP connections on an insecure ACL link

The Security Mode 4 of the Bluetooth 2.1 specification has strict
authentication and encryption requirements. It is the initiators job
to create a secure ACL link. However in case of malicious devices, the
acceptor has to make sure that the ACL is encrypted before allowing
any kind of L2CAP connection. The only exception here is the PSM 1 for
the service discovery protocol, because that is allowed to run on an
insecure ACL link.

Previously it was enough to reject a L2CAP connection during the
connection setup phase, but with Bluetooth 2.1 it is forbidden to
do any L2CAP protocol exchange on an insecure link (except SDP).

The new hci_conn_check_link_mode() function can be used to check the
integrity of an ACL link. This functions also takes care of the cases
where Security Mode 4 is disabled or one of the devices is based on
an older specification.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

+26 -5
+1
include/net/bluetooth/hci_core.h
··· 326 326 void hci_conn_check_pending(struct hci_dev *hdev); 327 327 328 328 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); 329 + int hci_conn_check_link_mode(struct hci_conn *conn); 329 330 int hci_conn_auth(struct hci_conn *conn); 330 331 int hci_conn_encrypt(struct hci_conn *conn); 331 332 int hci_conn_change_link_key(struct hci_conn *conn);
+1 -1
net/bluetooth/af_bluetooth.c
··· 49 49 #define BT_DBG(D...) 50 50 #endif 51 51 52 - #define VERSION "2.12" 52 + #define VERSION "2.13" 53 53 54 54 /* Bluetooth sockets */ 55 55 #define BT_MAX_PROTO 8
+13
net/bluetooth/hci_conn.c
··· 376 376 } 377 377 EXPORT_SYMBOL(hci_connect); 378 378 379 + /* Check link security requirement */ 380 + int hci_conn_check_link_mode(struct hci_conn *conn) 381 + { 382 + BT_DBG("conn %p", conn); 383 + 384 + if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 && 385 + !(conn->link_mode & HCI_LM_ENCRYPT)) 386 + return 0; 387 + 388 + return 1; 389 + } 390 + EXPORT_SYMBOL(hci_conn_check_link_mode); 391 + 379 392 /* Authenticate remote device */ 380 393 int hci_conn_auth(struct hci_conn *conn) 381 394 {
+11 -4
net/bluetooth/l2cap.c
··· 1568 1568 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 1569 1569 struct l2cap_conn_rsp rsp; 1570 1570 struct sock *sk, *parent; 1571 - int result, status = 0; 1571 + int result, status = L2CAP_CS_NO_INFO; 1572 1572 1573 1573 u16 dcid = 0, scid = __le16_to_cpu(req->scid); 1574 - __le16 psm = req->psm; 1574 + __le16 psm = req->psm; 1575 1575 1576 1576 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); 1577 1577 ··· 1580 1580 if (!parent) { 1581 1581 result = L2CAP_CR_BAD_PSM; 1582 1582 goto sendresp; 1583 + } 1584 + 1585 + /* Check if the ACL is secure enough (if not SDP) */ 1586 + if (psm != cpu_to_le16(0x0001) && 1587 + !hci_conn_check_link_mode(conn->hcon)) { 1588 + result = L2CAP_CR_SEC_BLOCK; 1589 + goto response; 1583 1590 } 1584 1591 1585 1592 result = L2CAP_CR_NO_MEM; ··· 2246 2239 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2247 2240 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2248 2241 rsp.result = cpu_to_le16(result); 2249 - rsp.status = cpu_to_le16(0); 2242 + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 2250 2243 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2251 2244 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2252 2245 } ··· 2318 2311 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2319 2312 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2320 2313 rsp.result = cpu_to_le16(result); 2321 - rsp.status = cpu_to_le16(0); 2314 + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 2322 2315 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2323 2316 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2324 2317 }