A vulnerability identified as CVE-2024-27028 was found and patched in the Linux kernel, specifically in the SPI (Serial Peripheral Interface) driver for MediaTek 65xx series chips (spi-mt65xx). This flaw could allow the kernel to crash due to a NULL pointer dereference in the interrupt handler. Let's break down what happened, how it works, how you could trigger it, and how it's been fixed – with code samples and all the references for deeper reading.
Understanding the Vulnerability
In the Linux kernel's SPI subsystem, spi_transfer chunks represent data movement between devices. Each spi_transfer has pointers for transmit (tx_buf) and receive (rx_buf) buffers. It's allowed (by design) for either to be NULL, so the driver must only access them if they're valid.
Problem:
The spi-mt65xx driver didn't check if tx_buf was NULL before writing to it in its interrupt handler. If a transfer with a NULL tx buffer was queued, the interrupt handler would try to dereference a NULL pointer, resulting in an immediate kernel *oops* or crash.
Here's a simplified excerpt before the patch
// Original vulnerable code from drivers/spi/spi-mt65xx.c
static irqreturn_t mt_spi_interrupt(int irq, void *dev_id)
{
struct mt_spi *mdata = (struct mt_spi *)dev_id;
struct spi_transfer *trans = mdata->cur_transfer;
uint8_t *tx = trans->tx_buf; // <-- May be NULL!
...
*tx = some_value; // <-- Crash if tx_buf is NULL!
}
If trans->tx_buf is NULL (because we're only receiving data) and an interrupt arrives, dereferencing it leads to a NULL pointer dereference inside the kernel.
Exploit Scenario: Triggering the Crash
This is easy for a user program to trigger from userspace (with suitable privileges), because the SPI API allows users to submit a transfer with only rx_buf set:
struct spi_transfer transfer = {
.tx_buf = NULL,
.rx_buf = rx_data,
.len = len,
};
// Send the read transfer
spi_sync(spi_device, &transfer);
If the kernel is running the vulnerable driver, and the transfer happens to trigger the buggy code path (interrupt fires, driver writes to tx_buf), the kernel will crash — often with a dmesg/oops resembling:
Unable to handle kernel NULL pointer dereference at virtual address 00000000
The official patch adds a NULL check to make sure tx_buf is valid before using it
- uint8_t *tx = trans->tx_buf;
+ uint8_t *tx = trans->tx_buf;
...
- *tx = some_value; // buggy
+ if (tx)
+ *tx = some_value;
Or in the full commit:
See kernel commit 33f678c86cfb
Now, accesses only occur if the buffer is not NULL — so safe.
Patched: February 17, 2024
- Linux versions affected: Any kernel with the vulnerable drivers/spi/spi-mt65xx.c code prior to the patch
Downstream vendors: Backport the fix to supported products.
- Kernel module developers: Always check for NULL in buffer pointers in I/O transfer structs!
Original References
- CVE-2024-27028 at NVD
- Kernel Git commit with patch
- oss-sec mailing list disclosure
- spi-mt65xx source in Linux kernel
Key Takeaways
- Kernel driver code must always check for NULL buffer pointers — especially in hardware interrupt contexts.
Timeline
Published on: 05/01/2024 13:15:49 UTC
Last modified on: 11/08/2024 19:35:02 UTC