diff options
author | Roland Dreier <roland@purestorage.com> | 2012-10-31 09:16:45 -0700 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2012-11-16 16:47:06 +0000 |
commit | ca8b38a5d0489f39245404acea9a1524b29d1cbb (patch) | |
tree | 4f302de3c8647bb48605368f76c4687ee9bc848c /drivers | |
parent | c7685e47cf98dbaeaf523b7c235bf251bba1354f (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: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_device.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index f8773aec5965..a0143a097f42 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -835,20 +835,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( |