Skip to content

Commit 0f386a6

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Ten fixes, seven of which are in drivers. The core fixes are one to fix a potential crash on resume, one to sort out our reference count releases to avoid releasing in-use modules and one to adjust the cmd per lun calculation to avoid an overflow in hyper-v" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ufs: ufs-pci: Force a full restore after suspend-to-disk scsi: qla2xxx: Fix unmap of already freed sgl scsi: qla2xxx: Fix a memory leak in an error path of qla2x00_process_els() scsi: qla2xxx: Return -ENOMEM if kzalloc() fails scsi: sd: Fix crashes in sd_resume_runtime() scsi: mpi3mr: Fix duplicate device entries when scanning through sysfs scsi: core: Put LLD module refcnt after SCSI device is released scsi: storvsc: Fix validation for unsolicited incoming packets scsi: iscsi: Fix set_param() handling scsi: core: Fix shost->cmd_per_lun calculation in scsi_add_host_with_dma()
2 parents 9c0c4d2 + 4e5483b commit 0f386a6

File tree

11 files changed

+69
-41
lines changed

11 files changed

+69
-41
lines changed

drivers/scsi/hosts.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
220220
goto fail;
221221
}
222222

223-
shost->cmd_per_lun = min_t(short, shost->cmd_per_lun,
223+
/* Use min_t(int, ...) in case shost->can_queue exceeds SHRT_MAX */
224+
shost->cmd_per_lun = min_t(int, shost->cmd_per_lun,
224225
shost->can_queue);
225226

226227
error = scsi_init_sense_cache(shost);

drivers/scsi/mpi3mr/mpi3mr_os.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3736,7 +3736,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
37363736
shost->max_lun = -1;
37373737
shost->unique_id = mrioc->id;
37383738

3739-
shost->max_channel = 1;
3739+
shost->max_channel = 0;
37403740
shost->max_id = 0xFFFFFFFF;
37413741

37423742
if (prot_mask >= 0)

drivers/scsi/qla2xxx/qla_bsg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ qla2x00_process_els(struct bsg_job *bsg_job)
431431
goto done_free_fcport;
432432

433433
done_free_fcport:
434-
if (bsg_request->msgcode == FC_BSG_RPT_ELS)
434+
if (bsg_request->msgcode != FC_BSG_RPT_ELS)
435435
qla2x00_free_fcport(fcport);
436436
done:
437437
return rval;

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4157,7 +4157,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
41574157
ql_dbg_pci(ql_dbg_init, ha->pdev,
41584158
0xe0ee, "%s: failed alloc dsd\n",
41594159
__func__);
4160-
return 1;
4160+
return -ENOMEM;
41614161
}
41624162
ha->dif_bundle_kallocs++;
41634163

drivers/scsi/qla2xxx/qla_target.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,8 +3319,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
33193319
"RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
33203320
vha->flags.online, qla2x00_reset_active(vha),
33213321
cmd->reset_count, qpair->chip_reset);
3322-
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
3323-
return 0;
3322+
goto out_unmap_unlock;
33243323
}
33253324

33263325
/* Does F/W have an IOCBs for this request */
@@ -3445,10 +3444,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
34453444
prm.sg = NULL;
34463445
prm.req_cnt = 1;
34473446

3448-
/* Calculate number of entries and segments required */
3449-
if (qlt_pci_map_calc_cnt(&prm) != 0)
3450-
return -EAGAIN;
3451-
34523447
if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
34533448
(cmd->sess && cmd->sess->deleted)) {
34543449
/*
@@ -3466,6 +3461,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
34663461
return 0;
34673462
}
34683463

3464+
/* Calculate number of entries and segments required */
3465+
if (qlt_pci_map_calc_cnt(&prm) != 0)
3466+
return -EAGAIN;
3467+
34693468
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
34703469
/* Does F/W have an IOCBs for this request */
34713470
res = qlt_check_reserve_free_req(qpair, prm.req_cnt);
@@ -3870,9 +3869,6 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
38703869

38713870
BUG_ON(cmd->cmd_in_wq);
38723871

3873-
if (cmd->sg_mapped)
3874-
qlt_unmap_sg(cmd->vha, cmd);
3875-
38763872
if (!cmd->q_full)
38773873
qlt_decr_num_pend_cmds(cmd->vha);
38783874

drivers/scsi/scsi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,10 @@ EXPORT_SYMBOL(scsi_device_get);
553553
*/
554554
void scsi_device_put(struct scsi_device *sdev)
555555
{
556-
module_put(sdev->host->hostt->module);
556+
struct module *mod = sdev->host->hostt->module;
557+
557558
put_device(&sdev->sdev_gendev);
559+
module_put(mod);
558560
}
559561
EXPORT_SYMBOL(scsi_device_put);
560562

drivers/scsi/scsi_sysfs.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,12 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
449449
struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL;
450450
struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL;
451451
unsigned long flags;
452+
struct module *mod;
452453

453454
sdev = container_of(work, struct scsi_device, ew.work);
454455

456+
mod = sdev->host->hostt->module;
457+
455458
scsi_dh_release_device(sdev);
456459

457460
parent = sdev->sdev_gendev.parent;
@@ -502,11 +505,17 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
502505

503506
if (parent)
504507
put_device(parent);
508+
module_put(mod);
505509
}
506510

