summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-08-03 02:59:56 +0200
committerNeilBrown <neilb@suse.de>2009-08-03 02:59:56 +0200
commit3673f305faf1bc66ead751344f8262ace851ff44 (patch)
tree4cbdd23d9af20632678e95b3e8f02ede241a3917
parentmd: when a level change reduces the number of devices, remove the excess. (diff)
downloadlinux-3673f305faf1bc66ead751344f8262ace851ff44.tar.xz
linux-3673f305faf1bc66ead751344f8262ace851ff44.zip
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>
-rw-r--r--drivers/md/md.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c194955aecae..249b2896d4ea 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;