Skip to content

Commit

Permalink
[SCSI] sd: Fix overflow with big physical blocks
Browse files Browse the repository at this point in the history
The hw_sector_size variable could overflow if a device reported huge
physical blocks.  Switch to the more accurate physical_block_size
terminology and make sure we use an unsigned int to match the range
permitted by READ CAPACITY(16).

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Martin K. Petersen authored and James Bottomley committed Oct 11, 2010
1 parent 3e51d3c commit 526f7c7
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 7 deletions.
13 changes: 7 additions & 6 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1554,7 +1554,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
}

/* Logical blocks per physical block exponent */
sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size;
sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size;

/* Lowest aligned logical block */
alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
Expand All @@ -1567,7 +1567,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
struct request_queue *q = sdp->request_queue;

sdkp->thin_provisioning = 1;
q->limits.discard_granularity = sdkp->hw_sector_size;
q->limits.discard_granularity = sdkp->physical_block_size;
q->limits.max_discard_sectors = 0xffffffff;

if (buffer[14] & 0x40) /* TPRZ */
Expand Down Expand Up @@ -1635,7 +1635,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
}

sdkp->capacity = lba + 1;
sdkp->hw_sector_size = sector_size;
sdkp->physical_block_size = sector_size;
return sector_size;
}

Expand Down Expand Up @@ -1756,10 +1756,10 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
(unsigned long long)sdkp->capacity,
sector_size, cap_str_10, cap_str_2);

if (sdkp->hw_sector_size != sector_size)
if (sdkp->physical_block_size != sector_size)
sd_printk(KERN_NOTICE, sdkp,
"%u-byte physical blocks\n",
sdkp->hw_sector_size);
sdkp->physical_block_size);
}
}

Expand All @@ -1773,7 +1773,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
else if (sector_size == 256)
sdkp->capacity >>= 1;

blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size);
blk_queue_physical_block_size(sdp->request_queue,
sdkp->physical_block_size);
sdkp->device->sector_size = sector_size;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/sd.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct scsi_disk {
atomic_t openers;
sector_t capacity; /* size in 512-byte sectors */
u32 index;
unsigned short hw_sector_size;
unsigned int physical_block_size;
u8 media_present;
u8 write_prot;
u8 protection_type;/* Data Integrity Field */
Expand Down

0 comments on commit 526f7c7

Please sign in to comment.