2023-03-10 00:01:05

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH 1/2] Bluetooth: L2CAP: Fix responding with wrong PDU type

From: Luiz Augusto von Dentz <[email protected]>

L2CAP_ECRED_CONN_REQ shall be responded with L2CAP_ECRED_CONN_RSP not
L2CAP_LE_CONN_RSP:

L2CAP LE EATT Server - Reject - run
Listening for connections
New client connection with handle 0x002a
Sending L2CAP Request from client
Client received response code 0x15
Unexpected L2CAP response code (expected 0x18)
L2CAP LE EATT Server - Reject - test failed

> ACL Data RX: Handle 42 flags 0x02 dlen 26
LE L2CAP: Enhanced Credit Connection Request (0x17) ident 1 len 18
PSM: 39 (0x0027)
MTU: 64
MPS: 64
Credits: 5
Source CID: 65
Source CID: 66
Source CID: 67
Source CID: 68
Source CID: 69
< ACL Data TX: Handle 42 flags 0x00 dlen 16
LE L2CAP: LE Connection Response (0x15) ident 1 len 8
invalid size
00 00 00 00 00 00 06 00

L2CAP LE EATT Server - Reject - run
Listening for connections
New client connection with handle 0x002a
Sending L2CAP Request from client
Client received response code 0x18
L2CAP LE EATT Server - Reject - test passed

Signed-off-by: Luiz Augusto von Dentz <[email protected]>
---
net/bluetooth/l2cap_core.c | 133 ++++++++++++++++++++++++-------------
1 file changed, 87 insertions(+), 46 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index adfc3ea06d08..49926f59cc12 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -708,6 +708,17 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
}
EXPORT_SYMBOL_GPL(l2cap_chan_del);

+static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id,
+ l2cap_chan_func_t func, void *data)
+{
+ struct l2cap_chan *chan, *l;
+
+ list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+ if (chan->ident == id)
+ func(chan, data);
+ }
+}
+
static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
void *data)
{
@@ -775,23 +786,9 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)

static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan)
{
- struct l2cap_conn *conn = chan->conn;
- struct l2cap_ecred_conn_rsp rsp;
- u16 result;
-
- if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
- result = L2CAP_CR_LE_AUTHORIZATION;
- else
- result = L2CAP_CR_LE_BAD_PSM;
-
l2cap_state_change(chan, BT_DISCONN);

- memset(&rsp, 0, sizeof(rsp));
-
- rsp.result = cpu_to_le16(result);
-
- l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
- &rsp);
+ __l2cap_ecred_conn_rsp_defer(chan);
}

static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
@@ -846,7 +843,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
break;
case L2CAP_MODE_EXT_FLOWCTL:
l2cap_chan_ecred_connect_reject(chan);
- break;
+ return;
}
}
}
@@ -3938,43 +3935,86 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
&rsp);
}

