]> www.infradead.org Git - users/hch/misc.git/commitdiff
Bluetooth: L2CAP: Fix L2CAP_ECRED_CONN_RSP response
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 14 Feb 2025 15:30:25 +0000 (10:30 -0500)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 20 Feb 2025 18:25:11 +0000 (13:25 -0500)
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: https://github.com/bluez/bluez/issues/1094
Fixes: 9aa9d9473f15 ("Bluetooth: L2CAP: Fix responding with wrong PDU type")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/l2cap_core.c

index fec11e576f310cda115c924245458368a663528a..b22078b679726db0599000dcb4f6e2c3e753cff1 100644 (file)
@@ -632,7 +632,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
            test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
                hci_conn_hold(conn->hcon);
 
-       list_add(&chan->list, &conn->chan_l);
+       /* Append to the list since the order matters for ECRED */
+       list_add_tail(&chan->list, &conn->chan_l);
 }
 
 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)
        struct l2cap_ecred_conn_rsp *rsp_flex =
                container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr);
 
-       if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+       /* Check if channel for outgoing connection or if it wasn't deferred
+        * since in those cases it must be skipped.
+        */
+       if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) ||
+           !test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
                return;
 
        /* Reset ident so only one response is sent */