Cloudanix VulnDB

CVE-2026-80975

High · 7.8

CVSS

7.8

EPSS

0.2%

Published

Sep 11, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A bug in Linux software that talks to a small hardware controller on some storage appliances can let someone already logged in crash the device or take it over if a hardware command times out.

Exploitation
Local Privilege
Attacker needs
Low Privilege
Complexity
Moderate
Impact
Privilege Gain
Component
OS kernel
Class
Use After Free
Remediation
Patch
Effort
Medium
Patch risk
Low

What it actually does

The Linux kernel qnap-mcu MFD driver publishes an on-stack receive buffer to the serdev receive path. After a command timeout or a failed write, that pointer remains live while the stack frame is gone, so a late or unsolicited MCU reply can overwrite kernel stack memory of whatever runs next on that CPU. The result is a use-after-free / use-after-return of kernel stack, with high confidentiality, integrity, and availability impact in kernel context (memory corruption, panic, or potential local privilege escalation).

Why it matters to the business

This is a local, high-severity kernel memory-corruption issue on Linux systems that load the qnap-mcu driver (typically QNAP-class NAS hardware with an MCU over serial). A low-privileged local user or malware already on the box could crash the appliance or, in a successful corruption, take kernel-level control and disrupt storage, management, and availability. It is not remotely exploitable by itself. EPSS is very low (~0.0017 and flat over 30 days), it is not in CISA KEV, ransomware use is not reported, and no public exploit maturity is known ~20 days after publication—so operational urgency is driven by patch hygiene on affected NAS/kernel builds rather than active mass exploitation.

How an attack unfolds

An attacker who already has local, low-privilege code execution on a machine running the qnap-mcu driver must cause MCU commands to time out or fail while serial data still arrives on the serdev receive path. Because the receive callback is not serialized against the timed-out exec path, a late reply or unsolicited MCU message is written into a stack buffer that has already returned. That kernel-stack corruption can panic the host or, if the attacker can influence subsequent stack use, be turned into further kernel-memory control. There are no named threat actors, no KEV listings, and no public exploits; the path is local-only and depends on hardware MCU traffic and timing, which limits real-world abuse compared with generic kernel UAFs.

How to fix it

Apply a Linux kernel update that includes the qnap-mcu fix: move the 37-byte receive buffer into struct qnap_mcu (devm-allocated for the lifetime of the driver) so late writes cannot hit a returned stack frame, and keep bus_lock serializing command use of that buffer. Do not attempt to NULL or zero reply->data/length on the timeout path—that races with the receive callback. If a vendor kernel (NAS firmware) ships this driver, install the vendor image that backports the same change. There is no complete configuration workaround if the driver is bound to live MCU hardware; until patched, restrict local untrusted users and do not load unused qnap-mcu modules. Exact distro/package version strings were not supplied with this record—track your kernel/NAS vendor advisory for the commit that keeps the reply buffer alive past command timeout.

How to confirm the fix worked

Confirm the running kernel (uname -r / vendor firmware version) includes the post-fix qnap-mcu code: the RX buffer lives on struct qnap_mcu rather than an on-stack array in qnap_mcu_exec(). On source trees, inspect drivers/mfd/qnap-mcu.c for the heap/devm buffer and absence of publishing a local rx[] into reply->data. After upgrade, reload or reboot so the old module is not resident (lsmod | grep qnap_mcu; check dmesg for driver bind). On KASAN/debug kernels used for verification, command timeouts plus delayed MCU traffic should no longer produce stack-use-after-return reports. Hosts without QNAP MCU hardware typically never load this driver and are not exposed.

Typical attack path

  1. Obtain local low-privilege access on a Linux host that loads the qnap-mcu driver.
  2. Cause or wait for qnap_mcu_exec() command timeouts or write failures so reply metadata still points at a returned stack buffer.
  3. Have a late MCU reply or unsolicited serial message processed by qnap_mcu_receive_buf() on the serdev/ldisc path.
  4. Corrupt kernel stack of the next user of that stack, producing a panic or further kernel-memory corruption.
  5. If corruption is controllable, escalate to kernel privileges or persist; otherwise the likely outcome is denial of service.

How to detect it

There is no known in-the-wild campaign, so look for crash evidence rather than attacker tooling. Review kernel logs (dmesg, journalctl -k, pstore/kmsg, panic/oops collectors, kdump vmcores) around qnap-mcu for use-after-free, stack-use-after-return, or general protection faults in qnap_mcu_receive_buf / qnap_mcu_exec. Correlate with MCU command timeouts and serdev/uart receive activity. On debug/KASAN builds, KASAN stack-use-after-return hits in this driver are a strong signal the bug was triggered. Process, file, and network IOCs are not expected: exploitation is in-kernel and local. Absence of oopses does not prove the race was never hit.

  • qnap_mcu_exec
  • qnap_mcu_receive_buf
  • qnap-mcu
  • qnap_mcu
  • BUG: KASAN: stack-out-of-bounds
  • BUG: KASAN: use-after-return
  • Unable to handle kernel paging request

What your security team should do

  • Inventory Linux NAS and custom kernels for the qnap-mcu MFD driver and prioritize patching those images even though EPSS and KEV risk are currently low.
  • Deploy vendor or distro kernels that contain the lifetime fix for the MCU reply buffer; reboot to unload the vulnerable module.
  • Until patched, limit local untrusted logins and containers on appliances that bind qnap-mcu, and treat kernel oopses in that driver as a patching trigger.
  • Do not invest in exploit development or offensive PoCs; monitor vendor advisories and kernel stable trees for the backport.
  • Add kernel-log alerting for qnap-mcu oops/panic symbols as a safety net, not as a substitute for patching.

The record

In the Linux kernel, the following vulnerability has been resolved: mfd: qnap-mcu: keep the reply buffer alive past a command timeout qnap_mcu_exec() publishes an on-stack buffer to the receive path: unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE]; ... reply->data = rx; reply->length = length; and qnap_mcu_receive_buf() writes into it from the serdev receive path, which runs out of flush_to_ldisc() and is not serialized against qnap_mcu_exec() at all. bus_lock cannot cover it, because qnap_mcu_exec() holds that mutex across wait_for_completion_timeout(). On a timeout qnap_mcu_exec() returns with reply->data still pointing at its own frame. A reply that arrives late, or an unsolicited message from the MCU, is then written into a stack frame that has been left, corrupting whatever runs next on that stack. The same applies when qnap_mcu_write() fails, since that path returns without touching the reply state either. Move the receive buffer into struct qnap_mcu. It is 37 bytes and the structure is devm_kzalloc()ed, so it lives as long as the driver, and a late write lands in memory that is still valid and is reinitialized by the next command. bus_lock keeps commands from sharing it. This deliberately does not clear reply->data or reply->length on the timeout path. Doing so races with qnap_mcu_receive_buf(), which reads both after its if (!reply->length) return size; check: clearing reply->data gives a NULL dereference, and clearing reply->length alone removes the reply->received == reply->length exit condition, so the copy loop runs until the uart chunk is consumed and overruns the buffer. Leaving both set keeps the write bounded by reply->length, which qnap_mcu_exec() has already checked against sizeof(mcu->rx).

Affected packages

Ecosystem Package Introduced Fixed