diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 10 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 13 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 8 |
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 | ||
480 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | 480 | static 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 | ||
535 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status) | 535 | static 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 | ||
548 | int hci_register_proto(struct hci_proto *hproto); | 548 | int 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 | ||
2200 | static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status) | 2200 | static 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 | ||