summaryrefslogtreecommitdiff
path: root/drivers/target
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2012-10-31 09:16:45 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-17 13:15:55 -0800
commit227ab73196544a25f0c03338c5b49d3fdc1d1e38 (patch)
treeb987a8cbba2a2bdbea7bb2081294fd0206d796d7 /drivers/target
parent506485a3c6d926cc01e6d05088eac94adf1d6ae5 (diff)
target: Avoid integer overflow in se_dev_align_max_sectors()
commit 3e03989b5868acf69a391a424dc71fcd6cc48167 upstream. The expression (max_sectors * block_size) might overflow a u32 (indeed, since iblock sets max_hw_sectors to UINT_MAX, it is guaranteed to overflow and end up with a much-too-small result in many common cases). Fix this by doing an equivalent calculation that doesn't require multiplication. While we're touching this code, avoid splitting a printk format across two lines and use pr_info(...) instead of printk(KERN_INFO ...). Signed-off-by: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_device.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index aa6267746383..4df8022fe3c8 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -826,20 +826,20 @@ int se_dev_check_shutdown(struct se_device *dev)
u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
{
- u32 tmp, aligned_max_sectors;
+ u32 aligned_max_sectors;
+ u32 alignment;
/*
* Limit max_sectors to a PAGE_SIZE aligned value for modern
* transport_allocate_data_tasks() operation.
*/
- tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
- aligned_max_sectors = (tmp / block_size);
- if (max_sectors != aligned_max_sectors) {
- printk(KERN_INFO "Rounding down aligned max_sectors from %u"
- " to %u\n", max_sectors, aligned_max_sectors);
- return aligned_max_sectors;
- }
+ alignment = max(1ul, PAGE_SIZE / block_size);
+ aligned_max_sectors = rounddown(max_sectors, alignment);
+
+ if (max_sectors != aligned_max_sectors)
+ pr_info("Rounding down aligned max_sectors from %u to %u\n",
+ max_sectors, aligned_max_sectors);
- return max_sectors;
+ return aligned_max_sectors;
}
void se_dev_set_default_attribs(