Broadcom produces Wi-Fi HardMAC SoCs which are used to handle the PHY and MAC layer processing. These chips are present in both mobile devices and Wi-Fi routers, and are capable of handling many Wi-Fi related events without delegating to the host OS.
One of the events handled by the BCM firmware is the processing of TDLS connections (802.11z). TDLS connections allow clients to exchange data between one another without passing it through the AP (thus preventing congestion at the AP).
In order to verify the integrity of TDLS messages, each message exchanged between the TDLS peers includes a message integrity code (MIC). The MIC is calculated using AES-CMAC with a key derived during the setup process (TPK-KCK).
When a TDLS Teardown Request frame is sent by either one of the peers in an established TDLS connection, the receiving client must verify the MIC before processing the request. The MIC for TDLS teardown requests is calculated as follows:
AES-CMAC(TPK-KCK, LinkID-IE || ReasonCode || DialogToken || TransactionSeq || FastTransition-IE)
(see "wpa_tdls_key_mic_teardown" under https://w1.fi/cgit/hostap/plain/src/rsn_supp/tdls.c)
It should be noted that all TDLS connections are accepted automatically from any peer and are handled solely by the BCM firmware (meaning there is no need for user interaction or involvement in any way - once a TDLS Setup Request is received by the firmware, it will proceed with the TDLS handshake and subsequently create a TDLS connection with the requesting peer).
When the BCM firmware receives a TDLS Teardown frame, it first verifies the Link-ID information element in order to make sure it matches the current link information. Then, if the Link ID is valid, it calls the "wlc_tdls_cal_teardown_mic_chk" function in order to verify the MIC of the request. The function starts by extracting the Fast Transition IE information element (FTIE - number 55). Then, if the IE is present, its contents are copied into a heap-allocated buffer of length 256. The copy is performed using the length field present in the IE, and at a fixed offset from the buffer's start address. Since the length of the FTIE is not verified prior to the copy, this allows an attacker to include a large FTIE (e.g., with a length field of 255), causing the memcpy to overflow the heap-allocated buffer.
Here's the high-level logic of the "wlc_tdls_cal_teardown_mic_chk" function:
uint8_t* buffer = malloc(256);
uint8_t* linkid_ie = bcm_parse_tlvs(..., 101);
memcpy(buffer, linkid_ie, 0x14);
uint8_t* ft_ie = bcm_parse_tlvs(..., 55);
memcpy(buf + 0x18, ft_ie, ft_ie + 2);
(Note that each IE is a TLV; the tag and value fields are each a single byte long. Therefore, ft_ie is the IE's length field).
It should also be noted that the heap implementation used in the BCM firmware does not perform safe unlinking or include heap header cookies, allowing heap overflows such as the one described above to be exploited more reliably.
I'm attaching a patch to wpa_supplicant 2.6 which modifies the TDLS Teardown frame sent by the supplicant in order to trigger the heap overflow. You can reproduce the issue by following these steps:
1. Download wpa_supplicant 2.6 from https://w1.fi/releases/wpa_supplicant-2.6.tar.gz
2. Apply the included patch file
3. Build wpa_supplicant (with TDLS support)
4. Use wpa_supplicant to connect to a network
5. Connect to wpa_cli:
5.1. Setup a TDLS connection to the BCM peer using "TDLS_SETUP <MAC_ADDRESS_OF_PEER>"
5.2. Teardown the connection using "TDLS_TEARDOWN <MAC_ADDRESS_OF_PEER>"
(Where MAC_ADDRESS_OF_PEER is the MAC address of a peer with a BCM SoC which is associated to the same network).
At this point the heap overflow will be triggered. The code in the patch will corrupt the heap, causing the remote BCM SoC to reset after a while.
I've been able to verify this vulnerability on the BCM4339 chip, running version 184.108.40.206 (as present on the Nexus 5). However, I believe this vulnerability's scope includes a wider range of Broadcom SoCs and versions.
This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.