From 27e06650a5eafe832a90fd2604f0c5e920857fae Mon Sep 17 00:00:00 2001 From: Wang Haoran Date: Sat, 20 Sep 2025 15:44:41 +0800 Subject: [PATCH 1/7] scsi: target: target_core_configfs: Add length check to avoid buffer overflow A buffer overflow arises from the usage of snprintf to write into the buffer "buf" in target_lu_gp_members_show function located in /drivers/target/target_core_configfs.c. This buffer is allocated with size LU_GROUP_NAME_BUF (256 bytes). snprintf(...) formats multiple strings into buf with the HBA name (hba->hba_group.cg_item), a slash character, a devicename (dev-> dev_group.cg_item) and a newline character, the total formatted string length may exceed the buffer size of 256 bytes. Since snprintf() returns the total number of bytes that would have been written (the length of %s/%sn ), this value may exceed the buffer length (256 bytes) passed to memcpy(), this will ultimately cause function memcpy reporting a buffer overflow error. An additional check of the return value of snprintf() can avoid this buffer overflow. Reported-by: Wang Haoran Reported-by: ziiiro Signed-off-by: Wang Haoran Signed-off-by: Martin K. Petersen --- drivers/target/target_core_configfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 0904ecae253a..b19acd662726 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -2774,7 +2774,7 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) config_item_name(&dev->dev_group.cg_item)); cur_len++; /* Extra byte for NULL terminator */ - if ((cur_len + len) > PAGE_SIZE) { + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { pr_warn("Ran out of lu_gp_show_attr" "_members buffer\n"); break; From 285654d58a747eb431ee538c803c077d90525674 Mon Sep 17 00:00:00 2001 From: John Meneghini Date: Thu, 25 Sep 2025 09:07:29 -0400 Subject: [PATCH 2/7] Revert "scsi: qla2xxx: Fix memcpy() field-spanning write issue" This reverts commit 6f4b10226b6b1e7d1ff3cdb006cf0f6da6eed71e. We've been testing this patch and it turns out there is a significant bug here. This leaks memory and causes a driver hang. Link: https://lore.kernel.org/linux-scsi/yq1zfajqpec.fsf@ca-mkp.ca.oracle.com/ Signed-off-by: John Meneghini Acked-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 10 ++++------ drivers/scsi/qla2xxx/qla_isr.c | 17 +++++++++-------- drivers/scsi/qla2xxx/qla_nvme.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 5 ++--- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 604e66bead1e..cb95b7b12051 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4890,7 +4890,9 @@ struct purex_item { struct purex_item *pkt); atomic_t in_use; uint16_t size; - uint8_t iocb[] __counted_by(size); + struct { + uint8_t iocb[64]; + } iocb; }; #include "qla_edif.h" @@ -5099,6 +5101,7 @@ typedef struct scsi_qla_host { struct list_head head; spinlock_t lock; } purex_list; + struct purex_item default_item; struct name_list_extended gnl; /* Count of active session/fcport */ @@ -5127,11 +5130,6 @@ typedef struct scsi_qla_host { #define DPORT_DIAG_IN_PROGRESS BIT_0 #define DPORT_DIAG_CHIP_RESET_IN_PROGRESS BIT_1 uint16_t dport_status; - - /* Must be last --ends in a flexible-array member. */ - TRAILING_OVERLAP(struct purex_item, default_item, iocb, - uint8_t __default_item_iocb[QLA_DEFAULT_PAYLOAD_SIZE]; - ); } scsi_qla_host_t; struct qla27xx_image_status { diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 4559b490614d..c4c6b5c6658c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1077,17 +1077,17 @@ static struct purex_item * qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size) { struct purex_item *item = NULL; + uint8_t item_hdr_size = sizeof(*item); if (size > QLA_DEFAULT_PAYLOAD_SIZE) { - item = kzalloc(struct_size(item, iocb, size), GFP_ATOMIC); + item = kzalloc(item_hdr_size + + (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC); } else { if (atomic_inc_return(&vha->default_item.in_use) == 1) { item = &vha->default_item; goto initialize_purex_header; } else { - item = kzalloc( - struct_size(item, iocb, QLA_DEFAULT_PAYLOAD_SIZE), - GFP_ATOMIC); + item = kzalloc(item_hdr_size, GFP_ATOMIC); } } if (!item) { @@ -1127,16 +1127,17 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt, * @vha: SCSI driver HA context * @pkt: ELS packet */ -static struct purex_item * -qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt) +static struct purex_item +*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt) { struct purex_item *item; - item = qla24xx_alloc_purex_item(vha, QLA_DEFAULT_PAYLOAD_SIZE); + item = qla24xx_alloc_purex_item(vha, + QLA_DEFAULT_PAYLOAD_SIZE); if (!item) return item; - memcpy(&item->iocb, pkt, QLA_DEFAULT_PAYLOAD_SIZE); + memcpy(&item->iocb, pkt, sizeof(item->iocb)); return item; } diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 065f9bcca26f..316594aa40cc 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -1308,7 +1308,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) ql_dbg(ql_dbg_unsol, vha, 0x2121, "PURLS OP[%01x] size %d xchg addr 0x%x portid %06x\n", - item->iocb[3], item->size, uctx->exchange_address, + item->iocb.iocb[3], item->size, uctx->exchange_address, fcport->d_id.b24); /* +48 0 1 2 3 4 5 6 7 8 9 A B C D E F * ----- ----------------------------------------------- diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 98a5c105fdfd..9a2f328200ab 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -6459,10 +6459,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void qla24xx_free_purex_item(struct purex_item *item) { - if (item == &item->vha->default_item) { + if (item == &item->vha->default_item) memset(&item->vha->default_item, 0, sizeof(struct purex_item)); - memset(&item->vha->__default_item_iocb, 0, QLA_DEFAULT_PAYLOAD_SIZE); - } else + else kfree(item); } From f966e02ae52192928d544262ee7a68611e333031 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Fri, 26 Sep 2025 09:29:26 +0800 Subject: [PATCH 3/7] scsi: ufs: core: Fix runtime suspend error deadlock Resolve the deadlock issue during runtime suspend when an error triggers the error handler. Prevent the deadlock by checking pm_op_in_progress and performing a quick recovery. This approach ensures that the error handler does not wait indefinitely for runtime PM to resume, allowing runtime suspend to proceed smoothly. Signed-off-by: Peter Wang Suggested-by: Bart Van Assche Reviewed-by: Bart Van Assche Message-Id: <20250926012940.3933367-1-peter.wang@mediatek.com> Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufshcd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index b2e103aa4e62..fd7defb3e2cf 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -6673,6 +6673,14 @@ static void ufshcd_err_handler(struct work_struct *work) } spin_unlock_irqrestore(hba->host->host_lock, flags); + ufshcd_rpm_get_noresume(hba); + if (hba->pm_op_in_progress) { + ufshcd_link_recovery(hba); + ufshcd_rpm_put(hba); + return; + } + ufshcd_rpm_put(hba); + ufshcd_err_handling_prepare(hba); spin_lock_irqsave(hba->host->host_lock, flags); From 0ba7a254afd037cfc2b656f379c54b43c6e574e8 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 29 Sep 2025 13:27:30 +0200 Subject: [PATCH 4/7] scsi: ufs: core: Fix PM QoS mutex initialization hba->pm_qos_mutex is used very early as a part of ufshcd_init(), so it need to be initialized before that call. This fixes the following warning: ------------[ cut here ]------------ DEBUG_LOCKS_WARN_ON(lock->magic != lock) WARNING: kernel/locking/mutex.c:577 at __mutex_lock+0x268/0x894, CPU#4: kworker/u32:4/72 Modules linked in: CPU: 4 UID: 0 PID: 72 Comm: kworker/u32:4 Not tainted 6.17.0-rc7-next-20250926+ #11223 PREEMPT Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Workqueue: events_unbound deferred_probe_work_func pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __mutex_lock+0x268/0x894 lr : __mutex_lock+0x268/0x894 ... Call trace: __mutex_lock+0x268/0x894 (P) mutex_lock_nested+0x24/0x30 ufshcd_pm_qos_update+0x30/0x78 ufshcd_setup_clocks+0x2d4/0x3c4 ufshcd_init+0x234/0x126c ufshcd_pltfrm_init+0x62c/0x82c ufs_qcom_probe+0x20/0x58 platform_probe+0x5c/0xac really_probe+0xbc/0x298 __driver_probe_device+0x78/0x12c driver_probe_device+0x40/0x164 __device_attach_driver+0xb8/0x138 bus_for_each_drv+0x80/0xdc __device_attach+0xa8/0x1b0 device_initial_probe+0x14/0x20 bus_probe_device+0xb0/0xb4 deferred_probe_work_func+0x8c/0xc8 process_one_work+0x208/0x60c worker_thread+0x244/0x388 kthread+0x150/0x228 ret_from_fork+0x10/0x20 irq event stamp: 57267 hardirqs last enabled at (57267): [] _raw_spin_unlock_irqrestore+0x74/0x78 hardirqs last disabled at (57266): [] clk_enable_lock+0x7c/0xf0 softirqs last enabled at (56270): [] handle_softirqs+0x4c4/0x4dc softirqs last disabled at (56265): [] __do_softirq+0x14/0x20 ---[ end trace 0000000000000000 ]--- Fixes: 79dde5f7dc7c ("scsi: ufs: core: Fix data race in CPU latency PM QoS request handling") Signed-off-by: Marek Szyprowski Reviewed-by: Bart Van Assche Message-Id: <20250929112730.3782765-1-m.szyprowski@samsung.com> Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufshcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index fd7defb3e2cf..319dd6f6229b 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -10669,6 +10669,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) */ spin_lock_init(&hba->clk_gating.lock); + /* Initialize mutex for PM QoS request synchronization */ + mutex_init(&hba->pm_qos_mutex); + /* * Set the default power management level for runtime and system PM. * Host controller drivers can override them in their @@ -10757,9 +10760,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) mutex_init(&hba->wb_mutex); - /* Initialize mutex for PM QoS request synchronization */ - mutex_init(&hba->pm_qos_mutex); - init_rwsem(&hba->clk_scaling_lock); ufshcd_init_clk_gating(hba); From 60cd16a3b7439ccb699d0bf533799eeb894fd217 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Sat, 20 Sep 2025 21:42:01 +0800 Subject: [PATCH 5/7] scsi: mvsas: Fix use-after-free bugs in mvs_work_queue During the detaching of Marvell's SAS/SATA controller, the original code calls cancel_delayed_work() in mvs_free() to cancel the delayed work item mwq->work_q. However, if mwq->work_q is already running, the cancel_delayed_work() may fail to cancel it. This can lead to use-after-free scenarios where mvs_free() frees the mvs_info while mvs_work_queue() is still executing and attempts to access the already-freed mvs_info. A typical race condition is illustrated below: CPU 0 (remove) | CPU 1 (delayed work callback) mvs_pci_remove() | mvs_free() | mvs_work_queue() cancel_delayed_work() | kfree(mvi) | | mvi-> // UAF Replace cancel_delayed_work() with cancel_delayed_work_sync() to ensure that the delayed work item is properly canceled and any executing delayed work item completes before the mvs_info is deallocated. This bug was found by static analysis. Fixes: 20b09c2992fe ("[SCSI] mvsas: add support for 94xx; layout change; bug fixes") Signed-off-by: Duoming Zhou Signed-off-by: Martin K. Petersen --- drivers/scsi/mvsas/mv_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 2c72da6b8cf0..7f1ad305eee6 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -124,7 +124,7 @@ static void mvs_free(struct mvs_info *mvi) if (mvi->shost) scsi_host_put(mvi->shost); list_for_each_entry(mwq, &mvi->wq_list, entry) - cancel_delayed_work(&mwq->work_q); + cancel_delayed_work_sync(&mwq->work_q); kfree(mvi->rsvd_tags); kfree(mvi); } From bb7663dec67b691528f104894429b3859fb16c14 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 29 Sep 2025 18:09:39 -0700 Subject: [PATCH 6/7] scsi: ufs: sysfs: Make HID attributes visible Call sysfs_update_group() after reading the device descriptor to ensure the HID sysfs attributes are visible when the feature is supported. Fixes: ae7795a8c258 ("scsi: ufs: core: Add HID support") Signed-off-by: Daniel Lee Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufs-sysfs.c | 2 +- drivers/ufs/core/ufs-sysfs.h | 1 + drivers/ufs/core/ufshcd.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index 0086816b27cd..c040afc6668e 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -1949,7 +1949,7 @@ static umode_t ufs_sysfs_hid_is_visible(struct kobject *kobj, return hba->dev_info.hid_sup ? attr->mode : 0; } -static const struct attribute_group ufs_sysfs_hid_group = { +const struct attribute_group ufs_sysfs_hid_group = { .name = "hid", .attrs = ufs_sysfs_hid, .is_visible = ufs_sysfs_hid_is_visible, diff --git a/drivers/ufs/core/ufs-sysfs.h b/drivers/ufs/core/ufs-sysfs.h index 8d94af3b8077..6efb82a082fd 100644 --- a/drivers/ufs/core/ufs-sysfs.h +++ b/drivers/ufs/core/ufs-sysfs.h @@ -14,5 +14,6 @@ void ufs_sysfs_remove_nodes(struct device *dev); extern const struct attribute_group ufs_sysfs_unit_descriptor_group; extern const struct attribute_group ufs_sysfs_lun_attributes_group; +extern const struct attribute_group ufs_sysfs_hid_group; #endif diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 319dd6f6229b..127b691402f9 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -8480,6 +8480,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba) DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP) & UFS_DEV_HID_SUPPORT; + sysfs_update_group(&hba->dev->kobj, &ufs_sysfs_hid_group); + model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; err = ufshcd_read_string_desc(hba, model_index, From 558ae4579810fa0fef011944230c65a6f3087f85 Mon Sep 17 00:00:00 2001 From: Hoyoung Seo Date: Tue, 30 Sep 2025 15:14:28 +0900 Subject: [PATCH 7/7] scsi: ufs: core: Include UTP error in INT_FATAL_ERRORS When a UTP error occurs in isolation, UFS is not currently recoverable. This is because the UTP error is not considered fatal in the error handling code, leading to either an I/O timeout or an OCS error. Add the UTP error flag to INT_FATAL_ERRORS so the controller will be reset in this situation. sd 0:0:0:0: [sda] tag#38 UNKNOWN(0x2003) Result: hostbyte=0x07 driverbyte=DRIVER_OK cmd_age=0s sd 0:0:0:0: [sda] tag#38 CDB: opcode=0x28 28 00 00 51 24 e2 00 00 08 00 I/O error, dev sda, sector 42542864 op 0x0:(READ) flags 0x80700 phys_seg 8 prio class 2 OCS error from controller = 9 for tag 39 pa_err[1] = 0x80000010 at 2667224756 us pa_err: total cnt=2 dl_err[0] = 0x80000002 at 2667148060 us dl_err[1] = 0x80002000 at 2667282844 us No record of nl_err No record of tl_err No record of dme_err No record of auto_hibern8_err fatal_err[0] = 0x804 at 2667282836 us --------------------------------------------------- REGISTER --------------------------------------------------- NAME OFFSET VALUE STD HCI SFR 0xfffffff0 0x0 AHIT 0x18 0x814 INTERRUPT STATUS 0x20 0x1000 INTERRUPT ENABLE 0x24 0x70ef5 [mkp: commit desc] Signed-off-by: Hoyoung Seo Reviewed-by: Bart Van Assche Message-Id: <20250930061428.617955-1-hy50.seo@samsung.com> Signed-off-by: Martin K. Petersen --- include/ufs/ufshci.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h index 612500a7088f..e64b70132101 100644 --- a/include/ufs/ufshci.h +++ b/include/ufs/ufshci.h @@ -180,6 +180,7 @@ static inline u32 ufshci_version(u32 major, u32 minor) #define UTP_TASK_REQ_COMPL 0x200 #define UIC_COMMAND_COMPL 0x400 #define DEVICE_FATAL_ERROR 0x800 +#define UTP_ERROR 0x1000 #define CONTROLLER_FATAL_ERROR 0x10000 #define SYSTEM_BUS_FATAL_ERROR 0x20000 #define CRYPTO_ENGINE_FATAL_ERROR 0x40000 @@ -199,7 +200,8 @@ static inline u32 ufshci_version(u32 major, u32 minor) CONTROLLER_FATAL_ERROR |\ SYSTEM_BUS_FATAL_ERROR |\ CRYPTO_ENGINE_FATAL_ERROR |\ - UIC_LINK_LOST) + UIC_LINK_LOST |\ + UTP_ERROR) /* HCS - Host Controller Status 30h */ #define DEVICE_PRESENT 0x1