hfsplus: fix overflow in hfsplus_get_block
authorChristoph Hellwig <hch@tuxera.com>
Wed, 16 Feb 2011 08:34:17 +0000 (09:34 +0100)
committerChristoph Hellwig <hch@lst.de>
Thu, 30 Jun 2011 11:40:58 +0000 (13:40 +0200)
For filesystems larger than 2TB the final sector number passed to
map_bh might overflow the range representable in a 32-bit data type.
Make sure we use a sector_t for it and the arithmetics calculating it.

Signed-off-by: Christoph Hellwig <hch@tuxera.com>
fs/hfsplus/extents.c

index b1991a2a08e09a968c4bd71408fb8698366cd1ca..b9c1a4b5ba89db557c604631c9a8d7f286b1d4d9 100644 (file)
@@ -209,6 +209,7 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
        struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
        int res = -EIO;
        u32 ablock, dblock, mask;
+       sector_t sector;
        int was_dirty = 0;
        int shift;
 
@@ -255,10 +256,12 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
 done:
        dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n",
                inode->i_ino, (long long)iblock, dblock);
+
        mask = (1 << sbi->fs_shift) - 1;
-       map_bh(bh_result, sb,
-               (dblock << sbi->fs_shift) + sbi->blockoffset +
-                       (iblock & mask));
+       sector = ((sector_t)dblock << sbi->fs_shift) +
+                 sbi->blockoffset + (iblock & mask);
+       map_bh(bh_result, sb, sector);
+
        if (create) {
                set_buffer_new(bh_result);
                hip->phys_size += sb->s_blocksize;