From patchwork Tue Jun 30 15:36:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Grigorev X-Patchwork-Id: 222973 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0226C433E3 for ; Tue, 30 Jun 2020 15:42:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 98D4D2074F for ; Tue, 30 Jun 2020 15:42:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389638AbgF3Pmk (ORCPT ); Tue, 30 Jun 2020 11:42:40 -0400 Received: from mxout03.lancloud.ru ([89.108.73.187]:43326 "EHLO mxout03.lancloud.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389639AbgF3Pmj (ORCPT ); Tue, 30 Jun 2020 11:42:39 -0400 Received: from LanCloud DKIM-Filter: OpenDKIM Filter v2.11.0 mxout03.lancloud.ru 06A7820A5394 Received: from LanCloud Received: from LanCloud Received: by spb1wst017.omp.ru (Postfix, from userid 10000) id 7B56CBA1D4A; Tue, 30 Jun 2020 18:36:41 +0300 (MSK) From: Denis Grigorev To: CC: Subject: [PATCH 3.16 03/10] Bluetooth: L2CAP ERTM shutdown protect sk and chan Date: Tue, 30 Jun 2020 18:36:34 +0300 Message-ID: <20200630153641.21004-4-d.grigorev@omprussia.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200630153641.21004-1-d.grigorev@omprussia.ru> References: <20200630153641.21004-1-d.grigorev@omprussia.ru> MIME-Version: 1.0 X-Originating-IP: [81.3.167.34] X-ClientProxiedBy: LFEXT01.lancloud.ru (fd00:f066::141) To LFEX09.lancloud.ru (fd00:f066::59) Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Dean Jenkins During execution of l2cap_sock_shutdown() which might sleep, the sk and chan structures can be in an unlocked condition which potentially allows the structures to be freed by other running threads. Therefore, there is a possibility of a malfunction or memory reuse after being freed. Keep the sk and chan structures alive during the execution of l2cap_sock_shutdown() by using their respective hold and put functions. This allows the structures to be freeable at the end of l2cap_sock_shutdown(). Signed-off-by: Kautuk Consul Signed-off-by: Dean Jenkins Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_sock.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 071d35c9f3b4..e56d34f027dd 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1092,7 +1092,12 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) if (!sk) return 0; + /* prevent sk structure from being freed whilst unlocked */ + sock_hold(sk); + chan = l2cap_pi(sk)->chan; + /* prevent chan structure from being freed whilst unlocked */ + l2cap_chan_hold(chan); conn = chan->conn; if (conn) @@ -1126,6 +1131,9 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) if (conn) mutex_unlock(&conn->chan_lock); + l2cap_chan_put(chan); + sock_put(sk); + return err; } From patchwork Tue Jun 30 15:36:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Grigorev X-Patchwork-Id: 222975 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2977C433E0 for ; Tue, 30 Jun 2020 15:42:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C5C882074F for ; Tue, 30 Jun 2020 15:42:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389640AbgF3Pmj (ORCPT ); Tue, 30 Jun 2020 11:42:39 -0400 Received: from mxout03.lancloud.ru ([89.108.73.187]:43312 "EHLO mxout03.lancloud.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389635AbgF3Pmj (ORCPT ); Tue, 30 Jun 2020 11:42:39 -0400 X-Greylist: delayed 355 seconds by postgrey-1.27 at vger.kernel.org; Tue, 30 Jun 2020 11:42:38 EDT Received: from LanCloud DKIM-Filter: OpenDKIM Filter v2.11.0 mxout03.lancloud.ru AB4CB20A539E Received: from LanCloud Received: from LanCloud Received: by spb1wst017.omp.ru (Postfix, from userid 10000) id 82949BA1D4F; Tue, 30 Jun 2020 18:36:41 +0300 (MSK) From: Denis Grigorev To: CC: Subject: [PATCH 3.16 05/10] Bluetooth: Add BT_DBG to l2cap_sock_shutdown() Date: Tue, 30 Jun 2020 18:36:36 +0300 Message-ID: <20200630153641.21004-6-d.grigorev@omprussia.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200630153641.21004-1-d.grigorev@omprussia.ru> References: <20200630153641.21004-1-d.grigorev@omprussia.ru> MIME-Version: 1.0 X-Originating-IP: [81.3.167.34] X-ClientProxiedBy: LFEXT01.lancloud.ru (fd00:f066::141) To LFEX09.lancloud.ru (fd00:f066::59) Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Dean Jenkins Add helpful BT_DBG debug to l2cap_sock_shutdown() and __l2cap_wait_ack() so that the code flow can be analysed. Signed-off-by: Dean Jenkins Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_sock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 6c351b43bb42..662835fe0e95 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1057,6 +1057,8 @@ static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan) add_wait_queue(sk_sleep(sk), &wait); set_current_state(TASK_INTERRUPTIBLE); do { + BT_DBG("Waiting for %d ACKs", chan->unacked_frames); + if (!timeo) timeo = HZ/5; @@ -1138,6 +1140,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) l2cap_chan_put(chan); sock_put(sk); + BT_DBG("err: %d", err); + return err; } From patchwork Tue Jun 30 15:36:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Grigorev X-Patchwork-Id: 222977 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6DED8C433E0 for ; Tue, 30 Jun 2020 15:36:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4921B20675 for ; Tue, 30 Jun 2020 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389403AbgF3Pgp (ORCPT ); Tue, 30 Jun 2020 11:36:45 -0400 Received: from mxout04.lancloud.ru ([89.108.124.63]:47962 "EHLO mxout04.lancloud.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389571AbgF3Pgo (ORCPT ); Tue, 30 Jun 2020 11:36:44 -0400 Received: from LanCloud DKIM-Filter: OpenDKIM Filter v2.11.0 mxout04.lancloud.ru 61C5D208B9E1 Received: from LanCloud Received: from LanCloud Received: by spb1wst017.omp.ru (Postfix, from userid 10000) id 84EFEBA1D59; Tue, 30 Jun 2020 18:36:41 +0300 (MSK) From: Denis Grigorev To: CC: Subject: [PATCH 3.16 06/10] Bluetooth: __l2cap_wait_ack() use msecs_to_jiffies() Date: Tue, 30 Jun 2020 18:36:37 +0300 Message-ID: <20200630153641.21004-7-d.grigorev@omprussia.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200630153641.21004-1-d.grigorev@omprussia.ru> References: <20200630153641.21004-1-d.grigorev@omprussia.ru> MIME-Version: 1.0 X-Originating-IP: [81.3.167.34] X-ClientProxiedBy: LFEXT01.lancloud.ru (fd00:f066::141) To LFEX09.lancloud.ru (fd00:f066::59) Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Dean Jenkins Use msecs_to_jiffies() instead of using HZ so that it is easier to specify the time in milliseconds. Also add a #define L2CAP_WAIT_ACK_POLL_PERIOD to specify the 200ms polling period so that it is defined in a single place. Signed-off-by: Dean Jenkins Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_sock.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 4abdcb220e3a..430381ba7e5e 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -54,6 +54,7 @@ #define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) #define L2CAP_MOVE_TIMEOUT msecs_to_jiffies(4000) #define L2CAP_MOVE_ERTX_TIMEOUT msecs_to_jiffies(60000) +#define L2CAP_WAIT_ACK_POLL_PERIOD msecs_to_jiffies(200) #define L2CAP_A2MP_DEFAULT_MTU 670 diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 662835fe0e95..0bd277fba24e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1052,7 +1052,7 @@ static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan) { DECLARE_WAITQUEUE(wait, current); int err = 0; - int timeo = HZ/5; + int timeo = L2CAP_WAIT_ACK_POLL_PERIOD; add_wait_queue(sk_sleep(sk), &wait); set_current_state(TASK_INTERRUPTIBLE); @@ -1060,7 +1060,7 @@ static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan) BT_DBG("Waiting for %d ACKs", chan->unacked_frames); if (!timeo) - timeo = HZ/5; + timeo = L2CAP_WAIT_ACK_POLL_PERIOD; if (signal_pending(current)) { err = sock_intr_errno(timeo); From patchwork Tue Jun 30 15:36:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Grigorev X-Patchwork-Id: 222976 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0257C433E2 for ; Tue, 30 Jun 2020 15:36:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D226F2074F for ; Tue, 30 Jun 2020 15:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389569AbgF3Pgp (ORCPT ); Tue, 30 Jun 2020 11:36:45 -0400 Received: from mxout04.lancloud.ru ([89.108.124.63]:47986 "EHLO mxout04.lancloud.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389575AbgF3Pgp (ORCPT ); Tue, 30 Jun 2020 11:36:45 -0400 Received: from LanCloud DKIM-Filter: OpenDKIM Filter v2.11.0 mxout04.lancloud.ru A3949208BA01 Received: from LanCloud Received: from LanCloud Received: by spb1wst017.omp.ru (Postfix, from userid 10000) id 8C220BA1D5A; Tue, 30 Jun 2020 18:36:41 +0300 (MSK) From: Denis Grigorev To: CC: Subject: [PATCH 3.16 07/10] Bluetooth: __l2cap_wait_ack() add defensive timeout Date: Tue, 30 Jun 2020 18:36:38 +0300 Message-ID: <20200630153641.21004-8-d.grigorev@omprussia.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200630153641.21004-1-d.grigorev@omprussia.ru> References: <20200630153641.21004-1-d.grigorev@omprussia.ru> MIME-Version: 1.0 X-Originating-IP: [81.3.167.34] X-ClientProxiedBy: LFEXT01.lancloud.ru (fd00:f066::141) To LFEX09.lancloud.ru (fd00:f066::59) Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Dean Jenkins Add a timeout to prevent the do while loop running in an infinite loop. This ensures that the channel will be instructed to close within 10 seconds so prevents l2cap_sock_shutdown() getting stuck forever. Returns -ENOLINK when the timeout is reached. The channel will be subequently closed and not all data will be ACK'ed. Signed-off-by: Dean Jenkins Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_sock.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 430381ba7e5e..7bdf16944df3 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -55,6 +55,7 @@ #define L2CAP_MOVE_TIMEOUT msecs_to_jiffies(4000) #define L2CAP_MOVE_ERTX_TIMEOUT msecs_to_jiffies(60000) #define L2CAP_WAIT_ACK_POLL_PERIOD msecs_to_jiffies(200) +#define L2CAP_WAIT_ACK_TIMEOUT msecs_to_jiffies(10000) #define L2CAP_A2MP_DEFAULT_MTU 670 diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 0bd277fba24e..00b43f008941 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1053,11 +1053,15 @@ static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan) DECLARE_WAITQUEUE(wait, current); int err = 0; int timeo = L2CAP_WAIT_ACK_POLL_PERIOD; + /* Timeout to prevent infinite loop */ + unsigned long timeout = jiffies + L2CAP_WAIT_ACK_TIMEOUT; add_wait_queue(sk_sleep(sk), &wait); set_current_state(TASK_INTERRUPTIBLE); do { - BT_DBG("Waiting for %d ACKs", chan->unacked_frames); + BT_DBG("Waiting for %d ACKs, timeout %04d ms", + chan->unacked_frames, time_after(jiffies, timeout) ? 0 : + jiffies_to_msecs(timeout - jiffies)); if (!timeo) timeo = L2CAP_WAIT_ACK_POLL_PERIOD; @@ -1076,6 +1080,11 @@ static int __l2cap_wait_ack(struct sock *sk, struct l2cap_chan *chan) if (err) break; + if (time_after(jiffies, timeout)) { + err = -ENOLINK; + break; + } + } while (chan->unacked_frames > 0 && chan->state == BT_CONNECTED); From patchwork Tue Jun 30 15:36:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Denis Grigorev X-Patchwork-Id: 222972 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18AB5C433E1 for ; Tue, 30 Jun 2020 15:42:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 038442074F for ; Tue, 30 Jun 2020 15:42:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389637AbgF3Pmm (ORCPT ); Tue, 30 Jun 2020 11:42:42 -0400 Received: from mxout03.lancloud.ru ([89.108.73.187]:43462 "EHLO mxout03.lancloud.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389641AbgF3Pmm (ORCPT ); Tue, 30 Jun 2020 11:42:42 -0400 Received: from LanCloud DKIM-Filter: OpenDKIM Filter v2.11.0 mxout03.lancloud.ru 9D97120A538E Received: from LanCloud Received: from LanCloud Received: by spb1wst017.omp.ru (Postfix, from userid 10000) id 9C754BA1D77; Tue, 30 Jun 2020 18:36:41 +0300 (MSK) From: Denis Grigorev To: CC: Subject: [PATCH 3.16 09/10] Bluetooth: Reorganize mutex lock in l2cap_sock_shutdown() Date: Tue, 30 Jun 2020 18:36:40 +0300 Message-ID: <20200630153641.21004-10-d.grigorev@omprussia.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200630153641.21004-1-d.grigorev@omprussia.ru> References: <20200630153641.21004-1-d.grigorev@omprussia.ru> MIME-Version: 1.0 X-Originating-IP: [81.3.167.34] X-ClientProxiedBy: LFEXT01.lancloud.ru (fd00:f066::141) To LFEX09.lancloud.ru (fd00:f066::59) Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Dean Jenkins This commit reorganizes the mutex lock and is now only protecting l2cap_chan_close(). This is now consistent with other places where l2cap_chan_close() is called. If a conn connection exists, call mutex_lock(&conn->chan_lock) before calling l2cap_chan_close() to ensure other L2CAP protocol operations do not interfere. Note that the conn structure has to be protected from being freed as it is possible for the connection to be disconnected whilst the locks are not held. This solution allows the mutex lock to be used even when the connection has just been disconnected. This commit also reduces the scope of chan locking. The only place where chan locking is needed is the call to l2cap_chan_close(chan, 0) which if necessary closes the channel. Therefore, move the l2cap_chan_lock(chan) and l2cap_chan_lock(chan) locking calls to around l2cap_chan_close(chan, 0). This allows __l2cap_wait_ack(sk, chan) to be called with no chan locks being held so L2CAP messaging over the ACL link can be done unimpaired. Signed-off-by: Dean Jenkins Signed-off-by: Harish Jenny K N Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_sock.c | 44 ++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 01e52bea698c..efc0326f6823 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1105,6 +1105,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) if (!sk) return 0; + lock_sock(sk); + if (sk->sk_shutdown) goto shutdown_already; @@ -1116,13 +1118,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) chan = l2cap_pi(sk)->chan; /* prevent chan structure from being freed whilst unlocked */ l2cap_chan_hold(chan); - conn = chan->conn; - if (conn) - mutex_lock(&conn->chan_lock); - - l2cap_chan_lock(chan); - lock_sock(sk); + BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); if (chan->mode == L2CAP_MODE_ERTM && chan->unacked_frames > 0 && @@ -1130,9 +1127,28 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) err = __l2cap_wait_ack(sk, chan); sk->sk_shutdown = SHUTDOWN_MASK; - release_sock(sk); + + l2cap_chan_lock(chan); + conn = chan->conn; + if (conn) + /* prevent conn structure from being freed */ + l2cap_conn_get(conn); + l2cap_chan_unlock(chan); + + if (conn) + /* mutex lock must be taken before l2cap_chan_lock() */ + mutex_lock(&conn->chan_lock); + + l2cap_chan_lock(chan); l2cap_chan_close(chan, 0); + l2cap_chan_unlock(chan); + + if (conn) { + mutex_unlock(&conn->chan_lock); + l2cap_conn_put(conn); + } + lock_sock(sk); if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && @@ -1140,20 +1156,16 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); + l2cap_chan_put(chan); + sock_put(sk); + +shutdown_already: if (!err && sk->sk_err) err = -sk->sk_err; release_sock(sk); - l2cap_chan_unlock(chan); - - if (conn) - mutex_unlock(&conn->chan_lock); - l2cap_chan_put(chan); - sock_put(sk); - -shutdown_already: - BT_DBG("err: %d", err); + BT_DBG("Sock shutdown complete err: %d", err); return err; }