summaryrefslogtreecommitdiff
path: root/drivers/md
AgeCommit message (Collapse)AuthorFilesLines
13 daysdm-verity: make error counter atomicMikulas Patocka2-6/+8
commit 8ec4d9c5a5cf4b61fc087f871465b1f79b393325 upstream. The error counter "v->corrupted_errs" was not atomic, thus it could be subject to race conditions. The call to dm_audit_log_target("max-corrupted-errors") may be skipped due to the races. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Fixes: 65ff5b7ddf05 ("dm verity: add error handling modes for corrupted blocks") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-verity: increase sprintf buffer sizeMikulas Patocka1-1/+1
commit 88dd117c92a142253fb7a17e791773902b3babc6 upstream. The prefix "DM_VERITY_ERR_BLOCK_NR" is 22 chars. Add '=', one digit for type, ',', up to 20 digits for a u64 block number, and a NUL terminator: that's 46 bytes. The buffer is 42 bytes. For block numbers >= 16 decimal digits (devices larger than ~16 EB with 4K blocks), snprintf silently truncates the uevent environment variable. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Fixes: 65ff5b7ddf05 ("dm verity: add error handling modes for corrupted blocks") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-verity: fix a possible NULL pointer dereferenceMikulas Patocka1-1/+1
commit e72b793ae440f6900fb17a4b8518c707b5cd3e17 upstream. Fix a possible NULL pointer dereference dm_verity_loadpin_is_bdev_trusted if the device has no table. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4-6 Fixes: b6c1c5745ccc ("dm: Add verity helpers for LoadPin") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-verity: avoid double increment of &use_bh_wq_enabledMikulas Patocka1-0/+2
commit 72e9ec2fe32b00994f41719cf77423fca67d48b2 upstream. verity_parse_opt_args is called twice, first with the only_modifier_opts, first with only_modifier_opts == true and then with only_modifier_opts == false. Thus, the static branch &use_bh_wq_enabled was incremented twice and the destructor verity_dtr would only decrement it once. Fix tihs bug by only incrementing it on the first call, on the second call, when v->use_bh_wq is true, do nothing. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4-6 Cc: stable@vger.kernel.org Fixes: df326e7a0699 ("dm verity: allow optional args to alter primary args handling") Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-verity: fix buffer overflow in FEC calculationMikulas Patocka2-3/+3
commit 31d6e6c0ba8d5a7bd59660035a089307100c5e8e upstream. There's a buffer overflow in dm-verity-fec: if (neras && *neras <= v->fec->roots) fio->erasures[(*neras)++] = i; This allows *neras to reach roots + 1 (the post-increment pushes it past roots). This value is then passed as no_eras to decode_rs8(). Inside the RS decoder (lib/reed_solomon/decode_rs.c:113-121), the erasure locator polynomial loop writes lambda[j] where j can reach nroots + 1 — one element past the end of lambda[] (which is sized nroots + 1, valid indices 0..nroots). The out-of-bounds write lands on syn[0], corrupting the syndrome buffer. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4-6 Cc: stable@vger.kernel.org Fixes: a739ff3f543a ("dm verity: add support for forward error correction") Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-integrity: don't increment hash_offset twiceMikulas Patocka1-3/+0
commit edf025f083854f80032b73a1aad69a3c90db236f upstream. hash_offset is already incremented in the loop "for (i = 0; i < to_copy; i++, ts--)". Do not increment it again. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Fixes: 84597a44a9d8 ("dm-integrity: dm integrity: add optional discard support") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-integrity: fix a bug if the bio is out of limitsMikulas Patocka1-4/+3
commit 5a266764fadaff8b5c1fe37a186ebf9b09cb953e upstream. If dm_integrity_check_limits fails, the code would exit with DM_MAPIO_KILL. However, the range would be already locked at this point, and it wouldn't be unlocked, resulting in a deadlock. Let's move the limit check up, so that when it exits, no resources are leaked. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Fixes: fb0987682c62 ("dm-integrity: introduce the Inline mode") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-integrity: fix leaking uninitialized kernel memoryMikulas Patocka1-1/+1
commit 7bb03b2b01b814a9fc14afbfc2cbb2cca5b34750 upstream. If hash size is less than device's tuple size, dm-integrity is supposed to zero the remaining space. There was a bug in the code that zeroing didn't work. This commit fixes it. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Fixes: fb0987682c62 ("dm-integrity: introduce the Inline mode") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm_early_create: fix freeing used table on dm_resume failureMikulas Patocka1-1/+1
commit 366665416f20527ff7cad548a32d1ddf23195740 upstream. If dm_resume fails, the kernel attempts to free table with dm_table_destroy, but the table was already instantiated with dm_swap_table. This commit skips the call to dm_table_destroy in this case. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Fixes: 6bbc923dfcf5 ("dm: add support to directly boot to a mapped device") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm: avoid leaking the caller's thread keyring via the table device fileIngo Blechschmidt1-1/+10
commit 981ccd97f7153d310dfa92a534525bbaf46752c2 upstream. The refactoring in commit a28d893eb327 ("md: port block device access to file") accidentally causes the caller's thread keyring to be kept alive long beyond the caller's lifetime. As a result, "cryptsetup luksSuspend" silently fails to wipe the LUKS volume key from memory. In detail: "cryptsetup luksOpen" uses its supposedly ephemeral thread keyring to pass the volume key to the kernel. dm-crypt's crypt_set_keyring_key() copies the key material into its own crypt_config structure and then drops its own reference to the key in the keyring with key_put(). With this fix, restoring pre-v6.9 behavior, the copy in the thread keyring is then promptly garbage collected, such that exactly one copy of the volume key remains. This single copy is correctly wiped from memory on "cryptsetup luksSuspend". Without this fix, the thread keyring and the volume key in it remains. This second copy is only freed on "luksClose". "luksSuspend" neither knows about this copy nor has any way to remove it, so the key remains recoverable from RAM after a suspend that is documented to have wiped it. This fix should not introduce new security problems, as the code is anyway gated by CAP_SYS_ADMIN. The device-mapper core, not the calling task, is the legitimate owner of this long-lived file. Fixes: a28d893eb327 ("md: port block device access to file") Closes: https://gitlab.com/cryptsetup/cryptsetup/-/work_items/993 Link: https://www.speicherleck.de/iblech/cryptsetup-luksSuspend-issue-reproduction/ Signed-off-by: Ingo Blechschmidt <iblech@speicherleck.de> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Tested-by: Ondrej Kozina <okozina@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-stats: fix merge accountingMikulas Patocka1-4/+2
commit 1917eb2db750ecbdf710f79a8042eaa545a063c7 upstream. There were wrong parentheses when setting stats_aux->merged, so that merging was never properly accounted. This commit fixes it. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4-6 Fixes: fd2ed4d25270 ("dm: add statistics support") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-stats: fix dm_jiffies_to_msec64Mikulas Patocka1-2/+2
commit 386df1a57b631c456d14f857cb0c0c2e11c16bef upstream. There were wrong calculations in dm_jiffies_to_msec64 that produced incorrect output when HZ was different from 1000. This commit fixes them. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4-6 Fixes: fd2ed4d25270 ("dm: add statistics support") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-pcache: reject option groups without valuesSamuel Moelius1-0/+8
commit d9c631e3fbd44246a2be781d26cfacbb9b8ec127 upstream. The pcache target parses optional arguments as name/value pairs. A table that advertises one optional argument and supplies only a recognized option name, for example "cache_mode", reaches parse_cache_opts() with argc == 1. The parser consumes the name, decrements argc to zero, then calls dm_shift_arg() again for the value. dm_shift_arg() returns NULL when no arguments remain, and the following strcmp() dereferences that NULL pointer. Check that each recognized option has a value before consuming it. This keeps valid "cache_mode writeback" and "data_crc true/false" tables unchanged while making malformed tables fail during target construction with a precise missing-value error. Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com> Reviewed-by: Zheng Gu <cengku@gmail.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-log: fix a bitset_size overflow on 32bit machinesBenjamin Marzinski1-0/+3
commit 9743132a41f4d9d0e54c5f2adcb821b04796bab1 upstream. Commit c20e36b7631d ("dm log: fix out-of-bounds write due to region_count overflow") made sure that region_count could fit in an unsigned int. But the bitmap memory isn't allocated based on region_count. It uses bitset_size (a size_t variable). The first step of calculating bitset_size is to set it to region_count, rounded up to a multiple of BITS_PER_LONG. If region_size is less than BITS_PER_LONG smaller than UINT_MAX, it will get rounded up to 2^32. On a 32bit architecture, this will make bitset_size wrap around to 0 and fail, despite region_count being valid. Since bitset_size gets divided by 8, it can hold any valid region_count. It just needs a special case to handle the rollover. If it is 0, the value rolled over, and bitset size should be set to the number of bytes needed to hold 2^32 bits. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Fixes: c20e36b7631d ("dm log: fix out-of-bounds write due to region_count overflow") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-ioctl: fix a possible overflow in list_version_get_infoMikulas Patocka1-1/+1
commit 76c6f845dc0c614304a6e6ee619b552f97cf24b3 upstream. sizeof(tt->version) is 12 bytes, but the code writes 16 bytes into the output buffer - info->vers->version[0], info->vers->version[1], info->vers->version[2] and info->vers->next. This can cause buffer overflow. Fix this buffer overflow by replacing "sizeof(tt->version)" with "sizeof(struct dm_target_versions)". Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4.6 Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm-bufio: fix wrong count calculation in dm_bufio_issue_discardMikulas Patocka1-1/+3
commit 422f1d4f141eaa3a6e4199ceec86cc6b9bf26570 upstream. block_to_sector converts a block number to a sector number and adds c->start to the result. It is inappropriate to use this function for converting the number of blocks to a number to sectors because c->start would be incorrectly added to the result. Luckily, the only target that uses dm_bufio_issue_discard is dm-ebs, which sets c->start to 0, so this bug is latent. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Assisted-by: Claude:claude-opus-4-6 Fixes: 6fbeb0048e6b ("dm bufio: implement discard") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm era: fix out-of-bounds memory access for non-zero start sectorSamuel Moelius1-1/+3
commit a868196f03c2b19418ae3d2b69e195d668a271e5 upstream. dm-era tracks writes in target-relative blocks, but era_map() calculates the writeset block before applying the target offset. Tables with a non-zero start sector can therefore pass an absolute mapped-device block to metadata_current_marked(). If the absolute block is beyond the current writeset size, writeset_marked() tests past the end of the in-core bitset. KASAN reports this as a vmalloc-out-of-bounds access. Apply the target offset before calculating the era block so writeset lookups use the target-relative block number. Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com> Reviewed-by: Ming-Hung Tsai <mtsai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Fixes: eec40579d848 ("dm: add era target") Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm thin metadata: fix metadata snapshot consistency on commit failureMing-Hung Tsai1-45/+18
commit 5bcd4d3058ebaf46ad2e163829d87dd4870c7a45 upstream. __reserve_metadata_snap() and __release_metadata_snap() modify the superblock's held_root directly in the block_manager's buffer. If the subsequent metadata commit fails, the held_root gets flushed to disk through the abort_transaction path, resulting in inconsistent metadata. Reproducer 1: __reserve_metadata_snap() 1. Create a 2 MiB metadata device and make the region after the 14th block inaccessible, to trigger metadata commit failure in the subsequent reserve_metadata_snap operation. The 14th block will be the shadow destination for the index block. dmsetup create tmeta --table "0 112 linear /dev/sdc 0 112 3984 error" 2. Create a 16 MiB thin-pool dmsetup create tdata --table "0 32768 zero" dd if=/dev/zero of=/dev/mapper/tmeta bs=4k count=1 dmsetup create tpool --table "0 32768 thin-pool /dev/mapper/tmeta \ /dev/mapper/tdata 128 0 1 skip_block_zeroing" 3. Take a metadata snapshot to trigger metadata commit failure and transaction abort. However, the held_root is written to disk, breaking metadata consistency. dmsetup message tpool 0 "reserve_metadata_snap" thin_check v1.2.2 result: Bad reference count for metadata block 6. Expected 2, but space map contains 1. Bad reference count for metadata block 7. Expected 2, but space map contains 1. Bad reference count for metadata block 13. Expected 1, but space map contains 0. Reproducer 2: __release_metadata_snap() 1. Create a 2 MiB metadata device and make the region after the 16th block inaccessible, to trigger metadata commit failure in the subsequent release_metadata_snap operation. The 16th block will be the shadow destination for the index block. dmsetup create tmeta --table "0 128 linear /dev/sdc 0 128 3968 error" 2. Create a 16 MiB thin-pool dmsetup create tdata --table "0 32768 zero" dd if=/dev/zero of=/dev/mapper/tmeta bs=4k count=1 dmsetup create tpool --table "0 32768 thin-pool /dev/mapper/tmeta \ /dev/mapper/tdata 128 0 1 skip_block_zeroing" 3. Reserve then release the metadata snapshot, to trigger metadata commit failure and transaction abort. The held_root gets removed from the on-disk superblock, causing inconsistent metadata. dmsetup message tpool 0 "reserve_metadata_snap" dmsetup message tpool 0 "release_metadata_snap" thin_check v1.2.2 result: Bad reference count for metadata block 6. Expected 1, but space map contains 2. Bad reference count for metadata block 7. Expected 1, but space map contains 2. 1 metadata blocks have leaked. Fix by deferring the held_root update to commit time. Additionally, move the existing-snapshot check in __reserve_metadata_snap before the shadow operation to avoid unnecessary work. In __release_metadata_snap, clear pmd->held_root before btree deletion so partial failure leaks blocks rather than leaving a stale reference, and unlock the snapshot block before decrementing its refcount. Fixes: 991d9fa02da0 ("dm: add thin provisioning target") Cc: stable@vger.kernel.org Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm thin metadata: fix superblock refcount leak on snapshot shadow failureGenjian Zhang1-1/+3
commit 4b22d0801fadfcae2e106e6ba32e49439c7c7ebf upstream. __reserve_metadata_snap() increments THIN_SUPERBLOCK_LOCATION in the metadata space map before shadowing it. When dm_tm_shadow_block() fails, a reference is leaked in the metadata space map. Fix by adding the missing dm_sm_dec_block(). Signed-off-by: Genjian Zhang <zhanggenjian@kylinos.cn> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Fixes: cc8394d86f04 ("dm thin: provide userspace access to pool metadata") Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 daysdm era: fix NULL pointer dereference in metadata_open()Cao Guanghui1-2/+4
[ Upstream commit 9ae672606c17891d90b282e3490b817620549599 ] metadata_open() returns NULL when kzalloc_obj() fails, but the caller era_ctr() only checks IS_ERR(md). Since IS_ERR(NULL) returns false, the NULL pointer is treated as a valid result and later assigned to era->md, leading to a NULL pointer dereference when the metadata is accessed. Fix this by returning ERR_PTR(-ENOMEM) on allocation failure, consistent with dm-cache-metadata.c, dm-thin-metadata.c, and dm-clone-metadata.c which all use ERR_PTR(-ENOMEM) for the same pattern. Fixes: eec40579d848 ("dm: add era target") Signed-off-by: Cao Guanghui <caoguanghui@kylinos.cn> Reviewed-by: Su Yue <glass.su@suse.com> Reviewed-by: Ming-Hung Tsai <mtsai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid5: avoid R5_Overlap races while breaking stripe batchesChen Cheng1-5/+5
[ Upstream commit 55b77337bdd088c77461588e5ec094421b89911b ] KCSAN report a race in break_stripe_batch_list() vs. raid5_make_request() on sh->dev[i].flags (plain word write vs. atomic bit op).. and .. one possible scenario is: CPU1 CPU2 break_stripe_batch_list(sh1) -> handle sh2 -> lock(sh2) -> sh2->batch_head = NULL -> unlock(sh2) -> test_and_clear_bit(R5_Overlap, sh2->dev[i].flags) -> wake_up_bit(sh2->dev[i].flags) raid5_make_request() -> add_all_stripe_bios(sh2) -> lock(sh2) -> stripe_bio_overlaps(sh2) returns true batch_head is NULL, so new bio overlap exist bio on sh2 -> true -> set_bit(R5_Overlap, sh2->dev[i].flags) -> unlock(sh2) -> wait_on_bit(sh2->dev[i].flags) -> sh2->dev[i].flags = sh1->dev[i].flags & ~R5_Overlap No wait_up_bit(), CPU2 could be wait_on_bit() forever... Fix by : - Expand the protect zone. - Use batch_head's device flag's snaphot when no held head_sh->stripe_lock. - Move sh/head_sh->batch_head = NULL to the end of protected zone , and , any concurrent add_all_stripe_bios() grabs sh->stripe_lock now either: - see batch_head != null, and , is rejected by stripe_bio_overlaps() under the lock (no R5_Overlap wait ) , or , - sees batch_head == NULL, only after dev[i].flags has already been set and the prior R5_Overlap waiters worken. KCSAN report: ================================================ BUG: KCSAN: data-race in break_stripe_batch_list / raid5_make_request write (marked) to 0xffff8e89c8117548 of 8 bytes by task 4042 on cpu 0: raid5_make_request+0xea0/0x2930 md_handle_request+0x4a2/0xa40 md_submit_bio+0x109/0x1a0 __submit_bio+0x2ec/0x390 submit_bio_noacct_nocheck+0x457/0x710 submit_bio_noacct+0x2a7/0xc20 submit_bio+0x56/0x250 blkdev_direct_IO+0x54c/0xda0 blkdev_write_iter+0x38f/0x570 aio_write+0x22b/0x490 io_submit_one+0xa51/0xf70 __x64_sys_io_submit+0xf7/0x220 x64_sys_call+0x1907/0x1c60 do_syscall_64+0x130/0x570 entry_SYSCALL_64_after_hwframe+0x76/0x7e read to 0xffff8e89c8117548 of 8 bytes by task 4010 on cpu 5: break_stripe_batch_list+0x249/0x480 handle_stripe_clean_event+0x720/0x9b0 handle_stripe+0x32fb/0x4500 handle_active_stripes.isra.0+0x6e0/0xa50 raid5d+0x7e0/0xba0 md_thread+0x15a/0x2d0 kthread+0x1e3/0x220 ret_from_fork+0x37a/0x410 ret_from_fork_asm+0x1a/0x30 value changed: 0x0000000000000019 -> 0x0000000000000099 --> R5_Overlap Fixes: fb642b92c267 ("md/raid5: duplicate some more handle_stripe_clean_event code in break_stripe_batch_list") Signed-off-by: Chen Cheng <chencheng@fnnas.com> Link: https://patch.msgid.link/20260619041013.1207148-1-chencheng@fnnas.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid5: use stripe state snapshot in break_stripe_batch_list()Chen Cheng1-19/+26
[ Upstream commit 9b249f5ffbeda24c57e6c56ed896c5ca4fc70549 ] The patch just suppress KCSAN noise. No functional change. RAID-5 can group multi full-stripe-write aka stripe_head into a batch aka batch_list, with one head_sh leading them. Call break_stripe_batch_list() when the batch is finished, or, a stripe has to be dropped out of the batch. break_stripe_batch_list() reads stripe state several times while request paths can update thost state words concurrently with lockless bitops, which reported by KCSAN. Use a snapshot to guarantees that the value used for warning, copying, and handle checks is internally consistent at current read moment. KCSAN report: ============================================== BUG: KCSAN: data-race in __add_stripe_bio / break_stripe_batch_list write (marked) to 0xffff8e89d4f0b988 of 8 bytes by task 4323 on cpu 3: __add_stripe_bio+0x35e/0x400 raid5_make_request+0x6ac/0x2930 md_handle_request+0x4a2/0xa40 md_submit_bio+0x109/0x1a0 __submit_bio+0x2ec/0x390 submit_bio_noacct_nocheck+0x457/0x710 submit_bio_noacct+0x2a7/0xc20 submit_bio+0x56/0x250 blkdev_direct_IO+0x54c/0xda0 blkdev_write_iter+0x38f/0x570 aio_write+0x22b/0x490 io_submit_one+0xa51/0xf70 read to 0xffff8e89d4f0b988 of 8 bytes by task 4290 on cpu 4: break_stripe_batch_list+0x3ce/0x480 handle_stripe_clean_event+0x720/0x9b0 handle_stripe+0x32fb/0x4500 handle_active_stripes.isra.0+0x6e0/0xa50 raid5d+0x7e0/0xba0 Signed-off-by: Chen Cheng <chencheng@fnnas.com> Link: https://patch.msgid.link/20260618134748.1168360-1-chencheng@fnnas.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Stable-dep-of: 55b77337bdd0 ("md/raid5: avoid R5_Overlap races while breaking stripe batches") Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid1: free r1_bio when REQ_NOWAIT is set and read would block on retryAbd-Alrhman Masalkhi1-0/+6
[ Upstream commit 69ad6ce47f9bf2b9fe0ed69b042db993d33bbf12 ] When a read is retried, raid1_read_request() may be called with a pre-allocated r1_bio. If wait_read_barrier() fails for a REQ_NOWAIT read, the bio is completed and the function returns immediately. In this case the existing r1_bio is leaked. This fixes a leak of pre-allocated r1_bio structures for retried reads. Fixes: 5aa705039c4f ("md: raid1 add nowait support") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260611083514.754922-1-abd.masalkhi@gmail.com?part=1 Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://patch.msgid.link/20260611101350.759154-1-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid1: honor REQ_NOWAIT when waiting for behind writesAbd-Alrhman Masalkhi5-12/+24
[ Upstream commit a286cb88ddb26c5f4377859d8e77233d9181eb82 ] raid1 supports REQ_NOWAIT reads by avoiding waits in the barrier path through wait_read_barrier(). However, a read can still block on a WriteMostly device when the array uses a bitmap and there are outstanding behind writes. In that case raid1 unconditionally calls wait_behind_writes(), which may sleep until all behind writes complete. As a result, a REQ_NOWAIT read can block despite the caller explicitly requesting non-blocking behavior. This ensures that raid1 consistently honors REQ_NOWAIT reads across all paths that may otherwise wait for behind writes. Fixes: 5aa705039c4f ("md: raid1 add nowait support") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://patch.msgid.link/20260611083514.754922-1-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid10: fix writes_pending and barrier reference leaks on discard failuresAbd-Alrhman Masalkhi1-0/+5
[ Upstream commit 393d687131d8aa8c7e4de2cb494438e145d20fc2 ] raid10_make_request() acquires a writes_pending reference with md_write_start() before calling raid10_handle_discard(). Several failure paths in raid10_handle_discard() complete the bio and return without releasing the corresponding reference, causing md_write_end() to be skipped. Call md_write_end() before returning from these failure paths to keep writes_pending accounting balanced. Additionally, discard split allocation failures can occur after wait_barrier() succeeds. Those paths return without calling allow_barrier(), leaking the associated barrier reference. Release the barrier before returning from those paths. Fixes: c9aa889b035f ("md: raid10 add nowait support") Fixes: 4cf58d952909 ("md/raid10: Handle bio_split() errors") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://patch.msgid.link/20260613182810.1317258-4-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid10: fix writes_pending leak on write request failuresAbd-Alrhman Masalkhi1-8/+15
[ Upstream commit e045d6ed33f8faa3e3dd6dc33c62ec01e3ad275d ] raid10_make_request() acquires a writes_pending reference with md_write_start() before dispatching write requests. Several failure paths in raid10_write_request() complete the bio and return without reaching the normal write completion path, causing the corresponding md_write_end() to be skipped. Make raid10_write_request() return a status indicating whether the write request was successfully queued. This allows raid10_make_request() to release the writes_pending reference with md_write_end() when a write request fails. Fixes: 4cf58d952909 ("md/raid10: Handle bio_split() errors") Fixes: c9aa889b035f ("md: raid10 add nowait support") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://patch.msgid.link/20260613182810.1317258-3-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid1: fix writes_pending and barrier reference leaks on write failuresAbd-Alrhman Masalkhi1-7/+12
[ Upstream commit 8e065a1602511282fc0da2dc89445e0eb71a681c ] raid1_make_request() acquires a writes_pending reference with md_write_start() before calling raid1_write_request(). Several failure paths in raid1_write_request() complete the bio and return without reaching the normal write completion path, causing the corresponding md_write_end() to be skipped. Make raid1_write_request() return a status indicating whether the write request was successfully queued. This allows raid1_make_request() to call md_write_end() when raid1_write_request() fails. Additionally, if wait_blocked_rdev() fails after wait_barrier() succeeds, the associated barrier reference is not released. Call allow_barrier() before returning from that path to keep the barrier accounting balanced. Fixes: b1a7ad8b5c4f ("md/raid1: Handle bio_split() errors") Fixes: f2a38abf5f1c ("md/raid1: Atomic write support") Fixes: 5aa705039c4f ("md: raid1 add nowait support") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260611083514.754922-1-abd.masalkhi@gmail.com?part=1 Closes: https://sashiko.dev/#/patchset/20260611132500.763528-1-abd.masalkhi@gmail.com?part=1 Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://patch.msgid.link/20260613182810.1317258-2-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysraid1: fix nr_pending leak in REQ_ATOMIC bad-block error pathAbd-Alrhman Masalkhi1-1/+3
[ Upstream commit 909d9dc3b5730c8ed7b764c68bc788342df2a07b ] In raid1_write_request(), each per-mirror loop iteration begins by incrementing rdev->nr_pending. If a REQ_ATOMIC write encounters a badblock within the requested range, the code jumps to err_handle without dropping the reference taken for the current mirror. err_handle's cleanup loop will only decrements for k < i and r1_bio->bios[k] is non-NULL. The current slot is therefore skipped, leaving its nr_pending reference leaked permanently. The reference prevents the rdev from ever being removed, since raid1_remove_conf() refuses to remove an rdev with nr_pending > 0. Fix this by calling rdev_dec_pending() before jumping to err_handle. Fixes: f2a38abf5f1c ("md/raid1: Atomic write support") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://patch.msgid.link/20260530151411.4119-1-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid1,raid10: fix bio accounting for split md cloned biosAbd-Alrhman Masalkhi2-5/+5
[ Upstream commit ba976e3501111d11c550848b3b7341a73035f582 ] Use md_cloned_bio() to control bio accounting instead of relying on r1bio_existed in raid1 or the io_accounting flag in raid10. The previous logic does not reliably reflect whether a bio is an md cloned bio. When a failed bio is split and resubmitted via bio_submit_split_bioset() on the error path, this can lead to either double accounting for md cloned bios, or missing accounting for bios returned from bio_submit_split_bioset() Fix this by using md_cloned_bio() to detect md cloned bios and skip accounting accordingly. Fixes: bb2a9acefaf9 ("md/raid1: switch to use md_account_bio() for io accounting") Fixes: 820455238366 ("md/raid10: switch to use md_account_bio() for io accounting") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Reviewed-by: Xiao Ni <xiao@kernel.org> Link: https://patch.msgid.link/20260501114652.590037-4-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid1,raid10: fix error-path detection with md_cloned_bio()Abd-Alrhman Masalkhi2-9/+24
[ Upstream commit 811545e0926d02a6a0b1a1258bb5544777c164d4 ] Detect the error path using md_cloned_bio() instead of relying on r1_bio in raid1 or r10_bio->read_slot in raid10, which may be NULL or -1 after splitting and resubmitting a failed bio. As a result, the error path may not be recognized and memory allocations can incorrectly use GFP_NOIO instead of (GFP_NOIO | __GFP_HIGH), which can lead to a deadlock under memory pressure. Fixes: 689389a06ce7 ("md/raid1: simplify handle_read_error().") Fixes: 545250f24809 ("md/raid10: simplify handle_read_error()") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Reviewed-by: Xiao Ni <xiao@kernel.org> Link: https://patch.msgid.link/20260501114652.590037-3-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid1,raid10: fix deadlock in read error recovery pathAbd-Alrhman Masalkhi2-9/+21
[ Upstream commit 7b15c24f805339a585cfe7d72f446b7e88b9bcc0 ] raid1d and raid10d may resubmit a split md cloned bio while handling a read error. In this case, resubmitting the bio can lead to a deadlock if the array is suspended before md_handle_request() acquires an active_io reference via percpu_ref_tryget_live(). Since the cloned bio already holds an active_io reference, trying to acquire another reference via percpu_ref_tryget_live() can lead to a deadlock while the array is suspended. Fix this by using percpu_ref_get() for md cloned bios. Fixes: bb2a9acefaf9 ("md/raid1: switch to use md_account_bio() for io accounting") Fixes: 820455238366 ("md/raid10: switch to use md_account_bio() for io accounting") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Reviewed-by: Xiao Ni <xiao@kernel.org> Reviewed-by: Yu Kuai <yukuai@fygo.io> Link: https://patch.msgid.link/20260501114652.590037-2-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysmd/raid10: reset read_slot when reusing r10bio for discardChen Cheng1-0/+1
[ Upstream commit 6b8a26af065ddc93de2aa5c9f0df98dce9723442 ] put_all_bios() always drops devs[i].bio, but it only drops devs[i].repl_bio when r10_bio->read_slot < 0. If discard reuses an r10bio that was previously used for a read, read_slot can still be non-negative, and discard cleanup can skip bio_put() on repl_bio. Reset read_slot to -1 when preparing an r10bio for discard so the replacement bio is always released correctly. Fixes: d30588b2731f ("md/raid10: improve raid10 discard request") Signed-off-by: Chen Cheng <chencheng@fnnas.com> Reviewed-by: Xiao Ni <xiao@kernel.org> Link: https://patch.msgid.link/20260515093019.3436882-1-chencheng@fnnas.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Signed-off-by: Sasha Levin <sashal@kernel.org>
13 daysdm: limit target bio polling to one shotFengnan Chang1-2/+11
[ Upstream commit 5aa0f9231cbacade065cedd8e9b5ebd067231171 ] dm_poll_bio() is the ->poll_bio() callback for a stacked dm device. The caller only knows about the dm queue, so it may decide to do a spinning poll if it thinks a single queue is being polled. Passing those flags unchanged to the mapped clone lets blk_mq_poll() spin on a target queue from inside dm_poll_bio(). With io_uring IOPOLL on a dm-stripe target this can keep a task in dm_poll_bio() -> bio_poll() -> blk_mq_poll() long enough to trigger an RCU CPU stall, before io_uring gets back to io_iopoll_check() and its need_resched() check. Keep dm's ->poll_bio() bounded by forcing one-shot polling for target bios. The caller can invoke dm_poll_bio() again if it wants to keep polling, and it also gets a chance to reap completions or reschedule between passes. Fixes: f22ecf9c14c1 ("blk-mq: delete task running check in blk_hctx_poll()") Signed-off-by: Fengnan Chang <changfengnan@bytedance.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-07-18dm-ioctl: report an error if a device has no tableMikulas Patocka1-1/+4
commit 457e32348d606a77f9b20e25e989734189834c07 upstream. When we send a message to a device that has no table, the return code was not set. The code would return "2", which is not considered a valid return value. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-06-02Merge tag 'for-7.1/dm-fixes-3' of ↵Linus Torvalds1-4/+8
git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm Pull device mapper fix from Mikulas Patocka: - fix race condition in dm-cache-policy-smq * tag 'for-7.1/dm-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm cache policy smq: check allocation under invalidate lock
2026-06-01dm cache policy smq: check allocation under invalidate lockGuangshuo Li1-4/+8
commit 2d1f7b65f5de ("dm cache policy smq: fix missing locks in invalidating cache blocks") added mq->lock around the destructive part of smq_invalidate_mapping(), but left the e->allocated check outside the critical section. That leaves a check-then-act race. Two concurrent invalidators can both observe e->allocated as true before either of them takes mq->lock. The first invalidator that acquires the lock removes the entry from the queues and hash table and then calls free_entry(), which clears e->allocated and puts the entry back on the free list. The second invalidator can then acquire mq->lock and continue with the stale result of the unlocked check. This can corrupt the SMQ queues or hash table by deleting an entry that is no longer on those structures. It can also hit the allocation check in free_entry() when the same entry is freed again. Move the allocation check under mq->lock so the predicate and the destructive operations are serialized by the same lock. Fixes: 2d1f7b65f5de ("dm cache policy smq: fix missing locks in invalidating cache blocks") Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2026-05-25Merge tag 'for-7.1/dm-fixes-2' of ↵Linus Torvalds1-2/+2
git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm Pull device mapper fix from Mikulas Patocka: - fix crashes in dm-vdo if GFP_NOWAIT allocation fails * tag 'for-7.1/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm vdo: use GFP_NOIO for blkdev_issue_zeroout on format path
2026-05-04dm vdo: use GFP_NOIO for blkdev_issue_zeroout on format pathBruce Johnston1-2/+2
GFP_NOWAIT is inappropriate when blkdev_issue_zeroout may sleep and bio_alloc can fail under pressure; use GFP_NOIO for clear_partition and vdo_clear_layout zeroout calls. Signed-off-by: Bruce Johnston <bjohnsto@redhat.com> Signed-off-by: Matthew Sakai <msakai@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Fixes: fc1d43826702 ("dm vdo: save the formatted metadata to disk")
2026-05-01Merge tag 'block-7.1-20260430' of ↵Linus Torvalds9-109/+250
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux Pull block fixes from Jens Axboe: - MD pull request via Yu: - Fix a raid5 UAF on IO across the reshape position - Avoid failing RAID1/RAID10 devices for invalid IO errors - Fix RAID10 divide-by-zero when far_copies is zero - Restore bitmap grow through sysfs - Use mddev_is_dm() instead of open-coding gendisk checks - Use ATTRIBUTE_GROUPS() for md default sysfs attributes - Replace open-coded wait loops with wait_event helpers - NVMe pull request via Keith: - Target data transfer size configuation (Aurelien) - Enable P2P for RDMA (Shivaji Kant) - TCP target updates (Maurizio, Alistair, Chaitanya, Shivam Kumar) - TCP host updates (Alistair, Chaitanya) - Authentication updates (Alistair, Daniel, Chris Leech) - Multipath fixes (John Garry) - New quirks (Alan Cui, Tao Jiang) - Apple driver fix (Fedor Pchelkin) - PCI admin doorbell update fix (Keith) - Properly propagate CDROM read-only state to the block layer * tag 'block-7.1-20260430' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (35 commits) md: use ATTRIBUTE_GROUPS() for md default sysfs attributes md: use mddev_is_dm() instead of open-coding gendisk checks md/raid1: replace wait loop with wait_event_idle() in raid1_write_request() md/md-bitmap: add a none backend for bitmap grow md/md-bitmap: split bitmap sysfs groups md: factor bitmap creation away from sysfs handling md: use mddev_lock_nointr() in mddev_suspend_and_lock_nointr() md: replace wait loop with wait_event() in md_handle_request() md/raid10: fix divide-by-zero in setup_geo() with zero far_copies md/raid1,raid10: don't fail devices for invalid IO errors MAINTAINERS: Add Xiao Ni as md/raid reviewer md/raid5: Fix UAF on IO across the reshape position cdrom, scsi: sr: propagate read-only status to block layer via set_disk_ro() nvme-auth: Hash DH shared secret to create session key nvme-pci: fix missed admin queue sq doorbell write nvme-auth: Include SC_C in RVAL controller hash nvme-tcp: teardown circular locking fixes nvmet-tcp: Don't clear tls_key when freeing sq Revert "nvmet-tcp: Don't free SQ on authentication success" nvme: skip trace completion for host path errors ...
2026-04-28md: use ATTRIBUTE_GROUPS() for md default sysfs attributesAbd-Alrhman Masalkhi1-10/+2
Replace the md_default_group and md_attr_groups with ATTRIBUTE_GROUPS(). Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://lore.kernel.org/linux-raid/20260423101303.48196-4-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md: use mddev_is_dm() instead of open-coding gendisk checksAbd-Alrhman Masalkhi1-2/+2
Replace direct checks on mddev->gendisk with mddev_is_dm() in md_handle_request() and md_run(). Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://lore.kernel.org/linux-raid/20260423101303.48196-3-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md/raid1: replace wait loop with wait_event_idle() in raid1_write_request()Abd-Alrhman Masalkhi1-11/+4
The wait loop is equivalent to wait_event_idle(); use it to improve readability. Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://lore.kernel.org/linux-raid/20260423101303.48196-2-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md/md-bitmap: add a none backend for bitmap growYu Kuai3-16/+137
Add a real none bitmap backend that exposes the common bitmap sysfs group and use it to keep bitmap/location available when an array has no bitmap. Then switch the bitmap location sysfs path to move only between none and the classic bitmap backend, using the no-sysfs bitmap helpers while merging or unmerging the internal bitmap sysfs group. This restores mdadm --grow bitmap addition through bitmap/location. Fixes: fb8cc3b0d9db ("md/md-bitmap: delay registration of bitmap_ops until creating bitmap") Reviewed-by: Su Yue <glass.su@suse.com> Link: https://lore.kernel.org/r/20260425024615.1696892-4-yukuai@fnnas.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md/md-bitmap: split bitmap sysfs groupsYu Kuai4-13/+40
Split the classic bitmap sysfs files into a common bitmap group with the location attribute and a separate internal bitmap group for the remaining files. At the same time, convert bitmap operations from a single sysfs group to a sysfs group array so backends can share part of their sysfs layout while adding backend-specific attributes separately. Switch the bitmap sysfs helpers to use sysfs_update_groups() for the add and update path, and remove groups in reverse order so shared named groups are unmerged before the last group removes the directory. Also make bitmap operation lookup depend only on the currently selected bitmap id matching the installed backend. This prepares the lookup path for a later registered none backend. Reviewed-by: Su Yue <glass.su@suse.com> Link: https://lore.kernel.org/r/20260425024615.1696892-3-yukuai@fnnas.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md: factor bitmap creation away from sysfs handlingYu Kuai1-29/+49
Factor bitmap creation and destruction into helpers that do not touch bitmap sysfs registration. This prepares the bitmap sysfs rework so callers such as the sysfs bitmap location path can create or destroy a bitmap backend without coupling that to sysfs group lifetime management. Reviewed-by: Su Yue <glass.su@suse.com> Link: https://lore.kernel.org/r/20260425024615.1696892-2-yukuai@fnnas.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md: use mddev_lock_nointr() in mddev_suspend_and_lock_nointr()Abd-Alrhman Masalkhi1-1/+1
This keeps mddev locking consistent and ensures that any future changes to locking behavior are done through the wrapper. Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://lore.kernel.org/r/20260415140319.376578-3-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md: replace wait loop with wait_event() in md_handle_request()Abd-Alrhman Masalkhi1-9/+1
The wait loop is equivalent to wait_event() and can be simplified by usaing it for improving readability. Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Link: https://lore.kernel.org/r/20260415140319.376578-2-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md/raid10: fix divide-by-zero in setup_geo() with zero far_copiesJunrui Luo1-0/+2
setup_geo() extracts near_copies (nc) and far_copies (fc) from the user-provided layout parameter without checking for zero. When fc=0 with the "improved" far set layout selected, 'geo->far_set_size = disks / fc' triggers a divide-by-zero. Validate nc and fc immediately after extraction, returning -1 if either is zero. Fixes: 475901aff158 ("MD RAID10: Improve redundancy for 'far' and 'offset' algorithms (part 1)") Cc: stable@vger.kernel.org Signed-off-by: Junrui Luo <moonafterrain@outlook.com> Link: https://lore.kernel.org/linux-raid/SYBPR01MB7881A5E2556806CC1D318582AF232@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md/raid1,raid10: don't fail devices for invalid IO errorsKeith Busch1-1/+6
BLK_STS_INVAL indicates the IO request itself was invalid, not that the device has failed. When raid1 treats this as a device error, it retries on alternate mirrors which fail the same way, eventually exceeding the read error threshold and removing the device from the array. This happens when stacking configurations bypass bio_split_to_limits() in the IO path: dm-raid calls md_handle_request() directly without going through md_submit_bio(), skipping the alignment validation that would otherwise reject invalid bios early. The invalid bio reaches the lower block layers, which fail the bio with BLK_STS_INVAL, and raid1 wrongly interprets this as a device failure. Add BLK_STS_INVAL to raid1_should_handle_error() so that invalid IO errors are propagated back to the caller rather than triggering device removal. This is consistent with the previous kernel behavior when alignment checks were done earlier in the direct-io path. Fixes: 5ff3f74e145adc7 ("block: simplify direct io validity check") Reported-by: Tomáš Trnka <trnka@scm.com> Closes: https://lore.kernel.org/linux-block/2982107.4sosBPzcNG@electra/ Signed-off-by: Keith Busch <kbusch@kernel.org> Tested-by: Tomáš Trnka <trnka@scm.com> Link: https://lore.kernel.org/r/20260416140345.3872265-1-kbusch@meta.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
2026-04-28md/raid5: Fix UAF on IO across the reshape positionBenjamin Marzinski3-25/+14
If make_stripe_request() returns STRIPE_WAIT_RESHAPE, raid5_make_request() will free the cloned bio. But raid5_make_request() can call make_stripe_request() multiple times, writing to the various stripes. If that bio got added to the toread or towrite lists of a stripe disk in an earlier call to make_stripe_request(), then it's not safe to just free the bio if a later part of it is found to cross the reshape position. Doing so can lead to a UAF error, when bio_endio() is called on the bio for the earlier stripes. Instead, raid5_make_request() needs to wait until all parts of the bio have called bio_endio(). To do this, bios that cross the reshape position while the reshape can't make progress are flagged as needing to wait for all parts to complete. When raid5_make_request() has a bio that failed make_stripe_request() with STRIPE_WAIT_RESHAPE, it sets bi->bi_private to a completion struct and waits for completion after ending the bio. When the bio_endio() is called for the last time on a clone bio with bi->bi_private set, it wakes up the waiter. This guarantees that raid5_make_request() doesn't return until the cloned bio needing a retry for io across the reshape boundary is safely cleaned up. There is a simple reproducer available at [1]. Compile the kernel with KASAN for more useful reporting when the error is triggered (this is not necessary to see the bug). [1] https://gist.github.com/bmarzins/e48598824305cf2171289e47d7241fa5 Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Reviewed-by: Xiao Ni <xni@redhat.com> Link: https://lore.kernel.org/r/20260408043548.1695157-1-bmarzins@redhat.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>