diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index e899a9371c00..b2d279c245cf 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -77,7 +77,9 @@ static void l2cap_sock_timeout(unsigned long arg) | |||
77 | 77 | ||
78 | bh_lock_sock(sk); | 78 | bh_lock_sock(sk); |
79 | 79 | ||
80 | if (sk->sk_state == BT_CONNECT && | 80 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) |
81 | reason = ECONNREFUSED; | ||
82 | else if (sk->sk_state == BT_CONNECT && | ||
81 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) | 83 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) |
82 | reason = ECONNREFUSED; | 84 | reason = ECONNREFUSED; |
83 | else | 85 | else |
@@ -2400,6 +2402,20 @@ static int l2cap_disconn_ind(struct hci_conn *hcon, u8 reason) | |||
2400 | return 0; | 2402 | return 0; |
2401 | } | 2403 | } |
2402 | 2404 | ||
2405 | static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) | ||
2406 | { | ||
2407 | if (encrypt == 0x00) { | ||
2408 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) { | ||
2409 | l2cap_sock_clear_timer(sk); | ||
2410 | l2cap_sock_set_timer(sk, HZ * 5); | ||
2411 | } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | ||
2412 | __l2cap_sock_close(sk, ECONNREFUSED); | ||
2413 | } else { | ||
2414 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) | ||
2415 | l2cap_sock_clear_timer(sk); | ||
2416 | } | ||
2417 | } | ||
2418 | |||
2403 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | 2419 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) |
2404 | { | 2420 | { |
2405 | struct l2cap_chan_list *l; | 2421 | struct l2cap_chan_list *l; |
@@ -2416,15 +2432,11 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
2416 | read_lock(&l->lock); | 2432 | read_lock(&l->lock); |
2417 | 2433 | ||
2418 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | 2434 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { |
2419 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2420 | |||
2421 | bh_lock_sock(sk); | 2435 | bh_lock_sock(sk); |
2422 | 2436 | ||
2423 | if (!status && encrypt == 0x00 && | 2437 | if (!status && (sk->sk_state == BT_CONNECTED || |
2424 | pi->sec_level == BT_SECURITY_HIGH && | ||
2425 | (sk->sk_state == BT_CONNECTED || | ||
2426 | sk->sk_state == BT_CONFIG)) { | 2438 | sk->sk_state == BT_CONFIG)) { |
2427 | __l2cap_sock_close(sk, ECONNREFUSED); | 2439 | l2cap_check_encryption(sk, encrypt); |
2428 | bh_unlock_sock(sk); | 2440 | bh_unlock_sock(sk); |
2429 | continue; | 2441 | continue; |
2430 | } | 2442 | } |