On Wed, Mar 21, 2012 at 4:18 AM, Stefan Gourguis <brockz@xxxxxxxxxxxx> wrote:
> And also my relevant demsg output:
> [ 1936.317399] Rounding down aligned max_sectors from 4294967295 to 8388600
Looks like a bug exposed with hch's change to iblock in c1775c389556:
- limits->max_hw_sectors = queue_max_hw_sectors(q);
- limits->max_sectors = queue_max_sectors(q);
+ limits->max_hw_sectors = UINT_MAX;
+ limits->max_sectors = UINT_MAX;
now the code in target_core_device.c is broken:
u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
{
u32 tmp, aligned_max_sectors;
/*
* Limit max_sectors to a PAGE_SIZE aligned value for modern
* transport_allocate_data_tasks() operation.
*/
tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
--> max_sectors is UINT_MAX, so max_sectors * block_size overflows.
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;
}
return max_sectors;
}
I think the attached patch (compile tested only, sorry...) should fix this.
From 52326b0b4dc09143ed8b79f6137c5bc27e597427 Mon Sep 17 00:00:00 2001
From: Roland Dreier <roland@xxxxxxxxxxxxxxx>
Date: Wed, 21 Mar 2012 10:08:21 -0700
Subject: [PATCH] target: Avoid integer overflow in se_dev_align_max_sectors()
Computing max_sectors * block_size might overflow 32 bits if
max_sectors is big. Fix this by rounding down directly without
needing that intermediate value.
Signed-off-by: Roland Dreier <roland@xxxxxxxxxxxxxxx>
---
drivers/target/target_core_device.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 755035f..67fd6e4 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -827,13 +827,12 @@ 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;
/*
* 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);
+ aligned_max_sectors = rounddown(max_sectors, PAGE_SIZE / 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);
--
1.7.9.1
[Linux SCSI]
[Kernel Newbies]
[Linux SCSI Target Infrastructure]
[Share Photos]
[IDE]
[Security]
[Git]
[Netfilter]
[Bugtraq]
[Photos]
[Yosemite]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Linux ATA RAID]
[Linux IIO]
[Samba]
[Video 4 Linux]
[Device Mapper]
[Linux Resources]