Skip to content

Commit b25120e

Browse files
committed
Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response
L2CAP_ECRED_CONN_RSP needs to respond DCID in the same order received as SCID but the order is reversed due to use of list_add which actually prepend channels to the list so the response is reversed: > ACL Data RX: Handle 16 flags 0x02 dlen 26 LE L2CAP: Enhanced Credit Connection Request (0x17) ident 2 len 18 PSM: 39 (0x0027) MTU: 256 MPS: 251 Credits: 65535 Source CID: 116 Source CID: 117 Source CID: 118 Source CID: 119 Source CID: 120 < ACL Data TX: Handle 16 flags 0x00 dlen 26 LE L2CAP: Enhanced Credit Connection Response (0x18) ident 2 len 18 MTU: 517 MPS: 247 Credits: 3 Result: Connection successful (0x0000) Destination CID: 68 Destination CID: 67 Destination CID: 66 Destination CID: 65 Destination CID: 64 Also make sure the response don't include channels that are not on BT_CONNECT2 since the chan->ident can be set to the same value as in the following trace: < ACL Data TX: Handle 16 flags 0x00 dlen 12 LE L2CAP: LE Flow Control Credit (0x16) ident 6 len 4 Source CID: 64 Credits: 1 ... > ACL Data RX: Handle 16 flags 0x02 dlen 18 LE L2CAP: Enhanced Credit Connection Request (0x17) ident 6 len 10 PSM: 39 (0x0027) MTU: 517 MPS: 251 Credits: 255 Source CID: 70 < ACL Data TX: Handle 16 flags 0x00 dlen 20 LE L2CAP: Enhanced Credit Connection Response (0x18) ident 6 len 12 MTU: 517 MPS: 247 Credits: 3 Result: Connection successful (0x0000) Destination CID: 64 Destination CID: 68 Closes: bluez/bluez#1094 Fixes: 9aa9d94 ("Bluetooth: L2CAP: Fix responding with wrong PDU type") Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent bd30e8d commit b25120e

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

net/bluetooth/l2cap_core.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
632632
test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
633633
hci_conn_hold(conn->hcon);
634634

635-
list_add(&chan->list, &conn->chan_l);
635+
/* Append to the list since the order matters for ECRED */
636+
list_add_tail(&chan->list, &conn->chan_l);
636637
}
637638

638639
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
@@ -3771,7 +3772,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
37713772
struct l2cap_ecred_conn_rsp *rsp_flex =
37723773
container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr);
37733774

3774-
if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
3775+
/* Check if channel for outgoing connection or if it wasn't deferred
3776+
* since in those cases it must be skipped.
3777+
*/
3778+
if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) ||
3779+
!test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
37753780
return;
37763781

37773782
/* Reset ident so only one response is sent */

0 commit comments

Comments
 (0)