CVE-2026-99207 in Linux
Riassunto
di VulDB • 28/10/2026
Nel kernel Linux è stata risolta la seguente vulnerabilità:
scsi: target: Disabilitare le interruzioni durante il mantenimento di delayed_cmd_lock
target_do_delayed_work() acquisisce dev->delayed_cmd_lock con una spin_lock() semplice. Viene eseguita da system_percpu_wq, quindi le interruzioni rimangono abilitate mentre il lock è detenuto. Ogni altra acquisizione di tale lock utilizza spin_lock_irqsave(): target_handle_task_attr() e transport_complete_ordered_sync() in target_core_transport.c, e target_non_ordered_release() in target_core_device.c.
Questo era sicuro finché ogni chiamante di transport_complete_task_attr() eseguiva nel contesto del processo: target_complete_ok_work() da target_completion_wq, transport_complete_qf() da dev->qf_work_queue e transport_generic_request_failure() dai percorsi di invio ed esecuzione.
Dall'commit 06933066d88a ("scsi: target: Add support for completing commands from backend context") ciò non è più vero. Con complete_type=1 su un fabric che imposta direct_compl_supp, target_complete() esegue target_complete_ok_work() in linea nel contesto di completamento del backend, come documentato da target_complete_cmd_with_sense come "Può essere chiamato dal contesto delle interruzioni". Per iblock questo è il bio end_io.
target_complete_ok_work() inizia con transport_complete_task_attr(), che acquisisce delayed_cmd_lock in due modi:
- Ogni comando ORDERED viene inserito in dev->delayed_cmd_list da target_handle_task_attr() e inviato da lì da target_do_delayed_work(), che lo contrassegna SCF_TASK_ORDERED_SYNC. Il suo completamento passa quindi attraverso transport_complete_ordered_sync(). - Un comando SIMPLE che si completa mentre un comando ORDERED è pendente rilascia l'ultimo riferimento a dev->non_ordered ucciso, e percpu_ref_put() esegue poi target_non_ordered_release() nel contesto di completamento.
Entrambi acquisiscono il lock e, se ci sono comandi in attesa, chiamano schedule_work(&dev->delayed_cmd_work), che accoda su system_percpu_wq, ovvero sulla CPU che ha preso il completamento. Ulteriori completamenti per la stessa coda vengono tipicamente consegnati anche lì, quindi uno che arriva mentre il lavoro detiene il lock gira indefinitamente in attesa (spin).
Raggiungere questa condizione richiede complete_type=1, che non è l'impostazione predefinita (vhost-scsi, l'unico fabric con direct_compl_supp, utilizza per default TARGET_QUEUE_COMPL), un backend i cui I/O si completano dal contesto delle interruzioni e comandi ORDERED dall'iniziatore. Gli ospiti Linux virtio_scsi inviano solo VIRTIO_SCSI_S_SIMPLE e non seguono mai il percorso ordinato; qualsiasi ospite che usa l'attributo del task ORDERED, che vhost-scsi accetta, lo fa invece.
target_do_delayed_work() è un elemento di lavoro (work item) ed esegue sempre nel contesto del processo, quindi spin_lock_irq() è sufficiente.
Trovata mediante ispezione; nessun report a runtime. Un singolo comando ORDERED passa attraverso entrambe le acquisizioni, quindi con CONFIG_PROVE_LOCKING la prima che si completa tramite completamento diretto dovrebbe produrre un report di stato inconsistente del lock su delayed_cmd_lock (hardirq o softirq, a seconda dove il backend completa).
If you want to get best quality of vulnerability data, you may have to visit VulDB.