diff options
author | Nagendra Singh Tomar <nagendra_tomar@adaptec.com> | 2007-02-02 07:04:56 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-02-02 20:45:41 -0500 |
commit | 017f2e37ae19ccd28e5edd965741fc374194c5dd (patch) | |
tree | 10e7f93abebfc1797ccbb342f6ed38f072dd4092 | |
parent | 91614c054c9ffc26b47a5cb3135113aa0f6e6ff0 (diff) |
[SCSI] sd: udev accessing an uninitialized scsi_disk field results in a crash
sd_probe() calls class_device_add() even before initializing the
sdkp->device variable. class_device_add() eventually results in the user mode
udev program to be called. udev program can read the the allow_restart
attribute of the newly created scsi device. This is resulting in a crash as
the show function for allow_restart (i.e sd_show_allow_restart) returns the
attribute value by reading the sdkp->device->allow_restart variable. As the
sdkp->device is not initialized before calling the user mode hotplug helper,
this results in a crash.
The patch below solves it by calling class_device_add() only after the
necessary fields in the scsi_disk structure are initialized properly.
Signed-off-by: Nagendra Singh Tomar <nagendra_tomar@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/sd.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 978bfc1e0c6a..b781a90d6699 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1647,16 +1647,6 @@ static int sd_probe(struct device *dev) | |||
1647 | if (error) | 1647 | if (error) |
1648 | goto out_put; | 1648 | goto out_put; |
1649 | 1649 | ||
1650 | class_device_initialize(&sdkp->cdev); | ||
1651 | sdkp->cdev.dev = &sdp->sdev_gendev; | ||
1652 | sdkp->cdev.class = &sd_disk_class; | ||
1653 | strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); | ||
1654 | |||
1655 | if (class_device_add(&sdkp->cdev)) | ||
1656 | goto out_put; | ||
1657 | |||
1658 | get_device(&sdp->sdev_gendev); | ||
1659 | |||
1660 | sdkp->device = sdp; | 1650 | sdkp->device = sdp; |
1661 | sdkp->driver = &sd_template; | 1651 | sdkp->driver = &sd_template; |
1662 | sdkp->disk = gd; | 1652 | sdkp->disk = gd; |
@@ -1670,6 +1660,16 @@ static int sd_probe(struct device *dev) | |||
1670 | sdp->timeout = SD_MOD_TIMEOUT; | 1660 | sdp->timeout = SD_MOD_TIMEOUT; |
1671 | } | 1661 | } |
1672 | 1662 | ||
1663 | class_device_initialize(&sdkp->cdev); | ||
1664 | sdkp->cdev.dev = &sdp->sdev_gendev; | ||
1665 | sdkp->cdev.class = &sd_disk_class; | ||
1666 | strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); | ||
1667 | |||
1668 | if (class_device_add(&sdkp->cdev)) | ||
1669 | goto out_put; | ||
1670 | |||
1671 | get_device(&sdp->sdev_gendev); | ||
1672 | |||
1673 | gd->major = sd_major((index & 0xf0) >> 4); | 1673 | gd->major = sd_major((index & 0xf0) >> 4); |
1674 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); | 1674 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); |
1675 | gd->minors = 16; | 1675 | gd->minors = 16; |