From e1ea2351fba3b96b20107b4483b133137f653717 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Jul 2013 15:05:28 -0700 Subject: [SCSI] sd: convert class code to use dev_groups The dev_attrs field of struct class is going away soon, dev_groups should be used instead. This converts the scsi disk class code to use the correct field. It required some functions to be moved around to place the show and store functions next to each other, the old order seemed to make no sense at all. Signed-off-by: Greg Kroah-Hartman Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 149 +++++++++++++++++++++++++++--------------------------- 1 file changed, 75 insertions(+), 74 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 86fcf2c313ad..b58e8f815a00 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -132,8 +132,8 @@ static const char *sd_cache_types[] = { }; static ssize_t -sd_store_cache_type(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +cache_type_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { int i, ct = -1, rcd, wce, sp; struct scsi_disk *sdkp = to_scsi_disk(dev); @@ -199,8 +199,18 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, } static ssize_t -sd_store_manage_start_stop(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +manage_start_stop_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + + return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); +} + +static ssize_t +manage_start_stop_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; @@ -212,10 +222,19 @@ sd_store_manage_start_stop(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RW(manage_start_stop); static ssize_t -sd_store_allow_restart(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); +} + +static ssize_t +allow_restart_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; @@ -230,47 +249,30 @@ sd_store_allow_restart(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RW(allow_restart); static ssize_t -sd_show_cache_type(struct device *dev, struct device_attribute *attr, - char *buf) +cache_type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); int ct = sdkp->RCD + 2*sdkp->WCE; return snprintf(buf, 40, "%s\n", sd_cache_types[ct]); } +static DEVICE_ATTR_RW(cache_type); static ssize_t -sd_show_fua(struct device *dev, struct device_attribute *attr, char *buf) +FUA_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); } +static DEVICE_ATTR_RO(FUA); static ssize_t -sd_show_manage_start_stop(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(dev); - struct scsi_device *sdp = sdkp->device; - - return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); -} - -static ssize_t -sd_show_allow_restart(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(dev); - - return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); -} - -static ssize_t -sd_show_protection_type(struct device *dev, struct device_attribute *attr, - char *buf) +protection_type_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); @@ -278,8 +280,8 @@ sd_show_protection_type(struct device *dev, struct device_attribute *attr, } static ssize_t -sd_store_protection_type(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +protection_type_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); unsigned int val; @@ -298,10 +300,11 @@ sd_store_protection_type(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RW(protection_type); static ssize_t -sd_show_protection_mode(struct device *dev, struct device_attribute *attr, - char *buf) +protection_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; @@ -320,24 +323,26 @@ sd_show_protection_mode(struct device *dev, struct device_attribute *attr, return snprintf(buf, 20, "%s%u\n", dix ? "dix" : "dif", dif); } +static DEVICE_ATTR_RO(protection_mode); static ssize_t -sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, - char *buf) +app_tag_own_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->ATO); } +static DEVICE_ATTR_RO(app_tag_own); static ssize_t -sd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, - char *buf) +thin_provisioning_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->lbpme); } +static DEVICE_ATTR_RO(thin_provisioning); static const char *lbp_mode[] = { [SD_LBP_FULL] = "full", @@ -349,8 +354,8 @@ static const char *lbp_mode[] = { }; static ssize_t -sd_show_provisioning_mode(struct device *dev, struct device_attribute *attr, - char *buf) +provisioning_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); @@ -358,8 +363,8 @@ sd_show_provisioning_mode(struct device *dev, struct device_attribute *attr, } static ssize_t -sd_store_provisioning_mode(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +provisioning_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; @@ -385,10 +390,11 @@ sd_store_provisioning_mode(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RW(provisioning_mode); static ssize_t -sd_show_max_medium_access_timeouts(struct device *dev, - struct device_attribute *attr, char *buf) +max_medium_access_timeouts_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); @@ -396,9 +402,9 @@ sd_show_max_medium_access_timeouts(struct device *dev, } static ssize_t -sd_store_max_medium_access_timeouts(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +max_medium_access_timeouts_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); int err; @@ -410,10 +416,11 @@ sd_store_max_medium_access_timeouts(struct device *dev, return err ? err : count; } +static DEVICE_ATTR_RW(max_medium_access_timeouts); static ssize_t -sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, - char *buf) +max_write_same_blocks_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); @@ -421,8 +428,8 @@ sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, } static ssize_t -sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +max_write_same_blocks_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; @@ -451,35 +458,29 @@ sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, return count; } - -static struct device_attribute sd_disk_attrs[] = { - __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, - sd_store_cache_type), - __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), - __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, - sd_store_allow_restart), - __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, - sd_store_manage_start_stop), - __ATTR(protection_type, S_IRUGO|S_IWUSR, sd_show_protection_type, - sd_store_protection_type), - __ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL), - __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), - __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), - __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, - sd_store_provisioning_mode), - __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, - sd_show_write_same_blocks, sd_store_write_same_blocks), - __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, - sd_show_max_medium_access_timeouts, - sd_store_max_medium_access_timeouts), - __ATTR_NULL, +static DEVICE_ATTR_RW(max_write_same_blocks); + +static struct attribute *sd_disk_attrs[] = { + &dev_attr_cache_type.attr, + &dev_attr_FUA.attr, + &dev_attr_allow_restart.attr, + &dev_attr_manage_start_stop.attr, + &dev_attr_protection_type.attr, + &dev_attr_protection_mode.attr, + &dev_attr_app_tag_own.attr, + &dev_attr_thin_provisioning.attr, + &dev_attr_provisioning_mode.attr, + &dev_attr_max_write_same_blocks.attr, + &dev_attr_max_medium_access_timeouts.attr, + NULL, }; +ATTRIBUTE_GROUPS(sd_disk); static struct class sd_disk_class = { .name = "scsi_disk", .owner = THIS_MODULE, .dev_release = scsi_disk_release, - .dev_attrs = sd_disk_attrs, + .dev_groups = sd_disk_groups, }; static const struct dev_pm_ops sd_pm_ops = { -- cgit v1.2.3 From 984f1733fcee3fbc78d47e26c5096921c5d9946a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 6 Sep 2013 11:49:51 -0400 Subject: [SCSI] sd: Fix potential out-of-bounds access This patch fixes an out-of-bounds error in sd_read_cache_type(), found by Google's AddressSanitizer tool. When the loop ends, we know that "offset" lies beyond the end of the data in the buffer, so no Caching mode page was found. In theory it may be present, but the buffer size is limited to 512 bytes. Signed-off-by: Alan Stern Reported-by: Dmitry Vyukov CC: Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b58e8f815a00..e62d17d41d4e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2420,14 +2420,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) } } - if (modepage == 0x3F) { - sd_printk(KERN_ERR, sdkp, "No Caching mode page " - "present\n"); - goto defaults; - } else if ((buffer[offset] & 0x3f) != modepage) { - sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); - goto defaults; - } + sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n"); + goto defaults; + Page_found: if (modepage == 8) { sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); -- cgit v1.2.3