Skip to content

Commit 57f5b75

Browse files
committed
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). Signed-off-by: Håvard Reierstad <[email protected]>
1 parent 322da1d commit 57f5b75

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

include/zephyr/bluetooth/l2cap.h

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

114+
/** @brief L2CAP maximum MPS
115+
*
116+
* The maximum MPS 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_MPS 65533
120+
114121
/** @brief The maximum number of channels in ECRED L2CAP signaling PDUs
115122
*
116123
* Currently, this is the maximum number of channels referred to in the

subsys/bluetooth/host/l2cap.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,6 +1929,22 @@ static void le_ecred_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
19291929

19301930
LOG_DBG("mtu 0x%04x mps 0x%04x credits 0x%04x result %u", mtu, mps, credits, result);
19311931

1932+
/* Validate parameters on successful connection. There are no limits for
1933+
* credits as values from 0 to UINT16_MAX are valid.
1934+
*/
1935+
if (result == BT_L2CAP_LE_SUCCESS) {
1936+
if (!L2CAP_LE_CID_IS_DYN(dcid)) {
1937+
LOG_ERR("dcid 0x%04x is not dynamic", dcid);
1938+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
1939+
} else if (!IN_RANGE(mtu, BT_L2CAP_ECRED_MIN_MTU, UINT16_MAX)) {
1940+
LOG_ERR("Invalid mtu %u", mtu);
1941+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
1942+
} else if (!IN_RANGE(mps, BT_L2CAP_ECRED_MIN_MPS, BT_L2CAP_MAX_MPS)) {
1943+
LOG_ERR("Invalid mps %u", mps);
1944+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
1945+
}
1946+
}
1947+
19321948
chan = l2cap_lookup_ident(conn, ident);
19331949
if (chan) {
19341950
psm = chan->psm;
@@ -2059,6 +2075,22 @@ static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
20592075
LOG_DBG("dcid 0x%04x mtu %u mps %u credits %u result 0x%04x", dcid, mtu, mps, credits,
20602076
result);
20612077

2078+
/* Validate parameters on successful connection. There are no limits for
2079+
* credits as values from 0 to UINT16_MAX are valid.
2080+
*/
2081+
if (result == BT_L2CAP_LE_SUCCESS) {
2082+
if (!L2CAP_LE_CID_IS_DYN(dcid)) {
2083+
LOG_ERR("dcid 0x%04x is not dynamic", dcid);
2084+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
2085+
} else if (!IN_RANGE(mtu, L2CAP_LE_MIN_MTU, UINT16_MAX)) {
2086+
LOG_ERR("Invalid mtu: %u", mtu);
2087+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
2088+
} else if (!IN_RANGE(mps, L2CAP_LE_MIN_MPS, BT_L2CAP_MAX_MPS)) {
2089+
LOG_ERR("Invalid mps: %u", mps);
2090+
result = BT_L2CAP_LE_ERR_UNACCEPT_PARAMS;
2091+
}
2092+
}
2093+
20622094
/* Keep the channel in case of security errors */
20632095
if (result == BT_L2CAP_LE_SUCCESS ||
20642096
result == BT_L2CAP_LE_ERR_AUTHENTICATION ||

0 commit comments

Comments
 (0)