Created
May 23, 2023 19:03
-
-
Save Vudentz/e513859ecb31e79c947dfcb4b5c60453 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c | |
index 376b523c7b26..ae397c6819d9 100644 | |
--- a/net/bluetooth/l2cap_core.c | |
+++ b/net/bluetooth/l2cap_core.c | |
@@ -4634,6 +4634,26 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, | |
return err; | |
} | |
+static struct l2cap_chan *l2cap_del_chan_by_scid(struct l2cap_conn *conn, | |
+ u16 cid, int err) | |
+{ | |
+ struct l2cap_chan *c; | |
+ | |
+ mutex_lock(&conn->chan_lock); | |
+ c = __l2cap_get_chan_by_scid(conn, cid); | |
+ if (c) { | |
+ /* Only lock if chan reference is not 0 */ | |
+ c = l2cap_chan_hold_unless_zero(c); | |
+ if (c) { | |
+ l2cap_chan_lock(c); | |
+ l2cap_chan_del(c, err); | |
+ } | |
+ } | |
+ mutex_unlock(&conn->chan_lock); | |
+ | |
+ return c; | |
+} | |
+ | |
static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |
struct l2cap_cmd_hdr *cmd, u16 cmd_len, | |
u8 *data) | |
@@ -4651,7 +4671,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |
BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); | |
- chan = l2cap_get_chan_by_scid(conn, dcid); | |
+ chan = l2cap_del_chan_by_scid(conn, dcid, ECONNRESET); | |
if (!chan) { | |
cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid); | |
return 0; | |
@@ -4662,11 +4682,6 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |
l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); | |
chan->ops->set_shutdown(chan); | |
- | |
- mutex_lock(&conn->chan_lock); | |
- l2cap_chan_del(chan, ECONNRESET); | |
- mutex_unlock(&conn->chan_lock); | |
- | |
chan->ops->close(chan); | |
l2cap_chan_unlock(chan); | |
@@ -4691,10 +4706,9 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, | |
BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); | |
- chan = l2cap_get_chan_by_scid(conn, scid); | |
- if (!chan) { | |
+ chan = l2cap_del_chan_by_scid(conn, scid, 0); | |
+ if (!chan) | |
return 0; | |
- } | |
if (chan->state != BT_DISCONN) { | |
l2cap_chan_unlock(chan); | |
@@ -4702,10 +4716,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, | |
return 0; | |
} | |
- mutex_lock(&conn->chan_lock); | |
- l2cap_chan_del(chan, 0); | |
- mutex_unlock(&conn->chan_lock); | |
- | |
chan->ops->close(chan); | |
l2cap_chan_unlock(chan); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment