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