scsi: qedf: Check if sense buffer has been allocated during completion
authorDupuis, Chad <chad.dupuis@cavium.com>
Fri, 2 Jun 2017 19:02:05 +0000 (12:02 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 13 Jun 2017 00:48:08 +0000 (20:48 -0400)
sc_cmd->sense_buffer is not guaranteed to be allocated so we need to
sc_cmd->check
if the pointer is NULL before trying to copy anything into it.

Fixes the crash:

[  143.793176] [0000:00:00.0]:[qedf_eh_device_reset:626]: LUN RESET Issued...
[  143.802996] BUG: unable to handle kernel NULL pointer dereference at           (null)
[  143.803063] IP: qedf_parse_fcp_rsp+0xe2/0x290 [qedf]
[  143.803077] PGD 0
[  143.803078] P4D 0

[  143.803103] Oops: 0002 [#1] SMP
[  143.803115] Modules linked in: msr(E) ebtable_filter(E) ebtables(E) ip6table_filter(E) ip6_tables(E) iptable_filter(E) ip_tables(E) x_tables(E) raw(E) scsi_transport_iscsi(E) br_netfilter(E) bridge(E) iscsi_ibft(E) iscsi_boot_sysfs(E) intel_rapl(E) sb_edac(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) coretemp(E) kvm_intel(E) kvm(E) irqbypass(E) crct10dif_pclmul(E) crc32_pclmul(E) xfs(E) ghash_clmulni_intel(E) pcbc(E) aesni_intel(E) aes_x86_64(E) crypto_simd(E) ipmi_ssif(E) glue_helper(E) iTCO_wdt(E) iTCO_vendor_support(E) lpc_ich(E) ipmi_si(E) pcspkr(E) hpilo(E) ioatdma(E) cryptd(E) ipmi_devintf(E) hpwdt(E) mfd_core(E) shpchp(E) dca(E) thermal(E) pcc_cpufreq(E) ipmi_msghandler(E) acpi_cpufreq(E) af_packet(E) btrfs(E) xor(E) raid6_pq(E) sr_mod(E) cdrom(E) ata_generic(E) sd_mod(E) 8021q(E) garp(E)
[  143.803302]  stp(E) llc(E) mrp(E) bnx2fc(E) cnic(E) uio(E) mgag200(E) ata_piix(E) i2c_algo_bit(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) ahci(E) fb_sys_fops(E) bnx2x(E) qedf(E) serio_raw(E) libahci(E) ttm(E) uhci_hcd(E) ehci_pci(E) qed(E) mdio(E) libcrc32c(E) ehci_hcd(E) crc32c_intel(E) drm(E) libata(E) usbcore(E) tg3(E) ptp(E) hpsa(E) pps_core(E) scsi_transport_sas(E) libphy(E) wmi(E) button(E) fcoe(E) libfcoe(E) libfc(E) scsi_transport_fc(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) scsi_mod(E) autofs4(E)
[  143.803438] CPU: 31 PID: 494 Comm: kworker/31:2 Tainted: G            E   4.12.0-rc1-69-default+ #1
[  143.803461] Hardware name: HP ProLiant DL380p Gen8, BIOS P70 08/20/2012
[  143.803480] Workqueue: qedf_io_wq qedf_fp_io_handler [qedf]
[  143.803496] task: ffff8804181a0000 task.stack: ffffc90003b64000
[  143.803514] RIP: 0010:qedf_parse_fcp_rsp+0xe2/0x290 [qedf]
[  143.803529] RSP: 0018:ffffc90003b67dc8 EFLAGS: 00010246
[  143.803544] RAX: 0000000000000000 RBX: ffff880401abdd48 RCX: 000000000000000c
[  143.803563] RDX: 0000000000000060 RSI: ffffffffa039c740 RDI: 0000000000000000
[  143.803581] RBP: ffffc90003b67df0 R08: ffffffffa039dba8 R09: 0000000000000000
[  143.803600] R10: 0000000000000000 R11: 0000000000000018 R12: 0000000000000000
[  143.803619] R13: ffff88040ac80bc8 R14: 0000000000000008 R15: ffff880407c14008
[  143.803638] FS:  0000000000000000(0000) GS:ffff88043f7c0000(0000) knlGS:0000000000000000
[  143.804360] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  143.805065] CR2: 0000000000000000 CR3: 0000000001c09000 CR4: 00000000000406e0
[  143.805753] Call Trace:
[  143.806436]  qedf_process_tmf_compl+0x19/0x30 [qedf]
[  143.807124]  qedf_process_cqe+0x265/0x280 [qedf]
[  143.807800]  qedf_fp_io_handler+0x26/0x60 [qedf]
[  143.808469]  process_one_work+0x138/0x370
[  143.809133]  worker_thread+0x4d/0x3b0
[  143.809797]  kthread+0x109/0x140
[  143.810451]  ? rescuer_thread+0x320/0x320
[  143.811100]  ? kthread_park+0x60/0x60
[  143.811743]  ret_from_fork+0x2c/0x40

Signed-off-by: Chad Dupuis <chad.dupuis@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qedf/qedf_io.c

index ea37c78418d76f7d1f8d284f6b15f4634554a0be..ded386036c2771a166a648c2d9a1960187501f3e 100644 (file)
@@ -1041,10 +1041,13 @@ static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req,
                fcp_sns_len = SCSI_SENSE_BUFFERSIZE;
        }
 
-       memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-       if (fcp_sns_len)
-               memcpy(sc_cmd->sense_buffer, sense_data,
-                   fcp_sns_len);
+       /* The sense buffer can be NULL for TMF commands */
+       if (sc_cmd->sense_buffer) {
+               memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+               if (fcp_sns_len)
+                       memcpy(sc_cmd->sense_buffer, sense_data,
+                           fcp_sns_len);
+       }
 }
 
 static void qedf_unmap_sg_list(struct qedf_ctx *qedf, struct qedf_ioreq *io_req)