diff options
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 1 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 7 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 5 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 12 |
5 files changed, 22 insertions, 5 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 262ebd1747d4..a65910bda381 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -191,6 +191,7 @@ struct bt_sock { | |||
191 | struct list_head accept_q; | 191 | struct list_head accept_q; |
192 | struct sock *parent; | 192 | struct sock *parent; |
193 | u32 defer_setup; | 193 | u32 defer_setup; |
194 | bool suspended; | ||
194 | }; | 195 | }; |
195 | 196 | ||
196 | struct bt_sock_list { | 197 | struct bt_sock_list { |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 72eb187a5f60..6fb68a9743af 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -450,7 +450,7 @@ unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wa | |||
450 | sk->sk_state == BT_CONFIG) | 450 | sk->sk_state == BT_CONFIG) |
451 | return mask; | 451 | return mask; |
452 | 452 | ||
453 | if (sock_writeable(sk)) | 453 | if (!bt_sk(sk)->suspended && sock_writeable(sk)) |
454 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 454 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
455 | else | 455 | else |
456 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 456 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6c065254afc0..53680fe84628 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2039,6 +2039,12 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
2039 | 2039 | ||
2040 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | 2040 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); |
2041 | 2041 | ||
2042 | if (ev->status && conn->state == BT_CONNECTED) { | ||
2043 | hci_acl_disconn(conn, 0x13); | ||
2044 | hci_conn_put(conn); | ||
2045 | goto unlock; | ||
2046 | } | ||
2047 | |||
2042 | if (conn->state == BT_CONFIG) { | 2048 | if (conn->state == BT_CONFIG) { |
2043 | if (!ev->status) | 2049 | if (!ev->status) |
2044 | conn->state = BT_CONNECTED; | 2050 | conn->state = BT_CONNECTED; |
@@ -2049,6 +2055,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
2049 | hci_encrypt_cfm(conn, ev->status, ev->encrypt); | 2055 | hci_encrypt_cfm(conn, ev->status, ev->encrypt); |
2050 | } | 2056 | } |
2051 | 2057 | ||
2058 | unlock: | ||
2052 | hci_dev_unlock(hdev); | 2059 | hci_dev_unlock(hdev); |
2053 | } | 2060 | } |
2054 | 2061 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 94552b33d528..6f9c25b633a6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -4589,6 +4589,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4589 | 4589 | ||
4590 | if (!status && (chan->state == BT_CONNECTED || | 4590 | if (!status && (chan->state == BT_CONNECTED || |
4591 | chan->state == BT_CONFIG)) { | 4591 | chan->state == BT_CONFIG)) { |
4592 | struct sock *sk = chan->sk; | ||
4593 | |||
4594 | bt_sk(sk)->suspended = false; | ||
4595 | sk->sk_state_change(sk); | ||
4596 | |||
4592 | l2cap_check_encryption(chan, encrypt); | 4597 | l2cap_check_encryption(chan, encrypt); |
4593 | l2cap_chan_unlock(chan); | 4598 | l2cap_chan_unlock(chan); |
4594 | continue; | 4599 | continue; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 29122ed28ea9..04e7c172d49c 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -592,10 +592,14 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
592 | sk->sk_state = BT_CONFIG; | 592 | sk->sk_state = BT_CONFIG; |
593 | chan->state = BT_CONFIG; | 593 | chan->state = BT_CONFIG; |
594 | 594 | ||
595 | /* or for ACL link, under defer_setup time */ | 595 | /* or for ACL link */ |
596 | } else if (sk->sk_state == BT_CONNECT2 && | 596 | } else if ((sk->sk_state == BT_CONNECT2 && |
597 | bt_sk(sk)->defer_setup) { | 597 | bt_sk(sk)->defer_setup) || |
598 | err = l2cap_chan_check_security(chan); | 598 | sk->sk_state == BT_CONNECTED) { |
599 | if (!l2cap_chan_check_security(chan)) | ||
600 | bt_sk(sk)->suspended = true; | ||
601 | else | ||
602 | sk->sk_state_change(sk); | ||
599 | } else { | 603 | } else { |
600 | err = -EINVAL; | 604 | err = -EINVAL; |
601 | } | 605 | } |