SCSI misc on 20251011

Fixes only in drivers (ufs, mvsas, qla2xxx, target) that came in just
 before or during the merge window.  The most important one is the
 qla2xxx which reverts a conversion to fix flexible array member
 warnings, that went up in this merge window but which turned out on
 further testing to be causing data corruption.
 
 Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
 -----BEGIN PGP SIGNATURE-----
 
 iLgEABMIAGAWIQTnYEDbdso9F2cI+arnQslM7pishQUCaOpnUhsUgAAAAAAEAA5t
 YW51MiwyLjUrMS4xMSwyLDImHGphbWVzLmJvdHRvbWxleUBoYW5zZW5wYXJ0bmVy
 c2hpcC5jb20ACgkQ50LJTO6YrIUCFQEA1cADof79U9suDka2hAa2l7D4wJQ53qSj
 R7CwarAVX2wA/3RaEHySnSk+ivyHRl5AOYlPrYsnBo1o2KUq1M6kfviM
 =itgd
 -----END PGP SIGNATURE-----

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "Fixes only in drivers (ufs, mvsas, qla2xxx, target) that came in just
  before or during the merge window.

  The most important one is the qla2xxx which reverts a conversion to
  fix flexible array member warnings, that went up in this merge window
  but which turned out on further testing to be causing data corruption"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ufs: core: Include UTP error in INT_FATAL_ERRORS
  scsi: ufs: sysfs: Make HID attributes visible
  scsi: mvsas: Fix use-after-free bugs in mvs_work_queue
  scsi: ufs: core: Fix PM QoS mutex initialization
  scsi: ufs: core: Fix runtime suspend error deadlock
  Revert "scsi: qla2xxx: Fix memcpy() field-spanning write issue"
  scsi: target: target_core_configfs: Add length check to avoid buffer overflow
This commit is contained in:
Linus Torvalds 2025-10-11 11:49:00 -07:00
commit 2a6edd867b
10 changed files with 36 additions and 25 deletions

View File

@ -124,7 +124,7 @@ static void mvs_free(struct mvs_info *mvi)
if (mvi->shost) if (mvi->shost)
scsi_host_put(mvi->shost); scsi_host_put(mvi->shost);
list_for_each_entry(mwq, &mvi->wq_list, entry) 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->rsvd_tags);
kfree(mvi); kfree(mvi);
} }

View File

