Skip to content

Latest commit

 

History

History
39 lines (22 loc) · 5.23 KB

CVE-2023-1423-hci-isr-invalid-alloc-nullptr.md

File metadata and controls

39 lines (22 loc) · 5.23 KB

HCI Priority Event Handling Misses Allocation Error Handling

Disclaimer: Our finding of this issue has been reproduced in our fuzzer on a target built from commit e1dddf7befa7309bd2afc567b2e00d2e7362f7c4. The original target was CVE-2021-3329 (which can be built via this script). Based on reviewing the source code, we concluded that the issue still applies as of the latest commit at time of writing (commit f19e6d481164420ed758f5c07d879aa75da93eed).

Summary

Processing of priority packets in the bluetooth HCI drivers may lead to a blocking buffer allocation (with a timeout K_FOREVER). In an ISR, this may lead to an unexpected failed allocation followed by a nullptr deref.

Description

The bluetooth h4 ISR handles sending and receiving packets from the bluetooth controller over the HCI. Incoming packets are received read from the controller and written to a FIFO list for further processing in the rx-thread. For high priority packets the processing can take place in the ISR. Incoming packets can may also trigger new outgoing packets, which are allocated from a pool. When the allocation pool is exhausted the current thread waits until a new buffer is available. However this does not work within the ISR context, as the PendSV interrupt is not immediately raised and therefore an nullptr is returned instead. This is in violation of the allocation API as the timeout K_FOREVER garanties a valid buffer is returned and the code therefore omits nullptr checks leading to a crash.

Processing of the incoming packets happens in the following call chain:

bt_uart_isr => process_rx => read_payload => bt_recv_prio => hci_event_prio => handle_event

The packets can contain a command done (hci_cmd_status => hci_cmd_done), which can trigger a bt_hci_host_num_completed_packets (report_completed_packet in old version) due to the defined unref-handler.

This will result in the creation of a new command BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS with bt_hci_cmd_create. This allocates a new buffer from hci_cmd_pool with timeout K_FOREVER using net_buf_alloc. When the pool is empty the previously mentioned behaviour of arch_swap unable to raise a PendSV interrupt happens and the issue unfolds. In contrast allocations made "directly" in the ISR use K_NO_WAIT and perform NULL checks, e.g. in read_payload.

We did observe crashes in net_buf_simple_reserve during buf->data update during fuzzing:

Frame net_buf_simple_reserve [ pc: 0000a582, ra: 000022d2 (bt_buf_set_type) ]
└─ ROM Access (Write) [ pc: 0000a586 (net_buf_simple_reserve), size: 4, address: 00000008, value: 00001985 (z_arm_hard_fault)]

Impact

A malicious / malfunctioning Bluetooth HCI Controller layer may be able to crash the host layer by sending a set of packets which trigger allocations in the host layer and then sending an affected priority event, resulting in a Denial of Service (DoS) condition.

Proposed Fix

We see two alternative approaches to fixing this issue

  • rewrite all buffer allocations which are reachable via priority event handling from an ISR to use timeout 0 and handle exhausted buffer pools.
  • remove the high priority handling of events in the ISR to adhere to implicit assumptions in the event handling code that buffer allocations with timeout K_FOREVER cannot fail

Note: We targeted a build against the h4 driver during fuzz testing. However, the other HCI implementations (h5, ...) seem to also be affected. In case hci driver-specific code changes are used to fix the issue, then the different driver implementations likely require changes as well.