The truncation of an integer representing a Bluetooth L2CAP Channel Identifier leads to an out-of-bounds channel access.
Proposed Security Advisory Text:
# Impact
While processing the L2CAP protocol, the Bluetooth Low Energy stack of Contiki-NG needs to map an incoming channel id to its metadata structure. While looking up the corresponding channel structure in get_channel_for_cid (in os/net/mac/ble/ble-l2cap.c), a bounds check is performed on the incoming channel id which is meant to ensure that the channel id does not exceed the maximum number of supported channels.
However, an integer truncation issue leads to only the lowest byte of the channel id to be checked, which leads to an incomplete out-of-bounds check. A crafted channel id leads to out-of-bounds memory to be read and written with attacker-controlled data.
integer truncation issue in get_channel_for_cid:
While the bounds check is performed on l2cap_channel_count
, only the lower byte is checked due to the uint8_t data type. Afterwards, the expression for i
is re-calculated without the explicit data type, which means without truncation into 8 bits. Instead, the full 16-bit value is used as the channel index. This pointer will point out-of-bounds of the channel array.
This leads to a large 16 out-of-bounds channel id to be used as an index into the array for large CID inputs.
Sample value: 0xff41 -> 0xff41 - 0x41 = 0xff00 == 0x00 (as uint8_t)
This results in out-of-bounds memory to be interpreted as a channel object, and this memory to potentially be corrupted in the following call to input_l2cap_frame_flow_channel
, which fills the out-of-bounds memory (the supposed channel object) with user-supplied data.
The fix here is to re-use the i
variable as an index, which was used to perform the bounds check, and is truncated to 8 bits.
As a side note, due to the unsignedness of the data type uint8_t i
, the check i >= 0
is always true. Instead, a signed data type such as int16_t
could be used to make the check take effect.
As out-of-bounds memory potentially gets corrupted with user-supplied data, this issue is likely exploitable for remote code execution.
Aready fixed in https://github.com/contiki-ng/contiki-ng/commit/3216ebf59e698b6dc71d0ba3e8052d5d5e09d2bd
Fix suggestion was: Re-use checked value instead of re-computing it without truncation.