From cbfa13544497904296afe1bdf19b8cfa6c160764 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 May 2024 09:06:40 +0200 Subject: [PATCH] 6.8-stable patches added patches: bluetooth-l2cap-fix-div-by-zero-in-l2cap_le_flowctl_init.patch bluetooth-l2cap-fix-slab-use-after-free-in-l2cap_connect.patch --- ...div-by-zero-in-l2cap_le_flowctl_init.patch | 445 ++++++++++++++++++ ...slab-use-after-free-in-l2cap_connect.patch | 118 +++++ queue-6.8/series | 2 + 3 files changed, 565 insertions(+) create mode 100644 queue-6.8/bluetooth-l2cap-fix-div-by-zero-in-l2cap_le_flowctl_init.patch create mode 100644 queue-6.8/bluetooth-l2cap-fix-slab-use-after-free-in-l2cap_connect.patch diff --git a/queue-6.8/bluetooth-l2cap-fix-div-by-zero-in-l2cap_le_flowctl_init.patch b/queue-6.8/bluetooth-l2cap-fix-div-by-zero-in-l2cap_le_flowctl_init.patch new file mode 100644 index 00000000000..db4e48303f5 --- /dev/null +++ b/queue-6.8/bluetooth-l2cap-fix-div-by-zero-in-l2cap_le_flowctl_init.patch @@ -0,0 +1,445 @@ +From a5b862c6a221459d54e494e88965b48dcfa6cc44 Mon Sep 17 00:00:00 2001 +From: Sungwoo Kim +Date: Sat, 4 May 2024 15:23:29 -0400 +Subject: Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() + +From: Sungwoo Kim + +commit a5b862c6a221459d54e494e88965b48dcfa6cc44 upstream. + +l2cap_le_flowctl_init() can cause both div-by-zero and an integer +overflow since hdev->le_mtu may not fall in the valid range. + +Move MTU from hci_dev to hci_conn to validate MTU and stop the connection +process earlier if MTU is invalid. +Also, add a missing validation in read_buffer_size() and make it return +an error value if the validation fails. +Now hci_conn_add() returns ERR_PTR() as it can fail due to the both a +kzalloc failure and invalid MTU value. + +divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI +CPU: 0 PID: 67 Comm: kworker/u5:0 Tainted: G W 6.9.0-rc5+ #20 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 +Workqueue: hci0 hci_rx_work +RIP: 0010:l2cap_le_flowctl_init+0x19e/0x3f0 net/bluetooth/l2cap_core.c:547 +Code: e8 17 17 0c 00 66 41 89 9f 84 00 00 00 bf 01 00 00 00 41 b8 02 00 00 00 4c +89 fe 4c 89 e2 89 d9 e8 27 17 0c 00 44 89 f0 31 d2 <66> f7 f3 89 c3 ff c3 4d 8d +b7 88 00 00 00 4c 89 f0 48 c1 e8 03 42 +RSP: 0018:ffff88810bc0f858 EFLAGS: 00010246 +RAX: 00000000000002a0 RBX: 0000000000000000 RCX: dffffc0000000000 +RDX: 0000000000000000 RSI: ffff88810bc0f7c0 RDI: ffffc90002dcb66f +RBP: ffff88810bc0f880 R08: aa69db2dda70ff01 R09: 0000ffaaaaaaaaaa +R10: 0084000000ffaaaa R11: 0000000000000000 R12: ffff88810d65a084 +R13: dffffc0000000000 R14: 00000000000002a0 R15: ffff88810d65a000 +FS: 0000000000000000(0000) GS:ffff88811ac00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000020000100 CR3: 0000000103268003 CR4: 0000000000770ef0 +PKRU: 55555554 +Call Trace: + + l2cap_le_connect_req net/bluetooth/l2cap_core.c:4902 [inline] + l2cap_le_sig_cmd net/bluetooth/l2cap_core.c:5420 [inline] + l2cap_le_sig_channel net/bluetooth/l2cap_core.c:5486 [inline] + l2cap_recv_frame+0xe59d/0x11710 net/bluetooth/l2cap_core.c:6809 + l2cap_recv_acldata+0x544/0x10a0 net/bluetooth/l2cap_core.c:7506 + hci_acldata_packet net/bluetooth/hci_core.c:3939 [inline] + hci_rx_work+0x5e5/0xb20 net/bluetooth/hci_core.c:4176 + process_one_work kernel/workqueue.c:3254 [inline] + process_scheduled_works+0x90f/0x1530 kernel/workqueue.c:3335 + worker_thread+0x926/0xe70 kernel/workqueue.c:3416 + kthread+0x2e3/0x380 kernel/kthread.c:388 + ret_from_fork+0x5c/0x90 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + +Modules linked in: +---[ end trace 0000000000000000 ]--- + +Fixes: 6ed58ec520ad ("Bluetooth: Use LE buffers for LE traffic") +Suggested-by: Luiz Augusto von Dentz +Signed-off-by: Sungwoo Kim +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + include/net/bluetooth/hci.h | 9 ++++ + include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 71 ++++++++++++++++++++++++++------------- + net/bluetooth/hci_event.c | 31 ++++++++++------- + net/bluetooth/iso.c | 2 - + net/bluetooth/l2cap_core.c | 17 +-------- + net/bluetooth/sco.c | 6 +-- + 7 files changed, 86 insertions(+), 51 deletions(-) + +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -1665,6 +1665,15 @@ struct hci_cp_le_set_event_mask { + __u8 mask[8]; + } __packed; + ++/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E ++ * 7.8.2 LE Read Buffer Size command ++ * MAX_LE_MTU is 0xffff. ++ * 0 is also valid. It means that no dedicated LE Buffer exists. ++ * It should use the HCI_Read_Buffer_Size command and mtu is shared ++ * between BR/EDR and LE. ++ */ ++#define HCI_MIN_LE_MTU 0x001b ++ + #define HCI_OP_LE_READ_BUFFER_SIZE 0x2002 + struct hci_rp_le_read_buffer_size { + __u8 status; +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -706,6 +706,7 @@ struct hci_conn { + __u16 handle; + __u16 sync_handle; + __u16 state; ++ __u16 mtu; + __u8 mode; + __u8 type; + __u8 role; +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -909,11 +909,37 @@ struct hci_conn *hci_conn_add(struct hci + { + struct hci_conn *conn; + ++ switch (type) { ++ case ACL_LINK: ++ if (!hdev->acl_mtu) ++ return ERR_PTR(-ECONNREFUSED); ++ break; ++ case ISO_LINK: ++ if (hdev->iso_mtu) ++ /* Dedicated ISO Buffer exists */ ++ break; ++ fallthrough; ++ case LE_LINK: ++ if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU) ++ return ERR_PTR(-ECONNREFUSED); ++ if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU) ++ return ERR_PTR(-ECONNREFUSED); ++ break; ++ case SCO_LINK: ++ case ESCO_LINK: ++ if (!hdev->sco_pkts) ++ /* Controller does not support SCO or eSCO over HCI */ ++ return ERR_PTR(-ECONNREFUSED); ++ break; ++ default: ++ return ERR_PTR(-ECONNREFUSED); ++ } ++ + bt_dev_dbg(hdev, "dst %pMR handle 0x%4.4x", dst, handle); + + conn = kzalloc(sizeof(*conn), GFP_KERNEL); + if (!conn) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + bacpy(&conn->dst, dst); + bacpy(&conn->src, &hdev->bdaddr); +@@ -944,10 +970,12 @@ struct hci_conn *hci_conn_add(struct hci + switch (type) { + case ACL_LINK: + conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK; ++ conn->mtu = hdev->acl_mtu; + break; + case LE_LINK: + /* conn->src should reflect the local identity address */ + hci_copy_identity_address(hdev, &conn->src, &conn->src_type); ++ conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; + break; + case ISO_LINK: + /* conn->src should reflect the local identity address */ +@@ -959,6 +987,8 @@ struct hci_conn *hci_conn_add(struct hci + else if (conn->role == HCI_ROLE_MASTER) + conn->cleanup = cis_cleanup; + ++ conn->mtu = hdev->iso_mtu ? hdev->iso_mtu : ++ hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu; + break; + case SCO_LINK: + if (lmp_esco_capable(hdev)) +@@ -966,9 +996,12 @@ struct hci_conn *hci_conn_add(struct hci + (hdev->esco_type & EDR_ESCO_MASK); + else + conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK; ++ ++ conn->mtu = hdev->sco_mtu; + break; + case ESCO_LINK: + conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK; ++ conn->mtu = hdev->sco_mtu; + break; + } + +@@ -1011,7 +1044,7 @@ struct hci_conn *hci_conn_add_unset(stru + + handle = hci_conn_hash_alloc_unset(hdev); + if (unlikely(handle < 0)) +- return NULL; ++ return ERR_PTR(-ECONNREFUSED); + + return hci_conn_add(hdev, type, dst, role, handle); + } +@@ -1317,8 +1350,8 @@ struct hci_conn *hci_connect_le(struct h + bacpy(&conn->dst, dst); + } else { + conn = hci_conn_add_unset(hdev, LE_LINK, dst, role); +- if (!conn) +- return ERR_PTR(-ENOMEM); ++ if (IS_ERR(conn)) ++ return conn; + hci_conn_hold(conn); + conn->pending_sec_level = sec_level; + } +@@ -1494,8 +1527,8 @@ static struct hci_conn *hci_add_bis(stru + return ERR_PTR(-EADDRINUSE); + + conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); +- if (!conn) +- return ERR_PTR(-ENOMEM); ++ if (IS_ERR(conn)) ++ return conn; + + conn->state = BT_CONNECT; + +@@ -1538,8 +1571,8 @@ struct hci_conn *hci_connect_le_scan(str + BT_DBG("requesting refresh of dst_addr"); + + conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER); +- if (!conn) +- return ERR_PTR(-ENOMEM); ++ if (IS_ERR(conn)) ++ return conn; + + if (hci_explicit_conn_params_set(hdev, dst, dst_type) < 0) { + hci_conn_del(conn); +@@ -1586,8 +1619,8 @@ struct hci_conn *hci_connect_acl(struct + acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!acl) { + acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER); +- if (!acl) +- return ERR_PTR(-ENOMEM); ++ if (IS_ERR(acl)) ++ return acl; + } + + hci_conn_hold(acl); +@@ -1655,9 +1688,9 @@ struct hci_conn *hci_connect_sco(struct + sco = hci_conn_hash_lookup_ba(hdev, type, dst); + if (!sco) { + sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER); +- if (!sco) { ++ if (IS_ERR(sco)) { + hci_conn_drop(acl); +- return ERR_PTR(-ENOMEM); ++ return sco; + } + } + +@@ -1847,8 +1880,8 @@ struct hci_conn *hci_bind_cis(struct hci + qos->ucast.cis); + if (!cis) { + cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER); +- if (!cis) +- return ERR_PTR(-ENOMEM); ++ if (IS_ERR(cis)) ++ return cis; + cis->cleanup = cis_cleanup; + cis->dst_type = dst_type; + cis->iso_qos.ucast.cig = BT_ISO_QOS_CIG_UNSET; +@@ -1983,14 +2016,8 @@ static void hci_iso_qos_setup(struct hci + struct bt_iso_io_qos *qos, __u8 phy) + { + /* Only set MTU if PHY is enabled */ +- if (!qos->sdu && qos->phy) { +- if (hdev->iso_mtu > 0) +- qos->sdu = hdev->iso_mtu; +- else if (hdev->le_mtu > 0) +- qos->sdu = hdev->le_mtu; +- else +- qos->sdu = hdev->acl_mtu; +- } ++ if (!qos->sdu && qos->phy) ++ qos->sdu = conn->mtu; + + /* Use the same PHY as ACL if set to any */ + if (qos->phy == BT_ISO_PHY_ANY) +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -954,6 +954,9 @@ static u8 hci_cc_read_buffer_size(struct + BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, + hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); + ++ if (!hdev->acl_mtu || !hdev->acl_pkts) ++ return HCI_ERROR_INVALID_PARAMETERS; ++ + return rp->status; + } + +@@ -1263,6 +1266,9 @@ static u8 hci_cc_le_read_buffer_size(str + + BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); + ++ if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU) ++ return HCI_ERROR_INVALID_PARAMETERS; ++ + return rp->status; + } + +@@ -2342,8 +2348,8 @@ static void hci_cs_create_conn(struct hc + if (!conn) { + conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr, + HCI_ROLE_MASTER); +- if (!conn) +- bt_dev_err(hdev, "no memory for new connection"); ++ if (IS_ERR(conn)) ++ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn)); + } + } + +@@ -3154,8 +3160,8 @@ static void hci_conn_complete_evt(struct + BDADDR_BREDR)) { + conn = hci_conn_add_unset(hdev, ev->link_type, + &ev->bdaddr, HCI_ROLE_SLAVE); +- if (!conn) { +- bt_dev_err(hdev, "no memory for new conn"); ++ if (IS_ERR(conn)) { ++ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn)); + goto unlock; + } + } else { +@@ -3343,8 +3349,8 @@ static void hci_conn_request_evt(struct + if (!conn) { + conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr, + HCI_ROLE_SLAVE); +- if (!conn) { +- bt_dev_err(hdev, "no memory for new connection"); ++ if (IS_ERR(conn)) { ++ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn)); + goto unlock; + } + } +@@ -3821,6 +3827,9 @@ static u8 hci_cc_le_read_buffer_size_v2( + BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu, + hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts); + ++ if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU) ++ return HCI_ERROR_INVALID_PARAMETERS; ++ + return rp->status; + } + +@@ -5912,8 +5921,8 @@ static void le_conn_complete_evt(struct + goto unlock; + + conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role); +- if (!conn) { +- bt_dev_err(hdev, "no memory for new connection"); ++ if (IS_ERR(conn)) { ++ bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn)); + goto unlock; + } + +@@ -7042,7 +7051,7 @@ static void hci_le_cis_req_evt(struct hc + if (!cis) { + cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE, + cis_handle); +- if (!cis) { ++ if (IS_ERR(cis)) { + hci_le_reject_cis(hdev, ev->cis_handle); + goto unlock; + } +@@ -7151,7 +7160,7 @@ static void hci_le_big_sync_established_ + if (!bis) { + bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY, + HCI_ROLE_SLAVE, handle); +- if (!bis) ++ if (IS_ERR(bis)) + continue; + } + +@@ -7223,7 +7232,7 @@ static void hci_le_big_info_adv_report_e + pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY, + HCI_ROLE_SLAVE); + +- if (!pa_sync) ++ if (IS_ERR(pa_sync)) + goto unlock; + + pa_sync->sync_handle = le16_to_cpu(ev->sync_handle); +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -1264,7 +1264,7 @@ static int iso_sock_sendmsg(struct socke + return -ENOTCONN; + } + +- mtu = iso_pi(sk)->conn->hcon->hdev->iso_mtu; ++ mtu = iso_pi(sk)->conn->hcon->mtu; + + release_sock(sk); + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -6241,7 +6241,7 @@ static int l2cap_finish_move(struct l2ca + BT_DBG("chan %p", chan); + + chan->rx_state = L2CAP_RX_STATE_RECV; +- chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; ++ chan->conn->mtu = chan->conn->hcon->mtu; + + return l2cap_resegment(chan); + } +@@ -6308,7 +6308,7 @@ static int l2cap_rx_state_wait_f(struct + */ + chan->next_tx_seq = control->reqseq; + chan->unacked_frames = 0; +- chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; ++ chan->conn->mtu = chan->conn->hcon->mtu; + + err = l2cap_resegment(chan); + +@@ -6848,18 +6848,7 @@ static struct l2cap_conn *l2cap_conn_add + + BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); + +- switch (hcon->type) { +- case LE_LINK: +- if (hcon->hdev->le_mtu) { +- conn->mtu = hcon->hdev->le_mtu; +- break; +- } +- fallthrough; +- default: +- conn->mtu = hcon->hdev->acl_mtu; +- break; +- } +- ++ conn->mtu = hcon->mtu; + conn->feat_mask = 0; + + conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS; +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -126,7 +126,6 @@ static void sco_sock_clear_timer(struct + /* ---- SCO connections ---- */ + static struct sco_conn *sco_conn_add(struct hci_conn *hcon) + { +- struct hci_dev *hdev = hcon->hdev; + struct sco_conn *conn = hcon->sco_data; + + if (conn) { +@@ -144,9 +143,10 @@ static struct sco_conn *sco_conn_add(str + + hcon->sco_data = conn; + conn->hcon = hcon; ++ conn->mtu = hcon->mtu; + +- if (hdev->sco_mtu > 0) +- conn->mtu = hdev->sco_mtu; ++ if (hcon->mtu > 0) ++ conn->mtu = hcon->mtu; + else + conn->mtu = 60; + diff --git a/queue-6.8/bluetooth-l2cap-fix-slab-use-after-free-in-l2cap_connect.patch b/queue-6.8/bluetooth-l2cap-fix-slab-use-after-free-in-l2cap_connect.patch new file mode 100644 index 00000000000..672a0808b8c --- /dev/null +++ b/queue-6.8/bluetooth-l2cap-fix-slab-use-after-free-in-l2cap_connect.patch @@ -0,0 +1,118 @@ +From 4d7b41c0e43995b0e992b9f8903109275744b658 Mon Sep 17 00:00:00 2001 +From: Sungwoo Kim +Date: Tue, 30 Apr 2024 02:32:10 -0400 +Subject: Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Sungwoo Kim + +commit 4d7b41c0e43995b0e992b9f8903109275744b658 upstream. + +Extend a critical section to prevent chan from early freeing. +Also make the l2cap_connect() return type void. Nothing is using the +returned value but it is ugly to return a potentially freed pointer. +Making it void will help with backports because earlier kernels did use +the return value. Now the compile will break for kernels where this +patch is not a complete fix. + +Call stack summary: + +[use] +l2cap_bredr_sig_cmd + l2cap_connect + ┌ mutex_lock(&conn->chan_lock); + │ chan = pchan->ops->new_connection(pchan); <- alloc chan + │ __l2cap_chan_add(conn, chan); + │ l2cap_chan_hold(chan); + │ list_add(&chan->list, &conn->chan_l); ... (1) + └ mutex_unlock(&conn->chan_lock); + chan->conf_state ... (4) <- use after free + +[free] +l2cap_conn_del +┌ mutex_lock(&conn->chan_lock); +│ foreach chan in conn->chan_l: ... (2) +│ l2cap_chan_put(chan); +│ l2cap_chan_destroy +│ kfree(chan) ... (3) <- chan freed +└ mutex_unlock(&conn->chan_lock); + +================================================================== +BUG: KASAN: slab-use-after-free in instrument_atomic_read +include/linux/instrumented.h:68 [inline] +BUG: KASAN: slab-use-after-free in _test_bit +include/asm-generic/bitops/instrumented-non-atomic.h:141 [inline] +BUG: KASAN: slab-use-after-free in l2cap_connect+0xa67/0x11a0 +net/bluetooth/l2cap_core.c:4260 +Read of size 8 at addr ffff88810bf040a0 by task kworker/u3:1/311 + +Fixes: 73ffa904b782 ("Bluetooth: Move conf_{req,rsp} stuff to struct l2cap_chan") +Signed-off-by: Sungwoo Kim +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/l2cap_core.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -3905,13 +3905,12 @@ static inline int l2cap_command_rej(stru + return 0; + } + +-static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, +- struct l2cap_cmd_hdr *cmd, +- u8 *data, u8 rsp_code, u8 amp_id) ++static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, ++ u8 *data, u8 rsp_code, u8 amp_id) + { + struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; + struct l2cap_conn_rsp rsp; +- struct l2cap_chan *chan = NULL, *pchan; ++ struct l2cap_chan *chan = NULL, *pchan = NULL; + int result, status = L2CAP_CS_NO_INFO; + + u16 dcid = 0, scid = __le16_to_cpu(req->scid); +@@ -3924,7 +3923,7 @@ static struct l2cap_chan *l2cap_connect( + &conn->hcon->dst, ACL_LINK); + if (!pchan) { + result = L2CAP_CR_BAD_PSM; +- goto sendresp; ++ goto response; + } + + mutex_lock(&conn->chan_lock); +@@ -4011,17 +4010,15 @@ static struct l2cap_chan *l2cap_connect( + } + + response: +- l2cap_chan_unlock(pchan); +- mutex_unlock(&conn->chan_lock); +- l2cap_chan_put(pchan); +- +-sendresp: + rsp.scid = cpu_to_le16(scid); + rsp.dcid = cpu_to_le16(dcid); + rsp.result = cpu_to_le16(result); + rsp.status = cpu_to_le16(status); + l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp); + ++ if (!pchan) ++ return; ++ + if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { + struct l2cap_info_req info; + info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); +@@ -4044,7 +4041,9 @@ sendresp: + chan->num_conf_req++; + } + +- return chan; ++ l2cap_chan_unlock(pchan); ++ mutex_unlock(&conn->chan_lock); ++ l2cap_chan_put(pchan); + } + + static int l2cap_connect_req(struct l2cap_conn *conn, diff --git a/queue-6.8/series b/queue-6.8/series index 124fb1ef0b6..3e4755ad1f0 100644 --- a/queue-6.8/series +++ b/queue-6.8/series @@ -2,3 +2,5 @@ drm-amd-display-fix-division-by-zero-in-setup_dsc_config.patch net-ks8851-fix-another-tx-stall-caused-by-wrong-isr-flag-handling.patch ice-pass-vsi-pointer-into-ice_vc_isvalid_q_id.patch ice-remove-unnecessary-duplicate-checks-for-vf-vsi-id.patch +bluetooth-l2cap-fix-slab-use-after-free-in-l2cap_connect.patch +bluetooth-l2cap-fix-div-by-zero-in-l2cap_le_flowctl_init.patch -- 2.47.3