Description
In the Linux kernel, the following vulnerability has been resolved:

ata: libata: cancel pending work after clearing deferred_qc

Syzbot reported a WARN_ON() in ata_scsi_deferred_qc_work(), caused by
ap->ops->qc_defer() returning non-zero before issuing the deferred qc.

ata_scsi_schedule_deferred_qc() is called during each command completion.
This function will check if there is a deferred QC, and if
ap->ops->qc_defer() returns zero, meaning that it is possible to queue the
deferred qc at this time (without being deferred), then it will queue the
work which will issue the deferred qc.

Once the work get to run, which can potentially be a very long time after
the work was scheduled, there is a WARN_ON() if ap->ops->qc_defer() returns
non-zero.

While we hold the ap->lock both when assigning and clearing deferred_qc,
and the work itself holds the ap->lock, the code currently does not cancel
the work after clearing the deferred qc.

This means that the following scenario can happen:
1) One or several NCQ commands are queued.
2) A non-NCQ command is queued, gets stored in ap->deferred_qc.
3) Last NCQ command gets completed, work is queued to issue the deferred
qc.
4) Timeout or error happens, ap->deferred_qc is cleared. The queued work is
currently NOT canceled.
5) Port is reset.
6) One or several NCQ commands are queued.
7) A non-NCQ command is queued, gets stored in ap->deferred_qc.
8) Work is finally run. Yet at this time, there is still NCQ commands in
flight.

The work in 8) really belongs to the non-NCQ command in 2), not to the
non-NCQ command in 7). The reason why the work is executed when it is not
supposed to, is because it was never canceled when ap->deferred_qc was
cleared in 4). Thus, ensure that we always cancel the work after clearing
ap->deferred_qc.

Another potential fix would have been to let ata_scsi_deferred_qc_work() do
nothing if ap->ops->qc_defer() returns non-zero. However, canceling the
work when clearing ap->deferred_qc seems slightly more logical, as we hold
the ap->lock when clearing ap->deferred_qc, so we know that the work cannot
be holding the lock. (The function could be waiting for the lock, but that
is okay since it will do nothing if ap->deferred_qc is not set.)
Published: 2026-03-25
Score: 5.5 Medium
EPSS: < 1% Very Low
KEV: No
Impact: Device instability and potential local disruption
Action: Patch It
AI Analysis

Impact

In the Linux kernel, a flaw in libata prevents pending work associated with a deferred queue command (QC) from being cancelled once the deferred QC is cleared. When the stray work later runs, it may attempt to execute a command that no longer belongs to the original request, causing WARN_ON messages and possible device resets. The weak area is a lack of proper cancellation logic, leading to incorrect command handling and instability. This is a local issue rooted in improper resource cleanup.

Affected Systems

All Linux kernel builds released before the patch that introduces the cancellation logic for deferred QC are affected, regardless of distribution or hardware configuration. The vulnerability exists in the kernel itself, so any system running an unpatched kernel version is at risk.

Risk and Exploitability

The CVSS score of 5.5 indicates a moderate severity. The EPSS score of less than 1% suggests a very low probability of exploitation in the wild. The vulnerability is not listed in CISA’s KEV catalog. Based on the description, it is inferred that exploitation would likely require a local user or a user with elevated privileges that can issue SATA commands triggering the deferred QC logic. Therefore, the risk is largely limited to local impact rather than remote exploitation.

Generated by OpenCVE AI on April 28, 2026 at 22:01 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Apply the Linux kernel patch that corrects libata deferred QC cancellation logic
  • If an immediate patch is unavailable, avoid using non‑NCQ commands or temporarily disable NCQ on affected storage devices to prevent the deferred QC path from being triggered
  • Monitor kernel logs (e.g., dmesg) for WARN_ON messages related to qc_defer failures and apply the patch promptly when such logs appear

Generated by OpenCVE AI on April 28, 2026 at 22:01 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Fri, 24 Apr 2026 19:15:00 +0000

Type Values Removed Values Added
Weaknesses NVD-CWE-noinfo
CPEs cpe:2.3:o:linux:linux_kernel:7.0:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc2:*:*:*:*:*:*

Thu, 26 Mar 2026 12:30:00 +0000

Type Values Removed Values Added
Weaknesses CWE-362

Thu, 26 Mar 2026 00:15:00 +0000

Type Values Removed Values Added
Weaknesses CWE-459
References
Metrics threat_severity

None

cvssV3_1

{'score': 5.5, 'vector': 'CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H'}

threat_severity

Moderate


Wed, 25 Mar 2026 22:00:00 +0000

Type Values Removed Values Added
Weaknesses CWE-362

Wed, 25 Mar 2026 10:45:00 +0000

Type Values Removed Values Added
Description In the Linux kernel, the following vulnerability has been resolved: ata: libata: cancel pending work after clearing deferred_qc Syzbot reported a WARN_ON() in ata_scsi_deferred_qc_work(), caused by ap->ops->qc_defer() returning non-zero before issuing the deferred qc. ata_scsi_schedule_deferred_qc() is called during each command completion. This function will check if there is a deferred QC, and if ap->ops->qc_defer() returns zero, meaning that it is possible to queue the deferred qc at this time (without being deferred), then it will queue the work which will issue the deferred qc. Once the work get to run, which can potentially be a very long time after the work was scheduled, there is a WARN_ON() if ap->ops->qc_defer() returns non-zero. While we hold the ap->lock both when assigning and clearing deferred_qc, and the work itself holds the ap->lock, the code currently does not cancel the work after clearing the deferred qc. This means that the following scenario can happen: 1) One or several NCQ commands are queued. 2) A non-NCQ command is queued, gets stored in ap->deferred_qc. 3) Last NCQ command gets completed, work is queued to issue the deferred qc. 4) Timeout or error happens, ap->deferred_qc is cleared. The queued work is currently NOT canceled. 5) Port is reset. 6) One or several NCQ commands are queued. 7) A non-NCQ command is queued, gets stored in ap->deferred_qc. 8) Work is finally run. Yet at this time, there is still NCQ commands in flight. The work in 8) really belongs to the non-NCQ command in 2), not to the non-NCQ command in 7). The reason why the work is executed when it is not supposed to, is because it was never canceled when ap->deferred_qc was cleared in 4). Thus, ensure that we always cancel the work after clearing ap->deferred_qc. Another potential fix would have been to let ata_scsi_deferred_qc_work() do nothing if ap->ops->qc_defer() returns non-zero. However, canceling the work when clearing ap->deferred_qc seems slightly more logical, as we hold the ap->lock when clearing ap->deferred_qc, so we know that the work cannot be holding the lock. (The function could be waiting for the lock, but that is okay since it will do nothing if ap->deferred_qc is not set.)
Title ata: libata: cancel pending work after clearing deferred_qc
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References

Subscriptions

Linux Linux Kernel
cve-icon MITRE

Status: PUBLISHED

Assigner: Linux

Published:

Updated: 2026-05-26T16:17:50.796Z

Reserved: 2026-01-13T15:37:46.000Z

Link: CVE-2026-23355

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Analyzed

Published: 2026-03-25T11:16:34.110

Modified: 2026-04-24T19:13:44.037

Link: CVE-2026-23355

cve-icon Redhat

Severity : Moderate

Publid Date: 2026-03-25T00:00:00Z

Links: CVE-2026-23355 - Bugzilla

cve-icon OpenCVE Enrichment

Updated: 2026-04-28T22:15:41Z

Weaknesses