public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: James.Bottomley@steeleye.com
Cc: linux-scsi@vger.kernel.org
Subject: [PATCH] fix possible NULL pointer dereference in scsi_scan.c
Date: Tue, 11 Mar 2003 20:12:27 +0100	[thread overview]
Message-ID: <20030311201227.A986@lst.de> (raw)

If the sdev allocation fails and q is non-null we could dereference
sdev->request_queue.  While at it reformat the function to use
goto-based cleanup - that's much easier to parse.


--- 1.64/drivers/scsi/scsi_scan.c	Fri Mar  7 01:02:09 2003
+++ edited/drivers/scsi/scsi_scan.c	Mon Mar 10 14:23:23 2003
@@ -385,83 +385,92 @@
 	struct scsi_device *sdev, *device;
 
 	sdev = kmalloc(sizeof(*sdev), GFP_ATOMIC);
-	if (sdev != NULL) {
-		memset(sdev, 0, sizeof(Scsi_Device));
-		sdev->vendor = scsi_null_device_strs;
-		sdev->model = scsi_null_device_strs;
-		sdev->rev = scsi_null_device_strs;
-		sdev->host = shost;
-		sdev->id = id;
-		sdev->lun = lun;
-		sdev->channel = channel;
-		sdev->online = TRUE;
-		INIT_LIST_HEAD(&sdev->siblings);
-		INIT_LIST_HEAD(&sdev->same_target_siblings);
-		INIT_LIST_HEAD(&sdev->cmd_list);
-		spin_lock_init(&sdev->list_lock);
-		/*
-		 * Some low level driver could use device->type
-		 */
-		sdev->type = -1;
-		/*
-		 * Assume that the device will have handshaking problems,
-		 * and then fix this field later if it turns out it
-		 * doesn't
-		 */
-		sdev->borken = 1;
-
-		if (!q || *q == NULL) {
-			sdev->request_queue = scsi_alloc_queue(shost);
-			if (!sdev->request_queue)
-				goto out_bail;
-		} else {
-			sdev->request_queue = *q;
-			*q = NULL;
-		}
+	if (!sdev)
+		goto out;
+
+	memset(sdev, 0, sizeof(*sdev));
+	sdev->vendor = scsi_null_device_strs;
+	sdev->model = scsi_null_device_strs;
+	sdev->rev = scsi_null_device_strs;
+	sdev->host = shost;
+	sdev->id = id;
+	sdev->lun = lun;
+	sdev->channel = channel;
+	sdev->online = TRUE;
+	INIT_LIST_HEAD(&sdev->siblings);
+	INIT_LIST_HEAD(&sdev->same_target_siblings);
+	INIT_LIST_HEAD(&sdev->cmd_list);
+	spin_lock_init(&sdev->list_lock);
+
+	/*
+	 * Some low level driver could use device->type
+	 */
+	sdev->type = -1;
+
+	/*
+	 * Assume that the device will have handshaking problems,
+	 * and then fix this field later if it turns out it
+	 * doesn't
+	 */
+	sdev->borken = 1;
+
+	if (!q || *q == NULL) {
+		sdev->request_queue = scsi_alloc_queue(shost);
+		if (!sdev->request_queue)
+			goto out_free_dev;
+	} else {
+		sdev->request_queue = *q;
+		*q = NULL;
+	}
+
+	sdev->request_queue->queuedata = sdev;
+	scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+	init_waitqueue_head(&sdev->scpnt_wait);
 
-		sdev->request_queue->queuedata = sdev;
-		scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
-		init_waitqueue_head(&sdev->scpnt_wait);
-
-		if (shost->hostt->slave_alloc)
-			if (shost->hostt->slave_alloc(sdev)) {
-				goto out_bail;
-			}
-		/*
-		 * If there are any same target siblings, add this to the
-		 * sibling list
-		 */
-		list_for_each_entry(device, &shost->my_devices, siblings) {
-			if(device->id == sdev->id &&
-			   device->channel == sdev->channel) {
-				list_add_tail(&sdev->same_target_siblings,
-					      &device->same_target_siblings);
-				sdev->scsi_level = device->scsi_level;
-				break;
-			}
+	if (shost->hostt->slave_alloc) {
+		if (shost->hostt->slave_alloc(sdev))
+			goto out_free_queue;
+	}
+
+	/*
+	 * If there are any same target siblings, add this to the
+	 * sibling list
+	 */
+	list_for_each_entry(device, &shost->my_devices, siblings) {
+		if (device->id == sdev->id &&
+		    device->channel == sdev->channel) {
+			list_add_tail(&sdev->same_target_siblings,
+				      &device->same_target_siblings);
+			sdev->scsi_level = device->scsi_level;
+			break;
 		}
-		/*
-		 * If there wasn't another lun already configured at this
-		 * target, then default this device to SCSI_2 until we
-		 * know better
-		 */
-		if(!sdev->scsi_level)
-			sdev->scsi_level = SCSI_2;
-		/*
-		 * Add it to the end of the shost->my_devices list.
-		 */
-		list_add_tail(&sdev->siblings, &shost->my_devices);
-		return (sdev);
 	}
-out_bail:
-	printk(ALLOC_FAILURE_MSG, __FUNCTION__);
+
+	/*
+	 * If there wasn't another lun already configured at this
+	 * target, then default this device to SCSI_2 until we
+	 * know better
+	 */
+	if (!sdev->scsi_level)
+		sdev->scsi_level = SCSI_2;
+
+	/*
+	 * Add it to the end of the shost->my_devices list.
+	 */
+	list_add_tail(&sdev->siblings, &shost->my_devices);
+	return sdev;
+
+out_free_queue:
 	if (q && sdev->request_queue) {
 		*q = sdev->request_queue;
 		sdev->request_queue = NULL;
 	} else if (sdev->request_queue)
 		scsi_free_queue(sdev->request_queue);
 
+out_free_dev:
 	kfree(sdev);
+out:
+	printk(ALLOC_FAILURE_MSG, __FUNCTION__);
 	return NULL;
 }
 

                 reply	other threads:[~2003-03-11 19:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030311201227.A986@lst.de \
    --to=hch@lst.de \
    --cc=James.Bottomley@steeleye.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox