diff mbox

dm-zoned: Fix overflow when converting zone ID to sectors

Message ID 20170703064458.8091-1-damien.lemoal@wdc.com (mailing list archive)
State Accepted, archived
Delegated to: Mike Snitzer
Headers show

Commit Message

Damien Le Moal July 3, 2017, 6:44 a.m. UTC
A zone ID is a 32 bits unsigned int which can overflow when doing the
bit shifts calculations in dmz_start_sect(). With a 256 MB zone size
drive, the overflow happens for a zone ID >= 8192.
Fix this by casting the zone ID to a sector_t before doing the bit
shift. While at it, similarly fix dmz_start_block().

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 drivers/md/dm-zoned-metadata.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Bart Van Assche July 10, 2017, 4:25 p.m. UTC | #1
On Mon, 2017-07-03 at 15:44 +0900, Damien Le Moal wrote:
> A zone ID is a 32 bits unsigned int which can overflow when doing the
> bit shifts calculations in dmz_start_sect(). With a 256 MB zone size
> drive, the overflow happens for a zone ID >= 8192.

Does the data from this example apply to a sector size of 512 bytes only?
Should this be mentioned in the patch description?

Anyway,

Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>


--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
Damien Le Moal July 11, 2017, 1:52 a.m. UTC | #2
Bart,

On 7/11/17 01:25, Bart Van Assche wrote:
> On Mon, 2017-07-03 at 15:44 +0900, Damien Le Moal wrote:
>> A zone ID is a 32 bits unsigned int which can overflow when doing the
>> bit shifts calculations in dmz_start_sect(). With a 256 MB zone size
>> drive, the overflow happens for a zone ID >= 8192.
> 
> Does the data from this example apply to a sector size of 512 bytes only?
> Should this be mentioned in the patch description?

This is with BIO level 512B sectors addressing unit, which is used even
with 4K LBA drives. So I did not mention it. I should have to be clear.

Best regards.
diff mbox

Patch

diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
index 4618441c..884ff7c 100644
--- a/drivers/md/dm-zoned-metadata.c
+++ b/drivers/md/dm-zoned-metadata.c
@@ -191,12 +191,12 @@  unsigned int dmz_id(struct dmz_metadata *zmd, struct dm_zone *zone)
 
 sector_t dmz_start_sect(struct dmz_metadata *zmd, struct dm_zone *zone)
 {
-	return dmz_id(zmd, zone) << zmd->dev->zone_nr_sectors_shift;
+	return (sector_t)dmz_id(zmd, zone) << zmd->dev->zone_nr_sectors_shift;
 }
 
 sector_t dmz_start_block(struct dmz_metadata *zmd, struct dm_zone *zone)
 {
-	return dmz_id(zmd, zone) << zmd->dev->zone_nr_blocks_shift;
+	return (sector_t)dmz_id(zmd, zone) << zmd->dev->zone_nr_blocks_shift;
 }
 
 unsigned int dmz_nr_chunks(struct dmz_metadata *zmd)