[PATCH v1 1/1] drivers/usb/storage: NULL pointer dereference [null-pointer-deref] (CWE 476) problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux