bnx2fc: Check sc_cmd device and host pointer before returning the command to the...
authorChad Dupuis <chad.dupuis@qlogic.com>
Thu, 7 Apr 2016 13:07:59 +0000 (09:07 -0400)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 15 Apr 2016 20:53:10 +0000 (16:53 -0400)
When we are in connection recovery and the internal command timer on a
request pops, either the scsi_cmnd->device or scsi_cmnd->device->host
back pointers may be NULL as the device that the command that the
request was submitted on may have been subsequently reaped due to the
connection recovery. This can cause one or both of the pointers above to
be NULL and cause a system crash if we try to return the command to the
midlayer.

Instead, double check the pointers before the return to the midlayer so
as to prevent the crash and let the upper layers finish the session
recovery and rediscover the device.

Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/bnx2fc/bnx2fc_io.c

index 562175869d0fcd0de9c65bf5c337833fbef87f29..026f394a38518f29f5bd9ffdd42ac24dc3b594cd 100644 (file)
@@ -179,12 +179,24 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
 
        bnx2fc_unmap_sg_list(io_req);
        io_req->sc_cmd = NULL;
+
+       /* Sanity checks before returning command to mid-layer */
        if (!sc_cmd) {
                printk(KERN_ERR PFX "scsi_done - sc_cmd NULL. "
                                    "IO(0x%x) already cleaned up\n",
                       io_req->xid);
                return;
        }
+       if (!sc_cmd->device) {
+               pr_err(PFX "0x%x: sc_cmd->device is NULL.\n", io_req->xid);
+               return;
+       }
+       if (!sc_cmd->device->host) {
+               pr_err(PFX "0x%x: sc_cmd->device->host is NULL.\n",
+                   io_req->xid);
+               return;
+       }
+
        sc_cmd->result = err_code << 16;
 
        BNX2FC_IO_DBG(io_req, "sc=%p, result=0x%x, retries=%d, allowed=%d\n",