507511
static void scsi_device_dev_release(struct device *dev)
508512
{
509513
struct scsi_device *sdp = to_scsi_device(dev);
514+
515+
/* Set module pointer as NULL in case of module unloading */
516+
if (!try_module_get(sdp->host->hostt->module))
517+
sdp->host->hostt->module = NULL;
518+
510519
execute_in_process_context(scsi_device_dev_release_usercontext,
511520
&sdp->ew);
512521
}

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,8 +2930,6 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
29302930
session->recovery_tmo = value;
29312931
break;
29322932
default:
2933-
err = transport->set_param(conn, ev->u.set_param.param,
2934-
data, ev->u.set_param.len);
29352933
if ((conn->state == ISCSI_CONN_BOUND) ||
29362934
(conn->state == ISCSI_CONN_UP)) {
29372935
err = transport->set_param(conn, ev->u.set_param.param,

drivers/scsi/sd.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3683,7 +3683,12 @@ static int sd_resume(struct device *dev)
36833683
static int sd_resume_runtime(struct device *dev)
36843684
{
36853685
struct scsi_disk *sdkp = dev_get_drvdata(dev);
3686-
struct scsi_device *sdp = sdkp->device;
3686+
struct scsi_device *sdp;
3687+
3688+
if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
3689+
return 0;
3690+
3691+
sdp = sdkp->device;
36873692

36883693
if (sdp->ignore_media_change) {
36893694
/* clear the device's sense data */

drivers/scsi/storvsc_drv.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,11 +1285,15 @@ static void storvsc_on_channel_callback(void *context)
12851285
foreach_vmbus_pkt(desc, channel) {
12861286
struct vstor_packet *packet = hv_pkt_data(desc);
12871287
struct storvsc_cmd_request *request = NULL;
1288+
u32 pktlen = hv_pkt_datalen(desc);
12881289
u64 rqst_id = desc->trans_id;
1290+
u32 minlen = rqst_id ? sizeof(struct vstor_packet) -
1291+
stor_device->vmscsi_size_delta : sizeof(enum vstor_packet_operation);
12891292

1290-
if (hv_pkt_datalen(desc) < sizeof(struct vstor_packet) -
1291-
stor_device->vmscsi_size_delta) {
1292-
dev_err(&device->device, "Invalid packet len\n");
1293+
if (pktlen < minlen) {
1294+
dev_err(&device->device,
1295+
"Invalid pkt: id=%llu, len=%u, minlen=%u\n",
1296+
rqst_id, pktlen, minlen);
12931297
continue;
12941298
}
12951299

@@ -1302,13 +1306,23 @@ static void storvsc_on_channel_callback(void *context)
13021306
if (rqst_id == 0) {
13031307
/*
13041308
* storvsc_on_receive() looks at the vstor_packet in the message
1305-
* from the ring buffer. If the operation in the vstor_packet is
1306-
* COMPLETE_IO, then we call storvsc_on_io_completion(), and
1307-
* dereference the guest memory address. Make sure we don't call
1308-
* storvsc_on_io_completion() with a guest memory address that is
1309-
* zero if Hyper-V were to construct and send such a bogus packet.
1309+
* from the ring buffer.
1310+
*
1311+
* - If the operation in the vstor_packet is COMPLETE_IO, then
1312+
* we call storvsc_on_io_completion(), and dereference the
1313+
* guest memory address. Make sure we don't call
1314+
* storvsc_on_io_completion() with a guest memory address
1315+
* that is zero if Hyper-V were to construct and send such
1316+
* a bogus packet.
1317+
*
1318+
* - If the operation in the vstor_packet is FCHBA_DATA, then
1319+
* we call cache_wwn(), and access the data payload area of
1320+
* the packet (wwn_packet); however, there is no guarantee
1321+
* that the packet is big enough to contain such area.
1322+
* Future-proof the code by rejecting such a bogus packet.
13101323
*/
1311-
if (packet->operation == VSTOR_OPERATION_COMPLETE_IO) {
1324+
if (packet->operation == VSTOR_OPERATION_COMPLETE_IO ||
1325+
packet->operation == VSTOR_OPERATION_FCHBA_DATA) {
13121326
dev_err(&device->device, "Invalid packet with ID of 0\n");
13131327
continue;
13141328
}

0 commit comments

Comments
 (0)