@@ -948,6 +948,16 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn)
948
948
return id ;
949
949
}
950
950
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
+
951
961
static void l2cap_send_cmd (struct l2cap_conn * conn , u8 ident , u8 code , u16 len ,
952
962
void * data )
953
963
{
@@ -970,7 +980,7 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
970
980
bt_cb (skb )-> force_active = BT_POWER_FORCE_ACTIVE_ON ;
971
981
skb -> priority = HCI_PRIO_MAX ;
972
982
973
- hci_send_acl (conn -> hchan , skb , flags );
983
+ l2cap_send_acl (conn , skb , flags );
974
984
}
975
985
976
986
static 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)
1792
1802
1793
1803
mutex_unlock (& conn -> chan_lock );
1794
1804
1795
- hci_chan_del (conn -> hchan );
1796
-
1797
1805
if (conn -> info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT )
1798
1806
cancel_delayed_work_sync (& conn -> info_timer );
1799
1807
1800
1808
hcon -> l2cap_data = NULL ;
1801
- conn -> hchan = NULL ;
1802
1809
l2cap_conn_put (conn );
1803
1810
}
1804
1811
1805
1812
static void l2cap_conn_free (struct kref * ref )
1806
1813
{
1807
1814
struct l2cap_conn * conn = container_of (ref , struct l2cap_conn , ref );
1808
1815
1816
+ hci_chan_del (conn -> hchan );
1809
1817
hci_conn_put (conn -> hcon );
1810
1818
kfree (conn );
1811
1819
}
@@ -7466,14 +7474,33 @@ static void l2cap_recv_reset(struct l2cap_conn *conn)
7466
7474
conn -> rx_len = 0 ;
7467
7475
}
7468
7476
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
+
7469
7487
void l2cap_recv_acldata (struct hci_conn * hcon , struct sk_buff * skb , u16 flags )
7470
7488
{
7471
- struct l2cap_conn * conn = hcon -> l2cap_data ;
7489
+ struct l2cap_conn * conn ;
7472
7490
int len ;
7473
7491
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
+
7474
7497
if (!conn )
7475
7498
conn = l2cap_conn_add (hcon );
7476
7499
7500
+ conn = l2cap_conn_hold_unless_zero (conn );
7501
+
7502
+ hci_dev_unlock (hcon -> hdev );
7503
+
7477
7504
if (!conn )
7478
7505
goto drop ;
7479
7506
@@ -7565,6 +7592,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
7565
7592
break ;
7566
7593
}
7567
7594
7595
+ l2cap_conn_put (conn );
7596
+
7568
7597
drop :
7569
7598
kfree_skb (skb );
7570
7599
}
0 commit comments