aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-02-06 17:56:36 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:41 -0500
commit6a8d3010b313d99adbb28f1826fac0234395bb26 (patch)
treee116cd7033e05e0e59b225484991e2a27188fc3e /net/bluetooth
parent984947dc64f82bc6cafa4d84ba1a139718f634a8 (diff)
Bluetooth: Fix double L2CAP connection request
If the remote L2CAP server uses authentication pending stage and encryption is enabled it can happen that a L2CAP connection request is sent twice due to a race condition in the connection state machine. When the remote side indicates any kind of connection pending, then track this state and skip sending of L2CAP commands for this period. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 07fdbc7dd54d..01f750142d55 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1946,11 +1946,14 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
1946 l2cap_pi(sk)->dcid = dcid; 1946 l2cap_pi(sk)->dcid = dcid;
1947 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; 1947 l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
1948 1948
1949 l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
1950
1949 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 1951 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1950 l2cap_build_conf_req(sk, req), req); 1952 l2cap_build_conf_req(sk, req), req);
1951 break; 1953 break;
1952 1954
1953 case L2CAP_CR_PEND: 1955 case L2CAP_CR_PEND:
1956 l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
1954 break; 1957 break;
1955 1958
1956 default: 1959 default:
@@ -2478,6 +2481,11 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
2478 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 2481 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2479 bh_lock_sock(sk); 2482 bh_lock_sock(sk);
2480 2483
2484 if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) {
2485 bh_unlock_sock(sk);
2486 continue;
2487 }
2488
2481 if (!status && (sk->sk_state == BT_CONNECTED || 2489 if (!status && (sk->sk_state == BT_CONNECTED ||
2482 sk->sk_state == BT_CONFIG)) { 2490 sk->sk_state == BT_CONFIG)) {
2483 l2cap_check_encryption(sk, encrypt); 2491 l2cap_check_encryption(sk, encrypt);