Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix l2cap_channels OOB in get_channel_for_cid #2081

Merged
merged 1 commit into from Jul 21, 2022

Conversation

Scepticz
Copy link
Contributor

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.

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.
@nfi nfi merged commit 3216ebf into contiki-ng:develop Jul 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants