In 2021, a security flaw identified as CVE-2021-47048 was discovered in the Linux kernel’s Zynq UltraScale+ MPSoC Quad SPI (QSPI) driver. This bug could allow attackers or a buggy kernel module to trigger a dangerous _use-after-free_ memory access, which could lead to unpredictable behaviors or even escalation of privileges on vulnerable systems.
This article explains the bug, its potential impact, and how it was resolved — in clear, plain English. You'll also see code snippets from the affected driver, plus references for further reading.
Background: What Is the ZynqMP GQSPI Driver?
The ZynqMP QSPI is a hardware controller present in some embedded ARM chips from Xilinx, used for high-speed communication with flash memory. Linux supports this hardware through the driver found in drivers/spi/spi-zynqmp-gqspi.c.
What Happened?
The bug is found in the function zynqmp_qspi_exec_op(). This function is responsible for executing SPI memory operations — like reads or writes — based on the structure struct spi_mem_op. Inside, the code was using an internal buffer called tmpbuf to process memory addresses.
However, after the buffer tmpbuf was freed, the code tried to use op->addr, which pointed to (now!) freed memory. When this happens, it can cause crashes or, in the worst cases, even give attackers a way to gain more control over your system’s kernel.
The Kernel Address SANitizer tool, or KASAN, would catch this as a use-after-free scenario and report a warning.
Here’s a simplified version of the vulnerable code
int zynqmp_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
u8 *tmpbuf = kmalloc(size, GFP_KERNEL);
// ...do some stuff with tmpbuf...
// Issue: tmpbuf is freed before this line
kfree(tmpbuf);
write_address_to_hardware(op->addr.val); // BAD: op->addr may point to freed tmpbuf!
// ...
}
The Fix: Copy The Data First!
Linux maintainers fixed this by copying the required data from the buffer into a local temporary variable before freeing the memory.
Here’s how the fix looks
int zynqmp_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
u8 *tmpbuf = kmalloc(size, GFP_KERNEL);
// Copy op->addr.val and op->cmd.opcode before freeing tmpbuf
u32 addr_val = op->addr.val;
u8 opcode = op->cmd.opcode;
// ...use tmpbuf for whatever is needed...
kfree(tmpbuf);
// Now use the local copies, which are safe!
write_address_to_hardware(addr_val);
write_opcode_to_hardware(opcode);
// ...
}
In short
- The required information is stored into stack variables before the buffer is destroyed, making sure nothing uses memory that’s already been given back to the system.
How Could This Be Exploited?
A successful exploit would likely require local access to the system (or a hostile kernel module).
- If the attacker manages to trigger this code path exactly when the memory is repurposed, it might allow data leakage, corruption, or a kernel crash (Denial of Service).
- In rare cases, attackers may be able to manipulate the contents of the freed memory, potentially turning this warning into code execution inside the kernel.
However, exploitation is tricky, and may not be easily triggerable from userspace. But the risk in kernel space is always serious.
Which Systems Are Affected?
- Any Linux device using the ZynqMP GQSPI driver (commonly boards based on Xilinx Zynq UltraScale+ MPSoC).
- Kernel versions before the fix was merged are vulnerable. The issue was fixed in kernel 5.14 and backported to stable series.
Official References & Commit
- CVE Details: CVE-2021-47048 at cvedetails.com
- Fix commit: kernel.org commit 2c450475353a6f1d1
Linux commit log:
spi: spi-zynqmp-gqspi: fix use-after-free in zynqmp_qspi_exec_op
Summary
CVE-2021-47048 was a _use-after-free_ bug in the SPI driver for Xilinx ZynqMP chips in Linux. By accessing released memory, it posed a stability and potential security risk. The bug is fixed by copying needed data to temporary variables before freeing resources, eliminating unsafe access.
Always keep your kernel updated and watch out for security notices, especially for embedded or industrial systems!
Further Reading
- A Simple Explanation of Use-After-Free Bugs (Google Project Zero)
- Linux Kernel Documentation: SPI Subsystem
Timeline
Published on: 02/28/2024 09:15:40 UTC
Last modified on: 12/09/2024 19:05:02 UTC