aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-12-15 15:51:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-12-15 15:51:42 -0500
commit66dbbd72005c5ebdd1de35ba5a41393f01df48d6 (patch)
tree67cbdbb1407e8592d79fbef1c86aea9510cd2f0e
parent07a20ed1e3c25925282aebb2f8cec0e3b5ae99b6 (diff)
parent14e3062fb18532175af4d1c4073597999f7a2248 (diff)
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "The most important one is the bfa fix because it's easy to oops the kernel with this driver (this includes the commit that corrects the compiler warning in the original), a regression in the new timespec conversion in aacraid and a regression in the Fibre Channel ELS handling patch. The other three are a theoretical problem with termination in the vendor/host matching code and a use after free in lpfc. The additional patches are a fix for an I/O hang in the mq code under certain circumstances and a rare oops in some debugging code" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: core: Fix a scsi_show_rq() NULL pointer dereference scsi: MAINTAINERS: change FCoE list to linux-scsi scsi: libsas: fix length error in sas_smp_handler() scsi: bfa: fix type conversion warning scsi: core: run queue if SCSI device queue isn't ready and queue is idle scsi: scsi_devinfo: cleanly zero-pad devinfo strings scsi: scsi_devinfo: handle non-terminated strings scsi: bfa: fix access to bfad_im_port_s scsi: aacraid: address UBSAN warning regression scsi: libfc: fix ELS request handling scsi: lpfc: Use after free in lpfc_rq_buf_free()
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/scsi/aacraid/commsup.c8
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c6
-rw-r--r--drivers/scsi/bfa/bfad_im.c6
-rw-r--r--drivers/scsi/bfa/bfad_im.h10
-rw-r--r--drivers/scsi/libfc/fc_lport.c4
-rw-r--r--drivers/scsi/libsas/sas_expander.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c2
-rw-r--r--drivers/scsi/scsi_debugfs.c6
-rw-r--r--drivers/scsi/scsi_devinfo.c27
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/sd.c4
12 files changed, 54 insertions, 33 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 82ad0eabce4f..e626cb622dca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5431,7 +5431,7 @@ F: drivers/media/tuners/fc2580*
5431 5431
5432FCOE SUBSYSTEM (libfc, libfcoe, fcoe) 5432FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
5433M: Johannes Thumshirn <jth@kernel.org> 5433M: Johannes Thumshirn <jth@kernel.org>
5434L: fcoe-devel@open-fcoe.org 5434L: linux-scsi@vger.kernel.org
5435W: www.Open-FCoE.org 5435W: www.Open-FCoE.org
5436S: Supported 5436S: Supported
5437F: drivers/scsi/libfc/ 5437F: drivers/scsi/libfc/
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index bec9f3193f60..80a8cb26cdea 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -2482,8 +2482,8 @@ int aac_command_thread(void *data)
2482 /* Synchronize our watches */ 2482 /* Synchronize our watches */
2483 if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec) 2483 if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec)
2484 && (now.tv_nsec > (NSEC_PER_SEC / HZ))) 2484 && (now.tv_nsec > (NSEC_PER_SEC / HZ)))
2485 difference = (((NSEC_PER_SEC - now.tv_nsec) * HZ) 2485 difference = HZ + HZ / 2 -
2486 + NSEC_PER_SEC / 2) / NSEC_PER_SEC; 2486 now.tv_nsec / (NSEC_PER_SEC / HZ);
2487 else { 2487 else {
2488 if (now.tv_nsec > NSEC_PER_SEC / 2) 2488 if (now.tv_nsec > NSEC_PER_SEC / 2)
2489 ++now.tv_sec; 2489 ++now.tv_sec;
@@ -2507,6 +2507,10 @@ int aac_command_thread(void *data)
2507 if (kthread_should_stop()) 2507 if (kthread_should_stop())
2508 break; 2508 break;
2509 2509
2510 /*
2511 * we probably want usleep_range() here instead of the
2512 * jiffies computation
2513 */
2510 schedule_timeout(difference); 2514 schedule_timeout(difference);
2511 2515
2512 if (kthread_should_stop()) 2516 if (kthread_should_stop())
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 72ca2a2e08e2..b2fa195adc7a 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3135,7 +3135,8 @@ bfad_im_bsg_vendor_request(struct bsg_job *job)
3135 struct fc_bsg_request *bsg_request = job->request; 3135 struct fc_bsg_request *bsg_request = job->request;
3136 struct fc_bsg_reply *bsg_reply = job->reply; 3136 struct fc_bsg_reply *bsg_reply = job->reply;
3137 uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; 3137 uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0];
3138 struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job)); 3138 struct Scsi_Host *shost = fc_bsg_to_shost(job);
3139 struct bfad_im_port_s *im_port = bfad_get_im_port(shost);
3139 struct bfad_s *bfad = im_port->bfad; 3140 struct bfad_s *bfad = im_port->bfad;
3140 void *payload_kbuf; 3141 void *payload_kbuf;
3141 int rc = -EINVAL; 3142 int rc = -EINVAL;
@@ -3350,7 +3351,8 @@ int
3350bfad_im_bsg_els_ct_request(struct bsg_job *job) 3351bfad_im_bsg_els_ct_request(struct bsg_job *job)
3351{ 3352{
3352 struct bfa_bsg_data *bsg_data; 3353 struct bfa_bsg_data *bsg_data;
3353 struct bfad_im_port_s *im_port = shost_priv(fc_bsg_to_shost(job)); 3354 struct Scsi_Host *shost = fc_bsg_to_shost(job);
3355 struct bfad_im_port_s *im_port = bfad_get_im_port(shost);
3354 struct bfad_s *bfad = im_port->bfad; 3356 struct bfad_s *bfad = im_port->bfad;
3355 bfa_bsg_fcpt_t *bsg_fcpt; 3357 bfa_bsg_fcpt_t *bsg_fcpt;
3356 struct bfad_fcxp *drv_fcxp; 3358 struct bfad_fcxp *drv_fcxp;
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 24e657a4ec80..c05d6e91e4bd 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -546,6 +546,7 @@ int
546bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, 546bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
547 struct device *dev) 547 struct device *dev)
548{ 548{
549 struct bfad_im_port_pointer *im_portp;
549 int error = 1; 550 int error = 1;
550 551
551 mutex_lock(&bfad_mutex); 552 mutex_lock(&bfad_mutex);
@@ -564,7 +565,8 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
564 goto out_free_idr; 565 goto out_free_idr;
565 } 566 }
566 567
567 im_port->shost->hostdata[0] = (unsigned long)im_port; 568 im_portp = shost_priv(im_port->shost);
569 im_portp->p = im_port;
568 im_port->shost->unique_id = im_port->idr_id; 570 im_port->shost->unique_id = im_port->idr_id;
569 im_port->shost->this_id = -1; 571 im_port->shost->this_id = -1;
570 im_port->shost->max_id = MAX_FCP_TARGET; 572 im_port->shost->max_id = MAX_FCP_TARGET;
@@ -748,7 +750,7 @@ bfad_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
748 750
749 sht->sg_tablesize = bfad->cfg_data.io_max_sge; 751 sht->sg_tablesize = bfad->cfg_data.io_max_sge;
750 752
751 return scsi_host_alloc(sht, sizeof(unsigned long)); 753 return scsi_host_alloc(sht, sizeof(struct bfad_im_port_pointer));
752} 754}
753 755
754void 756void
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index c81ec2a77ef5..06ce4ba2b7bc 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -69,6 +69,16 @@ struct bfad_im_port_s {
69 struct fc_vport *fc_vport; 69 struct fc_vport *fc_vport;
70}; 70};
71 71
72struct bfad_im_port_pointer {
73 struct bfad_im_port_s *p;
74};
75
76static inline struct bfad_im_port_s *bfad_get_im_port(struct Scsi_Host *host)
77{
78 struct bfad_im_port_pointer *im_portp = shost_priv(host);
79 return im_portp->p;
80}
81
72enum bfad_itnim_state { 82enum bfad_itnim_state {
73 ITNIM_STATE_NONE, 83 ITNIM_STATE_NONE,
74 ITNIM_STATE_ONLINE, 84 ITNIM_STATE_ONLINE,
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 5da46052e179..21be672679fb 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -904,10 +904,14 @@ static void fc_lport_recv_els_req(struct fc_lport *lport,
904 case ELS_FLOGI: 904 case ELS_FLOGI:
905 if (!lport->point_to_multipoint) 905 if (!lport->point_to_multipoint)
906 fc_lport_recv_flogi_req(lport, fp); 906 fc_lport_recv_flogi_req(lport, fp);
907 else
908 fc_rport_recv_req(lport, fp);
907 break; 909 break;
908 case ELS_LOGO: 910 case ELS_LOGO:
909 if (fc_frame_sid(fp) == FC_FID_FLOGI) 911 if (fc_frame_sid(fp) == FC_FID_FLOGI)
910 fc_lport_recv_logo_req(lport, fp); 912 fc_lport_recv_logo_req(lport, fp);
913 else
914 fc_rport_recv_req(lport, fp);
911 break; 915 break;
912 case ELS_RSCN: 916 case ELS_RSCN:
913 lport->tt.disc_recv_req(lport, fp); 917 lport->tt.disc_recv_req(lport, fp);
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index ca1566237ae7..3183d63de4da 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -2145,7 +2145,7 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
2145 struct sas_rphy *rphy) 2145 struct sas_rphy *rphy)
2146{ 2146{
2147 struct domain_device *dev; 2147 struct domain_device *dev;
2148 unsigned int reslen = 0; 2148 unsigned int rcvlen = 0;
2149 int ret = -EINVAL; 2149 int ret = -EINVAL;
2150 2150
2151 /* no rphy means no smp target support (ie aic94xx host) */ 2151 /* no rphy means no smp target support (ie aic94xx host) */
@@ -2179,12 +2179,12 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
2179 2179
2180 ret = smp_execute_task_sg(dev, job->request_payload.sg_list, 2180 ret = smp_execute_task_sg(dev, job->request_payload.sg_list,
2181 job->reply_payload.sg_list); 2181 job->reply_payload.sg_list);
2182 if (ret > 0) { 2182 if (ret >= 0) {
2183 /* positive number is the untransferred residual */ 2183 /* bsg_job_done() requires the length received */
2184 reslen = ret; 2184 rcvlen = job->reply_payload.payload_len - ret;
2185 ret = 0; 2185 ret = 0;
2186 } 2186 }
2187 2187
2188out: 2188out:
2189 bsg_job_done(job, ret, reslen); 2189 bsg_job_done(job, ret, rcvlen);
2190} 2190}
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 56faeb049b4a..87c08ff37ddd 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -753,12 +753,12 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
753 drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); 753 drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys);
754 rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); 754 rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe);
755 if (rc < 0) { 755 if (rc < 0) {
756 (rqbp->rqb_free_buffer)(phba, rqb_entry);
757 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 756 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
758 "6409 Cannot post to RQ %d: %x %x\n", 757 "6409 Cannot post to RQ %d: %x %x\n",
759 rqb_entry->hrq->queue_id, 758 rqb_entry->hrq->queue_id,
760 rqb_entry->hrq->host_index, 759 rqb_entry->hrq->host_index,
761 rqb_entry->hrq->hba_index); 760 rqb_entry->hrq->hba_index);
761 (rqbp->rqb_free_buffer)(phba, rqb_entry);
762 } else { 762 } else {
763 list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); 763 list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list);
764 rqbp->buffer_count++; 764 rqbp->buffer_count++;
diff --git a/drivers/scsi/scsi_debugfs.c b/drivers/scsi/scsi_debugfs.c
index 01f08c03f2c1..c3765d29fd3f 100644
--- a/drivers/scsi/scsi_debugfs.c
+++ b/drivers/scsi/scsi_debugfs.c
@@ -8,9 +8,11 @@ void scsi_show_rq(struct seq_file *m, struct request *rq)
8{ 8{
9 struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req); 9 struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req);
10 int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); 10 int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc);
11 char buf[80]; 11 const u8 *const cdb = READ_ONCE(cmd->cmnd);
12 char buf[80] = "(?)";
12 13
13 __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len); 14 if (cdb)
15 __scsi_format_command(buf, sizeof(buf), cdb, cmd->cmd_len);
14 seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf, 16 seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf,
15 cmd->retries, msecs / 1000, msecs % 1000); 17 cmd->retries, msecs / 1000, msecs % 1000);
16} 18}
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 78d4aa8df675..449ef5adbb2b 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -34,7 +34,6 @@ struct scsi_dev_info_list_table {
34}; 34};
35 35
36 36
37static const char spaces[] = " "; /* 16 of them */
38static blist_flags_t scsi_default_dev_flags; 37static blist_flags_t scsi_default_dev_flags;
39static LIST_HEAD(scsi_dev_info_list); 38static LIST_HEAD(scsi_dev_info_list);
40static char scsi_dev_flags[256]; 39static char scsi_dev_flags[256];
@@ -298,20 +297,13 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length,
298 size_t from_length; 297 size_t from_length;
299 298
300 from_length = strlen(from); 299 from_length = strlen(from);
301 strncpy(to, from, min(to_length, from_length)); 300 /* This zero-pads the destination */
302 if (from_length < to_length) { 301 strncpy(to, from, to_length);
303 if (compatible) { 302 if (from_length < to_length && !compatible) {
304 /* 303 /*
305 * NUL terminate the string if it is short. 304 * space pad the string if it is short.
306 */ 305 */
307 to[from_length] = '\0'; 306 memset(&to[from_length], ' ', to_length - from_length);
308 } else {
309 /*
310 * space pad the string if it is short.
311 */
312 strncpy(&to[from_length], spaces,
313 to_length - from_length);
314 }
315 } 307 }
316 if (from_length > to_length) 308 if (from_length > to_length)
317 printk(KERN_WARNING "%s: %s string '%s' is too long\n", 309 printk(KERN_WARNING "%s: %s string '%s' is too long\n",
@@ -458,7 +450,8 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
458 /* 450 /*
459 * vendor strings must be an exact match 451 * vendor strings must be an exact match
460 */ 452 */
461 if (vmax != strlen(devinfo->vendor) || 453 if (vmax != strnlen(devinfo->vendor,
454 sizeof(devinfo->vendor)) ||
462 memcmp(devinfo->vendor, vskip, vmax)) 455 memcmp(devinfo->vendor, vskip, vmax))
463 continue; 456 continue;
464 457
@@ -466,7 +459,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
466 * @model specifies the full string, and 459 * @model specifies the full string, and
467 * must be larger or equal to devinfo->model 460 * must be larger or equal to devinfo->model
468 */ 461 */
469 mlen = strlen(devinfo->model); 462 mlen = strnlen(devinfo->model, sizeof(devinfo->model));
470 if (mmax < mlen || memcmp(devinfo->model, mskip, mlen)) 463 if (mmax < mlen || memcmp(devinfo->model, mskip, mlen))
471 continue; 464 continue;
472 return devinfo; 465 return devinfo;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 00742c50cd44..d9ca1dfab154 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1967,6 +1967,8 @@ static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx)
1967out_put_device: 1967out_put_device:
1968 put_device(&sdev->sdev_gendev); 1968 put_device(&sdev->sdev_gendev);
1969out: 1969out:
1970 if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev))
1971 blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY);
1970 return false; 1972 return false;
1971} 1973}
1972 1974
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 24fe68522716..a028ab3322a9 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1312,6 +1312,7 @@ static int sd_init_command(struct scsi_cmnd *cmd)
1312static void sd_uninit_command(struct scsi_cmnd *SCpnt) 1312static void sd_uninit_command(struct scsi_cmnd *SCpnt)
1313{ 1313{
1314 struct request *rq = SCpnt->request; 1314 struct request *rq = SCpnt->request;
1315 u8 *cmnd;
1315 1316
1316 if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) 1317 if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK)
1317 sd_zbc_write_unlock_zone(SCpnt); 1318 sd_zbc_write_unlock_zone(SCpnt);
@@ -1320,9 +1321,10 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
1320 __free_page(rq->special_vec.bv_page); 1321 __free_page(rq->special_vec.bv_page);
1321 1322
1322 if (SCpnt->cmnd != scsi_req(rq)->cmd) { 1323 if (SCpnt->cmnd != scsi_req(rq)->cmd) {
1323 mempool_free(SCpnt->cmnd, sd_cdb_pool); 1324 cmnd = SCpnt->cmnd;
1324 SCpnt->cmnd = NULL; 1325 SCpnt->cmnd = NULL;
1325 SCpnt->cmd_len = 0; 1326 SCpnt->cmd_len = 0;
1327 mempool_free(cmnd, sd_cdb_pool);
1326 } 1328 }
1327} 1329}
1328 1330