Dear developers,
We recently identified a potential issue in the Nimble controller. Please let us know if you need any additional information. We would also be happy to submit a patch to help resolve this issue.
Please kindly find the description and suggested fix below.
Description
Apache Mynewt NimBLE BLE Controller contains an improper input validation vulnerability in the handling of LL_CHANNEL_MAP_IND control PDUs.
In ble_ll_ctrl_rx_chanmap_req():
|
static int |
|
ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) |
|
{ |
|
uint16_t instant; |
|
uint16_t conn_events; |
|
|
|
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) |
|
if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { |
|
return BLE_LL_CTRL_UNKNOWN_RSP; |
|
} |
|
#endif |
|
|
|
/* If instant is in the past, we have to end the connection */ |
|
instant = get_le16(dptr + BLE_LL_CHAN_MAP_LEN); |
|
conn_events = (instant - connsm->event_cntr) & 0xFFFF; |
|
if (conn_events >= 32767) { |
|
ble_ll_conn_timeout(connsm, BLE_ERR_INSTANT_PASSED); |
|
} else { |
|
connsm->chanmap_instant = instant; |
|
memcpy(connsm->req_chanmap, dptr, BLE_LL_CHAN_MAP_LEN); |
|
connsm->flags.chanmap_update_sched = 1; |
|
} |
|
|
|
return BLE_ERR_MAX; |
the received 5-byte channel map (dptr[0..4]) is copied directly into connsm->req_chanmap using memcpy() without validation.
No validation is performed to ensure that the channel map contains a valid number of enabled data channels.
Impact
An attacker acting as a malicious or non-compliant central device can send a crafted LL_CHANNEL_MAP_IND control PDU with an invalid channel map (ChM) field consisting entirely of zeros.
When the channel map is applied, the controller executes the following path:
ble_ll_conn_next_event()
→ ble_ll_conn_calc_dci()
→ ble_ll_conn_calc_dci_csa1()
→ ble_ll_utils_remapped_channel()
Inside ble_ll_utils_remapped_channel():
|
ble_ll_utils_chan_map_remap(const uint8_t *chan_map, uint8_t remap_index) |
|
{ |
|
uint8_t cntr; |
|
uint8_t mask; |
|
uint8_t usable_chans; |
|
uint8_t chan; |
|
int i, j; |
|
|
|
/* NOTE: possible to build a map but this would use memory. For now, |
|
* we just calculate |
|
* Iterate through channel map to find this channel |
|
*/ |
|
chan = 0; |
|
cntr = 0; |
|
for (i = 0; i < BLE_LL_CHMAP_LEN; i++) { |
|
usable_chans = chan_map[i]; |
|
if (usable_chans != 0) { |
|
mask = 0x01; |
|
for (j = 0; j < 8; j++) { |
|
if (usable_chans & mask) { |
|
if (cntr == remap_index) { |
|
return (chan + j); |
|
} |
|
++cntr; |
|
} |
|
mask <<= 1; |
|
} |
|
} |
|
chan += 8; |
|
} |
|
|
|
/* we should never reach here */ |
|
BLE_LL_ASSERT(0); |
|
return 0; |
|
} |
The implementation assumes that the channel map contains at least one enabled data channel. When the channel map is all zeros, no valid channel can be selected, and the function reaches: BLE_LL_ASSERT(0);
This results in a denial of service (DoS).
Suggested patch for this issue
According to the Bluetooth Core Specification (Vol 6, Part B), the minimum number of used channels in the channel map shall be 2. Therefore, an all-zero channel map is invalid.
Specifically, the fix should validate the ChM field in ble_ll_ctrl_rx_chanmap_req() before copying it into connsm->req_chanmap. Channel maps with fewer than two enabled channels should be rejected, and the connection should be terminated with BLE_ERR_INV_LMP_LL_PARM.
Reference(s)
- Bluetooth Core Specification Vol 6, Part B, Section 4.5.8 (Channel Map Update)
- Apache NimBLE source:
ble_ll_ctrl_rx_chanmap_req
ble_ll_utils_remapped_channel
Additional info
We identified this issue by rehosting the NimBLE controller and performing over-the-air–like testing with injected malformed Link Layer control PDUs.
Dear developers,
We recently identified a potential issue in the Nimble controller. Please let us know if you need any additional information. We would also be happy to submit a patch to help resolve this issue.
Please kindly find the description and suggested fix below.
Description
Apache Mynewt NimBLE BLE Controller contains an improper input validation vulnerability in the handling of
LL_CHANNEL_MAP_INDcontrol PDUs.In
ble_ll_ctrl_rx_chanmap_req():mynewt-nimble/nimble/controller/src/ble_ll_ctrl.c
Lines 2474 to 2497 in 55c2d46
the received 5-byte channel map (
dptr[0..4]) is copied directly intoconnsm->req_chanmapusingmemcpy()without validation.No validation is performed to ensure that the channel map contains a valid number of enabled data channels.
Impact
An attacker acting as a malicious or non-compliant central device can send a crafted LL_CHANNEL_MAP_IND control PDU with an invalid channel map (ChM) field consisting entirely of zeros.
When the channel map is applied, the controller executes the following path:
Inside
ble_ll_utils_remapped_channel():mynewt-nimble/nimble/controller/src/ble_ll_utils.c
Lines 217 to 251 in 55c2d46
The implementation assumes that the channel map contains at least one enabled data channel. When the channel map is all zeros, no valid channel can be selected, and the function reaches: BLE_LL_ASSERT(0);
This results in a denial of service (DoS).
Suggested patch for this issue
According to the Bluetooth Core Specification (Vol 6, Part B), the minimum number of used channels in the channel map shall be 2. Therefore, an all-zero channel map is invalid.
Specifically, the fix should validate the
ChMfield inble_ll_ctrl_rx_chanmap_req()before copying it intoconnsm->req_chanmap. Channel maps with fewer than two enabled channels should be rejected, and the connection should be terminated withBLE_ERR_INV_LMP_LL_PARM.Reference(s)
ble_ll_ctrl_rx_chanmap_reqble_ll_utils_remapped_channelAdditional info
We identified this issue by rehosting the NimBLE controller and performing over-the-air–like testing with injected malformed Link Layer control PDUs.