btnxpuart: out of bounds read of firmware in nxp_recv_fw_req_v3()
From: Maoyi Xie
Date: Tue Jun 16 2026 - 03:50:05 EST
Hi all,
I think nxp_recv_fw_req_v3() in drivers/bluetooth/btnxpuart.c can read past the
end of the firmware image. I would appreciate it if you could take a look.
The chip's v3 firmware download request carries a u32 offset and a u16 len. The
handler checks only the lower bound, then sends firmware from that offset.
offset = __le32_to_cpu(req->offset);
if (offset < nxpdev->fw_v3_offset_correction) {
... goto free_skb;
}
nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
serdev_device_write_buf(nxpdev->serdev,
nxpdev->fw->data + nxpdev->fw_dnld_v3_offset, len);
Nothing checks that fw_dnld_v3_offset + len stays within nxpdev->fw->size. So a
chip that asks for an offset or len past the firmware image makes the kernel read
past nxpdev->fw->data and send that memory back to the chip over UART.
The v1 handler already bounds this. nxp_recv_fw_req_v1() guards the same write.
if (nxpdev->fw_dnld_v1_offset + len <= nxpdev->fw->size)
serdev_device_write_buf(...);
The v3 handler is missing that check.
I reproduced the read on 7.1-rc7 by replaying the serdev_device_write_buf()
source read, with the firmware image ending at an unmapped page.
BUG: unable to handle page fault for address: ...
#PF: error_code(0x0000) - not-present page (a read)
RIP: 0010:... (the fw->data + offset read)
The fix I tried bounds the request against the image size, like the v1 path does.
nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
+ if (nxpdev->fw_dnld_v3_offset >= nxpdev->fw->size ||
+ len > nxpdev->fw->size - nxpdev->fw_dnld_v3_offset) {
+ bt_dev_err(hdev, "FW download out of range");
+ goto free_skb;
+ }
serdev_device_write_buf(nxpdev->serdev,
nxpdev->fw->data + nxpdev->fw_dnld_v3_offset, len);
This needs a misbehaving controller, not a remote attacker. It still looks like
an out of bounds read to me. Does this look right, and is that the place to bound
it? Happy to send a proper patch once you confirm.
Thanks,
Maoyi
https://maoyixie.com/