CVE-2026-46060
Description
In the Linux kernel, the following vulnerability has been resolved:
crypto: qat - fix IRQ cleanup on 6xxx probe failure
When adf_dev_up() partially completes and then fails, the IRQ handlers registered during adf_isr_resource_alloc() are not detached before the MSI-X vectors are released.
Since the device is enabled with pcim_enable_device(), calling pci_alloc_irq_vectors() internally registers pcim_msi_release() as a devres action. On probe failure, devres runs pcim_msi_release() which calls pci_free_irq_vectors(), tearing down the MSI-X vectors while IRQ handlers (for example 'qat0-bundle0') are still attached. This causes remove_proc_entry() warnings:
[ 22.163964] remove_proc_entry: removing non-empty directory 'irq/143', leaking at least 'qat0-bundle0'
Moving the devm_add_action_or_reset() before adf_dev_up() does not solve the problem since devres runs in LIFO order and pcim_msi_release(), registered later inside adf_dev_up(), would still fire before adf_device_down().
Fix by calling adf_dev_down() explicitly when adf_dev_up() fails, to properly free IRQ handlers before devres releases the MSI-X vectors.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In the Linux kernel's QAT driver, failure during probe on 6xxx devices can trigger a warning because IRQ handlers are not detached before MSI-X vectors are freed; explicit adf_dev_down() call fixes the cleanup order.
Vulnerability
A resource cleanup bug exists in the crypto: qat driver for Intel QuickAssist Technology (QAT) 6xxx devices. When adf_dev_up() partially completes and then fails during probe, the IRQ handlers registered by adf_isr_resource_alloc() are not detached before the MSI-X vectors are released. Because the device is enabled with pcim_enable_device(), calling pci_alloc_irq_vectors() internally registers pcim_msi_release() as a devres action. Upon probe failure, devres runs pcim_msi_release(), which calls pci_free_irq_vectors(), tearing down the MSI-X vectors while IRQ handlers (e.g., qat0-bundle0) are still attached. This triggers remove_proc_entry() warnings about a non-empty directory. Without this fix, affected kernel versions exhibiting the issue are those that introduced the problematic probe path, specifically designed as a fix for the 6xxx device family. The patch was applied to the stable kernel tree.
Exploitation
An attacker does not directly trigger this vulnerability; it is a kernel bug that manifests automatically upon probe failure. However, an attacker who can cause the adf_dev_up() function to fail mid-way (e.g., by manipulating device configuration or inducing resource exhaustion) could provoke the kernel warning. The condition requires the QAT driver to be in use and the probe to fail after adf_isr_resource_alloc() but before adf_dev_up() completes. The bug is rooted in the driver's internal resource management and does not require user interaction beyond normal system operations that may lead to probe failure.
Impact
When triggered, the bug does not cause data loss or privilege escalation but results in a kernel diagnostic warning (remove_proc_entry: removing non-empty directory ...). This warning indicates that the /proc/irq/ directory for the affected IRQ number is not properly cleaned up, potentially leading to resource leakage. Under some configurations, repeated probe failures could accumulate leaked proc entries, but no direct security vulnerability (e.g., information disclosure or code execution) is described. The impact is limited to kernel log noise and minor resource management degradation.
Mitigation
The fix is available in the stable kernel tree as commit 7cd651f1357dcc477e6483c3a4706836b46bdc92 [1]. It explicitly calls adf_dev_down() when adf_dev_up() fails, ensuring that IRQ handlers are freed before devres releases the MSI-X vectors. Affected systems should update their kernel to include this patch. No workaround is mentioned beyond applying the fix. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of this writing.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
627f561bf894ecrypto: qat - fix IRQ cleanup on 6xxx probe failure
2 files changed · +6 −4
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
7cd651f1357dcrypto: qat - fix IRQ cleanup on 6xxx probe failure
2 files changed · +6 −4
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
95aed2af87eccrypto: qat - fix IRQ cleanup on 6xxx probe failure
2 files changed · +6 −4
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index 0684ea9be2ac53..c52462a48c340e 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -209,8 +209,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index 0684ea9be2ac53..c52462a48c340e 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -209,8 +209,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
7cd651f1357dcrypto: qat - fix IRQ cleanup on 6xxx probe failure
2 files changed · +6 −4
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
95aed2af87eccrypto: qat - fix IRQ cleanup on 6xxx probe failure
2 files changed · +6 −4
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index 0684ea9be2ac53..c52462a48c340e 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -209,8 +209,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index 0684ea9be2ac53..c52462a48c340e 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -209,8 +209,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
27f561bf894ecrypto: qat - fix IRQ cleanup on 6xxx probe failure
2 files changed · +6 −4
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c+3 −2 modifieddiff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c index c1dc9c56fdf549..f0d112e4b56c3c 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_drv.c @@ -182,8 +182,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; ret = adf_dev_up(accel_dev, true); - if (ret) + if (ret) { + adf_dev_down(accel_dev); return ret; + } ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev); if (ret) -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing cleanup call to adf_dev_down() on adf_dev_up() failure leaves IRQ handlers attached while devres tears down MSI-X vectors, causing a use-after-free of IRQ handler data structures."
Attack vector
An attacker does not directly trigger this bug; it is a driver probe-time error path issue. The vulnerability manifests when the kernel's PCI subsystem probes a QAT 6xxx device and adf_dev_up() partially completes but then fails. Because the device is enabled with pcim_enable_device(), the pci_alloc_irq_vectors() call internally registers pcim_msi_release() as a devres action. On probe failure, devres runs pcim_msi_release() which calls pci_free_irq_vectors(), tearing down MSI-X vectors while IRQ handlers (e.g. 'qat0-bundle0') are still attached, leading to remove_proc_entry() warnings and potential use-after-free of IRQ handler data.
Affected code
The vulnerable code is in drivers/crypto/intel/qat/qat_6xxx/adf_drv.c, in the adf_probe() function. The error path after a failed adf_dev_up() call did not invoke adf_dev_down() to detach IRQ handlers before returning.
What the fix does
The patch adds an explicit call to adf_dev_down(accel_dev) inside the error branch when adf_dev_up() fails [patch_id=2660047]. This ensures that IRQ handlers registered during adf_isr_resource_alloc() are properly detached before devres releases the MSI-X vectors. Simply moving devm_add_action_or_reset() earlier would not work because devres runs in LIFO order and pcim_msi_release() (registered later inside adf_dev_up()) would still fire before adf_device_down().
Preconditions
- configA QAT 6xxx device must be present on the PCI bus and the driver must attempt to probe it.
- inputadf_dev_up() must partially complete (registering IRQ handlers via adf_isr_resource_alloc()) and then fail, triggering the probe error path.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.