From patchwork Tue May 2 14:57:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruihan Li X-Patchwork-Id: 678460 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B051C7EE23 for ; Tue, 2 May 2023 14:58:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234528AbjEBO6E (ORCPT ); Tue, 2 May 2023 10:58:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234138AbjEBO6B (ORCPT ); Tue, 2 May 2023 10:58:01 -0400 Received: from pku.edu.cn (mx19.pku.edu.cn [162.105.129.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CDC582733 for ; Tue, 2 May 2023 07:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=+23j70KJbA3hTfSGNHgn4j0Bbr5o3LtuB5 dNkDC+QWE=; b=RHMoB8tpZc7+Vwm4SpuMtjw9OraKJpBFCJDuNlDCNttPZ11stM 7bU6oyo97473y0TvMD5rVp0i1lmPb9gitcKwlWCuggHvSbAS9lpf6qvx7Bjzl47H Kihkoe9PCZAhF9f20hG2qZLqPaGzHWnUdLuoc0b6mF+kBOzwc38oqNz/k= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBXX5fjJFFk6i5LAQ--.10226S3; Tue, 02 May 2023 22:57:47 +0800 (CST) From: Ruihan Li To: linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Ruihan Li , syzbot+690b90b14f14f43f4688@syzkaller.appspotmail.com Subject: [PATCH v3 1/6] Bluetooth: Fix potential double free caused by hci_conn_unlink Date: Tue, 2 May 2023 22:57:32 +0800 Message-Id: <20230502145737.140856-2-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230502145737.140856-1-lrh2000@pku.edu.cn> References: <20230502145737.140856-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 X-CM-TRANSID: 5oFpogBXX5fjJFFk6i5LAQ--.10226S3 X-Coremail-Antispam: 1UD129KBjvJXoWxJrWkCrWrXrW8JryrKr1xXwb_yoW8ur45pa y3WayfurWktrnavF4jyw48WFs0vw1kZFy3Krn5tryrXws0vr48Ar40kryjqrZ8ZrZ5WF4Y vF4Utr18KF4UG37anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUvE1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E 87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1lnxkEFVAIw20F6c xK64vIFxWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2Wl Yx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbV WUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svP MxAIw28IcxkI7VAKI48JMxAIw28IcVCjz48v1sIEY20_Kr1UJr1l4I8I3I0E4IkC6x0Yz7 v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF 1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIx AIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI 42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWI evJa73UjIFyTuYvjfUFYFADUUUU X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgETBVPy77xtrwAAsl Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org The hci_conn_unlink function is being called by hci_conn_del, which means it should not call hci_conn_del with the input parameter conn again. If it does, conn may have already been released when hci_conn_unlink returns, leading to potential UAF and double-free issues. This patch resolves the problem by modifying hci_conn_unlink to release only conn's child links when necessary, but never release conn itself. Reported-by: syzbot+690b90b14f14f43f4688@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-bluetooth/000000000000484a8205faafe216@google.com/ Fixes: 06149746e720 ("Bluetooth: hci_conn: Add support for linking multiple hcon") Signed-off-by: Ruihan Li --- net/bluetooth/hci_conn.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 640b951bf..70e1655a9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1083,8 +1083,18 @@ static void hci_conn_unlink(struct hci_conn *conn) if (!conn->parent) { struct hci_link *link, *t; - list_for_each_entry_safe(link, t, &conn->link_list, list) - hci_conn_unlink(link->conn); + list_for_each_entry_safe(link, t, &conn->link_list, list) { + struct hci_conn *child = link->conn; + + hci_conn_unlink(child); + + /* Due to race, SCO connection might be not established + * yet at this point. Delete it now, otherwise it is + * possible for it to be stuck and can't be deleted. + */ + if (child->handle == HCI_CONN_HANDLE_UNSET) + hci_conn_del(child); + } return; } @@ -1100,13 +1110,6 @@ static void hci_conn_unlink(struct hci_conn *conn) kfree(conn->link); conn->link = NULL; - - /* Due to race, SCO connection might be not established - * yet at this point. Delete it now, otherwise it is - * possible for it to be stuck and can't be deleted. - */ - if (conn->handle == HCI_CONN_HANDLE_UNSET) - hci_conn_del(conn); } int hci_conn_del(struct hci_conn *conn) From patchwork Tue May 2 14:57:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruihan Li X-Patchwork-Id: 678461 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4833FC77B73 for ; Tue, 2 May 2023 14:58:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234518AbjEBO6C (ORCPT ); Tue, 2 May 2023 10:58:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233981AbjEBO6B (ORCPT ); Tue, 2 May 2023 10:58:01 -0400 Received: from pku.edu.cn (mx18.pku.edu.cn [162.105.129.181]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6C4FD26BF for ; Tue, 2 May 2023 07:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=avNJ51aScZutbdGQ55v1LNc39r1/FL5jKi j8SkDff7k=; b=qceQn9oUNhzP03vjImu4OMXOYNPqf6B8DKaqOKZLqXu+T390eb 07oyCTclMcQ4a617IxSEGo8rwqO3qGUcIpNnnjQ1caW9JQF5xhLtSLKrNz0Xsf8i +8PNWVGwYsbjgttGffkx82PN2CcIEHtz/+cbCdckVcJqs4Gr5FDWIbuK8= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBXX5fjJFFk6i5LAQ--.10226S4; Tue, 02 May 2023 22:57:47 +0800 (CST) From: Ruihan Li To: linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Ruihan Li Subject: [PATCH v3 2/6] Bluetooth: Refcnt drop must be placed last in hci_conn_unlink Date: Tue, 2 May 2023 22:57:33 +0800 Message-Id: <20230502145737.140856-3-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230502145737.140856-1-lrh2000@pku.edu.cn> References: <20230502145737.140856-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 X-CM-TRANSID: 5oFpogBXX5fjJFFk6i5LAQ--.10226S4 X-Coremail-Antispam: 1UD129KBjvJXoW7Cr4fKr1ftrW5WFWUGF15urg_yoW8GFW8pa y5uay3AFWkJrn0vF1qy3WkWrykCF1kZFy29r1rAryrJa1rtr4jyr4rCF1UKw15ZrWkGF1f ZF4vqwn5KFWDGFDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9j1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UM28EF7xvwVC2 z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2vYz4IE04k24V AvwVAKI4IrM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xf McIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7 v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm -wCF04k20xvY0x0EwIxGrwCF04k20xvE74AGY7Cv6cx26w4UJr1UMxC20s026xCaFVCjc4 AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE 17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMI IF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4l IxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvf C2KfnxnUUI43ZEXa7VU1c4S5UUUUU== X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgETBVPy77xtrgAAsk Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org If hci_conn_put(conn->parent) reduces conn->parent's reference count to zero, it can immediately deallocate conn->parent. At the same time, conn->link->list has its head in conn->parent, causing use-after-free problems in the latter list_del_rcu(&conn->link->list). This problem can be easily solved by reordering the two operations, i.e., first performing the list removal with list_del_rcu and then decreasing the refcnt with hci_conn_put. Reported-by: Luiz Augusto von Dentz Closes: https://lore.kernel.org/linux-bluetooth/CABBYNZ+1kce8_RJrLNOXd_8=Mdpb=2bx4Nto-hFORk=qiOkoCg@mail.gmail.com/ Fixes: 06149746e720 ("Bluetooth: hci_conn: Add support for linking multiple hcon") Signed-off-by: Ruihan Li --- net/bluetooth/hci_conn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 70e1655a9..44d0643fc 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1102,12 +1102,12 @@ static void hci_conn_unlink(struct hci_conn *conn) if (!conn->link) return; - hci_conn_put(conn->parent); - conn->parent = NULL; - list_del_rcu(&conn->link->list); synchronize_rcu(); + hci_conn_put(conn->parent); + conn->parent = NULL; + kfree(conn->link); conn->link = NULL; } From patchwork Tue May 2 14:57:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruihan Li X-Patchwork-Id: 679170 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA0C5C7EE26 for ; Tue, 2 May 2023 14:58:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234536AbjEBO6G (ORCPT ); Tue, 2 May 2023 10:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234160AbjEBO6B (ORCPT ); Tue, 2 May 2023 10:58:01 -0400 Received: from pku.edu.cn (mx19.pku.edu.cn [162.105.129.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C2D5A2717 for ; Tue, 2 May 2023 07:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=QX59XWsjXAPMfcbtTgOB0urFn/qyJKJu6y 1wAr68sqo=; b=F9i0a7XVGXjmVZnbwRoIihLArfT9YJFnqCNMaB72a/Qkil0Uc9 OWoaP2HaQWDQ4iW/fFMQrJ2oWV+WrBak0vWvjVGtSs9EQHECDKUoqSaRtN71qZjv dvV7GQFwJuNlSeEcA+jG/gLpSa6Rv3JtMX5NVxBbirFrhK+ee8hQ768pE= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBXX5fjJFFk6i5LAQ--.10226S5; Tue, 02 May 2023 22:57:48 +0800 (CST) From: Ruihan Li To: linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Ruihan Li , syzbot+8bb72f86fc823817bc5d@syzkaller.appspotmail.com Subject: [PATCH v3 3/6] Bluetooth: Fix UAF in hci_conn_hash_flush again Date: Tue, 2 May 2023 22:57:34 +0800 Message-Id: <20230502145737.140856-4-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230502145737.140856-1-lrh2000@pku.edu.cn> References: <20230502145737.140856-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 X-CM-TRANSID: 5oFpogBXX5fjJFFk6i5LAQ--.10226S5 X-Coremail-Antispam: 1UD129KBjvJXoWxXFyDWFW3Cry5Gr15Cr45ZFb_yoWrGFWDpa y5Wa45ur4kJrn5ZF1jyw4kAFn0qr4kZFy3KrW8J34rJ3yYyr4UArs0kryUt3y5ArZ5JFWU ZF40gr17KFyUJ37anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9j1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UM28EF7xvwVC2 z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2vYz4IE04k24V AvwVAKI4IrM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xf McIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7 v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm -wCF04k20xvY0x0EwIxGrwCF04k20xvE74AGY7Cv6cx26w4UJr1UMxC20s026xCaFVCjc4 AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE 17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMI IF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4l IxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvf C2KfnxnUUI43ZEXa7VU1c4S5UUUUU== X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgEPBVPy77wh+AAXs1 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Commit 06149746e720 ("Bluetooth: hci_conn: Add support for linking multiple hcon") reintroduced a previously fixed bug [1] ("KASAN: slab-use-after-free Read in hci_conn_hash_flush"). This bug was originally fixed by commit 5dc7d23e167e ("Bluetooth: hci_conn: Fix possible UAF"). The hci_conn_unlink function was added to avoid invalidating the link traversal caused by successive hci_conn_del operations releasing extra connections. However, currently hci_conn_unlink itself also releases extra connections, resulted in the reintroduced bug. This patch follows a more robust solution for cleaning up all connections, by repeatedly removing the first connection until there are none left. This approach does not rely on the inner workings of hci_conn_del and ensures proper cleanup of all connections. Meanwhile, we need to make sure that hci_conn_del never fails. Indeed it doesn't, as it now always returns zero. To make this a bit clearer, this patch also changes its return type to void. Reported-by: syzbot+8bb72f86fc823817bc5d@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-bluetooth/000000000000aa920505f60d25ad@google.com/ Fixes: 06149746e720 ("Bluetooth: hci_conn: Add support for linking multiple hcon") Signed-off-by: Ruihan Li --- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_conn.c | 29 +++++++++++++---------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a6c8aee2f..8baf34639 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1327,7 +1327,7 @@ int hci_le_create_cis(struct hci_conn *conn); struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, u8 role); -int hci_conn_del(struct hci_conn *conn); +void hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 44d0643fc..eef148291 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1112,7 +1112,7 @@ static void hci_conn_unlink(struct hci_conn *conn) conn->link = NULL; } -int hci_conn_del(struct hci_conn *conn) +void hci_conn_del(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; @@ -1163,8 +1163,6 @@ int hci_conn_del(struct hci_conn *conn) * rest of hci_conn_del. */ hci_conn_cleanup(conn); - - return 0; } struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type) @@ -2465,22 +2463,21 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) /* Drop all connection on the device */ void hci_conn_hash_flush(struct hci_dev *hdev) { - struct hci_conn_hash *h = &hdev->conn_hash; - struct hci_conn *c, *n; + struct list_head *head = &hdev->conn_hash.list; + struct hci_conn *conn; BT_DBG("hdev %s", hdev->name); - list_for_each_entry_safe(c, n, &h->list, list) { - c->state = BT_CLOSED; - - hci_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM); - - /* Unlink before deleting otherwise it is possible that - * hci_conn_del removes the link which may cause the list to - * contain items already freed. - */ - hci_conn_unlink(c); - hci_conn_del(c); + /* We should not traverse the list here, because hci_conn_del + * can remove extra links, which may cause the list traversal + * to hit items that have already been released. + */ + while ((conn = list_first_entry_or_null(head, + struct hci_conn, + list)) != NULL) { + conn->state = BT_CLOSED; + hci_disconn_cfm(conn, HCI_ERROR_LOCAL_HOST_TERM); + hci_conn_del(conn); } } From patchwork Tue May 2 14:57:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruihan Li X-Patchwork-Id: 679168 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C936C7EE25 for ; Tue, 2 May 2023 14:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234542AbjEBO6J (ORCPT ); Tue, 2 May 2023 10:58:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234187AbjEBO6B (ORCPT ); Tue, 2 May 2023 10:58:01 -0400 Received: from pku.edu.cn (mx18.pku.edu.cn [162.105.129.181]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CD9962723 for ; Tue, 2 May 2023 07:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=HxCd4rFmxpf8MfjsXA8dHp1Xyd+DZGMT1H r7aQFCMrA=; b=epzL2WH+Ohcrpl9r2IjoNk68zWNUJ4I1S1L/rm+dGXp86Zwjl7 kQKrwWLvsOrTyBQu65+hI28oNNzDuSRPZV9AFq733/A0psdtg2l43FoLaR8u095n dplnxVItw7NhNsqSQg8Wticf01g9bw+dLkcCpUc54BZ1ppfOFSFCZFKK0= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBXX5fjJFFk6i5LAQ--.10226S6; Tue, 02 May 2023 22:57:48 +0800 (CST) From: Ruihan Li To: linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Ruihan Li Subject: [PATCH v3 4/6] Bluetooth: Perform hci_conn_drop in hci_conn_unlink Date: Tue, 2 May 2023 22:57:35 +0800 Message-Id: <20230502145737.140856-5-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230502145737.140856-1-lrh2000@pku.edu.cn> References: <20230502145737.140856-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 X-CM-TRANSID: 5oFpogBXX5fjJFFk6i5LAQ--.10226S6 X-Coremail-Antispam: 1UD129KBjvJXoW7trykKF4xuw1DCr1UAw4xWFg_yoW8KF4Dpa 4Y934UXa1kJrZ09Fn2kr4kXFnYqr1DAFy7tr18Jr18Jws5tr1jyw4SkF18Kr45ZrWkJF1x ZF4jqr1IgF1UGr7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9j1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UM28EF7xvwVC2 z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2vYz4IE04k24V AvwVAKI4IrM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xf McIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7 v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm -wCF04k20xvY0x0EwIxGrwCF04k20xvE74AGY7Cv6cx26w4UJr1UMxC20s026xCaFVCjc4 AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE 17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMI IF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4l IxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvf C2KfnxnUUI43ZEXa7VU1c4S5UUUUU== X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgETBVPy77xtrQAAsn Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Since hci_conn_link invokes both hci_conn_get and hci_conn_hold, hci_conn_unlink should perform both hci_conn_put and hci_conn_drop as well. However, currently it performs only hci_conn_put. This patch makes hci_conn_unlink call hci_conn_drop as well, which simplifies the logic in hci_conn_del a bit and may benefit future users of hci_conn_unlink. But it is noted that this change additionally implies that hci_conn_unlink can queue disc_work on conn itself, with the following call stack: hci_conn_unlink(conn) [conn->parent == NULL] -> hci_conn_unlink(child) [child->parent == conn] -> hci_conn_drop(child->parent) -> queue_delayed_work(&conn->disc_work) Queued disc_work after hci_conn_del can be spurious, so during the process of hci_conn_del, it is necessary to make the call to cancel_delayed_work(&conn->disc_work) after invoking hci_conn_unlink. Signed-off-by: Ruihan Li --- net/bluetooth/hci_conn.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index eef148291..e76ebb50d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1105,6 +1105,7 @@ static void hci_conn_unlink(struct hci_conn *conn) list_del_rcu(&conn->link->list); synchronize_rcu(); + hci_conn_drop(conn->parent); hci_conn_put(conn->parent); conn->parent = NULL; @@ -1118,7 +1119,6 @@ void hci_conn_del(struct hci_conn *conn) BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); - cancel_delayed_work_sync(&conn->disc_work); cancel_delayed_work_sync(&conn->auto_accept_work); cancel_delayed_work_sync(&conn->idle_work); @@ -1134,12 +1134,7 @@ void hci_conn_del(struct hci_conn *conn) else hdev->acl_cnt += conn->sent; } else { - struct hci_conn *acl = conn->parent; - - if (acl) { - hci_conn_unlink(conn); - hci_conn_drop(acl); - } + hci_conn_unlink(conn); /* Unacked ISO frames */ if (conn->type == ISO_LINK) { @@ -1152,6 +1147,11 @@ void hci_conn_del(struct hci_conn *conn) } } + /* hci_conn_unlink may trigger additional disc_work, so + * ensure to perform cancelling after that. + */ + cancel_delayed_work_sync(&conn->disc_work); + if (conn->amp_mgr) amp_mgr_put(conn->amp_mgr); From patchwork Tue May 2 14:57:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruihan Li X-Patchwork-Id: 679169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF989C77B73 for ; Tue, 2 May 2023 14:58:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234494AbjEBO6G (ORCPT ); Tue, 2 May 2023 10:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55650 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234223AbjEBO6B (ORCPT ); Tue, 2 May 2023 10:58:01 -0400 Received: from pku.edu.cn (mx19.pku.edu.cn [162.105.129.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CE0142D41 for ; Tue, 2 May 2023 07:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=9xGmf8aJdntu7YhLTCkjnA49nu1UugN/HF b1MKGUwPM=; b=YQnlniD7cSnV3PFVXCc0pBsUeC9CN01uDZ4OZhlMFDc5oFwkK6 qoYkVvKl3k2miQLjUxYfEwJO++Lh79xUmNgLJ5YhOrdFIMCpB1byOh+SQWJq0Glu L2BzA2u3Xqyfrq0SLwkQwsT5kl6UfCajh+YJsW4DpnXr5wCXGroEsIMyg= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBXX5fjJFFk6i5LAQ--.10226S7; Tue, 02 May 2023 22:57:48 +0800 (CST) From: Ruihan Li To: linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Ruihan Li Subject: [PATCH v3 5/6] Bluetooth: Unlink CISes when LE disconnects in hci_conn_del Date: Tue, 2 May 2023 22:57:36 +0800 Message-Id: <20230502145737.140856-6-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230502145737.140856-1-lrh2000@pku.edu.cn> References: <20230502145737.140856-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 X-CM-TRANSID: 5oFpogBXX5fjJFFk6i5LAQ--.10226S7 X-Coremail-Antispam: 1UD129KBjvJXoWxGF15ZrWDtFW8tw4DXw4ruFg_yoW5CFyUpa 43K3s7ur4kJwn3uFnYvay8AFsYvr1kAFy7Kr48Xw1Ut390qr1vyr4Fkw1qgrZ8Cr95Za4U ZF4jqr42gF15C3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9j1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UM28EF7xvwVC2 z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2vYz4IE04k24V AvwVAKI4IrM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xf McIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7 v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm -wCF04k20xvY0x0EwIxGrwCF04k20xvE74AGY7Cv6cx26w4UJr1UMxC20s026xCaFVCjc4 AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE 17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMI IF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4l IxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvf C2KfnxnUUI43ZEXa7VU1c4S5UUUUU== X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgETBVPy77xtsAAAs6 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Currently, hci_conn_del calls hci_conn_unlink for BR/EDR, (e)SCO, and CIS connections, i.e., everything except LE connections. However, if (e)SCO connections are unlinked when BR/EDR disconnects, CIS connections should also be unlinked when LE disconnects. In terms of disconnection behavior, CIS and (e)SCO connections are not too different. One peculiarity of CIS is that when CIS connections are disconnected, the CIS handle isn't deleted, as per [BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E] 7.1.6 Disconnect command: All SCO, eSCO, and CIS connections on a physical link should be disconnected before the ACL connection on the same physical connection is disconnected. If it does not, they will be implicitly disconnected as part of the ACL disconnection. ... Note: As specified in Section 7.7.5, on the Central, the handle for a CIS remains valid even after disconnection and, therefore, the Host can recreate a disconnected CIS at a later point in time using the same connection handle. This peculiarity has nothing to do with the code, as long as the current implementation always ties the CIS handle, the CIS connection, and the LE connection together in hci_link, and manually performs CIS deletion in cis_cleanup after CIS disconnections. Signed-off-by: Ruihan Li --- net/bluetooth/hci_conn.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index e76ebb50d..de553e062 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1092,7 +1092,9 @@ static void hci_conn_unlink(struct hci_conn *conn) * yet at this point. Delete it now, otherwise it is * possible for it to be stuck and can't be deleted. */ - if (child->handle == HCI_CONN_HANDLE_UNSET) + if ((child->type == SCO_LINK || + child->type == ESCO_LINK) && + child->handle == HCI_CONN_HANDLE_UNSET) hci_conn_del(child); } @@ -1119,11 +1121,17 @@ void hci_conn_del(struct hci_conn *conn) BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); + hci_conn_unlink(conn); + + /* hci_conn_unlink may trigger additional disc_work, so + * ensure to perform cancelling after that. + */ + cancel_delayed_work_sync(&conn->disc_work); + cancel_delayed_work_sync(&conn->auto_accept_work); cancel_delayed_work_sync(&conn->idle_work); if (conn->type == ACL_LINK) { - hci_conn_unlink(conn); /* Unacked frames */ hdev->acl_cnt += conn->sent; } else if (conn->type == LE_LINK) { @@ -1134,8 +1142,6 @@ void hci_conn_del(struct hci_conn *conn) else hdev->acl_cnt += conn->sent; } else { - hci_conn_unlink(conn); - /* Unacked ISO frames */ if (conn->type == ISO_LINK) { if (hdev->iso_pkts) @@ -1147,11 +1153,6 @@ void hci_conn_del(struct hci_conn *conn) } } - /* hci_conn_unlink may trigger additional disc_work, so - * ensure to perform cancelling after that. - */ - cancel_delayed_work_sync(&conn->disc_work); - if (conn->amp_mgr) amp_mgr_put(conn->amp_mgr); From patchwork Tue May 2 14:57:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruihan Li X-Patchwork-Id: 679171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CCB8C77B7E for ; Tue, 2 May 2023 14:58:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234512AbjEBO6B (ORCPT ); Tue, 2 May 2023 10:58:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233656AbjEBO6A (ORCPT ); Tue, 2 May 2023 10:58:00 -0400 Received: from pku.edu.cn (mx18.pku.edu.cn [162.105.129.181]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CDE91273C for ; Tue, 2 May 2023 07:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pku.edu.cn; s=dkim; h=Received:From:To:Cc:Subject:Date: Message-Id:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding; bh=5F7Xn4VuaYHkhG59E72wk6A+DGy1euMitS xWn5Qzcc4=; b=nvHp7qSt/32GAyT6oiapULjO84JpoJTv04/ae8muEZyZtbGJfM FmRbz1Qi/AIb99cgJyddc6Z+L+Lqn5cKIHcmC0c1RLqEm6ixN9221FPTxzKzMz5u 8+EGNja7B7f2FObgww++ZyvOLjBRoCPsfcc14qoxjHv5U+TEEygfJsVcE= Received: from localhost.localdomain (unknown [10.7.101.92]) by front01 (Coremail) with SMTP id 5oFpogBXX5fjJFFk6i5LAQ--.10226S8; Tue, 02 May 2023 22:57:48 +0800 (CST) From: Ruihan Li To: linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Johan Hedberg , Luiz Augusto von Dentz , Ruihan Li Subject: [PATCH v3 6/6] Bluetooth: Avoid recursion in hci_conn_unlink Date: Tue, 2 May 2023 22:57:37 +0800 Message-Id: <20230502145737.140856-7-lrh2000@pku.edu.cn> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230502145737.140856-1-lrh2000@pku.edu.cn> References: <20230502145737.140856-1-lrh2000@pku.edu.cn> MIME-Version: 1.0 X-CM-TRANSID: 5oFpogBXX5fjJFFk6i5LAQ--.10226S8 X-Coremail-Antispam: 1UD129KBjvJXoWxury8Cr17ZF4fWF1UJw1DWrg_yoW5XFy8pa 43Wa4fZr48twna9F42yw1DJrn0qr1kZFy3KryrJF1kJw4Fvw4qyr40k34UKry5ZrWkWFy7 AF4jqF18KF4UGw7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9j1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AE w4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2 IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UM28EF7xvwVC2 z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2vYz4IE04k24V AvwVAKI4IrM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xf McIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7 v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm -wCF04k20xvY0x0EwIxGrwCF04k20xvE74AGY7Cv6cx26w4UJr1UMxC20s026xCaFVCjc4 AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE 17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMI IF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4l IxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvf C2KfnxnUUI43ZEXa7VU1c4S5UUUUU== X-CM-SenderInfo: yssqiiarrvmko6sn3hxhgxhubq/1tbiAgEPBVPy77wh+AAds- Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Previously, hci_conn_unlink was implemented as a recursion function. To unlink physical connections (e.g. ACL/LE), it calls itself to unlink all its logical channels (e.g. SCO/eSCO/ISO). Recursion is not required. This patch refactors hci_conn_unlink into two functions, where hci_conn_unlink_parent takes a physical connection, checks out all its logical channels, and calls hci_conn_unlink_child for each logical channel to unlink it. Signed-off-by: Ruihan Li --- net/bluetooth/hci_conn.c | 55 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index de553e062..243d68a64 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1074,34 +1074,13 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, return conn; } -static void hci_conn_unlink(struct hci_conn *conn) +static void hci_conn_unlink_parent(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; bt_dev_dbg(hdev, "hcon %p", conn); - if (!conn->parent) { - struct hci_link *link, *t; - - list_for_each_entry_safe(link, t, &conn->link_list, list) { - struct hci_conn *child = link->conn; - - hci_conn_unlink(child); - - /* Due to race, SCO connection might be not established - * yet at this point. Delete it now, otherwise it is - * possible for it to be stuck and can't be deleted. - */ - if ((child->type == SCO_LINK || - child->type == ESCO_LINK) && - child->handle == HCI_CONN_HANDLE_UNSET) - hci_conn_del(child); - } - - return; - } - - if (!conn->link) + if (WARN_ON(!conn->link)) return; list_del_rcu(&conn->link->list); @@ -1115,6 +1094,36 @@ static void hci_conn_unlink(struct hci_conn *conn) conn->link = NULL; } +static void hci_conn_unlink_children(struct hci_conn *conn) +{ + struct hci_dev *hdev = conn->hdev; + struct hci_link *link, *t; + + bt_dev_dbg(hdev, "hcon %p", conn); + + list_for_each_entry_safe(link, t, &conn->link_list, list) { + struct hci_conn *child = link->conn; + + hci_conn_unlink_parent(child); + + /* Due to race, SCO connection might be not established + * yet at this point. Delete it now, otherwise it is + * possible for it to be stuck and can't be deleted. + */ + if (child->type == SCO_LINK || child->type == ESCO_LINK) + if (child->handle == HCI_CONN_HANDLE_UNSET) + hci_conn_del(child); + } +} + +static void hci_conn_unlink(struct hci_conn *conn) +{ + if (conn->parent) + hci_conn_unlink_parent(conn); + else + hci_conn_unlink_children(conn); +} + void hci_conn_del(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev;