diff options
author | Mike Snitzer <snitzer@redhat.com> | 2021-12-15 18:31:51 +0100 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2021-12-15 20:16:35 +0100 |
commit | 1cef171abd39102dcc862c6bfbf7f954f4f1f66f (patch) | |
tree | fc2b6b5387e4db7c4055e81d01e463ab2864d505 /drivers/md/dm-integrity.c | |
parent | dm btree remove: fix use after free in rebalance_children() (diff) | |
download | linux-1cef171abd39102dcc862c6bfbf7f954f4f1f66f.tar.xz linux-1cef171abd39102dcc862c6bfbf7f954f4f1f66f.zip |
dm integrity: fix data corruption due to improper use of bvec_kmap_local
Commit 25058d1c725c ("dm integrity: use bvec_kmap_local in
__journal_read_write") didn't account for __journal_read_write() later
adding the biovec's bv_offset. As such using bvec_kmap_local() caused
the start of the biovec to be skipped.
Trivial test that illustrates data corruption:
# integritysetup format /dev/pmem0
# integritysetup open /dev/pmem0 integrityroot
# mkfs.xfs /dev/mapper/integrityroot
...
bad magic number
bad magic number
Metadata corruption detected at xfs_sb block 0x0/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0x0/0x1000
releasing dirty buffer (bulk) to free list!
Fix this by using kmap_local_page() instead of bvec_kmap_local() in
__journal_read_write().
Fixes: 25058d1c725c ("dm integrity: use bvec_kmap_local in __journal_read_write")
Reported-by: Tony Asleson <tasleson@redhat.com>
Reviewed-by: Heinz Mauelshagen <heinzm@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-integrity.c')
-rw-r--r-- | drivers/md/dm-integrity.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 6319deccbe09..7af242de3202 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -1963,7 +1963,7 @@ static bool __journal_read_write(struct dm_integrity_io *dio, struct bio *bio, n_sectors -= bv.bv_len >> SECTOR_SHIFT; bio_advance_iter(bio, &bio->bi_iter, bv.bv_len); retry_kmap: - mem = bvec_kmap_local(&bv); + mem = kmap_local_page(bv.bv_page); if (likely(dio->op == REQ_OP_WRITE)) flush_dcache_page(bv.bv_page); |