aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h10
-rw-r--r--net/bluetooth/l2cap.c13
-rw-r--r--net/bluetooth/rfcomm/core.c8
3 files changed, 25 insertions, 6 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ea13baa3851b..c8255adee8f5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -474,7 +474,7 @@ struct hci_proto {
474 int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); 474 int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
475 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); 475 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
476 int (*auth_cfm) (struct hci_conn *conn, __u8 status); 476 int (*auth_cfm) (struct hci_conn *conn, __u8 status);
477 int (*encrypt_cfm) (struct hci_conn *conn, __u8 status); 477 int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
478}; 478};
479 479
480static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) 480static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
@@ -532,17 +532,17 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
532 hp->auth_cfm(conn, status); 532 hp->auth_cfm(conn, status);
533} 533}
534 534
535static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status) 535static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
536{ 536{
537 register struct hci_proto *hp; 537 register struct hci_proto *hp;
538 538
539 hp = hci_proto[HCI_PROTO_L2CAP]; 539 hp = hci_proto[HCI_PROTO_L2CAP];
540 if (hp && hp->encrypt_cfm) 540 if (hp && hp->encrypt_cfm)
541 hp->encrypt_cfm(conn, status); 541 hp->encrypt_cfm(conn, status, encrypt);
542 542
543 hp = hci_proto[HCI_PROTO_SCO]; 543 hp = hci_proto[HCI_PROTO_SCO];
544 if (hp && hp->encrypt_cfm) 544 if (hp && hp->encrypt_cfm)
545 hp->encrypt_cfm(conn, status); 545 hp->encrypt_cfm(conn, status, encrypt);
546} 546}
547 547
548int hci_register_proto(struct hci_proto *hproto); 548int hci_register_proto(struct hci_proto *hproto);
@@ -579,7 +579,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
579{ 579{
580 struct list_head *p; 580 struct list_head *p;
581 581
582 hci_proto_encrypt_cfm(conn, status); 582 hci_proto_encrypt_cfm(conn, status, encrypt);
583 583
584 read_lock_bh(&hci_cb_list_lock); 584 read_lock_bh(&hci_cb_list_lock);
585 list_for_each(p, &hci_cb_list) { 585 list_for_each(p, &hci_cb_list) {
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2e3abdfbd69d..252264062f59 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2197,7 +2197,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
2197 return 0; 2197 return 0;
2198} 2198}
2199 2199
2200static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status) 2200static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
2201{ 2201{
2202 struct l2cap_chan_list *l; 2202 struct l2cap_chan_list *l;
2203 struct l2cap_conn *conn = hcon->l2cap_data; 2203 struct l2cap_conn *conn = hcon->l2cap_data;
@@ -2215,8 +2215,19 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status)
2215 read_lock(&l->lock); 2215 read_lock(&l->lock);
2216 2216
2217 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { 2217 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
2218 struct l2cap_pinfo *pi = l2cap_pi(sk);
2219
2218 bh_lock_sock(sk); 2220 bh_lock_sock(sk);
2219 2221
2222 if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) &&
2223 (sk->sk_state == BT_CONNECTED ||
2224 sk->sk_state == BT_CONFIG) &&
2225 !status && encrypt == 0x00) {
2226 __l2cap_sock_close(sk, ECONNREFUSED);
2227 bh_unlock_sock(sk);
2228 continue;
2229 }
2230
2220 if (sk->sk_state != BT_CONNECT2) { 2231 if (sk->sk_state != BT_CONNECT2) {
2221 bh_unlock_sock(sk); 2232 bh_unlock_sock(sk);
2222 continue; 2233 continue;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 1f92f9ab4959..e7a6a03cea37 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2003,6 +2003,14 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2003 list_for_each_safe(p, n, &s->dlcs) { 2003 list_for_each_safe(p, n, &s->dlcs) {
2004 d = list_entry(p, struct rfcomm_dlc, list); 2004 d = list_entry(p, struct rfcomm_dlc, list);
2005 2005
2006 if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) &&
2007 (d->state == BT_CONNECTED ||
2008 d->state == BT_CONFIG) &&
2009 !status && encrypt == 0x00) {
2010 __rfcomm_dlc_close(d, ECONNREFUSED);
2011 continue;
2012 }
2013
2006 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) 2014 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2007 continue; 2015 continue;
2008 2016