scsi_dh: Verify "dev" is a sdev before accessing it.
authorChandra Seetharaman <sekharan@us.ibm.com>
Thu, 17 Jul 2008 00:35:08 +0000 (17:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 17 Jul 2008 00:54:21 +0000 (17:54 -0700)
Before accessing the device data structure in hardware handlers,
make sure it is a indeed a sdev device.

Yinghai Lu <yhlu.kernel@gmail.com> found the bug on Jul 16, 2008,
and later tested/verified the following fix.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/device_handler/scsi_dh_hp_sw.c
drivers/scsi/device_handler/scsi_dh_rdac.c

index ed53f14..f2467e9 100644 (file)
@@ -416,12 +416,17 @@ static int clariion_bus_notify(struct notifier_block *nb,
                                unsigned long action, void *data)
 {
        struct device *dev = data;
-       struct scsi_device *sdev = to_scsi_device(dev);
+       struct scsi_device *sdev;
        struct scsi_dh_data *scsi_dh_data;
        struct clariion_dh_data *h;
        int i, found = 0;
        unsigned long flags;
 
+       if (!scsi_is_sdev_device(dev))
+               return 0;
+
+       sdev = to_scsi_device(dev);
+
        if (action == BUS_NOTIFY_ADD_DEVICE) {
                for (i = 0; clariion_dev_list[i].vendor; i++) {
                        if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
index 12ceab7..ae6be87 100644 (file)
@@ -131,11 +131,16 @@ static int hp_sw_bus_notify(struct notifier_block *nb,
                            unsigned long action, void *data)
 {
        struct device *dev = data;
-       struct scsi_device *sdev = to_scsi_device(dev);
+       struct scsi_device *sdev;
        struct scsi_dh_data *scsi_dh_data;
        int i, found = 0;
        unsigned long flags;
 
+       if (!scsi_is_sdev_device(dev))
+               return 0;
+
+       sdev = to_scsi_device(dev);
+
        if (action == BUS_NOTIFY_ADD_DEVICE) {
                for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
                        if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor,
index 6fff077..fdf34b0 100644 (file)
@@ -608,12 +608,17 @@ static int rdac_bus_notify(struct notifier_block *nb,
                            unsigned long action, void *data)
 {
        struct device *dev = data;
-       struct scsi_device *sdev = to_scsi_device(dev);
+       struct scsi_device *sdev;
        struct scsi_dh_data *scsi_dh_data;
        struct rdac_dh_data *h;
        int i, found = 0;
        unsigned long flags;
 
+       if (!scsi_is_sdev_device(dev))
+               return 0;
+
+       sdev = to_scsi_device(dev);
+
        if (action == BUS_NOTIFY_ADD_DEVICE) {
                for (i = 0; rdac_dev_list[i].vendor; i++) {
                        if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor,