]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dm-verity: don't crash if panic_on_corruption is not selected
authorMikulas Patocka <mpatocka@redhat.com>
Tue, 29 Oct 2024 11:17:13 +0000 (12:17 +0100)
committerMikulas Patocka <mpatocka@redhat.com>
Mon, 4 Nov 2024 16:39:23 +0000 (17:39 +0100)
If the user sets panic_on_error and doesn't set panic_on_corruption,
dm-verity should not panic on data mismatch. But, currently it panics,
because it treats data mismatch as I/O error.

This commit fixes the logic so that if there is data mismatch and
panic_on_corruption or restart_on_corruption is not selected, the system
won't restart or panic.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Fixes: f811b83879fb ("dm-verity: introduce the options restart_on_error and panic_on_error")
drivers/md/dm-verity-target.c
drivers/md/dm-verity.h

index 7d4d90b4395aee9d48d4a58af9efe94e5de30480..c142ec5458b70fe782e550ae1acfa1e45bd2a210 100644 (file)
@@ -356,9 +356,9 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io,
                else if (verity_handle_err(v,
                                           DM_VERITY_BLOCK_TYPE_METADATA,
                                           hash_block)) {
-                       struct bio *bio =
-                               dm_bio_from_per_bio_data(io,
-                                                        v->ti->per_io_data_size);
+                       struct bio *bio;
+                       io->had_mismatch = true;
+                       bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
                        dm_audit_log_bio(DM_MSG_PREFIX, "verify-metadata", bio,
                                         block, 0);
                        r = -EIO;
@@ -482,6 +482,7 @@ static int verity_handle_data_hash_mismatch(struct dm_verity *v,
                return -EIO; /* Error correction failed; Just return error */
 
        if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, blkno)) {
+               io->had_mismatch = true;
                dm_audit_log_bio(DM_MSG_PREFIX, "verify-data", bio, blkno, 0);
                return -EIO;
        }
@@ -606,6 +607,7 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
 
        if (unlikely(status != BLK_STS_OK) &&
            unlikely(!(bio->bi_opf & REQ_RAHEAD)) &&
+           !io->had_mismatch &&
            !verity_is_system_shutting_down()) {
                if (v->error_mode == DM_VERITY_MODE_PANIC) {
                        panic("dm-verity device has I/O error");
@@ -779,6 +781,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
        io->orig_bi_end_io = bio->bi_end_io;
        io->block = bio->bi_iter.bi_sector >> (v->data_dev_block_bits - SECTOR_SHIFT);
        io->n_blocks = bio->bi_iter.bi_size >> v->data_dev_block_bits;
+       io->had_mismatch = false;
 
        bio->bi_end_io = verity_end_io;
        bio->bi_private = io;
index 6b75159bf835acebb8e2c7c116a3dda0c0b430b7..c996140bda94db1e5ba31a0656d98c896f186639 100644 (file)
@@ -92,6 +92,7 @@ struct dm_verity_io {
        sector_t block;
        unsigned int n_blocks;
        bool in_bh;
+       bool had_mismatch;
 
        struct work_struct work;
        struct work_struct bh_work;