Getting conn->sk must sock_hold, otherwise the socket may be freed concurrently. Access to conn->hcon is safe when holding hdev->lock. Fix the locking in iso_conn_ready to obey this. Signed-off-by: Pauli Virtanen <pav@xxxxxx> --- net/bluetooth/iso.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index ea0209fb9872..c2045adbd7b6 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -179,6 +179,7 @@ static void iso_chan_del(struct sock *sk, int err) sock_set_flag(sk, SOCK_ZAPPED); } +/* Must hold hdev->lock */ static void iso_conn_del(struct hci_conn *hcon, int err) { struct iso_conn *conn = hcon->iso_data; @@ -1547,19 +1548,23 @@ static bool iso_match_big(struct sock *sk, void *data) static void iso_conn_ready(struct iso_conn *conn) { struct sock *parent; - struct sock *sk = conn->sk; + struct sock *sk; struct hci_ev_le_big_sync_estabilished *ev; struct hci_conn *hcon; BT_DBG("conn %p", conn); - if (sk) { - iso_sock_ready(conn->sk); - } else { - hcon = conn->hcon; - if (!hcon) - return; + iso_conn_lock(conn); + hcon = conn->hcon; + sk = conn->sk; + if (sk) + sock_hold(sk); + iso_conn_unlock(conn); + if (sk) { + iso_sock_ready(sk); + sock_put(sk); + } else if (hcon) { ev = hci_recv_event_data(hcon->hdev, HCI_EVT_LE_BIG_SYNC_ESTABILISHED); if (ev) -- 2.41.0