CVE-2026-99207 in Linux
Summary
by MITRE • 10/28/2026
In the Linux kernel, the following vulnerability has been resolved:
scsi: target: Disable interrupts while holding delayed_cmd_lock
target_do_delayed_work() takes dev->delayed_cmd_lock with a plain spin_lock(). It runs from system_percpu_wq, so interrupts stay enabled while the lock is held. Every other acquisition of that lock uses spin_lock_irqsave(): target_handle_task_attr() and transport_complete_ordered_sync() in target_core_transport.c, and target_non_ordered_release() in target_core_device.c.
That was safe while every caller of transport_complete_task_attr() ran in process context: target_complete_ok_work() from target_completion_wq, transport_complete_qf() from dev->qf_work_queue, and transport_generic_request_failure() from the submit and execute paths.
Since commit 06933066d88a ("scsi: target: Add support for completing commands from backend context") that is no longer true. With complete_type=1 on a fabric that sets direct_compl_supp, target_complete() runs target_complete_ok_work() inline in the backend's completion context, which target_complete_cmd_with_sense() documents as "May be called from interrupt context". For iblock that is the bio end_io.
target_complete_ok_work() starts with transport_complete_task_attr(), which takes delayed_cmd_lock in two ways:
- Every ORDERED command is put on dev->delayed_cmd_list by target_handle_task_attr() and dispatched from there by target_do_delayed_work(), which marks it SCF_TASK_ORDERED_SYNC. Its completion therefore goes through transport_complete_ordered_sync().
- A SIMPLE command that completes while an ORDERED command is pending drops the last reference to the killed dev->non_ordered, and percpu_ref_put() then runs target_non_ordered_release() in the completing context.
Both take the lock and, if commands are waiting, call schedule_work(&dev->delayed_cmd_work), which queues on system_percpu_wq, i.e. on the CPU that took the completion. Further completions for the same queue are typically delivered there too, so one arriving while the work holds the lock spins on it forever.
Reaching this needs complete_type=1, which is not the default (vhost-scsi, the only fabric with direct_compl_supp, defaults to TARGET_QUEUE_COMPL), a backend whose I/O completes from interrupt context, and ORDERED commands from the initiator. Linux virtio_scsi guests send only VIRTIO_SCSI_S_SIMPLE and never take the ordered path; any guest that uses the ORDERED task attribute, which vhost-scsi accepts, does.
target_do_delayed_work() is a work item and always runs in process context, so spin_lock_irq() is sufficient.
Found by inspection; no runtime report. A single ORDERED command goes through both acquisitions, so with CONFIG_PROVE_LOCKING the first one completed through direct completion should produce an inconsistent lock state report on delayed_cmd_lock (hardirq or softirq, depending on where the backend completes).
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 10/28/2026
The Linux kernel SCSI target subsystem contains a concurrency vulnerability arising from improper interrupt handling during lock acquisition. Specifically, the function target_do_delayed_work acquires dev->delayed_cmd_lock using spin_lock without disabling local interrupts. This work item executes within system_percpu_wq, which operates in process context where interrupts remain enabled by default. While this approach was previously safe because all callers of transport_complete_task_attr operated strictly in process contexts such as target_completion_wq or device queue work queues, a recent architectural change introduced the possibility of interrupt-context execution for certain completion paths. The vulnerability manifests when direct command completion is supported and enabled via complete_type=1 on fabrics like vhost-scsi that set direct_compl_supp. In these scenarios, backend I/O completions may occur in interrupt context, specifically within bio end_io handlers for iblock backends, leading to a mismatch between the lock acquisition method and the execution environment.
The operational impact stems from the interaction between ordered command handling and simple command completion under high concurrency. When an ORDERED command is processed, it is placed on dev->delayed_cmd_list by target_handle_task_attr and dispatched via target_do_delayed_work, which marks it with SCF_TASK_ORDERED_SYNC. Its subsequent completion flows through transport_complete_ordered_sync, where the lock is correctly acquired using spin_lock_irqsave to disable interrupts. However, if a SIMPLE command completes while an ORDERED command is pending, it may drop the last reference to dev->non_ordered, triggering target_non_ordered_release in the completing context. This function also acquires delayed_cmd_lock and schedules work on system_percpu_wq. If this scheduling occurs while another instance of the work item already holds the lock, subsequent completions for the same queue will spin indefinitely because interrupts are not disabled during the initial acquisition by target_do_delayed_work. This results in a potential denial of service condition where CPU resources are consumed in tight loops waiting for an uncontested lock that cannot be released due to interrupt masking requirements.
This vulnerability is classified under CWE-674, which covers Uncontrolled Recursion and Infinite Looping, as well as CWE-362 regarding Concurrent Execution using Shared Resource with Improper Synchronization. From a threat modeling perspective aligned with MITRE ATT&CK techniques, this flaw relates to T1059 Command Line Interface or more specifically resource exhaustion through inefficient locking strategies that can be triggered by specific initiator configurations. Although the default configuration for vhost-scsi does not enable direct completion support and virtio_scsi guests typically do not utilize ORDERED task attributes, systems explicitly configured with complete_type=1 on compatible fabrics are at risk. The issue was identified through static code inspection rather than runtime reporting, but enabling CONFIG_PROVE_LOCKING would likely expose inconsistent lock state warnings related to hardirq or softirq contexts depending on the backend completion path.
Mitigation strategies involve ensuring that all acquisitions of dev->delayed_cmd_lock consistently disable interrupts when there is any possibility of interrupt-context execution. The primary fix requires modifying target_do_delayed_work to use spin_lock_irqsave instead of plain spin_lock, aligning its behavior with other callers such as target_handle_task_attr and transport_complete_ordered_sync. For administrators unable to apply kernel patches immediately, restricting the configuration to avoid direct command completion support on fabrics that enable it can mitigate the risk. Additionally, ensuring that initiators do not send ORDERED task attributes when using backends prone to interrupt-context completions provides a secondary layer of defense. Regular updates to the Linux kernel are recommended as this issue has been resolved in upstream versions, eliminating the inconsistency between lock acquisition methods and execution contexts.