The Parfait (version 2.1.0) static code analysis tool found the following NULL pointer dereference problem. dev_to_shost() in include/scsi/scsi_host.h has the ability to return NULL if the scsi host device does not have the Scsi_host->parent field set. With the possibilty of a NULL pointer being set for the Scsi_Host->parent field, calls to host_to_us() have to make sure the return pointer is not null. Changes were made to check for a return value of NULL on calls to host_to_us(). Signed-off-by: Joe Moriarty <joe.moriarty@xxxxxxxxxx> Reviewed-by: Steven Sistare <steven.sistare@xxxxxxxxxx> Acked-by: Hakon Bugge <hakon.bugge@xxxxxxxxxx> --- drivers/usb/storage/scsiglue.c | 53 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index c267f2812a04..94af609d49bf 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -66,6 +66,9 @@ static int slave_alloc (struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); + if (!us) + pr_warn("Error in %s: us = NULL\n", __func__); + /* * Set the INQUIRY transfer length to 36. We don't use any of * the extra data and many devices choke if asked for more or @@ -102,6 +105,11 @@ static int slave_configure(struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); + if (!us) { + pr_warn("Error in %s: us = NULL\n", __func__); + return 0; + } + /* * Many devices have trouble transferring more than 32KB at a time, * while others have trouble with more than 64K. At this time we @@ -331,6 +339,11 @@ static int target_alloc(struct scsi_target *starget) { struct us_data *us = host_to_us(dev_to_shost(starget->dev.parent)); + if (!us) { + pr_warn("Error in %s: us = NULL\n", __func__); + return 0; + } + /* * Some USB drives don't support REPORT LUNS, even though they * report a SCSI revision level above 2. Tell the SCSI layer @@ -361,6 +374,11 @@ static int queuecommand_lck(struct scsi_cmnd *srb, { struct us_data *us = host_to_us(srb->device->host); + if (!us) { + pr_warn("Error in %s: us = NULL\n", __func__); + return 0; + } + /* check for state-transition errors */ if (us->srb != NULL) { printk(KERN_ERR USB_STORAGE "Error in %s: us->srb = %p\n", @@ -395,6 +413,11 @@ static int command_abort(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); + if (!us) { + pr_warn("Error in %s: us = NULL\n", __func__); + return FAILED; + } + usb_stor_dbg(us, "%s called\n", __func__); /* @@ -438,12 +461,17 @@ static int device_reset(struct scsi_cmnd *srb) struct us_data *us = host_to_us(srb->device->host); int result; - usb_stor_dbg(us, "%s called\n", __func__); + if (us) { + usb_stor_dbg(us, "%s called\n", __func__); - /* lock the device pointers and do the reset */ - mutex_lock(&(us->dev_mutex)); - result = us->transport_reset(us); - mutex_unlock(&us->dev_mutex); + /* lock the device pointers and do the reset */ + mutex_lock(&(us->dev_mutex)); + result = us->transport_reset(us); + mutex_unlock(&us->dev_mutex); + } else { + pr_warn("Error in %s: us = NULL\n", __func__); + result = -ENXIO; + } return result < 0 ? FAILED : SUCCESS; } @@ -454,9 +482,15 @@ static int bus_reset(struct scsi_cmnd *srb) struct us_data *us = host_to_us(srb->device->host); int result; - usb_stor_dbg(us, "%s called\n", __func__); + if (us) { + usb_stor_dbg(us, "%s called\n", __func__); + + result = usb_stor_port_reset(us); + } else { + pr_warn("Error in %s: us = NULL\n", __func__); + result = -ENXIO; + } - result = usb_stor_port_reset(us); return result < 0 ? FAILED : SUCCESS; } @@ -506,6 +540,11 @@ static int show_info (struct seq_file *m, struct Scsi_Host *host) struct us_data *us = host_to_us(host); const char *string; + if (!us) { + pr_warn("Error in %s: us = NULL\n", __func__); + return 0; + } + /* print the controller name */ seq_printf(m, " Host scsi%d: usb-storage\n", host->host_no); -- 2.15.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html