Skip to content

Commit

Permalink
dm-verity: restart or panic on an I/O error
Browse files Browse the repository at this point in the history
Maxim Suhanov reported that dm-verity doesn't crash if an I/O error
happens. In theory, this could be used to subvert security, because an
attacker can create sectors that return error with the Write Uncorrectable
command. Some programs may misbehave if they have to deal with EIO.

This commit fixes dm-verity, so that if "panic_on_corruption" or
"restart_on_corruption" was specified and an I/O error happens, the
machine will panic or restart.

This commit also changes kernel_restart to emergency_restart -
kernel_restart calls reboot notifiers and these reboot notifiers may wait
for the bio that failed. emergency_restart doesn't call the notifiers.

Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
  • Loading branch information
Mikulas Patocka committed Sep 26, 2024
1 parent 0a92e5c commit e6a3531
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions drivers/md/dm-verity-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,10 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type,
if (v->mode == DM_VERITY_MODE_LOGGING)
return 0;

if (v->mode == DM_VERITY_MODE_RESTART)
kernel_restart("dm-verity device corrupted");
if (v->mode == DM_VERITY_MODE_RESTART) {
pr_emerg("dm-verity device corrupted\n");
emergency_restart();
}

if (v->mode == DM_VERITY_MODE_PANIC)
panic("dm-verity device corrupted");
Expand Down Expand Up @@ -596,6 +598,23 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
if (!static_branch_unlikely(&use_bh_wq_enabled) || !io->in_bh)
verity_fec_finish_io(io);

if (unlikely(status != BLK_STS_OK) &&
unlikely(!(bio->bi_opf & REQ_RAHEAD)) &&
!verity_is_system_shutting_down()) {
if (v->mode == DM_VERITY_MODE_RESTART ||
v->mode == DM_VERITY_MODE_PANIC)
DMERR_LIMIT("%s has error: %s", v->data_dev->name,
blk_status_to_str(status));

if (v->mode == DM_VERITY_MODE_RESTART) {
pr_emerg("dm-verity device corrupted\n");
emergency_restart();
}

if (v->mode == DM_VERITY_MODE_PANIC)
panic("dm-verity device corrupted");
}

bio_endio(bio);
}

Expand Down

0 comments on commit e6a3531

Please sign in to comment.