From 39b1886bc434c31302e204f4f5a12bb90bc9dafc Mon Sep 17 00:00:00 2001 From: Coly Li Date: Apr 13 2024 06:54:00 +0000 Subject: dm-integrity: don't modify bio's immutable bio_vec in integrity_metadata() (git-fixes). --- diff --git a/patches.suse/dm-integrity-don-t-modify-bio-s-immutable-bio_vec-in-b86f.patch b/patches.suse/dm-integrity-don-t-modify-bio-s-immutable-bio_vec-in-b86f.patch new file mode 100644 index 0000000..f98b74d --- /dev/null +++ b/patches.suse/dm-integrity-don-t-modify-bio-s-immutable-bio_vec-in-b86f.patch @@ -0,0 +1,69 @@ +From b86f4b790c998afdbc88fe1aa55cfe89c4068726 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 5 Dec 2023 16:39:16 +0100 +Subject: [PATCH] dm-integrity: don't modify bio's immutable bio_vec in + integrity_metadata() +Git-commit: b86f4b790c998afdbc88fe1aa55cfe89c4068726 +Patch-mainline: v6.7-rc7 +References: git-fixes + +__bio_for_each_segment assumes that the first struct bio_vec argument +doesn't change - it calls "bio_advance_iter_single((bio), &(iter), +(bvl).bv_len)" to advance the iterator. Unfortunately, the dm-integrity +code changes the bio_vec with "bv.bv_len -= pos". When this code path +is taken, the iterator would be out of sync and dm-integrity would +report errors. This happens if the machine is out of memory and +"kmalloc" fails. + +Fix this bug by making a copy of "bv" and changing the copy instead. + +(Coly Li: rebased for Linux 5.14 based SUSE kernel) + +Fixes: 7eada909bfd7 ("dm: add integrity target") +Cc: stable@vger.kernel.org # v4.12+ +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Coly Li + +--- + drivers/md/dm-integrity.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -1769,11 +1769,12 @@ static void integrity_metadata(struct wo + sectors_to_process = dio->range.n_sectors; + + __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { ++ struct bio_vec bv_copy = bv; + unsigned pos; + char *mem, *checksums_ptr; + + again: +- mem = bvec_kmap_local(&bv); ++ mem = bvec_kmap_local(&bv_copy); + pos = 0; + checksums_ptr = checksums; + do { +@@ -1782,7 +1783,7 @@ again: + sectors_to_process -= ic->sectors_per_block; + pos += ic->sectors_per_block << SECTOR_SHIFT; + sector += ic->sectors_per_block; +- } while (pos < bv.bv_len && sectors_to_process && checksums != checksums_onstack); ++ } while (pos < bv_copy.bv_len && sectors_to_process && checksums != checksums_onstack); + kunmap_local(mem); + + r = dm_integrity_rw_tag(ic, checksums, &dio->metadata_block, &dio->metadata_offset, +@@ -1807,9 +1808,9 @@ again: + if (!sectors_to_process) + break; + +- if (unlikely(pos < bv.bv_len)) { +- bv.bv_offset += pos; +- bv.bv_len -= pos; ++ if (unlikely(pos < bv_copy.bv_len)) { ++ bv_copy.bv_offset += pos; ++ bv_copy.bv_len -= pos; + goto again; + } + } diff --git a/series.conf b/series.conf index d173588..0388ccf 100644 --- a/series.conf +++ b/series.conf @@ -45063,6 +45063,7 @@ patches.suse/perf-Fix-perf_event_validate_size-lockdep-splat.patch patches.suse/spi-atmel-Fix-clock-issue-when-using-devices-with-di.patch patches.suse/ring-buffer-Fix-slowpath-of-interrupted-event.patch + patches.suse/dm-integrity-don-t-modify-bio-s-immutable-bio_vec-in-b86f.patch patches.suse/reset-hisilicon-hi6220-fix-Wvoid-pointer-to-enum-cas.patch patches.suse/reset-Fix-crash-when-freeing-non-existent-optional-r.patch patches.suse/bus-ti-sysc-Flush-posted-write-only-after-srst_udela.patch