Re: [PATCH v2] md/raid1: reject out-of-range raid_disks in setup_conf()

From: yu kuai

Date: Thu Nov 05 2026 - 20:45:38 EST


Hi,

在 2026/10/30 12:40, Gowtham S Bhushan 写道:
> mddev->raid_disks can be set from user space with SET_ARRAY_INFO and
> is not bounded before RUN_ARRAY reaches raid1_run(). With a very large
> value, setup_conf() asks the allocator for more than KMALLOC_MAX_SIZE
> when allocating conf->mirrors, and the allocator warns:
>
> WARNING: mm/slub.c:5459 at ___kmalloc_large_node
> setup_conf+0x15d/0x700
> raid1_run+0x109/0x250
> md_run+0x6c3/0xec0
> do_md_run+0x27/0x3b0
> md_ioctl+0x163f/0x1ca0
>
> The array fails to start, but machines running with panic_on_warn
> crash and syzbot keeps reporting it.
>
> Fail early instead. Version 1.x metadata can describe at most 1920
> devices, so use that as the upper bound, and test the sign before the
> value is used. At that limit the allocations that scale with
> raid_disks (conf->mirrors, the r1bio mempool element and the resync
> buffers) stay well below KMALLOC_MAX_SIZE.
>
> Reported-by: syzbot+75f49ec552cc74d9d69b@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=75f49ec552cc74d9d69b
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
>
> Signed-off-by: Gowtham S Bhushan <gowtham398gs@xxxxxxxxx>
> ---
> drivers/md/raid1.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index f0646fb24371..1cfe983167de 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -48,6 +48,13 @@ static void allow_barrier(struct r1conf *conf, sector_t sector_nr);
> static void lower_barrier(struct r1conf *conf, sector_t sector_nr);
> static void raid1_free(struct mddev *mddev, void *priv);
>
> +/*
> + * Version 1.x md metadata keeps a 256-byte header and then 2 bytes per
> + * device in a 4096-byte block, so no array described by it can have more
> + * devices than this. Arrays created through the ioctl alone have no
> + * on-disk limit, so apply the same cap to them.
> + */
> +#define RAID1_MAX_DISKS ((4096 - 256) / 2)
> #define RAID_1_10_NAME "raid1"
> #include "raid1-10.c"
>
> @@ -3051,6 +3058,11 @@ static struct r1conf *setup_conf(struct mddev *mddev)
> size_t r1bio_size;
> int err = -ENOMEM;
>
> + /* raid_disks comes from user space and sizes the allocations below */
> +
> + if (mddev->raid_disks <= 0 || mddev->raid_disks > RAID1_MAX_DISKS)
> + return ERR_PTR(-EINVAL);

There is still the same kmalloc in raid1_reshape().

> +
> conf = kzalloc_obj(struct r1conf);
> if (!conf)
> goto abort;

--
Thanks,
Kuai