Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: https://github.com/bluez/bluez/issues/1868
Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

+11 -9
+3 -3
include/net/bluetooth/l2cap.h
··· 284 284 #define L2CAP_CR_LE_BAD_KEY_SIZE 0x0007 285 285 #define L2CAP_CR_LE_ENCRYPTION 0x0008 286 286 #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 290 290 291 291 /* connect/create channel status */ 292 292 #define L2CAP_CS_NO_INFO 0x0000
+8 -6
net/bluetooth/l2cap_core.c
··· 5051 5051 struct l2cap_chan *chan, *pchan; 5052 5052 u16 mtu, mps; 5053 5053 __le16 psm; 5054 - u8 result, len = 0; 5054 + u8 result, rsp_len = 0; 5055 5055 int i, num_scid; 5056 5056 bool defer = false; 5057 5057 5058 5058 if (!enable_ecred) 5059 5059 return -EINVAL; 5060 + 5061 + memset(pdu, 0, sizeof(*pdu)); 5060 5062 5061 5063 if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) { 5062 5064 result = L2CAP_CR_LE_INVALID_PARAMS; ··· 5067 5065 5068 5066 cmd_len -= sizeof(*req); 5069 5067 num_scid = cmd_len / sizeof(u16); 5068 + 5069 + /* Always respond with the same number of scids as in the request */ 5070 + rsp_len = cmd_len; 5070 5071 5071 5072 if (num_scid > L2CAP_ECRED_MAX_CID) { 5072 5073 result = L2CAP_CR_LE_INVALID_PARAMS; ··· 5080 5075 mps = __le16_to_cpu(req->mps); 5081 5076 5082 5077 if (mtu < L2CAP_ECRED_MIN_MTU || mps < L2CAP_ECRED_MIN_MPS) { 5083 - result = L2CAP_CR_LE_UNACCEPT_PARAMS; 5078 + result = L2CAP_CR_LE_INVALID_PARAMS; 5084 5079 goto response; 5085 5080 } 5086 5081 ··· 5099 5094 } 5100 5095 5101 5096 BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps); 5102 - 5103 - memset(pdu, 0, sizeof(*pdu)); 5104 5097 5105 5098 /* Check if we have socket listening on psm */ 5106 5099 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, ··· 5124 5121 BT_DBG("scid[%d] 0x%4.4x", i, scid); 5125 5122 5126 5123 pdu->dcid[i] = 0x0000; 5127 - len += sizeof(*pdu->dcid); 5128 5124 5129 5125 /* Check for valid dynamic CID range */ 5130 5126 if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { ··· 5190 5188 return 0; 5191 5189 5192 5190 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP, 5193 - sizeof(*pdu) + len, pdu); 5191 + sizeof(*pdu) + rsp_len, pdu); 5194 5192 5195 5193 return 0; 5196 5194 }