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