@ -4890,7 +4890,9 @@ struct purex_item {
struct purex_item *pkt); struct purex_item *pkt);
atomic_t in_use; atomic_t in_use;
uint16_t size; uint16_t size;
uint8_t iocb[] __counted_by(size); struct {
uint8_t iocb[64];
} iocb;
}; };
#include "qla_edif.h" #include "qla_edif.h"
@ -5099,6 +5101,7 @@ typedef struct scsi_qla_host {
struct list_head head; struct list_head head;
spinlock_t lock; spinlock_t lock;
} purex_list; } purex_list;
struct purex_item default_item;
struct name_list_extended gnl; struct name_list_extended gnl;
/* Count of active session/fcport */ /* Count of active session/fcport */
@ -5127,11 +5130,6 @@ typedef struct scsi_qla_host {
#define DPORT_DIAG_IN_PROGRESS BIT_0 #define DPORT_DIAG_IN_PROGRESS BIT_0
#define DPORT_DIAG_CHIP_RESET_IN_PROGRESS BIT_1 #define DPORT_DIAG_CHIP_RESET_IN_PROGRESS BIT_1
uint16_t dport_status; 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; } scsi_qla_host_t;
struct qla27xx_image_status { struct qla27xx_image_status {

View File

@ -1077,17 +1077,17 @@ static struct purex_item *
qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size) qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
{ {
struct purex_item *item = NULL; struct purex_item *item = NULL;
uint8_t item_hdr_size = sizeof(*item);
if (size > QLA_DEFAULT_PAYLOAD_SIZE) { 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 { } else {
if (atomic_inc_return(&vha->default_item.in_use) == 1) { if (atomic_inc_return(&vha->default_item.in_use) == 1) {
item = &vha->default_item; item = &vha->default_item;
goto initialize_purex_header; goto initialize_purex_header;
} else { } else {
item = kzalloc( item = kzalloc(item_hdr_size, GFP_ATOMIC);
struct_size(item, iocb, QLA_DEFAULT_PAYLOAD_SIZE),
GFP_ATOMIC);
} }
} }
if (!item) { if (!item) {
@ -1127,16 +1127,17 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
* @vha: SCSI driver HA context * @vha: SCSI driver HA context
* @pkt: ELS packet * @pkt: ELS packet
*/ */
static struct purex_item * static struct purex_item
qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt) *qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
{ {
struct purex_item *item; 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) if (!item)
return item; return item;
memcpy(&item->iocb, pkt, QLA_DEFAULT_PAYLOAD_SIZE); memcpy(&item->iocb, pkt, sizeof(item->iocb));
return item; return item;
} }

View File

@ -1308,7 +1308,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp)
ql_dbg(ql_dbg_unsol, vha, 0x2121, ql_dbg(ql_dbg_unsol, vha, 0x2121,
"PURLS OP[%01x] size %d xchg addr 0x%x portid %06x\n", "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); fcport->d_id.b24);
/* +48 0 1 2 3 4 5 6 7 8 9 A B C D E F /* +48 0 1 2 3 4 5 6 7 8 9 A B C D E F
* ----- ----------------------------------------------- * ----- -----------------------------------------------

View File

@ -6459,10 +6459,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
void void
qla24xx_free_purex_item(struct purex_item *item) 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, 0, sizeof(struct purex_item));
memset(&item->vha->__default_item_iocb, 0, QLA_DEFAULT_PAYLOAD_SIZE); else
} else
kfree(item); kfree(item);
} }

View File

@ -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)); config_item_name(&dev->dev_group.cg_item));
cur_len++; /* Extra byte for NULL terminator */ 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" pr_warn("Ran out of lu_gp_show_attr"
"_members buffer\n"); "_members buffer\n");
break; break;

View File

@ -1949,7 +1949,7 @@ static umode_t ufs_sysfs_hid_is_visible(struct kobject *kobj,
return hba->dev_info.hid_sup ? attr->mode : 0; 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", .name = "hid",
.attrs = ufs_sysfs_hid, .attrs = ufs_sysfs_hid,
.is_visible = ufs_sysfs_hid_is_visible, .is_visible = ufs_sysfs_hid_is_visible,

View File

@ -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_unit_descriptor_group;
extern const struct attribute_group ufs_sysfs_lun_attributes_group; extern const struct attribute_group ufs_sysfs_lun_attributes_group;
extern const struct attribute_group ufs_sysfs_hid_group;
#endif #endif

View File

@ -6684,6 +6684,14 @@ static void ufshcd_err_handler(struct work_struct *work)
} }
spin_unlock_irqrestore(hba->host->host_lock, flags); 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); ufshcd_err_handling_prepare(hba);
spin_lock_irqsave(hba->host->host_lock, flags); spin_lock_irqsave(hba->host->host_lock, flags);
@ -8489,6 +8497,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba)
DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP) & DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP) &
UFS_DEV_HID_SUPPORT; UFS_DEV_HID_SUPPORT;
sysfs_update_group(&hba->dev->kobj, &ufs_sysfs_hid_group);
model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];
err = ufshcd_read_string_desc(hba, model_index, err = ufshcd_read_string_desc(hba, model_index,
@ -10677,6 +10687,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
*/ */
spin_lock_init(&hba->clk_gating.lock); 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. * Set the default power management level for runtime and system PM.
* Host controller drivers can override them in their * Host controller drivers can override them in their
@ -10765,9 +10778,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
mutex_init(&hba->wb_mutex); mutex_init(&hba->wb_mutex);
/* Initialize mutex for PM QoS request synchronization */
mutex_init(&hba->pm_qos_mutex);
init_rwsem(&hba->clk_scaling_lock); init_rwsem(&hba->clk_scaling_lock);
ufshcd_init_clk_gating(hba); ufshcd_init_clk_gating(hba);

View File

@ -180,6 +180,7 @@ static inline u32 ufshci_version(u32 major, u32 minor)
#define UTP_TASK_REQ_COMPL 0x200 #define UTP_TASK_REQ_COMPL 0x200
#define UIC_COMMAND_COMPL 0x400 #define UIC_COMMAND_COMPL 0x400
#define DEVICE_FATAL_ERROR 0x800 #define DEVICE_FATAL_ERROR 0x800
#define UTP_ERROR 0x1000
#define CONTROLLER_FATAL_ERROR 0x10000 #define CONTROLLER_FATAL_ERROR 0x10000
#define SYSTEM_BUS_FATAL_ERROR 0x20000 #define SYSTEM_BUS_FATAL_ERROR 0x20000
#define CRYPTO_ENGINE_FATAL_ERROR 0x40000 #define CRYPTO_ENGINE_FATAL_ERROR 0x40000
@ -199,7 +200,8 @@ static inline u32 ufshci_version(u32 major, u32 minor)
CONTROLLER_FATAL_ERROR |\ CONTROLLER_FATAL_ERROR |\
SYSTEM_BUS_FATAL_ERROR |\ SYSTEM_BUS_FATAL_ERROR |\
CRYPTO_ENGINE_FATAL_ERROR |\ CRYPTO_ENGINE_FATAL_ERROR |\
UIC_LINK_LOST) UIC_LINK_LOST |\
UTP_ERROR)
/* HCS - Host Controller Status 30h */ /* HCS - Host Controller Status 30h */
#define DEVICE_PRESENT 0x1 #define DEVICE_PRESENT 0x1