Skip to content

Commit f8e1ca9

Browse files
author
Mikulas Patocka
committed
dm-integrity: fix a race condition when accessing recalc_sector
There's a race condition when accessing the variable ic->sb->recalc_sector. The function integrity_recalc writes to this variable when it makes some progress and the function dm_integrity_map_continue may read this variable concurrently. One problem is that on 32-bit architectures the 64-bit variable is not read and written atomically - it may be possible to read garbage if read races with write. Another problem is that memory accesses to this variable are not guarded with memory barriers. This commit fixes the race - it moves reading ic->sb->recalc_sector to an earlier place where we hold &ic->endio_wait.lock. Signed-off-by: Mikulas Patocka <[email protected]> Cc: [email protected]
1 parent faada21 commit f8e1ca9

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/md/dm-integrity.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2174,6 +2174,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
21742174
struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io));
21752175
unsigned int journal_section, journal_entry;
21762176
unsigned int journal_read_pos;
2177+
sector_t recalc_sector;
21772178
struct completion read_comp;
21782179
bool discard_retried = false;
21792180
bool need_sync_io = ic->internal_hash && dio->op == REQ_OP_READ;
@@ -2314,6 +2315,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
23142315
goto lock_retry;
23152316
}
23162317
}
2318+
recalc_sector = le64_to_cpu(ic->sb->recalc_sector);
23172319
spin_unlock_irq(&ic->endio_wait.lock);
23182320

23192321
if (unlikely(journal_read_pos != NOT_FOUND)) {
@@ -2368,7 +2370,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
23682370
if (need_sync_io) {
23692371
wait_for_completion_io(&read_comp);
23702372
if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
2371-
dio->range.logical_sector + dio->range.n_sectors > le64_to_cpu(ic->sb->recalc_sector))
2373+
dio->range.logical_sector + dio->range.n_sectors > recalc_sector)
23722374
goto skip_check;
23732375
if (ic->mode == 'B') {
23742376
if (!block_bitmap_op(ic, ic->recalc_bitmap, dio->range.logical_sector,

0 commit comments

Comments
 (0)