Commit 8300d380 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.19/dm-fixes-5' of...

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
parents 0a35d162 617b3658
......@@ -1001,12 +1001,13 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
static int validate_raid_redundancy(struct raid_set *rs)
{
unsigned int i, rebuild_cnt = 0;
unsigned int rebuilds_per_group = 0, copies;
unsigned int rebuilds_per_group = 0, copies, raid_disks;
unsigned int group_size, last_group_start;
for (i = 0; i < rs->md.raid_disks; i++)
if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
!rs->dev[i].rdev.sb_page)
for (i = 0; i < rs->raid_disks; i++)
if (!test_bit(FirstUse, &rs->dev[i].rdev.flags) &&
((!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
!rs->dev[i].rdev.sb_page)))
rebuild_cnt++;
switch (rs->md.level) {
......@@ -1046,8 +1047,9 @@ static int validate_raid_redundancy(struct raid_set *rs)
* A A B B C
* C D D E E
*/
raid_disks = min(rs->raid_disks, rs->md.raid_disks);
if (__is_raid10_near(rs->md.new_layout)) {
for (i = 0; i < rs->md.raid_disks; i++) {
for (i = 0; i < raid_disks; i++) {
if (!(i % copies))
rebuilds_per_group = 0;
if ((!rs->dev[i].rdev.sb_page ||
......@@ -1070,10 +1072,10 @@ static int validate_raid_redundancy(struct raid_set *rs)
* results in the need to treat the last (potentially larger)
* set differently.
*/
group_size = (rs->md.raid_disks / copies);
last_group_start = (rs->md.raid_disks / group_size) - 1;
group_size = (raid_disks / copies);
last_group_start = (raid_disks / group_size) - 1;
last_group_start *= group_size;
for (i = 0; i < rs->md.raid_disks; i++) {
for (i = 0; i < raid_disks; i++) {
if (!(i % copies) && !(i > last_group_start))
rebuilds_per_group = 0;
if ((!rs->dev[i].rdev.sb_page ||
......@@ -1588,7 +1590,7 @@ static sector_t __rdev_sectors(struct raid_set *rs)
{
int i;
for (i = 0; i < rs->md.raid_disks; i++) {
for (i = 0; i < rs->raid_disks; i++) {
struct md_rdev *rdev = &rs->dev[i].rdev;
if (!test_bit(Journal, &rdev->flags) &&
......@@ -3766,13 +3768,13 @@ static int raid_iterate_devices(struct dm_target *ti,
unsigned int i;
int r = 0;
for (i = 0; !r && i < rs->md.raid_disks; i++)
if (rs->dev[i].data_dev)
r = fn(ti,
rs->dev[i].data_dev,
for (i = 0; !r && i < rs->raid_disks; i++) {
if (rs->dev[i].data_dev) {
r = fn(ti, rs->dev[i].data_dev,
0, /* No offset on data devs */
rs->md.dev_sectors,
data);
rs->md.dev_sectors, data);
}
}
return r;
}
......
......@@ -7933,7 +7933,7 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
int err = 0;
int number = rdev->raid_disk;
struct md_rdev __rcu **rdevp;
struct disk_info *p = conf->disks + number;
struct disk_info *p;
struct md_rdev *tmp;
print_raid5_conf(conf);
......@@ -7952,6 +7952,9 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
log_exit(conf);
return 0;
}
if (unlikely(number >= conf->pool_size))
return 0;
p = conf->disks + number;
if (rdev == rcu_access_pointer(p->rdev))
rdevp = &p->rdev;
else if (rdev == rcu_access_pointer(p->replacement))
......@@ -8062,6 +8065,7 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev)
*/
if (rdev->saved_raid_disk >= 0 &&
rdev->saved_raid_disk >= first &&
rdev->saved_raid_disk <= last &&
conf->disks[rdev->saved_raid_disk].rdev == NULL)
first = rdev->saved_raid_disk;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment