@@ -948,6 +948,16 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
948948 return id ;
949949}
950950
951+ static void l2cap_send_acl (struct l2cap_conn * conn , struct sk_buff * skb ,
952+ u8 flags )
953+ {
954+ /* Check if the hcon still valid before attempting to send */
955+ if (hci_conn_valid (conn -> hcon -> hdev , conn -> hcon ))
956+ hci_send_acl (conn -> hchan , skb , flags );
957+ else
958+ kfree_skb (skb );
959+ }
960+
951961static void l2cap_send_cmd (struct l2cap_conn * conn , u8 ident , u8 code , u16 len ,
952962 void * data )
953963{
@@ -970,7 +980,7 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
970980 bt_cb (skb )-> force_active = BT_POWER_FORCE_ACTIVE_ON ;
971981 skb -> priority = HCI_PRIO_MAX ;
972982
973- hci_send_acl (conn -> hchan , skb , flags );
983+ l2cap_send_acl (conn , skb , flags );
974984}
975985
976986static void l2cap_do_send (struct l2cap_chan * chan , struct sk_buff * skb )
@@ -1792,20 +1802,18 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
17921802
17931803 mutex_unlock (& conn -> chan_lock );
17941804
1795- hci_chan_del (conn -> hchan );
1796-
17971805 if (conn -> info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT )
17981806 cancel_delayed_work_sync (& conn -> info_timer );
17991807
18001808 hcon -> l2cap_data = NULL ;
1801- conn -> hchan = NULL ;
18021809 l2cap_conn_put (conn );
18031810}
18041811
18051812static void l2cap_conn_free (struct kref * ref )
18061813{
18071814 struct l2cap_conn * conn = container_of (ref , struct l2cap_conn , ref );
18081815
1816+ hci_chan_del (conn -> hchan );
18091817 hci_conn_put (conn -> hcon );
18101818 kfree (conn );
18111819}
@@ -7466,14 +7474,33 @@ static void l2cap_recv_reset(struct l2cap_conn *conn)
74667474 conn -> rx_len = 0 ;
74677475}
74687476
7477+ static struct l2cap_conn * l2cap_conn_hold_unless_zero (struct l2cap_conn * c )
7478+ {
7479+ BT_DBG ("conn %p orig refcnt %u" , c , kref_read (& c -> ref ));
7480+
7481+ if (!kref_get_unless_zero (& c -> ref ))
7482+ return NULL ;
7483+
7484+ return c ;
7485+ }
7486+
74697487void l2cap_recv_acldata (struct hci_conn * hcon , struct sk_buff * skb , u16 flags )
74707488{
7471- struct l2cap_conn * conn = hcon -> l2cap_data ;
7489+ struct l2cap_conn * conn ;
74727490 int len ;
74737491
7492+ /* Lock hdev to access l2cap_data to avoid race with l2cap_conn_del */
7493+ hci_dev_lock (hcon -> hdev );
7494+
7495+ conn = hcon -> l2cap_data ;
7496+
74747497 if (!conn )
74757498 conn = l2cap_conn_add (hcon );
74767499
7500+ conn = l2cap_conn_hold_unless_zero (conn );
7501+
7502+ hci_dev_unlock (hcon -> hdev );
7503+
74777504 if (!conn )
74787505 goto drop ;
74797506
@@ -7565,6 +7592,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
75657592 break ;
75667593 }
75677594
7595+ l2cap_conn_put (conn );
7596+
75687597drop :
75697598 kfree_skb (skb );
75707599}
0 commit comments