[PATCH OLK-5.10] scsi: core: pair EH runtime PM get and put
mainline inclusion from mainline-v7.2 commit 872f486259ae0bc6b73ca4735a15d013241f73e9 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18399 CVE: CVE-2026-74754 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- shost->eh_noresume is currently consulted twice in one error handling iteration: once before scsi_autopm_get_host() and once again before scsi_autopm_put_host(). That is racy when a PM-triggered error path flips shost->eh_noresume while the SCSI EH thread is still running. The problem flow looks like this: PM path ufshcd_set_dev_pwr_mode() shost->eh_noresume = 1 ufshcd_execute_start_stop <-- trigger EH ... shost->eh_noresume = 0 EH path scsi_error_handler() if (!shost->eh_noresume) scsi_autopm_get_host() <-- skipped ... if (!shost->eh_noresume) scsi_autopm_put_host() <-- executed later In that case one EH iteration can skip autoresume on entry and still drop a runtime PM reference on exit. That leaves an unmatched runtime PM put and can trigger a runtime PM usage count underflow. Fix this by making eh_noresume a regular bool so it can be accessed with READ_ONCE() and WRITE_ONCE(). Snapshot it once per EH iteration and use that snapshot for both runtime PM get and put decisions. Fixes: ae0751ffc77e ("[SCSI] add flag to skip the runtime PM calls on the host") Signed-off-by: Hongjie Fang <hongjiefang@asrmicro.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Peter Wang <peter.wang@mediatek.com> Link: https://patch.msgid.link/20260729111614.2407559-1-hongjiefang@asrmicro.com Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org> Conflicts: drivers/scsi/scsi_error.c drivers/scsi/ufs/ufshcd.c [ctx conflicts] Signed-off-by: Zhou Minqiang <zhouminqiang2@huawei.com> --- drivers/scsi/scsi_error.c | 9 +++++++-- drivers/scsi/ufs/ufshcd.c | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 18512b33a190..90f275ac43c6 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -2204,6 +2204,8 @@ static void scsi_unjam_host(struct Scsi_Host *shost) int scsi_error_handler(void *data) { struct Scsi_Host *shost = data; + bool eh_noresume; + unsigned long flags; /* * We use TASK_INTERRUPTIBLE so that the thread is not @@ -2245,7 +2247,10 @@ int scsi_error_handler(void *data) * what we need to do to get it up and online again (if we can). * If we fail, we end up taking the thing offline. */ - if (!shost->eh_noresume && scsi_autopm_get_host(shost) != 0) { + spin_lock_irqsave(shost->host_lock, flags); + eh_noresume = shost->eh_noresume; + spin_unlock_irqrestore(shost->host_lock, flags); + if (!eh_noresume && scsi_autopm_get_host(shost) != 0) { SCSI_LOG_ERROR_RECOVERY(1, shost_printk(KERN_ERR, shost, "scsi_eh_%d: unable to autoresume\n", @@ -2269,7 +2274,7 @@ int scsi_error_handler(void *data) * which are still online. */ scsi_restart_operations(shost); - if (!shost->eh_noresume) + if (!eh_noresume) scsi_autopm_put_host(shost); } __set_current_state(TASK_RUNNING); diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ae00892ba44a..b3c6f41a5284 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8291,7 +8291,9 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, * we are functional while we are here, skip host resume in error * handling context. */ + spin_lock_irqsave(hba->host->host_lock, flags); hba->host->eh_noresume = 1; + spin_unlock_irqrestore(hba->host->host_lock, flags); if (hba->wlun_dev_clr_ua) { ret = ufshcd_send_request_sense(hba, sdp); if (ret) @@ -8321,7 +8323,9 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, hba->curr_dev_pwr_mode = pwr_mode; out: scsi_device_put(sdp); + spin_lock_irqsave(hba->host->host_lock, flags); hba->host->eh_noresume = 0; + spin_unlock_irqrestore(hba->host->host_lock, flags); return ret; } -- 2.52.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/27501 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/3IP... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/27501 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/3IP...
participants (2)
-
patchwork bot -
Zhou Minqiang