Skip to content

Commit 8300d38

Browse files
committed
Merge tag 'for-5.19/dm-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mike Snitzer: "Three fixes for invalid memory accesses discovered by using KASAN while running the lvm2 testsuite's dm-raid tests. Includes changes to MD's raid5.c given the dependency dm-raid has on the MD code" * tag 'for-5.19/dm-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm raid: fix KASAN warning in raid5_add_disks dm raid: fix KASAN warning in raid5_remove_disk dm raid: fix accesses beyond end of raid member array
2 parents 0a35d16 + 617b365 commit 8300d38

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

drivers/md/dm-raid.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,12 +1001,13 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
10011001
static int validate_raid_redundancy(struct raid_set *rs)
10021002
{
10031003
unsigned int i, rebuild_cnt = 0;
1004-
unsigned int rebuilds_per_group = 0, copies;
1004+
unsigned int rebuilds_per_group = 0, copies, raid_disks;
10051005
unsigned int group_size, last_group_start;
10061006

1007-
for (i = 0; i < rs->md.raid_disks; i++)
1008-
if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
1009-
!rs->dev[i].rdev.sb_page)
1007+
for (i = 0; i < rs->raid_disks; i++)
1008+
if (!test_bit(FirstUse, &rs->dev[i].rdev.flags) &&
1009+
((!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
1010+
!rs->dev[i].rdev.sb_page)))
10101011
rebuild_cnt++;
10111012

10121013
switch (rs->md.level) {
@@ -1046,8 +1047,9 @@ static int validate_raid_redundancy(struct raid_set *rs)
10461047
* A A B B C
10471048
* C D D E E
10481049
*/
1050+
raid_disks = min(rs->raid_disks, rs->md.raid_disks);
10491051
if (__is_raid10_near(rs->md.new_layout)) {
1050-
for (i = 0; i < rs->md.raid_disks; i++) {
1052+
for (i = 0; i < raid_disks; i++) {
10511053
if (!(i % copies))
10521054
rebuilds_per_group = 0;
10531055
if ((!rs->dev[i].rdev.sb_page ||
@@ -1070,10 +1072,10 @@ static int validate_raid_redundancy(struct raid_set *rs)
10701072
* results in the need to treat the last (potentially larger)
10711073
* set differently.
10721074
*/
1073-
group_size = (rs->md.raid_disks / copies);
1074-
last_group_start = (rs->md.raid_disks / group_size) - 1;
1075+
group_size = (raid_disks / copies);
1076+
last_group_start = (raid_disks / group_size) - 1;
10751077
last_group_start *= group_size;
1076-
for (i = 0; i < rs->md.raid_disks; i++) {
1078+
for (i = 0; i < raid_disks; i++) {
10771079
if (!(i % copies) && !(i > last_group_start))
10781080
rebuilds_per_group = 0;
10791081
if ((!rs->dev[i].rdev.sb_page ||
@@ -1588,7 +1590,7 @@ static sector_t __rdev_sectors(struct raid_set *rs)
15881590
{
15891591
int i;
15901592

1591-
for (i = 0; i < rs->md.raid_disks; i++) {
1593+
for (i = 0; i < rs->raid_disks; i++) {
15921594
struct md_rdev *rdev = &rs->dev[i].rdev;
15931595

15941596
if (!test_bit(Journal, &rdev->flags) &&
@@ -3766,13 +3768,13 @@ static int raid_iterate_devices(struct dm_target *ti,
37663768
unsigned int i;
37673769
int r = 0;
37683770

3769-
for (i = 0; !r && i < rs->md.raid_disks; i++)
3770-
if (rs->dev[i].data_dev)
3771-
r = fn(ti,
3772-
rs->dev[i].data_dev,
3773-
0, /* No offset on data devs */
3774-
rs->md.dev_sectors,
3775-
data);
3771+
for (i = 0; !r && i < rs->raid_disks; i++) {
3772+
if (rs->dev[i].data_dev) {
3773+
r = fn(ti, rs->dev[i].data_dev,
3774+
0, /* No offset on data devs */
3775+
rs->md.dev_sectors, data);
3776+
}
3777+
}
37763778

37773779
return r;
37783780
}

drivers/md/raid5.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7933,7 +7933,7 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
79337933
int err = 0;
79347934
int number = rdev->raid_disk;
79357935
struct md_rdev __rcu **rdevp;
7936-
struct disk_info *p = conf->disks + number;
7936+
struct disk_info *p;
79377937
struct md_rdev *tmp;
79387938

79397939
print_raid5_conf(conf);
@@ -7952,6 +7952,9 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
79527952
log_exit(conf);
79537953
return 0;
79547954
}
7955+
if (unlikely(number >= conf->pool_size))
7956+
return 0;
7957+
p = conf->disks + number;
79557958
if (rdev == rcu_access_pointer(p->rdev))
79567959
rdevp = &p->rdev;
79577960
else if (rdev == rcu_access_pointer(p->replacement))
@@ -8062,6 +8065,7 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev)
80628065
*/
80638066
if (rdev->saved_raid_disk >= 0 &&
80648067
rdev->saved_raid_disk >= first &&
8068+
rdev->saved_raid_disk <= last &&
80658069
conf->disks[rdev->saved_raid_disk].rdev == NULL)
80668070
first = rdev->saved_raid_disk;
80678071

0 commit comments

Comments
 (0)