Zephyr OS is an Apache licensed real-time operating system project backed by the Linux Foundation and many big industry vendors. Zephyr is mainly used in embedded and resource-constrained systems. It supports a very wide variety of boards with different CPU architectures including ARM Cortex-M, Intel x86, ARC, NIOS II, Tensilica Xtensa, SPARC V8, and RISC-V 32. Zephyr’s native network stack supports multiple protocols including LwM2M, BSD sockets, OpenThread, full Bluetooth LE stack including Link Layer (LL), and Bluetooth Mesh.
The Bluetooth stack is split into two main components: host and controller. Zephyr’s Bluetooth LE controller is used as a part of the Black Duck Defensics Bluetooth LE fuzzing solution. To ensure the highest quality and security of our product, Zephyr’s Bluetooth LE stack’s lowest layers were fuzz tested using Defensics Bluetooth LE test suites.
Eight different vulnerabilities were discovered in the Bluetooth LE Link Layer and L2CAP implementation. The vulnerabilities can be divided into three high-level categories:
CVE ID | Vulnerability type | Host / Controller | Description |
CVE-2021-3430 | Freeze | Controller | Assertion failure on repeated LL_CONNECTION_PARAM_REQ |
CVE-2021-3431 | Freeze | Controller | Assertion failure on certain repeated LL packets |
CVE-2021-3432 | Freeze | Controller | Invalid interval in CONNECT_IND leads to Division by Zero |
CVE-2021-3433 | Deadlock | Controller | Invalid channel map in CONNECT_IND results to Deadlock |
CVE-2021-3434 | Freeze | Host | L2CAP: Stack based buffer overflow in le_ecred_conn_req() |
CVE-2021-3435 | Information leak | Host | L2CAP: Information leakage in le_ecred_conn_req() |
CVE-2021-3454 | Freeze | Host | L2CAP: Truncated L2CAP K-frame causes assertion failure |
CVE-2021-3455 | Freeze | Host | Disconnecting L2CAP channel right after invalid ATT request leads to use-after-free |
All the reported vulnerabilities can be triggered from within the range of Bluetooth LE. Triggering the vulnerability does not require authentication or encryption. The only requirement is that the device is in advertising mode and accepting connections.
The attacker is able to disrupt all ongoing communication and create a denial-of-service situation caused by reachable assertion by sending repeated LL_CONNECTION_PARAM_REQ packets to any Zephyr-based Bluetooth LE device that is advertising and connectable.
The attacker is able to disrupt all ongoing communication and create a denial-of-service situation caused by reachable assertion by sending repeated LL_FEATURE_REQ, LL_PING_REQ, LL_LENGTH_REQ, or LL_PHY_REQ packets to any Zephyr-based Bluetooth LE device that is advertising and connectable.
The attacker is able to disrupt all ongoing communication and create a denial-of-service situation caused by division by zero by sending an invalid interval value in a CONNECT_IND packet to any Zephyr-based Bluetooth LE device that is advertising and connectable.
The attacker is able to create a denial-of-service situation caused by deadlock by sending an invalid channel map value in a CONNECT_IND packet to any Zephyr-based Bluetooth LE device that is advertising and connectable.
The attacker is able to create a denial-of-service situation at minimum, but could also potentially achieve remote code execution by exploiting the stack-based buffer overflow in Zephyr’s L2CAP implementation.
The attacker is able to read potentially confidential information, up to 6 bytes of uninitialized memory content, by sending one malformed L2CAP_CREDIT_BASED_CONNECTION_REQ packet. The request can be repeated to gain more data.
The attacker is able to disrupt all ongoing communication and create a denial-of-service situation caused by reachable assertion by sending a truncated L2CAP K-frame packet to any Zephyr-based Bluetooth LE device that is advertising and connectable.
The attacker is able to create a denial-of-service situation at minimum, but also potentially achieve remote code execution by exploiting the use-after-free in Zephyr’s L2CAP implementation.
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-46h3-hjcq-2jjr
The assertion failure happened in ull_conn.c inside a ctlr_rx() function because the implementation did not clearly allow two connection parameters request procedures to be initiated by the central device at the same time. This is the correct behavior from specification point of view, but there should be a less destructive way to handle that. If the assertions were disabled, this test case would not cause problems.
This issue was resolved by replacing the assert with a comment and marking the buffer ready to be released. The fix was introduced in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/33272
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-7548-5m6f-mqv9
The assertion failure happened in the Nordic’s implementation of the lower Link Layer in lll_conn.c, isr_done() because of the Link Layer control procedure transaction collision. If the assertions were disabled, we saw a denial-of-service situation because the stack went into state, and it did not restart advertising after disconnection. Reboot is needed to recover.
Fixing this required adding new a locking mechanism for Link Layer control procedures. The fix was introduced in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/33340
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-7364-p4wc-8mj4
Function ull_slave_setup() in ull-slave.c did not check if the interval value was in valid range. CONNECT_IND with an interval value set to 0x0000 causes division by zero, leading to freeze.
This vulnerability was fixed in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/33278
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-3c2f-w4v6-qxrp
Error handling of the ull_slave_setup() function in ull-slave.c was not working properly. There were two places where the function did an early return if it detected an invalid channel map value in CONNEC_IND PDU to prevent misbehavior or freeze. The problem was that the early return did not seem to be enough, as the device did not resume advertising after rejecting the connection when it received a channel map value with all zeros.
Freeze on channel map value 0x000000 was initially found in the Sweyntooth bundle of vulnerabilities and it was partially fixed with these commits:
https://github.com/zephyrproject-rtos/zephyr/commit/4a5f263e5a658bb35c1dd9215fe62939f175c859
https://github.com/zephyrproject-rtos/zephyr/commit/94d5f0854e491e594c2040fe0f061850848081fc
This vulnerability was fixed in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/33278
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-8w87-6rfp-cfrm
Function le_ecred_conn_req() did not check if the size of the incoming L2CAP_CREDIT_BASED_CONNECTION_REQ was too big and interpreted the overflowing data as a huge list of source CIDs. At the beginning of the function, variable chan is allocated memory from stack for L2CAP_ECRED_CHAN_MAX number of pointers to bt_l2cap_chan structs. Variable dcid is allocated memory from stack for L2CAP_ECRED_CHAN_MAX number of uint16_t values. L2CAP_ECRED_CHAN_MAX has been defined to be 5.
Later, the buffer overflow happened when l2cap_chan_accept() was called for all the source CIDs one by one. This didn’t yet freeze the execution. Another overflow happened on line 1152 where dcid is overflown.
Finally, there was another buffer overflow when constructing the L2CAP_CREDIT_BASED_CONNECTION_RSP, which then caused the freeze.
Enabling assertions led to assertion failure when trying to copy too much data into an outgoing L2CAP_CREDIT_BASED_CONNECTION_RSP packet.
This vulnerability was fixed in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/33305
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-xhg3-gvj6-4rqh
Bug laid on the line where the value for i is calculated. This line did not take into account that if the connection request packet was too small, the buf still contains the whole packet, not just the source CIDs.
Later, uninitialized memory content was copied into the buffer of the outgoing packet.
Variable dcid is allocated from the stack. An uninitialized array could contain anything that happens to be in this memory location, for example, encryption keys.
This vulnerability was fixed in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/33305
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-fx88-6c29-vrp3
This happened because in the l2cap_chan_le_recv() function, when getting the SDU length from the buffer, the length of the buffer is not checked, and a later call to net_buf_pull_le16(buf) leads to assertion. If assertions were disabled, the SDU length would be calculated wrong and the packet would soon be dropped due to invalid SDU length.
This vulnerability was fixed in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/32588
Zephyr security advisory: https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-7g38-3x9v-v7vp
When the central device connected to the peripheral and created an L2CAP connection for enhanced ATT, it sent some invalid ATT requests and disconnected, which immediately caused a freeze. This happened because the L2CAP channel was already in a disconnected state when the Zephyr stack called sent callback l2cap_chan_sdu_sent() and further bt_att_sent(). In bt_att_sent() freeze happens because the already freed memory block is being accessed.
This vulnerability was fixed in this pull request: https://github.com/zephyrproject-rtos/zephyr/pull/35597
Product manufacturers using the Zephyr OS in their product are encouraged to update their Zephyr version to include latest security fixes. Zephyr’s security policy guarantees that security patches are backported to the two most recent releases and to active LTS release. For non-LTS Zephyr versions, manufacturers may need to take care of backporting the security patches themselves.
End users with products that include the firmware based on vulnerable Zephyr OS versions are strongly encouraged to upgrade to latest firmware version available from the vendor.
Matias Karhumaa from the Black Duck Cybersecurity Research Center (CyRC) in Oulu, Finland, discovered these weaknesses with Defensics Bluetooth LE LL peripheral test suite and Bluetooth LE L2CAP server test suite.
Black Duck would like to thank the Zephyr security team and the maintainers of Zephyr Bluetooth subsystem for their responsiveness and for great cooperation.