-void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
{
- struct {
- struct l2cap_ecred_conn_rsp rsp;
- __le16 dcid[5];
- } __packed pdu;
- struct l2cap_conn *conn = chan->conn;
- u16 ident = chan->ident;
- int i = 0;
+ int *result = data;

- if (!ident)
+ if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
return;

- BT_DBG("chan %p ident %d", chan, ident);
-
- pdu.rsp.mtu = cpu_to_le16(chan->imtu);
- pdu.rsp.mps = cpu_to_le16(chan->mps);
- pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
- pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
-
- mutex_lock(&conn->chan_lock);
-
- list_for_each_entry(chan, &conn->chan_l, list) {
- if (chan->ident != ident)
- continue;
-
- /* Reset ident so only one response is sent */
- chan->ident = 0;
-
- /* Include all channels pending with the same ident */
- pdu.dcid[i++] = cpu_to_le16(chan->scid);
+ switch (chan->state) {
+ case BT_CONNECT2:
+ /* If channel still pending accept add to result */
+ (*result)++;
+ return;
+ case BT_CONNECTED:
+ return;
+ default:
+ /* If not connected or pending accept it has been refused */
+ *result = -ECONNREFUSED;
+ return;
}
+}

- mutex_unlock(&conn->chan_lock);
+struct l2cap_ecred_rsp_data {
+ struct {
+ struct l2cap_ecred_conn_rsp rsp;
+ __le16 scid[L2CAP_ECRED_MAX_CID];
+ } __packed pdu;
+ int count;
+};

- l2cap_send_cmd(conn, ident, L2CAP_ECRED_CONN_RSP,
- sizeof(pdu.rsp) + i * sizeof(__le16), &pdu);
+static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
+{
+ struct l2cap_ecred_rsp_data *rsp = data;
+
+ if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
+ return;
+
+ /* Reset ident so only one response is sent */
+ chan->ident = 0;
+
+ /* Include all channels pending with the same ident */
+ if (!rsp->pdu.rsp.result)
+ rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid);
+ else
+ l2cap_chan_del(chan, ECONNRESET);
+}
+
+void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+{
+ struct l2cap_conn *conn = chan->conn;
+ struct l2cap_ecred_rsp_data data;
+ u16 id = chan->ident;
+ int result = 0;
+
+ if (!id)
+ return;
+
+ BT_DBG("chan %p id %d", chan, id);
+
+ memset(&data, 0, sizeof(data));
+
+ data.pdu.rsp.mtu = cpu_to_le16(chan->imtu);
+ data.pdu.rsp.mps = cpu_to_le16(chan->mps);
+ data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
+ data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
+
+ /* Verify that all channels are ready */
+ __l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result);
+
+ if (result > 0)
+ return;
+
+ if (result < 0)
+ data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION);
+
+ /* Build response */
+ __l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data);
+
+ l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP,
+ sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)),
+ &data.pdu);
}

void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
@@ -6078,6 +6118,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));

chan->ident = cmd->ident;
+ chan->mode = L2CAP_MODE_EXT_FLOWCTL;

if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
l2cap_state_change(chan, BT_CONNECT2);
--
2.39.2



2023-03-10 01:34:30

by bluez.test.bot

[permalink] [raw]
Subject: RE: [1/2] Bluetooth: L2CAP: Fix responding with wrong PDU type

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=728435

---Test result---

Test Summary:
CheckPatch PASS 1.66 seconds
GitLint PASS 0.49 seconds
SubjectPrefix PASS 0.14 seconds
BuildKernel PASS 37.94 seconds
CheckAllWarning PASS 41.00 seconds
CheckSparse PASS 46.38 seconds
CheckSmatch PASS 125.41 seconds
BuildKernel32 PASS 36.22 seconds
TestRunnerSetup PASS 522.89 seconds
TestRunner_l2cap-tester PASS 18.55 seconds
TestRunner_iso-tester PASS 20.48 seconds
TestRunner_bnep-tester PASS 6.67 seconds
TestRunner_mgmt-tester PASS 126.45 seconds
TestRunner_rfcomm-tester PASS 10.46 seconds
TestRunner_sco-tester PASS 9.62 seconds
TestRunner_ioctl-tester PASS 11.35 seconds
TestRunner_mesh-tester PASS 8.34 seconds
TestRunner_smp-tester PASS 9.55 seconds
TestRunner_userchan-tester PASS 6.98 seconds
IncrementalBuild PASS 48.87 seconds



---
Regards,
Linux Bluetooth

2023-03-11 00:53:50

by patchwork-bot+bluetooth

[permalink] [raw]
Subject: Re: [PATCH 1/2] Bluetooth: L2CAP: Fix responding with wrong PDU type

Hello:

This series was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <[email protected]>:

On Thu, 9 Mar 2023 16:00:54 -0800 you wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> L2CAP_ECRED_CONN_REQ shall be responded with L2CAP_ECRED_CONN_RSP not
> L2CAP_LE_CONN_RSP:
>
> L2CAP LE EATT Server - Reject - run
> Listening for connections
> New client connection with handle 0x002a
> Sending L2CAP Request from client
> Client received response code 0x15
> Unexpected L2CAP response code (expected 0x18)
> L2CAP LE EATT Server - Reject - test failed
>
> [...]

Here is the summary with links:
- [1/2] Bluetooth: L2CAP: Fix responding with wrong PDU type
(no matching commit)
- [2/2] Bluetooth: L2CAP: Delay identity address updates
https://git.kernel.org/bluetooth/bluetooth-next/c/1c991f006035

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html