diff options
author | NeilBrown <neilb@suse.de> | 2009-08-03 10:59:56 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2009-08-03 10:59:56 +1000 |
commit | 3673f305faf1bc66ead751344f8262ace851ff44 (patch) | |
tree | 4cbdd23d9af20632678e95b3e8f02ede241a3917 /drivers/md | |
parent | 3a981b03f38dc3b8a69b77cbc679e66c1318a44a (diff) |
md: avoid array overflow with bad v1.x metadata
We trust the 'desc_nr' field in v1.x metadata enough to use it
as an index in an array. This isn't really safe.
So range-check the value first.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index c194955aeca..249b2896d4e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1308,7 +1308,12 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) } if (mddev->level != LEVEL_MULTIPATH) { int role; - role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); + if (rdev->desc_nr < 0 || + rdev->desc_nr >= le32_to_cpu(sb->max_dev)) { + role = 0xffff; + rdev->desc_nr = -1; + } else + role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); switch(role) { case 0xffff: /* spare */ break; |