diff options
| author | Yu Kuai <yukuai@fygo.io> | 2026-08-03 03:50:13 +0800 |
|---|---|---|
| committer | Yu Kuai <yukuai@fygo.io> | 2026-08-07 14:43:33 +0800 |
| commit | a41bb2ee1aca486853e84920565e50c15f86fa5d (patch) | |
| tree | d5f68da2d2d3593a54cdc73d7ae103f971f3f453 | |
| parent | dbd21b489ac1afda73de401a446ecad2b53f413c (diff) | |
| download | linux-a41bb2ee1aca486853e84920565e50c15f86fa5d.tar.gz linux-a41bb2ee1aca486853e84920565e50c15f86fa5d.zip | |
md/raid5: reject zero-sector reshape chunks
Sashiko reported that RAID5 can accept a reshape chunk size that becomes
zero sectors. chunk_size_store() stores the sysfs byte value as n >> 9, so
writing a value below 512 bytes sets mddev->new_chunk_sectors to zero.
RAID5 then accepted that pending reshape geometry and raid5_start_reshape()
installed it into conf->chunk_sectors, letting reshape code divide by zero.
Reject zero-sector chunks both in check_reshape(), where normal sysfs
requests are validated, and in raid5_start_reshape(), so assembly/resume
paths also cannot install zero chunk geometry.
Test script: in QEMU, create a plain three-disk RAID5 array with 64K
chunks, write/read back a small pattern, write 1 to
/sys/block/md0/md/chunk_size, add a fourth disk, and run mdadm --grow
--raid-devices=4 --backup-file=... . The script scans dmesg for divide
error/Oops/KASAN signatures.
Bad kernel, eb29914412c3:
echo 1 > /sys/block/md0/md/chunk_size
mdadm --grow /dev/md0 --raid-devices=4 --backup-file=/root/md0-grow.bak
Oops: divide error: 0000 [#1] SMP KASAN NOPTI
RIP: raid5_get_active_stripe+0x863/0xc10
Call Trace:
raid5_sync_request
md_do_sync
md_thread
Kernel panic - not syncing: Fatal exception
Fixed kernel: echo 1 > /sys/block/md0/md/chunk_size bash: echo: write
error: Invalid argument chunk_write_rc=1 grow_rc=skipped RESULT:
REJECTED_ZERO_CHUNK_NO_OOPS
Tested-by: Mykola Marzhan <mykola@meshstor.io>
Link: https://patch.msgid.link/20260802195038.164272-5-yukuai@kernel.org
Signed-off-by: Yu Kuai <yukuai@fygo.io>
| -rw-r--r-- | drivers/md/raid5.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e2c5a7072aca..d128d238e1da 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -8548,6 +8548,8 @@ static int check_reshape(struct mddev *mddev) return 0; /* nothing to do */ if (has_failed(conf)) return -EINVAL; + if (!mddev->new_chunk_sectors) + return -EINVAL; if (mddev->delta_disks < 0 && mddev->reshape_position == MaxSector) { /* We might be able to shrink, but the devices must * be made bigger first. @@ -8591,6 +8593,9 @@ static int raid5_start_reshape(struct mddev *mddev) if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) return -EBUSY; + if (!mddev->new_chunk_sectors) + return -EINVAL; + if (!check_stripe_cache(mddev)) return -ENOSPC; |
