md: guard against possible bad array geometry in v1 metadata
authorNeilBrown <neilb@suse.de>
Tue, 4 Mar 2008 22:29:31 +0000 (14:29 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 5 Mar 2008 00:35:17 +0000 (16:35 -0800)
Make sure the data doesn't start before the end of the superblock when the
superblock is at the start of the device.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/md/md.c

index 7da6ec244e15de75184478818b553a66ec59454f..b375de5c1af2bbe4164ab332d528edacf98c58f3 100644 (file)
@@ -1105,7 +1105,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
        bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
        if (rdev->sb_size & bmask)
-               rdev-> sb_size = (rdev->sb_size | bmask)+1;
+               rdev->sb_size = (rdev->sb_size | bmask) + 1;
+
+       if (minor_version
+           && rdev->data_offset < sb_offset + (rdev->sb_size/512))
+               return -EINVAL;
 
        if (sb->level == cpu_to_le32(LEVEL_MULTIPATH))
                rdev->desc_nr = -1;
@@ -1137,7 +1141,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
                else
                        ret = 0;
        }
-       if (minor_version) 
+       if (minor_version)
                rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
        else
                rdev->size = rdev->sb_offset;