Skip to content

Commit 4c976e3

Browse files
HaavardReinordicjm
authored andcommitted
[nrf fromtree] Bluetooth: Host: Add conn rsp param check
Check whether the connection response parameters both with and without ECRED are within the valid ranges from the Bluetooth Core Specification (part 3.A.4 v6.0). Changes validation checks in requests to match the same pattern. Signed-off-by: Håvard Reierstad <[email protected]> (cherry picked from commit 7debc8a) Signed-off-by: Håvard Reierstad <[email protected]>
1 parent b07b1bb commit 4c976e3

File tree

3 files changed

+60
-9
lines changed

3 files changed

+60
-9
lines changed

include/zephyr/bluetooth/l2cap.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,20 @@ extern "C" {
111111
*/
112112
#define BT_L2CAP_ECRED_MIN_MPS 64
113113

114+
/** @brief L2CAP maximum MTU
115+
*
116+
* The maximum MTU for an L2CAP Based Connection. This is the same with or without ECRED. This
117+
* requirement is taken from text in Core 3.A.4.22 and 3.A.4.26 v6.0.
118+
*/
119+
#define BT_L2CAP_MAX_MTU UINT16_MAX
120+
121+
/** @brief L2CAP maximum MPS
122+
*
123+
* The maximum MPS for an L2CAP Based Connection. This is the same with or without ECRED. This
124+
* requirement is taken from text in Core 3.A.4.22 and 3.A.4.26 v6.0.
125+
*/
126+
#define BT_L2CAP_MAX_MPS 65533
127+
114128
/** @brief The maximum number of channels in ECRED L2CAP signaling PDUs
115129
*
116130
* Currently, this is the maximum number of channels referred to in the

subsys/bluetooth/host/l2cap.c

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,11 +1479,6 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
14791479

14801480
LOG_DBG("psm 0x%02x scid 0x%04x mtu %u mps %u credits %u", psm, scid, mtu, mps, credits);
14811481

1482-
if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS) {
1483-
LOG_ERR("Invalid LE-Conn Req params: mtu %u mps %u", mtu, mps);
1484-
return;
1485-
}
1486-
14871482
buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CONN_RSP, ident,
14881483
sizeof(*rsp));
14891484
if (!buf) {
@@ -1493,6 +1488,16 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
14931488
rsp = net_buf_add(buf, sizeof(*rsp));
14941489
(void)memset(rsp, 0, sizeof(*rsp));
14951490

1491+
/* Validate parameters. Requirements are from Core Spec v6.0, Vol 3.A.4.22. Valid credit
1492+
* range is from 0 to UINT16_MAX, thus no credit validation is needed.
1493+
*/
1494+
if (!IN_RANGE(mtu, L2CAP_LE_MIN_MTU, BT_L2CAP_MAX_MTU) ||
1495+
!IN_RANGE(mps, L2CAP_LE_MIN_MPS, BT_L2CAP_MAX_MPS)) {
1496+
LOG_ERR("Invalid le conn req params: mtu %u mps %u", mtu, mps);
1497+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
1498+
goto rsp;
1499+
}
1500+
14961501
/* Check if there is a server registered */
14971502
server = bt_l2cap_server_lookup_psm(psm);
14981503
if (!server) {
@@ -1578,8 +1583,12 @@ static void le_ecred_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
15781583

15791584
LOG_DBG("psm 0x%02x mtu %u mps %u credits %u", psm, mtu, mps, credits);
15801585

1581-
if (mtu < BT_L2CAP_ECRED_MIN_MTU || mps < BT_L2CAP_ECRED_MIN_MPS) {
1582-
LOG_ERR("Invalid ecred conn req params. mtu %u mps %u", mtu, mps);
1586+
/* Validate parameters. Requirements are from Core Spec v6.0, Vol 3.A.4.25. */
1587+
if (!IN_RANGE(mtu, BT_L2CAP_ECRED_MIN_MTU, BT_L2CAP_MAX_MTU) ||
1588+
!IN_RANGE(mps, BT_L2CAP_ECRED_MIN_MPS, BT_L2CAP_MAX_MPS) ||
1589+
!IN_RANGE(credits, BT_L2CAP_ECRED_CREDITS_MIN, BT_L2CAP_ECRED_CREDITS_MAX)) {
1590+
LOG_ERR("Invalid le ecred conn req params: mtu %u mps %u credits %u", mtu, mps,
1591+
credits);
15831592
result = BT_L2CAP_LE_ERR_INVALID_PARAMS;
15841593
goto response;
15851594
}
@@ -1982,13 +1991,24 @@ static void le_ecred_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
19821991

19831992
LOG_DBG("dcid 0x%04x", dcid);
19841993

1985-
/* If a Destination CID is 0x0000, the channel was not
1994+
/* Validate parameters before assignment. Requirements are from Core Spec
1995+
* v6.0, Vol 3.A.4.26. If a Destination CID is 0x0000, the channel was not
19861996
* established.
19871997
*/
1988-
if (!dcid) {
1998+
if (dcid == 0U) {
19891999
bt_l2cap_chan_remove(conn, &chan->chan);
19902000
bt_l2cap_chan_del(&chan->chan);
19912001
continue;
2002+
} else if (!L2CAP_LE_CID_IS_DYN(dcid) ||
2003+
!IN_RANGE(mtu, BT_L2CAP_ECRED_MIN_MTU, BT_L2CAP_MAX_MTU) ||
2004+
!IN_RANGE(mps, BT_L2CAP_ECRED_MIN_MPS, BT_L2CAP_MAX_MPS) ||
2005+
!IN_RANGE(credits, BT_L2CAP_ECRED_CREDITS_MIN,
2006+
BT_L2CAP_ECRED_CREDITS_MAX)) {
2007+
LOG_WRN("Invalid ecred conn rsp params: dcid 0x%04x mtu %u mps %u "
2008+
"credits %u. Disconnecting.",
2009+
dcid, mtu, mps, credits);
2010+
bt_conn_disconnect(conn, BT_HCI_ERR_UNACCEPT_CONN_PARAM);
2011+
return;
19922012
}
19932013

19942014
c = bt_l2cap_le_lookup_tx_cid(conn, dcid);
@@ -2086,6 +2106,20 @@ static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
20862106

20872107
switch (result) {
20882108
case BT_L2CAP_LE_SUCCESS:
2109+
/* Validate parameters on successful connection. Requirements are from Core Spec
2110+
* v6.0, Vol 3.A.4.23. Valid credit range is from 0 to UINT16_MAX, thus no credit
2111+
* validation is needed.
2112+
*/
2113+
if ((!L2CAP_LE_CID_IS_DYN(dcid) ||
2114+
!IN_RANGE(mtu, L2CAP_LE_MIN_MTU, BT_L2CAP_MAX_MTU) ||
2115+
!IN_RANGE(mps, L2CAP_LE_MIN_MPS, BT_L2CAP_MAX_MPS))) {
2116+
LOG_WRN("Invalid conn rsp params: dcid 0x%04x mtu %u mps %u. "
2117+
"Disconnecting.",
2118+
dcid, mtu, mps);
2119+
bt_conn_disconnect(conn, BT_HCI_ERR_UNACCEPT_CONN_PARAM);
2120+
return;
2121+
}
2122+
20892123
chan->tx.cid = dcid;
20902124
chan->tx.mtu = mtu;
20912125
chan->tx.mps = mps;

subsys/bluetooth/host/l2cap_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ struct bt_l2cap_le_credits {
125125
uint16_t credits;
126126
} __packed;
127127

128+
#define BT_L2CAP_ECRED_CREDITS_MIN 1
129+
#define BT_L2CAP_ECRED_CREDITS_MAX UINT16_MAX
130+
128131
#define BT_L2CAP_ECRED_CONN_REQ 0x17
129132
struct bt_l2cap_ecred_conn_req {
130133
uint16_t psm;

0 commit comments

Comments
 (0)