Skip to content

Commit b689dfb

Browse files
martinkpetersengregkh
authored andcommitted
scsi: sd: Fix capacity calculation with 32-bit sector_t
commit 7c856152cb92f8eee2df29ef325a1b1f43161aff upstream. We previously made sure that the reported disk capacity was less than 0xffffffff blocks when the kernel was not compiled with large sector_t support (CONFIG_LBDAF). However, this check assumed that the capacity was reported in units of 512 bytes. Add a sanity check function to ensure that we only enable disks if the entire reported capacity can be expressed in terms of sector_t. Reported-by: Steve Magnani <steve.magnani@digidescorp.com> Cc: Bart Van Assche <Bart.VanAssche@sandisk.com> Reviewed-by: Bart Van Assche <Bart.VanAssche@sandisk.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4489619 commit b689dfb

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

drivers/scsi/sd.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,22 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
20512051

20522052
#define READ_CAPACITY_RETRIES_ON_RESET 10
20532053

2054+
/*
2055+
* Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set
2056+
* and the reported logical block size is bigger than 512 bytes. Note
2057+
* that last_sector is a u64 and therefore logical_to_sectors() is not
2058+
* applicable.
2059+
*/
2060+
static bool sd_addressable_capacity(u64 lba, unsigned int sector_size)
2061+
{
2062+
u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9);
2063+
2064+
if (sizeof(sector_t) == 4 && last_sector > U32_MAX)
2065+
return false;
2066+
2067+
return true;
2068+
}
2069+
20542070
static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
20552071
unsigned char *buffer)
20562072
{
@@ -2116,7 +2132,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
21162132
return -ENODEV;
21172133
}
21182134

2119-
if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) {
2135+
if (!sd_addressable_capacity(lba, sector_size)) {
21202136
sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
21212137
"kernel compiled with support for large block "
21222138
"devices.\n");
@@ -2202,7 +2218,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
22022218
return sector_size;
22032219
}
22042220

2205-
if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
2221+
if (!sd_addressable_capacity(lba, sector_size)) {
22062222
sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
22072223
"kernel compiled with support for large block "
22082224
"devices.\n");

0 commit comments

Comments
 (0)