Potential overflow of sdkp->capacity

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(Please CC me, I'm not on the list)

Hi folks,

while tracing a problem in an old kernel version regarding a big (3TB)
disk, I suspect I found a potential overflow of the sdkp->capacity
variable when disks with > 512 byte sectors are involved and support for
large block devices is turned off.

I haven't tested this on recent krenel versions, but from looking at the
code in 3.1-rc4, it seems the overflow is still present.

In sd_read_capacity(), the capacity is read from the disk, in sectors.
This is done by  read_capacity_16() or read_capacity_10. Both of these
functions check sizeof(sdkp->capacity) to see if the capacity would fit:

1789         if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
1790                 sd_printk(KERN_ERR, sdkp, "Too big for this kernel.  Use a "
1791                         "kernel compiled with support for large block "
1792                         "devices.\n");
1793                 sdkp->capacity = 0;
1794                 return -EOVERFLOW;
1795         }

Now, at the end of sd_read_capacity, the sdkp->capacity variable is
normalized to 512-byte sectors:

1926         /* Rescale capacity to 512-byte units */
1927         if (sector_size == 4096)
1928                 sdkp->capacity <<= 3;
1929         else if (sector_size == 2048)
1930                 sdkp->capacity <<= 2;
1931         else if (sector_size == 1024)
1932                 sdkp->capacity <<= 1;
1933         else if (sector_size == 256)
1934                 sdkp->capacity >>= 1;


At this rescaling, no check for the size of capacity is done.

My particular case was a 3TB disk, with 732558336 (0x2ba9f400) sectors,
each 4096 bytes big. The 732558336 fits within a 32-bit word, so no
error is produced. Then, the capacity is corrected with by shifting it
three bits, producing 5860466688 (0x15d4fa000), which is one bit too
long to fit into sdkp->capacity, making the capacity incorrect (which in
my 2.6.26 kernel produces "access beyond end of device" errors).

It seems an extra check before scaling the capacity, or when loading the
capacity, is appropriate. I'm not well-versed enough in kernel coding to
provide a proper patch, but I suspect somebody can pick this up from
here.

Gr.

Matthijs

Attachment: signature.asc
Description: Digital signature


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux