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 ed53f14007a2107621441357eb2396b473ec62d1..f2467e936e554ea703c60621d42e3dceeaf6760f 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 12ceab7b366297fee5bad7ada6d3d7143d00fe2f..ae6be87d6a8327d8b523236c0d3aadf1622f63c1 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 6fff077a888d8d69dc128d80f2519dd125a73621..fdf34b0ec6e1770951181d82a314380a27934d50 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,