Skip to content

Commit c28d2bf

Browse files
committed
Bluetooth: L2CAP: Fix result of L2CAP_ECRED_CONN_RSP when MTU is too short
Test L2CAP/ECFC/BV-26-C expect the response to L2CAP_ECRED_CONN_REQ with and MTU value < L2CAP_ECRED_MIN_MTU (64) to be L2CAP_CR_LE_INVALID_PARAMS rather than L2CAP_CR_LE_UNACCEPT_PARAMS. Also fix not including the correct number of CIDs in the response since the spec requires all CIDs being rejected to be included in the response. Link: bluez/bluez#1868 Fixes: 15f02b9 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 7accb1c commit c28d2bf

2 files changed

Lines changed: 11 additions & 9 deletions

File tree

include/net/bluetooth/l2cap.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,9 @@ struct l2cap_conn_rsp {
284284
#define L2CAP_CR_LE_BAD_KEY_SIZE 0x0007
285285
#define L2CAP_CR_LE_ENCRYPTION 0x0008
286286
#define L2CAP_CR_LE_INVALID_SCID 0x0009
287-
#define L2CAP_CR_LE_SCID_IN_USE 0X000A
288-
#define L2CAP_CR_LE_UNACCEPT_PARAMS 0X000B
289-
#define L2CAP_CR_LE_INVALID_PARAMS 0X000C
287+
#define L2CAP_CR_LE_SCID_IN_USE 0x000A
288+
#define L2CAP_CR_LE_UNACCEPT_PARAMS 0x000B
289+
#define L2CAP_CR_LE_INVALID_PARAMS 0x000C
290290

291291
/* connect/create channel status */
292292
#define L2CAP_CS_NO_INFO 0x0000

net/bluetooth/l2cap_core.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5051,13 +5051,15 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
50515051
struct l2cap_chan *chan, *pchan;
50525052
u16 mtu, mps;
50535053
__le16 psm;
5054-
u8 result, len = 0;
5054+
u8 result, rsp_len = 0;
50555055
int i, num_scid;
50565056
bool defer = false;
50575057

50585058
if (!enable_ecred)
50595059
return -EINVAL;
50605060

5061+
memset(pdu, 0, sizeof(*pdu));
5062+
50615063
if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) {
50625064
result = L2CAP_CR_LE_INVALID_PARAMS;
50635065
goto response;
@@ -5066,6 +5068,9 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
50665068
cmd_len -= sizeof(*req);
50675069
num_scid = cmd_len / sizeof(u16);
50685070

5071+
/* Always respond with the same number of scids as in the request */
5072+
rsp_len = cmd_len;
5073+
50695074
if (num_scid > L2CAP_ECRED_MAX_CID) {
50705075
result = L2CAP_CR_LE_INVALID_PARAMS;
50715076
goto response;
@@ -5075,7 +5080,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
50755080
mps = __le16_to_cpu(req->mps);
50765081

50775082
if (mtu < L2CAP_ECRED_MIN_MTU || mps < L2CAP_ECRED_MIN_MPS) {
5078-
result = L2CAP_CR_LE_UNACCEPT_PARAMS;
5083+
result = L2CAP_CR_LE_INVALID_PARAMS;
50795084
goto response;
50805085
}
50815086

@@ -5095,8 +5100,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
50955100

50965101
BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
50975102

5098-
memset(pdu, 0, sizeof(*pdu));
5099-
51005103
/* Check if we have socket listening on psm */
51015104
pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
51025105
&conn->hcon->dst, LE_LINK);
@@ -5121,7 +5124,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
51215124
BT_DBG("scid[%d] 0x%4.4x", i, scid);
51225125

51235126
pdu->dcid[i] = 0x0000;
5124-
len += sizeof(*pdu->dcid);
51255127

51265128
/* Check for valid dynamic CID range */
51275129
if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
@@ -5188,7 +5190,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
51885190
return 0;
51895191

51905192
l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP,
5191-
sizeof(*pdu) + len, pdu);
5193+
sizeof(*pdu) + rsp_len, pdu);
51925194

51935195
return 0;
51945196
}

0 commit comments

Comments
 (0)