diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index e62a5f368a51..22de82071e35 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -2901,12 +2901,25 @@ static int abort_conn_sync(struct hci_dev *hdev, void *data) { struct hci_conn *conn; u16 handle = PTR_UINT(data); + u8 reason; + int err; + + rcu_read_lock(); conn = hci_conn_hash_lookup_handle(hdev, handle); + if (conn) { + reason = READ_ONCE(conn->abort_reason); + conn = reason ? hci_conn_get(conn) : NULL; + } + + rcu_read_unlock(); + if (!conn) return 0; - return hci_abort_conn_sync(hdev, conn, conn->abort_reason); + err = hci_abort_conn_sync(hdev, conn, reason); + hci_conn_put(conn); + return err; } int hci_abort_conn(struct hci_conn *conn, u8 reason) @@ -2918,6 +2931,8 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) */ if (conn->abort_reason) return 0; + if (WARN_ON(!reason)) + reason = HCI_ERROR_UNSPECIFIED; bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);