aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-09-09 01:19:20 -0400
committerMarcel Holtmann <marcel@holtmann.org>2008-09-09 01:19:20 -0400
commite7c29cb16c833441fd2160642bb13025f4e7ac70 (patch)
tree7ba44be60b7bf9c4e7bee459735ebabdc85eb8fd
parent09ab6f4c2376a0fc31abde1e2991513f900ea825 (diff)
[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>
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bluetooth/hci_conn.c13
-rw-r--r--net/bluetooth/l2cap.c15
4 files changed, 26 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5e785b968e7e..46a43b721dd6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -326,6 +326,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev);
326void hci_conn_check_pending(struct hci_dev *hdev); 326void hci_conn_check_pending(struct hci_dev *hdev);
327 327
328struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); 328struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type);
329int hci_conn_check_link_mode(struct hci_conn *conn);
329int hci_conn_auth(struct hci_conn *conn); 330int hci_conn_auth(struct hci_conn *conn);
330int hci_conn_encrypt(struct hci_conn *conn); 331int hci_conn_encrypt(struct hci_conn *conn);
331int hci_conn_change_link_key(struct hci_conn *conn); 332int hci_conn_change_link_key(struct hci_conn *conn);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 1edfdf4c095b..f6348e078aa4 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -49,7 +49,7 @@
49#define BT_DBG(D...) 49#define BT_DBG(D...)
50#endif 50#endif
51 51
52#define VERSION "2.12" 52#define VERSION "2.13"
53 53
54/* Bluetooth sockets */ 54/* Bluetooth sockets */
55#define BT_MAX_PROTO 8 55#define BT_MAX_PROTO 8
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a2f9efaa3361..b7002429f152 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -376,6 +376,19 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
376} 376}
377EXPORT_SYMBOL(hci_connect); 377EXPORT_SYMBOL(hci_connect);
378 378
379/* Check link security requirement */
380int 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}
390EXPORT_SYMBOL(hci_conn_check_link_mode);
391
379/* Authenticate remote device */ 392/* Authenticate remote device */
380int hci_conn_auth(struct hci_conn *conn) 393int hci_conn_auth(struct hci_conn *conn)
381{ 394{
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a96d6de80d12..9610a9c85b98 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1568,10 +1568,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1568 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 1568 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1569 struct l2cap_conn_rsp rsp; 1569 struct l2cap_conn_rsp rsp;
1570 struct sock *sk, *parent; 1570 struct sock *sk, *parent;
1571 int result, status = 0; 1571 int result, status = L2CAP_CS_NO_INFO;
1572 1572
1573 u16 dcid = 0, scid = __le16_to_cpu(req->scid); 1573 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
1574 __le16 psm = req->psm; 1574 __le16 psm = req->psm;
1575 1575
1576 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); 1576 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1577 1577
@@ -1582,6 +1582,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1582 goto sendresp; 1582 goto sendresp;
1583 } 1583 }
1584 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;
1590 }
1591
1585 result = L2CAP_CR_NO_MEM; 1592 result = L2CAP_CR_NO_MEM;
1586 1593
1587 /* Check for backlog size */ 1594 /* Check for backlog size */
@@ -2239,7 +2246,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
2239 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2246 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2240 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2247 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2241 rsp.result = cpu_to_le16(result); 2248 rsp.result = cpu_to_le16(result);
2242 rsp.status = cpu_to_le16(0); 2249 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
2243 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2250 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2244 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2251 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
2245 } 2252 }
@@ -2311,7 +2318,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
2311 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2318 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2312 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2319 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2313 rsp.result = cpu_to_le16(result); 2320 rsp.result = cpu_to_le16(result);
2314 rsp.status = cpu_to_le16(0); 2321 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
2315 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2322 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2316 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2323 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
2317 } 2324 }