From: Greg Kroah-Hartman Date: Thu, 26 Feb 2026 14:49:37 +0000 (-0800) Subject: 6.18-stable patches X-Git-Tag: v6.18.14~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3ed19b3c4249bd66df7094d94b954ec809ea3544;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: ata-libata-core-fix-cancellation-of-a-port-deferred-qc-work.patch ata-libata-eh-correctly-handle-deferred-qc-timeouts.patch --- diff --git a/queue-6.18/ata-libata-core-fix-cancellation-of-a-port-deferred-qc-work.patch b/queue-6.18/ata-libata-core-fix-cancellation-of-a-port-deferred-qc-work.patch new file mode 100644 index 0000000000..48d7e2be1e --- /dev/null +++ b/queue-6.18/ata-libata-core-fix-cancellation-of-a-port-deferred-qc-work.patch @@ -0,0 +1,49 @@ +From 55db009926634b20955bd8abbee921adbc8d2cb4 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Fri, 20 Feb 2026 12:09:12 +0900 +Subject: ata: libata-core: fix cancellation of a port deferred qc work + +From: Damien Le Moal + +commit 55db009926634b20955bd8abbee921adbc8d2cb4 upstream. + +cancel_work_sync() is a sleeping function so it cannot be called with +the spin lock of a port being held. Move the call to this function in +ata_port_detach() after EH completes, with the port lock released, +together with other work cancellation calls. + +Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Reviewed-by: Igor Pylypiv +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-core.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -6163,10 +6163,6 @@ static void ata_port_detach(struct ata_p + } + } + +- /* Make sure the deferred qc work finished. */ +- cancel_work_sync(&ap->deferred_qc_work); +- WARN_ON(ap->deferred_qc); +- + /* Tell EH to disable all devices */ + ap->pflags |= ATA_PFLAG_UNLOADING; + ata_port_schedule_eh(ap); +@@ -6177,9 +6173,11 @@ static void ata_port_detach(struct ata_p + /* wait till EH commits suicide */ + ata_port_wait_eh(ap); + +- /* it better be dead now */ ++ /* It better be dead now and not have any remaining deferred qc. */ + WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); ++ WARN_ON(ap->deferred_qc); + ++ cancel_work_sync(&ap->deferred_qc_work); + cancel_delayed_work_sync(&ap->hotplug_task); + cancel_delayed_work_sync(&ap->scsi_rescan_task); + diff --git a/queue-6.18/ata-libata-eh-correctly-handle-deferred-qc-timeouts.patch b/queue-6.18/ata-libata-eh-correctly-handle-deferred-qc-timeouts.patch new file mode 100644 index 0000000000..cd89c82852 --- /dev/null +++ b/queue-6.18/ata-libata-eh-correctly-handle-deferred-qc-timeouts.patch @@ -0,0 +1,84 @@ +From eddb98ad9364b4e778768785d46cfab04ce52100 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Fri, 20 Feb 2026 13:43:00 +0900 +Subject: ata: libata-eh: correctly handle deferred qc timeouts + +From: Damien Le Moal + +commit eddb98ad9364b4e778768785d46cfab04ce52100 upstream. + +A deferred qc may timeout while waiting for the device queue to drain +to be submitted. In such case, since the qc is not active, +ata_scsi_cmd_error_handler() ends up calling scsi_eh_finish_cmd(), +which frees the qc. But as the port deferred_qc field still references +this finished/freed qc, the deferred qc work may eventually attempt to +call ata_qc_issue() against this invalid qc, leading to errors such as +reported by UBSAN (syzbot run): + +UBSAN: shift-out-of-bounds in drivers/ata/libata-core.c:5166:24 +shift exponent 4210818301 is too large for 64-bit type 'long long unsigned int' +... +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120 + ubsan_epilogue+0xa/0x30 lib/ubsan.c:233 + __ubsan_handle_shift_out_of_bounds+0x279/0x2a0 lib/ubsan.c:494 + ata_qc_issue.cold+0x38/0x9f drivers/ata/libata-core.c:5166 + ata_scsi_deferred_qc_work+0x154/0x1f0 drivers/ata/libata-scsi.c:1679 + process_one_work+0x9d7/0x1920 kernel/workqueue.c:3275 + process_scheduled_works kernel/workqueue.c:3358 [inline] + worker_thread+0x5da/0xe40 kernel/workqueue.c:3439 + kthread+0x370/0x450 kernel/kthread.c:467 + ret_from_fork+0x754/0xd80 arch/x86/kernel/process.c:158 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 + + +Fix this by checking if the qc of a timed out SCSI command is a deferred +one, and in such case, clear the port deferred_qc field and finish the +SCSI command with DID_TIME_OUT. + +Reported-by: syzbot+1f77b8ca15336fff21ff@syzkaller.appspotmail.com +Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation") +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Reviewed-by: Igor Pylypiv +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-eh.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -640,12 +640,28 @@ void ata_scsi_cmd_error_handler(struct S + set_host_byte(scmd, DID_OK); + + ata_qc_for_each_raw(ap, qc, i) { +- if (qc->flags & ATA_QCFLAG_ACTIVE && +- qc->scsicmd == scmd) ++ if (qc->scsicmd != scmd) ++ continue; ++ if ((qc->flags & ATA_QCFLAG_ACTIVE) || ++ qc == ap->deferred_qc) + break; + } + +- if (i < ATA_MAX_QUEUE) { ++ if (qc == ap->deferred_qc) { ++ /* ++ * This is a deferred command that timed out while ++ * waiting for the command queue to drain. Since the qc ++ * is not active yet (deferred_qc is still set, so the ++ * deferred qc work has not issued the command yet), ++ * simply signal the timeout by finishing the SCSI ++ * command and clear the deferred qc to prevent the ++ * deferred qc work from issuing this qc. ++ */ ++ WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE); ++ ap->deferred_qc = NULL; ++ set_host_byte(scmd, DID_TIME_OUT); ++ scsi_eh_finish_cmd(scmd, &ap->eh_done_q); ++ } else if (i < ATA_MAX_QUEUE) { + /* the scmd has an associated qc */ + if (!(qc->flags & ATA_QCFLAG_EH)) { + /* which hasn't failed yet, timeout */ diff --git a/queue-6.18/series b/queue-6.18/series index bbf6f19e20..408dbca0a6 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -639,3 +639,5 @@ drm-amd-display-clear-hdmi-hpd-pending-work-only-if-it-is-enabled.patch net-stmmac-dwmac-loongson-set-clk_csr_i-to-100-150mhz.patch drm-amd-display-add-an-hdmi_hpd_debounce_delay_ms-module.patch revert-drm-amdgpu-don-t-attach-the-tlb-fence-for-si.patch +ata-libata-eh-correctly-handle-deferred-qc-timeouts.patch +ata-libata-core-fix-cancellation-of-a-port-deferred-qc-work.patch